Beispiel #1
0
/**
 * Update the current "run" path
 *
 * Return TRUE if the running should be stopped
 */
static bool run_test(void)
{
    int py = p_ptr->py;
    int px = p_ptr->px;

    int prev_dir;
    int new_dir;
    int check_dir = 0;
    int left_dir;
    int right_dir;

    int row, col;
    int i, max, inv;
    int option, option2;


    /* No options yet */
    option = 0;
    option2 = 0;

    /* Where we came from */
    prev_dir = p_ptr->run_old_dir;

    /* Range of newly adjacent grids */
    max = (prev_dir & 0x01) + 1;

    /* Simplistic running for outdoors -NRM- */
    if ((stage_map[p_ptr->stage][STAGE_TYPE] != CAVE)
	&& (stage_map[p_ptr->stage][STAGE_TYPE] != TOWN)) {
	/* Look at every newly adjacent square. */
	for (i = -max; i <= max; i++) {
	    s16b this_o_idx, next_o_idx = 0;


	    /* New direction */
	    new_dir = cycle[chome[prev_dir] + i];

	    /* New location */
	    row = py + ddy[new_dir];
	    col = px + ddx[new_dir];


	    /* Visible monsters abort running */
	    if (cave_m_idx[row][col] > 0) {
		monster_type *m_ptr = &m_list[cave_m_idx[row][col]];

		/* Visible monster */
		if (m_ptr->ml)
		    return (TRUE);
	    }

	    /* Visible objects abort running */
	    for (this_o_idx = cave_o_idx[row][col]; this_o_idx;
		 this_o_idx = next_o_idx) {
		object_type *o_ptr;

		/* Acquire object */
		o_ptr = &o_list[this_o_idx];

		/* Acquire next object */
		next_o_idx = o_ptr->next_o_idx;

		/* Visible object */
		if (o_ptr->marked && !squelch_hide_item(o_ptr))
		    return (TRUE);
	    }
	}

	/* Assume main direction */
	new_dir = p_ptr->run_old_dir;
	row = py + ddy[new_dir];
	col = px + ddx[new_dir];


	/* Step if there's a path in the right direction */
	if ((cave_feat[row][col] == FEAT_FLOOR)
	    || (cave_feat[row][col] == FEAT_INVIS)) {
	    p_ptr->run_cur_dir = new_dir;
	    return (FALSE);
	}

	/* Check to the left */
	left_dir = cycle[chome[prev_dir] - 1];
	row = py + ddy[left_dir];
	col = px + ddx[left_dir];
	if ((cave_feat[row][col] == FEAT_FLOOR)
	    || (cave_feat[row][col] == FEAT_INVIS))
	    option = left_dir;

	/* Check to the right */
	right_dir = cycle[chome[prev_dir] + 1];
	row = py + ddy[right_dir];
	col = px + ddx[right_dir];
	if ((cave_feat[row][col] == FEAT_FLOOR)
	    || (cave_feat[row][col] == FEAT_INVIS))
	    option2 = right_dir;

	/* Stop if it's a fork */
	if (option && option2)
	    return (TRUE);

	/* Otherwise step in the secondary direction */
	if (option) {
	    p_ptr->run_cur_dir = left_dir;
	    return (FALSE);
	} else if (option2) {
	    p_ptr->run_cur_dir = right_dir;
	    return (FALSE);
	}

	/* No paths, so try grass */
	row = py + ddy[new_dir];
	col = px + ddx[new_dir];


	/* Step if there's grass in the right direction */
	if ((cave_feat[row][col] == FEAT_GRASS)
	    || (cave_feat[row][col] == FEAT_GRASS_INVIS)) {
	    p_ptr->run_cur_dir = new_dir;
	    return (FALSE);
	}

	/* Check to the left */
	row = py + ddy[left_dir];
	col = px + ddx[left_dir];
	if ((cave_feat[row][col] == FEAT_GRASS)
	    || (cave_feat[row][col] == FEAT_GRASS_INVIS))
	    option = left_dir;

	/* Check to the right */
	right_dir = cycle[chome[prev_dir] + 1];
	row = py + ddy[right_dir];
	col = px + ddx[right_dir];
	if ((cave_feat[row][col] == FEAT_GRASS)
	    || (cave_feat[row][col] == FEAT_GRASS_INVIS))
	    option2 = right_dir;

	/* Stop if it's a fork */
	if (option && option2)
	    return (TRUE);

	/* Otherwise step in the secondary direction */
	if (option) {
	    p_ptr->run_cur_dir = left_dir;
	    return (FALSE);
	} else if (option2) {
	    p_ptr->run_cur_dir = right_dir;
	    return (FALSE);
	}

    }

    /* Look at every newly adjacent square. */
    for (i = -max; i <= max; i++) {
	s16b this_o_idx, next_o_idx = 0;


	/* New direction */
	new_dir = cycle[chome[prev_dir] + i];

	/* New location */
	row = py + ddy[new_dir];
	col = px + ddx[new_dir];


	/* Visible monsters abort running */
	if (cave_m_idx[row][col] > 0) {
	    monster_type *m_ptr = &m_list[cave_m_idx[row][col]];

	    /* Visible monster */
	    if (m_ptr->ml)
		return (TRUE);
	}

	/* Visible objects abort running */
	for (this_o_idx = cave_o_idx[row][col]; this_o_idx;
	     this_o_idx = next_o_idx) {
	    object_type *o_ptr;

	    /* Acquire object */
	    o_ptr = &o_list[this_o_idx];

	    /* Acquire next object */
	    next_o_idx = o_ptr->next_o_idx;

	    /* Visible object */
	    if (o_ptr->marked)
		return (TRUE);
	}


	/* Assume unknown */
	inv = TRUE;

	/* Check memorized grids */
	if (cave_info[row][col] & (CAVE_MARK)) {
	    bool notice = TRUE;

	    /* Examine the terrain */
	    switch (cave_feat[row][col]) {
		/* Floors */
	    case FEAT_FLOOR:

		/* Invis traps */
	    case FEAT_INVIS:
	    case FEAT_GRASS_INVIS:

		/* Secret doors */
	    case FEAT_SECRET:

		/* Normal veins */
	    case FEAT_MAGMA:
	    case FEAT_QUARTZ:

		/* Hidden treasure */
	    case FEAT_MAGMA_H:
	    case FEAT_QUARTZ_H:

		/* Special passable terrain. */
	    case FEAT_LAVA:
	    case FEAT_WATER:
	    case FEAT_TREE:
	    case FEAT_TREE2:
	    case FEAT_GRASS:
		{
		    /* Ignore */
		    notice = FALSE;

		    /* Done */
		    break;
		}

		/* Walls */
	    case FEAT_WALL_EXTRA:
	    case FEAT_WALL_INNER:
	    case FEAT_WALL_OUTER:
	    case FEAT_WALL_SOLID:
	    case FEAT_PERM_EXTRA:
	    case FEAT_PERM_INNER:
	    case FEAT_PERM_OUTER:
	    case FEAT_PERM_SOLID:
		{
		    /* Ignore */
		    notice = FALSE;

		    /* Done */
		    break;
		}

		/* Open doors */
	    case FEAT_OPEN:
	    case FEAT_BROKEN:
		{
		    /* Option -- ignore */
		    if (OPT(run_ignore_doors))
			notice = FALSE;

		    /* Done */
		    break;
		}

		/* Stairs */
	    case FEAT_LESS:
	    case FEAT_MORE:
		{
		    /* Option -- ignore */
		    if (OPT(run_ignore_stairs))
			notice = FALSE;

		    /* Done */
		    break;
		}
	    }

	    /* Interesting feature */
	    if (notice)
		return (TRUE);

	    /* The grid is "visible" */
	    inv = FALSE;
	}

	/* Analyze unknown grids and floors */
	if (inv || cave_floor_bold(row, col)) {
	    /* Looking for open area */
	    if (p_ptr->run_open_area) {
		/* Nothing */
	    }

	    /* The first new direction. */
	    else if (!option) {
		option = new_dir;
	    }

	    /* Three new directions. Stop running. */
	    else if (option2) {
		return (TRUE);
	    }

	    /* Two non-adjacent new directions.  Stop running. */
	    else if (option != cycle[chome[prev_dir] + i - 1]) {
		return (TRUE);
	    }

	    /* Two new (adjacent) directions (case 1) */
	    else if (new_dir & 0x01) {
		check_dir = cycle[chome[prev_dir] + i - 2];
		option2 = new_dir;
	    }

	    /* Two new (adjacent) directions (case 2) */
	    else {
		check_dir = cycle[chome[prev_dir] + i + 1];
		option2 = option;
		option = new_dir;
	    }
	}

	/* Obstacle, while looking for open area */
	else {
	    if (p_ptr->run_open_area) {
		if (i < 0) {
		    /* Break to the right */
		    p_ptr->run_break_right = TRUE;
		}

		else if (i > 0) {
		    /* Break to the left */
		    p_ptr->run_break_left = TRUE;
		}
	    }
	}
    }


    /* Looking for open area */
    if (p_ptr->run_open_area) {
	/* Hack -- look again */
	for (i = -max; i < 0; i++) {
	    new_dir = cycle[chome[prev_dir] + i];

	    row = py + ddy[new_dir];
	    col = px + ddx[new_dir];

	    /* Unknown grid or non-wall */
	    /* Was: cave_floor_bold(row, col) */
	    if (!(cave_info[row][col] & (CAVE_MARK))
		|| (cave_feat[row][col] < FEAT_SECRET)
		|| (cave_feat[row][col] > FEAT_SHOP_HEAD)) {
		/* Looking to break right */
		if (p_ptr->run_break_right) {
		    return (TRUE);
		}
	    }

	    /* Obstacle */
	    else {
		/* Looking to break left */
		if (p_ptr->run_break_left) {
		    return (TRUE);
		}
	    }
	}

	/* Hack -- look again */
	for (i = max; i > 0; i--) {
	    new_dir = cycle[chome[prev_dir] + i];

	    row = py + ddy[new_dir];
	    col = px + ddx[new_dir];

	    /* Unknown grid or non-wall */
	    /* Was: cave_floor_bold(row, col) */
	    if (!(cave_info[row][col] & (CAVE_MARK))
		|| (cave_feat[row][col] < FEAT_SECRET)
		|| (cave_feat[row][col] > FEAT_SHOP_HEAD)) {
		/* Looking to break left */
		if (p_ptr->run_break_left) {
		    return (TRUE);
		}
	    }

	    /* Obstacle */
	    else {
		/* Looking to break right */
		if (p_ptr->run_break_right) {
		    return (TRUE);
		}
	    }
	}
    }


    /* Not looking for open area */
    else {
	/* No options */
	if (!option) {
	    return (TRUE);
	}

	/* One option */
	else if (!option2) {
	    /* Primary option */
	    p_ptr->run_cur_dir = option;

	    /* No other options */
	    p_ptr->run_old_dir = option;
	}

	/* Two options, examining corners */
	else if (OPT(run_use_corners) && !OPT(run_cut_corners)) {
	    /* Primary option */
	    p_ptr->run_cur_dir = option;

	    /* Hack -- allow curving */
	    p_ptr->run_old_dir = option2;
	}

	/* Two options, pick one */
	else {
	    /* Get next location */
	    row = py + ddy[option];
	    col = px + ddx[option];

	    /* Don't see that it is closed off. */
	    /* This could be a potential corner or an intersection. */
	    if (!see_wall(option, row, col) || !see_wall(check_dir, row, col)) {
		/* Can not see anything ahead and in the direction we */
		/* are turning, assume that it is a potential corner. */
		if (OPT(run_use_corners) && see_nothing(option, row, col)
		    && see_nothing(option2, row, col)) {
		    p_ptr->run_cur_dir = option;
		    p_ptr->run_old_dir = option2;
		}

		/* STOP: we are next to an intersection or a room */
		else {
		    return (TRUE);
		}
	    }

	    /* This corner is seen to be enclosed; we cut the corner. */
	    else if (OPT(run_cut_corners)) {
		p_ptr->run_cur_dir = option2;
		p_ptr->run_old_dir = option2;
	    }

	    /* This corner is seen to be enclosed, and we */
	    /* deliberately go the long way. */
	    else {
		p_ptr->run_cur_dir = option;
		p_ptr->run_old_dir = option2;
	    }
	}
    }


    /* About to hit a known wall, stop */
    if (see_wall(p_ptr->run_cur_dir, py, px)) {
	return (TRUE);
    }


    /* Failure */
    return (FALSE);
}
/*
 * Update the current "run" path
 *
 * Return TRUE if the running should be stopped
 */
static bool run_test(void)
{
	int fy = m_ptr->fy;
	int fx = m_ptr->fx;

	int prev_dir;
	int new_dir;
	int check_dir = 0;

	int row, col;
	int i, max;
	int option, option2;

	int feat;

	bool notice;

	/* No options yet */
	option = 0;
	option2 = 0;

	/* Where we came from */
	prev_dir = m_ptr->run_old_dir;


	/* Range of newly adjacent grids */
	max = (prev_dir & 0x01) + 1;


	/* Look at every newly adjacent square. */
	for (i = -max; i <= max; i++)
	{
		s16b this_o_idx, next_o_idx = 0;


		/* New direction */
		new_dir = cycle[chome[prev_dir] + i];

		/* New location */
		row = fy + ddy[new_dir];
		col = fx + ddx[new_dir];


		/* Visible monsters abort running */
		if (cave_m_idx[row][col] > 0)
		{
			return (TRUE);
		}

		/* Analyze unknown grids and floors */
		if (cave_floor_bold(row, col))
		{
			/* Looking for open area */
			if (m_ptr->mflag & (MFLAG_RUN_OPEN_AREA))
			{
				/* Nothing */
			}

			/* The first new direction. */
			else if (!option)
			{
				option = new_dir;
			}

			/* Three new directions. Stop running. */
			else if (option2)
			{
				return (TRUE);
			}

			/* Two non-adjacent new directions.  Stop running. */
			else if (option != cycle[chome[prev_dir] + i - 1])
			{
				return (TRUE);
			}

			/* Two new (adjacent) directions (case 1) */
			else if (new_dir & 0x01)
			{
				check_dir = cycle[chome[prev_dir] + i - 2];
				option2 = new_dir;
			}

			/* Two new (adjacent) directions (case 2) */
			else
			{
				check_dir = cycle[chome[prev_dir] + i + 1];
				option2 = option;
				option = new_dir;
			}
		}

		/* Obstacle, while looking for open area */
		else
		{
			if (m_ptr->mflag & (MFLAG_RUN_OPEN_AREA))
			{
				if (i < 0)
				{
					/* Break to the right */
					m_ptr->mflag |= MFLAG_RUN_BREAK_RIGHT;
				}

				else if (i > 0)
				{
					/* Break to the left */
					m_ptr->mflag |= MFLAG_RUN_BREAK_LEFT;
				}
			}
		}
	}


	/* Looking for open area */
	if (m_ptr->mflag & (MFLAG_RUN_OPEN_AREA)run_open_area)
	{
		/* Hack -- look again */
		for (i = -max; i < 0; i++)
		{
			new_dir = cycle[chome[prev_dir] + i];

			row = fy + ddy[new_dir];
			col = fx + ddx[new_dir];

			/* Get feature */
			feat = cave_feat[row][col];

			/* Get mimiced feature */
			feat = f_info[feat].mimic;

			/* Unknown grid or non-wall */
			/* Was: cave_floor_bold(row, col) */
			if (!(cave_info[row][col] & (CAVE_MARK)) ||
			    (!(f_info[feat].flags1 & (FF1_WALL))) )
			{
				/* Looking to break right */
				if ((m_ptr->mflag & (MFLAG_RUN_BREAK_RIGHT)))
				{
					return (TRUE);
				}
			}


			/* Obstacle */
			else
			{
				/* Looking to break left */
				if ((m_ptr->mflag & (MFLAG_RUN_BREAK_LEFT)))
				{
					return (TRUE);
				}
			}
		}

		/* Hack -- look again */
		for (i = max; i > 0; i--)
		{
			new_dir = cycle[chome[prev_dir] + i];

			row = fy + ddy[new_dir];
			col = fx + ddx[new_dir];

			/* Get feature */
			feat = cave_feat[row][col];

			/* Get mimiced feature */
			feat = f_info[feat].mimic;

			/* Unknown grid or non-wall */
			/* Was: cave_floor_bold(row, col) */
			if (!(cave_info[row][col] & (CAVE_MARK)) ||
			    (!(f_info[feat].flags1 & (FF1_WALL))))
			{
				/* Looking to break left */
				if ((m_ptr->mflag & (MFLAG_RUN_BREAK_LEFT)))
				{
					return (TRUE);
				}
			}

			/* Obstacle */
			else
			{
				/* Looking to break right */
				if ((m_ptr->mflag & (MFLAG_RUN_BREAK_RIGHT)))
				{
					return (TRUE);
				}
			}
		}
	}


	/* Not looking for open area */
	else
	{
		/* No options */
		if (!option)
		{
			return (TRUE);
		}

		/* One option */
		else if (!option2)
		{
			/* Primary option */
			m_ptr->run_cur_dir = option;

			/* No other options */
			m_ptr->run_old_dir = option;
		}

		/* Two options, examining corners */
		else if (run_use_corners && !run_cut_corners)
		{
			/* Primary option */
			m_ptr->run_cur_dir = option;

			/* Hack -- allow curving */
			m_ptr->run_old_dir = option2;
		}

		/* Two options, pick one */
		else
		{
			/* Get next location */
			row = fy + ddy[option];
			col = fx + ddx[option];

			/* Don't see that it is closed off. */
			/* This could be a potential corner or an intersection. */
			if (!see_wall(option, row, col) ||
			    !see_wall(check_dir, row, col))
			{
				/* Can not see anything ahead and in the direction we */
				/* are turning, assume that it is a potential corner. */
				if (run_use_corners &&
				    see_nothing(option, row, col) &&
				    see_nothing(option2, row, col))
				{
					m_ptr->run_cur_dir = option;
					m_ptr->run_old_dir = option2;
				}

				/* STOP: we are next to an intersection or a room */
				else
				{
					return (TRUE);
				}
			}

			/* This corner is seen to be enclosed; we cut the corner. */
			else if (run_cut_corners)
			{
				m_ptr->run_cur_dir = option2;
				m_ptr->run_old_dir = option2;
			}

			/* This corner is seen to be enclosed, and we */
			/* deliberately go the long way. */
			else
			{
				m_ptr->run_cur_dir = option;
				m_ptr->run_old_dir = option2;
			}
		}
	}


	/* About to hit a known wall, stop */
	if (see_wall(m_ptr->run_cur_dir, fy, fx))
	{
		return (TRUE);
	}


	/* Failure */
	return (FALSE);
}