コード例 #1
0
ファイル: wizard.c プロジェクト: NickMcConnell/RePosBand
/*
 * Hack -- quick debugging hook
 */
static void do_cmd_wiz_hack_ben(void)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int i, y, x;


	for (i = 0; i < MONSTER_FLOW_DEPTH; ++i)
	{
		/* Update map */
		for (y = Term->offset_y; y < Term->offset_y + SCREEN_HGT; y++)
		{
			for (x = Term->offset_x; x < Term->offset_x + SCREEN_WID; x++)
			{
				byte a = TERM_RED;

				if (!in_bounds_fully(y, x)) continue;

				/* Display proper cost */
				if (cave_cost[y][x] != i) continue;

				/* Reliability in yellow */
				if (cave_when[y][x] == cave_when[py][px])
				{
					a = TERM_YELLOW;
				}

				/* Display player/floors/walls */
				if ((y == py) && (x == px))
				{
					print_rel('@', a, y, x);
				}
				else if (cave_floor_bold(y, x))
				{
					print_rel('*', a, y, x);
				}
				else
				{
					print_rel('#', a, y, x);
				}
			}
		}

		/* Prompt */
		prt(format("Depth %d: ", i), 0, 0);

		/* Get key */
		if (inkey() == ESCAPE) break;

		/* Redraw map */
		prt_map();
	}

	/* Done */
	prt("", 0, 0);

	/* Redraw map */
	prt_map();
}
コード例 #2
0
ファイル: cmd2.c プロジェクト: NickMcConnell/RePosBand
/*
 * Determine if a given grid may be "tunneled"
 */
static bool do_cmd_tunnel_test(int y, int x)
{
	/* Must have knowledge */
	if (!(cave_info[y][x] & (CAVE_MARK)))
	{
		/* Message */
		msg_print("You see nothing there.");

		/* Nope */
		return (FALSE);
	}

	/* Must be a wall/door/etc */
	if (cave_floor_bold(y, x))
	{
		/* Message */
		msg_print("You see nothing there to tunnel.");

		/* Nope */
		return (FALSE);
	}

	/* Okay */
	return (TRUE);
}
コード例 #3
0
ファイル: pathfind.c プロジェクト: EpicMan/angband
static bool is_valid_pf(int y, int x)
{
	/* Unvisited means allowed */
	if (!(cave_info[y][x] & (CAVE_MARK))) return (TRUE);

	/* Require open space */
	return (cave_floor_bold(y, x));
}
コード例 #4
0
ファイル: cmd2.c プロジェクト: CJNyfalt/angband
/*
 * Determine if a given grid may be "walked"
 */
static bool do_cmd_walk_test(int y, int x)
{

	int m_idx = cave->m_idx[y][x];
	
	/* Allow attack on visible monsters if unafraid */
	if ((m_idx > 0) && (cave_monster(cave, m_idx)->ml) && !is_mimicking(m_idx))
	{
		/* Handle player fear */
		if(check_state(p_ptr, OF_AFRAID, p_ptr->state.flags))
		{
			/* Extract monster name (or "it") */
			char m_name[80];
			const monster_type *m_ptr;

			m_ptr = cave_monster(cave, m_idx);
			monster_desc(m_name, sizeof(m_name), m_ptr, 0);

			/* Message */
			msgt(MSG_AFRAID,
				"You are too afraid to attack %s!", m_name);

			/* Nope */
			return (FALSE);
		}
		
		return (TRUE);
	}

	/* If we don't know the grid, allow attempts to walk into it */
	if (!(cave->info[y][x] & CAVE_MARK))
		return TRUE;

	/* Require open space */
	if (!cave_floor_bold(y, x))
	{
		/* Rubble */
		if (cave->feat[y][x] == FEAT_RUBBLE)
			msgt(MSG_HITWALL, "There is a pile of rubble in the way!");

		/* Door */
		else if (cave->feat[y][x] < FEAT_SECRET)
			return TRUE;

		/* Wall */
		else
			msgt(MSG_HITWALL, "There is a wall in the way!");

		/* Cancel repeat */
		disturb(p_ptr, 0, 0);

		/* Nope */
		return (FALSE);
	}

	/* Okay */
	return (TRUE);
}
コード例 #5
0
ファイル: pathfind.c プロジェクト: mangband/mangband
static bool is_valid_pf(player_type *p_ptr, int y, int x)
{
	int Ind = Get_Ind[p_ptr->conn];
	int Depth = p_ptr->dun_depth;
	/* Unvisited means allowed */
	if (!(p_ptr->cave_flag[y][x] & (CAVE_MARK))) return (TRUE);

	/* Require open space */
	return (cave_floor_bold(Depth, y, x));
}
コード例 #6
0
ファイル: cmd2.c プロジェクト: NickMcConnell/RePosBand
/*
 * Determine if a given grid may be "walked"
 */
static bool do_cmd_walk_test(int y, int x)
{
	/* Allow attack on visible monsters if unafraid */
	if ((cave_m_idx[y][x] > 0) && (mon_list[cave_m_idx[y][x]].ml))
	{
		/* Handle player fear */
		if(p_ptr->state.afraid)
		{
			/* Extract monster name (or "it") */
			char m_name[80];
			monster_type *m_ptr;

			m_ptr = &mon_list[cave_m_idx[y][x]];
			monster_desc(m_name, sizeof(m_name), m_ptr, 0);

			/* Message */
			message_format(MSG_AFRAID, 0,
				"You are too afraid to attack %s!", m_name);

			/* Nope */
			return (FALSE);
		}
		
		return (TRUE);
	}

	/* If we don't know the grid, allow attempts to walk into it */
	if (!(cave_info[y][x] & CAVE_MARK))
		return TRUE;

	/* Require open space or PASS_WALL/KILL_WALL flag -Simon */
	if (!cave_floor_bold(y, x) && !(player_has(PF_PASS_WALL) || player_has(PF_KILL_WALL)))
	{			
		/* Rubble */
		if (cave_feat[y][x] == FEAT_RUBBLE)
			message(MSG_HITWALL, 0, "There is a pile of rubble in the way!");
		
		/* Door */
		else if (cave_feat[y][x] < FEAT_SECRET)
			return TRUE;

		/* Wall */
		else
			message(MSG_HITWALL, 0, "There is a wall in the way!");

		/* Cancel repeat */
		disturb(0, 0);

		/* Nope */
		return (FALSE);
	}

	/* Okay */
	return (TRUE);
}
コード例 #7
0
ファイル: cmd2.c プロジェクト: CJNyfalt/Oangband
/*
 * Tunnel through wall.   Assumes valid location.
 *
 * Note that it is impossible to "extend" rooms past their
 * outer walls (which are actually part of the room).
 *
 * Attempting to do so will produce floor grids which are not part
 * of the room, and whose "illumination" status do not change with
 * the rest of the room.
 */
static bool twall(int y, int x)
{
	/* Paranoia -- Require a wall or door or some such */
	if (cave_floor_bold(y, x) && (cave_feat[y][x] == FEAT_TREE)) return (FALSE);

	/* Sound */
	sound(SOUND_DIG);

	/* Forget the wall */
	cave_info[y][x] &= ~(CAVE_MARK);

	/* Remove the feature */
	cave_set_feat(y, x, FEAT_FLOOR);

	/* Update the visuals */
	p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS);

	/* Result */
	return (TRUE);
}
コード例 #8
0
ファイル: monster3.c プロジェクト: jcubic/ToME
/* Player and monster swap places */
bool player_monster_swap(monster_type *m_ptr)
{
	char m_name[80];
	cave_type *c_ptr;

	if (!m_ptr) return FALSE;

	if (has_flag(m_ptr, FLAG_NO_PUSHBACK)) return FALSE;

	c_ptr = &cave[m_ptr->fy][m_ptr->fx];

	m_ptr->csleep = 0;

	/* Extract monster name (or "it") */
	monster_desc(m_name, m_ptr, 0);

	/* Auto-Recall if possible and visible */
	if (m_ptr->ml) monster_race_track(m_ptr->r_idx, m_ptr->ego);

	/* Track a new monster */
	if (m_ptr->ml) health_track(c_ptr->m_idx);

	/* displace? */
	if (cave_floor_bold(p_ptr->py, p_ptr->px) ||
		monst_can_pass_square(m_ptr, p_ptr->py, p_ptr->px, NULL))
	{
		msg_format("You push past %s.", m_name);
		m_ptr->fy = p_ptr->py;
		m_ptr->fx = p_ptr->px;
		cave[p_ptr->py][p_ptr->px].m_idx = c_ptr->m_idx;
		c_ptr->m_idx = 0;
		update_mon(cave[p_ptr->py][p_ptr->px].m_idx, TRUE);
		return TRUE;
	}
	else
	{
		msg_format("%^s is in your way!", m_name);
		energy_use = 0;
		return FALSE;
	}
}
コード例 #9
0
ファイル: pathfind.c プロジェクト: artes-liberales/FAangband
/**
 * 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);
}
コード例 #10
0
/*
 * 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);
}
コード例 #11
0
ファイル: wizard.c プロジェクト: mtadd/angband
/*
 * Query the dungeon
 */
static void do_cmd_wiz_query(void)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int y, x;

	struct keypress cmd;

	u16b mask = 0x00;


	/* Get a "debug command" */
	if (!get_com("Debug Command Query: ", &cmd)) return;

	/* Extract a flag */
	switch (cmd.code)
	{
		case '0': mask = (1 << 0); break;
		case '1': mask = (1 << 1); break;
		case '2': mask = (1 << 2); break;
		case '3': mask = (1 << 3); break;
		case '4': mask = (1 << 4); break;
		case '5': mask = (1 << 5); break;
		case '6': mask = (1 << 6); break;
		case '7': mask = (1 << 7); break;

		case 'm': mask |= (CAVE_MARK); break;
		case 'g': mask |= (CAVE_GLOW); break;
		case 'r': mask |= (CAVE_ROOM); break;
		case 'i': mask |= (CAVE_ICKY); break;
		case 's': mask |= (CAVE_SEEN); break;
		case 'v': mask |= (CAVE_VIEW); break;
		case 't': mask |= (CAVE_TEMP); break;
		case 'w': mask |= (CAVE_WALL); break;
	}

	/* Scan map */
	for (y = Term->offset_y; y < Term->offset_y + SCREEN_HGT; y++)
	{
		for (x = Term->offset_x; x < Term->offset_x + SCREEN_WID; x++)
		{
			byte a = TERM_RED;

			if (!in_bounds_fully(y, x)) continue;

			/* Given mask, show only those grids */
			if (mask && !(cave->info[y][x] & mask)) continue;

			/* Given no mask, show unknown grids */
			if (!mask && (cave->info[y][x] & (CAVE_MARK))) continue;

			/* Color */
			if (cave_floor_bold(y, x)) a = TERM_YELLOW;

			/* Display player/floors/walls */
			if ((y == py) && (x == px))
				print_rel(L'@', a, y, x);
			else if (cave_floor_bold(y, x))
				print_rel(L'*', a, y, x);
			else
				print_rel(L'#', a, y, x);
		}
	}

	/* Get keypress */
	msg("Press any key.");
	message_flush();

	/* Redraw map */
	prt_map();
}
コード例 #12
0
ファイル: target.c プロジェクト: konijn/angband
/**
 * Draw a visible path over the squares between (x1,y1) and (x2,y2).
 *
 * The path consists of "*", which are white except where there is a
 * monster, object or feature in the grid.
 *
 * This routine has (at least) three weaknesses:
 * - remembered objects/walls which are no longer present are not shown,
 * - squares which (e.g.) the player has walked through in the dark are
 *   treated as unknown space.
 * - walls which appear strange due to hallucination aren't treated correctly.
 *
 * The first two result from information being lost from the dungeon arrays,
 * which requires changes elsewhere
 */
static int draw_path(u16b path_n, u16b *path_g, char *c, byte *a, int y1, int x1)
{
	int i;
	bool on_screen;

	/* No path, so do nothing. */
	if (path_n < 1) return 0;

	/* The starting square is never drawn, but notice if it is being
     * displayed. In theory, it could be the last such square.
     */
	on_screen = panel_contains(y1, x1);

	/* Draw the path. */
	for (i = 0; i < path_n; i++) {
		byte colour;

		/* Find the co-ordinates on the level. */
		int y = GRID_Y(path_g[i]);
		int x = GRID_X(path_g[i]);

		/*
		 * As path[] is a straight line and the screen is oblong,
		 * there is only section of path[] on-screen.
		 * If the square being drawn is visible, this is part of it.
		 * If none of it has been drawn, continue until some of it
		 * is found or the last square is reached.
		 * If some of it has been drawn, finish now as there are no
		 * more visible squares to draw.
		 */
		 if (panel_contains(y,x)) on_screen = TRUE;
		 else if (on_screen) break;
		 else continue;

	 	/* Find the position on-screen */
		move_cursor_relative(y,x);

		/* This square is being overwritten, so save the original. */
		Term_what(Term->scr->cx, Term->scr->cy, a+i, c+i);

		/* Choose a colour. */
		if (cave->m_idx[y][x] && cave_monster(cave, cave->m_idx[y][x])->ml) {
			/* Visible monsters are red. */
			monster_type *m_ptr = cave_monster(cave, cave->m_idx[y][x]);
			monster_race *r_ptr = &r_info[m_ptr->r_idx];

			/*mimics act as objects*/
			if (rf_has(r_ptr->flags, RF_UNAWARE)) 
				colour = TERM_YELLOW;
			else
				colour = TERM_L_RED;
		}

		else if (cave->o_idx[y][x] && object_byid(cave->o_idx[y][x])->marked)
			/* Known objects are yellow. */
			colour = TERM_YELLOW;

		else if (!cave_floor_bold(y,x) &&
				 ((cave->info[y][x] & (CAVE_MARK)) || player_can_see_bold(y,x)))
			/* Known walls are blue. */
			colour = TERM_BLUE;

		else if (!(cave->info[y][x] & (CAVE_MARK)) && !player_can_see_bold(y,x))
			/* Unknown squares are grey. */
			colour = TERM_L_DARK;

		else
			/* Unoccupied squares are white. */
			colour = TERM_WHITE;

		/* Draw the path segment */
		(void)Term_addch(colour, '*');
	}
	return i;
}
コード例 #13
0
ファイル: wizard2.c プロジェクト: mjdrinen/FAangband
/**
 * Debug scent trails and noise bursts.
 */
static void do_cmd_wiz_hack_ben(void)
{

#ifdef MONSTER_FLOW

    char cmd;

    int py = p_ptr->py;
    int px = p_ptr->px;

    int i, y, x, y2, x2;

    /* Get a "debug command" */
    if (!get_com("Press 'S' for scent, 'N' for noise info: ", &cmd))
        return;


    /* Analyze the command */
    switch (cmd) {
    case 'S':
    case 's':
    {
        /* Update map */
        for (y = Term->offset_y; y <= Term->offset_y + SCREEN_HGT; y++) {
            for (x = Term->offset_x; x <= Term->offset_x + SCREEN_WID; x++) {
                byte a;

                int age = get_scent(y, x);

                /* Must have scent */
                if (age == -1)
                    continue;

                /* Pretty colors by age */
                if (age > SMELL_STRENGTH)
                    a = TERM_L_DARK;

                else if (age < 10)
                    a = TERM_BLUE;
                else if (age < 20)
                    a = TERM_L_BLUE;
                else if (age < 30)
                    a = TERM_GREEN;
                else if (age < 40)
                    a = TERM_L_GREEN;
                else if (age < 50)
                    a = TERM_YELLOW;
                else if (age < 60)
                    a = TERM_ORANGE;
                else if (age < 70)
                    a = TERM_L_RED;
                else
                    a = TERM_RED;


                /* Display player/floors/walls */
                if ((y == py) && (x == px)) {
                    print_rel('@', a, y, x);
                } else {
                    print_rel('0' + (age % 10), a, y, x);
                }
            }
        }

        /* Prompt */
        prt("Scent ages", 0, 0);

        /* Wait for a keypress */
        (void) inkey();

        /* Redraw map */
        prt_map();

        break;

    }

    case 'N':
    case 'n':
    {

        /* Get a "debug command" */
        if (!get_com
                ("Press 'D' for direction of flow, 'C' for actual cost values: ",
                 &cmd))
            return;

        if ((cmd == 'D') || (cmd == 'd')) {
            /* Update map */
            for (y = Term->offset_y; y <= Term->offset_y + SCREEN_HGT; y++) {
                for (x = Term->offset_x; x <= Term->offset_x + SCREEN_WID; x++) {
                    int lowest_cost = cave_cost[y][x];
                    int dir = -1;
                    int cost;

                    if (lowest_cost == 0)
                        continue;

                    for (i = 0; i < 8; i++) {
                        /* Get the location */
                        y2 = y + ddy_ddd[i];
                        x2 = x + ddx_ddd[i];

                        cost = cave_cost[y2][x2];
                        if (!cost)
                            continue;

                        /* If this grid's scent is younger, save it */
                        if (lowest_cost > cost)
                            lowest_cost = cost;

                        /* If it isn't, look elsewhere */
                        else
                            continue;

                        /* Save this direction */
                        dir = i;
                    }

                    /* If we didn't find any younger scent, print a '5' */
                    if (dir == -1)
                        print_rel('5', TERM_YELLOW, y, x);

                    /* Otherwise, convert to true direction and print */
                    else {
                        i = ddd[dir];
                        print_rel('0' + i, TERM_L_BLUE, y, x);
                    }
                }
            }

            /* Prompt */
            prt("Directions given to advancing monsters using noise info",
                0, 0);

            /* Wait for a keypress */
            (void) inkey();

            /* Redraw map */
            prt_map();
        }

        /* Actual cost values */
        else {
            int j;

            for (i = cost_at_center - 2; i <= 100 + NOISE_STRENGTH; ++i) {
                /* First show grids with no scent */
                if (i == cost_at_center - 2)
                    j = 0;

                /* Then show specially marked grids (bug-checking) */
                else if (i == cost_at_center - 1)
                    j = 255;

                /* Then show standard grids */
                else
                    j = i;

                /* Update map */
                for (y = Term->offset_y; y <= Term->offset_y + SCREEN_HGT; y++) {
                    for (x = Term->offset_x; x <= Term->offset_x + SCREEN_WID; x++) {
                        byte a = TERM_YELLOW;

                        /* Display proper cost */
                        if (cave_cost[y][x] != j)
                            continue;

                        /* Display player/floors/walls */
                        if ((y == py) && (x == px)) {
                            print_rel('@', a, y, x);
                        } else if (cave_floor_bold(y, x)) {
                            print_rel('*', a, y, x);
                        } else {
                            print_rel('#', a, y, x);
                        }
                    }
                }

                /* Prompt */
                if (j == 0) {
                    prt("Grids with no scent", 0, 0);
                } else if (j == 255) {
                    prt("Specially marked grids", 0, 0);
                } else {
                    prt(format("Depth %d: ", j), 0, 0);
                }

                /* Get key */
                if (inkey() == ESCAPE)
                    break;

                /* Redraw map */
                prt_map();
            }
        }

        break;
    }

    default:
    {
        break;
    }
    }

    /* Done */
    prt("", 0, 0);

    /* Redraw map */
    prt_map();

#else				/* MONSTER_FLOW */

    /* Oops */
    msg_print("Monster flow is not included in this copy of the game.");

#endif				/* MONSTER_FLOW */

}
コード例 #14
0
ファイル: cmd1.c プロジェクト: tonberrytoby/angband
/*
 * Move player in the given direction.
 *
 * This routine should only be called when energy has been expended.
 *
 * Note that this routine handles monsters in the destination grid,
 * and also handles attempting to move into walls/doors/rubble/etc.
 */
void move_player(int dir, bool disarm)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int y = py + ddy[dir];
	int x = px + ddx[dir];
	
	int m_idx = cave->m_idx[y][x];

	/* Attack monsters */
	if (m_idx > 0) {
		/* Mimics surprise the player */
		if (is_mimicking(m_idx)) {
			become_aware(m_idx);

			/* Mimic wakes up */
			mon_clear_timed(m_idx, MON_TMD_SLEEP, MON_TMD_FLG_NOMESSAGE);

		} else {
			py_attack(y, x);
		}
	}

	/* Optionally alter traps/doors on movement */
	else if (disarm && (cave->info[y][x] & CAVE_MARK) &&
			(cave_isknowntrap(cave, y, x) ||
			cave_iscloseddoor(cave, y, x)))
	{
		/* Auto-repeat if not already repeating */
		if (cmd_get_nrepeats() == 0)
			cmd_set_repeat(99);

		do_cmd_alter_aux(dir);
	}

	/* Cannot walk through walls */
	else if (!cave_floor_bold(y, x))
	{
		/* Disturb the player */
		disturb(p_ptr, 0, 0);

		/* Notice unknown obstacles */
		if (!(cave->info[y][x] & CAVE_MARK))
		{
			/* Rubble */
			if (cave->feat[y][x] == FEAT_RUBBLE)
			{
				msgt(MSG_HITWALL, "You feel a pile of rubble blocking your way.");
				cave->info[y][x] |= (CAVE_MARK);
				cave_light_spot(cave, y, x);
			}

			/* Closed door */
			else if (cave->feat[y][x] < FEAT_SECRET)
			{
				msgt(MSG_HITWALL, "You feel a door blocking your way.");
				cave->info[y][x] |= (CAVE_MARK);
				cave_light_spot(cave, y, x);
			}

			/* Wall (or secret door) */
			else
			{
				msgt(MSG_HITWALL, "You feel a wall blocking your way.");
				cave->info[y][x] |= (CAVE_MARK);
				cave_light_spot(cave, y, x);
			}
		}

		/* Mention known obstacles */
		else
		{
			if (cave->feat[y][x] == FEAT_RUBBLE)
				msgt(MSG_HITWALL, "There is a pile of rubble blocking your way.");
			else if (cave->feat[y][x] < FEAT_SECRET)
				msgt(MSG_HITWALL, "There is a door blocking your way.");
			else
				msgt(MSG_HITWALL, "There is a wall blocking your way.");
		}
	}

	/* Normal movement */
	else
	{
		/* See if trap detection status will change */
		bool old_dtrap = ((cave->info2[py][px] & (CAVE2_DTRAP)) != 0);
		bool new_dtrap = ((cave->info2[y][x] & (CAVE2_DTRAP)) != 0);

		/* Note the change in the detect status */
		if (old_dtrap != new_dtrap)
			p_ptr->redraw |= (PR_DTRAP);

		/* Disturb player if the player is about to leave the area */
		if (OPT(disturb_detect) && p_ptr->running && 
			!p_ptr->running_firststep && old_dtrap && !new_dtrap)
		{
			disturb(p_ptr, 0, 0);
			return;
		}

		/* Move player */
		monster_swap(py, px, y, x);
  
		/* New location */
		y = py = p_ptr->py;
		x = px = p_ptr->px;

		/* Searching */
		if (p_ptr->searching ||
				(p_ptr->state.skills[SKILL_SEARCH_FREQUENCY] >= 50) ||
				one_in_(50 - p_ptr->state.skills[SKILL_SEARCH_FREQUENCY]))
			search(FALSE);

		/* Handle "store doors" */
		if ((cave->feat[p_ptr->py][p_ptr->px] >= FEAT_SHOP_HEAD) &&
			(cave->feat[p_ptr->py][p_ptr->px] <= FEAT_SHOP_TAIL))
		{
			/* Disturb */
			disturb(p_ptr, 0, 0);
			cmd_insert(CMD_ENTER_STORE);
		}

		/* All other grids (including traps) */
		else
		{
			/* Handle objects (later) */
			p_ptr->notice |= (PN_PICKUP);
		}


		/* Discover invisible traps */
		if (cave->feat[y][x] == FEAT_INVIS)
		{
			/* Disturb */
			disturb(p_ptr, 0, 0);

			/* Message */
			msg("You found a trap!");

			/* Pick a trap */
			pick_trap(y, x);

			/* Hit the trap */
			hit_trap(y, x);
		}

		/* Set off an visible trap */
		else if (cave_isknowntrap(cave, y, x))
		{
			/* Disturb */
			disturb(p_ptr, 0, 0);

			/* Hit the trap */
			hit_trap(y, x);
		}
	}

	p_ptr->running_firststep = FALSE;
}
コード例 #15
0
ファイル: pathfind.c プロジェクト: EpicMan/angband
/*
 * Take one step along the current "run" path
 *
 * Called with a real direction to begin a new run, and with zero
 * to continue a run in progress.
 */
void run_step(int dir)
{
	int x, y;

	/* Start run */
	if (dir)
	{
		/* Initialize */
		run_init(dir);

		/* Hack -- Set the run counter */
		p_ptr->running = (p_ptr->command_arg ? p_ptr->command_arg : 1000);

		/* Calculate torch radius */
		p_ptr->update |= (PU_TORCH);
	}

	/* Continue run */
	else
	{
		if (!p_ptr->running_withpathfind)
		{
			/* Update run */
			if (run_test())
			{
				/* Disturb */
				disturb(0, 0);
	
				/* Done */
				return;
			}
		}
		else
		{
			/* Abort if we have finished */
			if (pf_result_index < 0)
			{
				disturb(0, 0);
				p_ptr->running_withpathfind = FALSE;
				return;
			}

			/* Abort if we would hit a wall */
			else if (pf_result_index == 0)
			{
				/* Get next step */
				y = p_ptr->py + ddy[pf_result[pf_result_index] - '0'];
				x = p_ptr->px + ddx[pf_result[pf_result_index] - '0'];

				/* Known wall */
				if ((cave_info[y][x] & (CAVE_MARK)) && !cave_floor_bold(y, x))
				{
					disturb(0,0);
					p_ptr->running_withpathfind = FALSE;
					return;
				}
			}

			/*
			 * Hack -- walking stick lookahead.
			 *
			 * If the player has computed a path that is going to end up in a wall,
			 * we notice this and convert to a normal run. This allows us to click
			 * on unknown areas to explore the map.
			 *
			 * We have to look ahead two, otherwise we don't know which is the last
			 * direction moved and don't initialise the run properly.
			 */
			else if (pf_result_index > 0)
			{
				/* Get next step */
				y = p_ptr->py + ddy[pf_result[pf_result_index] - '0'];
				x = p_ptr->px + ddx[pf_result[pf_result_index] - '0'];

				/* Known wall */
				if ((cave_info[y][x] & (CAVE_MARK)) && !cave_floor_bold(y, x))
				{
					disturb(0,0);
					p_ptr->running_withpathfind = FALSE;
					return;
				}

				/* Get step after */
				y = y + ddy[pf_result[pf_result_index-1] - '0'];
				x = x + ddx[pf_result[pf_result_index-1] - '0'];

				/* Known wall */
				if ((cave_info[y][x] & (CAVE_MARK)) && !cave_floor_bold(y, x))
				{
					p_ptr->running_withpathfind = FALSE;

					run_init(pf_result[pf_result_index] - '0');
				}
			}

			p_ptr->run_cur_dir = pf_result[pf_result_index--] - '0';
		}
	}


	/* Decrease counter */
	p_ptr->running--;

	/* Take time */
	p_ptr->energy_use = 100;

	/* Move the player */
	move_player(p_ptr->run_cur_dir);
}
コード例 #16
0
ファイル: attack.c プロジェクト: simongre/RePosBand
/*
 * Fire an object from the pack or floor.
 *
 * You may only fire items that "match" your missile launcher.
 *
 * See "calc_bonuses()" for more calculations and such.
 *
 * Note that "firing" a missile is MUCH better than "throwing" it.
 *
 * Note: "unseen" monsters are very hard to hit.
 *
 * Objects are more likely to break if they "attempt" to hit a monster.
 *
 * Rangers (with Bows) and Anyone (with "Extra Shots") get extra shots.
 * The "extra shot" code works by decreasing the amount of energy
 * required to make each shot, spreading the shots out over time.
 *
 * Note that when firing missiles, the launcher multiplier is applied
 * after all the bonuses are added in, making multipliers very useful.
 *
 * Note that Bows of "Extra Might" get extra range and an extra bonus
 * for the damage multiplier.
 */
void do_cmd_fire(cmd_code code, cmd_arg args[])
{
	int dir, item;
	int i, j, y, x;
	s16b ty, tx;
	int tdam, tdis, thits;
	int bonus, chance;

	object_type *o_ptr;
	object_type *j_ptr;

	object_type *i_ptr;
	object_type object_type_body;

	bool hit_body = FALSE;

	byte missile_attr;
	char missile_char;

	char o_name[80];

	u32b msg_type = 0;

	int path_n;
	u16b path_g[256];

	int msec = op_ptr->delay_factor * op_ptr->delay_factor;

	/* Get the "bow" */
	j_ptr = &p_ptr->inventory[INVEN_BOW];

	/* Require a usable launcher */
	if (!j_ptr->tval || !p_ptr->state.ammo_tval)
	{
		msg_print("You have nothing to fire with.");
		return;
	}

	/* Get item to fire and direction to fire in. */
	item = args[0].item;
	dir = args[1].direction;

	/* Check the item being fired is usable by the player. */
	if (!item_is_available(item, NULL, (USE_EQUIP | USE_INVEN | USE_FLOOR)))
	{
		msg_format("That item is not within your reach.");
		return;
	}

	/* Get the object for the ammo */
	o_ptr = object_from_item_idx(item);

	/* Check the ammo can be used with the launcher */
	if (o_ptr->tval != p_ptr->state.ammo_tval)
	{
		msg_format("That ammo cannot be fired by your current weapon.");
		return;
	}

	/* Base range XXX XXX */
	tdis = 6 + 2 * p_ptr->state.ammo_mult;

	/* Start at the player */
	x = p_ptr->px;
	y = p_ptr->py;

	/* Predict the "target" location */
	ty = y + 99 * ddy[dir];
	tx = x + 99 * ddx[dir];

	/* Check for target validity */
	if ((dir == 5) && target_okay())
	{
		target_get(&tx, &ty);
		if (distance(y, x, ty, tx) > tdis)
		{
			if (!get_check("Target out of range.  Fire anyway? "))
				return;
		}
	}

	/* Sound */
	sound(MSG_SHOOT);

	object_notice_on_firing(o_ptr);

	/* Describe the object */
	object_desc(o_name, sizeof(o_name), o_ptr, ODESC_FULL | ODESC_SINGULAR);

	/* Find the color and symbol for the object for throwing */
	missile_attr = object_attr(o_ptr);
	missile_char = object_char(o_ptr);

	/* Use the proper number of shots */
	thits = p_ptr->state.num_fire;

	/* Actually "fire" the object */
	bonus = (p_ptr->state.to_h + o_ptr->to_h + j_ptr->to_h);
	chance = p_ptr->state.skills[SKILL_TO_HIT_BOW] +
			(bonus * BTH_PLUS_ADJ);

	/* Take a (partial) turn */
	p_ptr->energy_use = (100 / thits);

	/* Calculate the path */
	path_n = project_path(path_g, tdis, y, x, ty, tx, 0);

	/* Hack -- Handle stuff */
	handle_stuff();

	/* Project along the path */
	for (i = 0; i < path_n; ++i)
	{
		int ny = GRID_Y(path_g[i]);
		int nx = GRID_X(path_g[i]);

		/* Hack -- Stop before hitting walls */
		if (!cave_floor_bold(ny, nx)) break;

		/* Advance */
		x = nx;
		y = ny;

		/* Only do visuals if the player can "see" the missile */
		if (player_can_see_bold(y, x))
		{
			/* Visual effects */
			print_rel(missile_char, missile_attr, y, x);
			move_cursor_relative(y, x);

			Term_fresh();
			if (p_ptr->redraw) redraw_stuff();

			Term_xtra(TERM_XTRA_DELAY, msec);
			light_spot(y, x);

			Term_fresh();
			if (p_ptr->redraw) redraw_stuff();
		}

		/* Delay anyway for consistency */
		else
		{
			/* Pause anyway, for consistancy */
			Term_xtra(TERM_XTRA_DELAY, msec);
		}

		/* Handle monster */
		if (cave_m_idx[y][x] > 0)
		{
			monster_type *m_ptr = &mon_list[cave_m_idx[y][x]];
			monster_race *r_ptr = &r_info[m_ptr->r_idx];

			int chance2 = chance - distance(p_ptr->py, p_ptr->px, y, x);
			int visible = m_ptr->ml;
			int multiplier = 1;

			const char *hit_verb = "hits";
			const slay_t *best_s_ptr = NULL;

			/* Note the collision */
			hit_body = TRUE;

			/* Did we hit it (penalize distance travelled) */
			if (test_hit(chance2, r_ptr->ac, m_ptr->ml))
			{
				bool fear = FALSE;

				/* Assume a default death */
				cptr note_dies = " dies.";

				improve_attack_modifier(o_ptr, m_ptr, &best_s_ptr);
				improve_attack_modifier(j_ptr, m_ptr, &best_s_ptr);
				if (best_s_ptr != NULL)
					hit_verb = best_s_ptr->range_verb;

				/* Some monsters get "destroyed" */
				if (monster_is_unusual(r_ptr))
				{
					/* Special note at death */
					note_dies = " is destroyed.";
				}

				/* Calculate multiplier */
				multiplier = p_ptr->state.ammo_mult;
				if (best_s_ptr != NULL) multiplier += best_s_ptr->mult;

				/* Apply damage: multiplier, slays, criticals, bonuses */
				tdam = damroll(o_ptr->dd, o_ptr->ds);
				tdam += o_ptr->to_d + j_ptr->to_d;
				tdam *= multiplier;
				tdam = critical_shot(o_ptr->weight, o_ptr->to_h, tdam, &msg_type);

				object_notice_attack_plusses(o_ptr);
				object_notice_attack_plusses(&p_ptr->inventory[INVEN_BOW]);

				/* No negative damage; change verb if no damage done */
				if (tdam <= 0)
				{
					tdam = 0;
					hit_verb = "fail to harm";
				}

				/* Handle unseen monster */
				if (!visible)
				{
					/* Invisible monster */
					message_format(MSG_SHOOT_HIT, 0, "The %s finds a mark.", o_name);
				}

				/* Handle visible monster */
				else
				{
					char m_name[80];

					/* Get "the monster" or "it" */
					monster_desc(m_name, sizeof(m_name), m_ptr, 0);

					/* Tell the player what happened */
					if (msg_type == MSG_SHOOT_HIT)
						message_format(MSG_SHOOT_HIT, 0, "The %s %s %s.", o_name, hit_verb, m_name);
					else
					{
						if (msg_type == MSG_HIT_GOOD)
						{
							message_format(MSG_HIT_GOOD, 0, "The %s %s %s. %s", o_name, hit_verb, m_name,
										   "It was a good hit!");
						}
						else if (msg_type == MSG_HIT_GREAT)
						{
							message_format(MSG_HIT_GREAT, 0, "The %s %s %s. %s", o_name, hit_verb, m_name,
										   "It was a great hit!");
						}
						else if (msg_type == MSG_HIT_SUPERB)
						{
							message_format(MSG_HIT_SUPERB, 0, "The %s %s %s. %s", o_name, hit_verb, m_name,
										   "It was a superb hit!");
						}
					}
					/* Hack -- Track this monster race */
					if (m_ptr->ml) monster_race_track(m_ptr->r_idx);

					/* Hack -- Track this monster */
					if (m_ptr->ml) health_track(cave_m_idx[y][x]);

				}

				/* Complex message */
				if (p_ptr->wizard)
				{
					msg_format("You do %d (out of %d) damage.",
					           tdam, m_ptr->hp);
				}

				/* Hit the monster, check for death */
				if (mon_take_hit(cave_m_idx[y][x], tdam, &fear, note_dies))
				{
					/* Dead monster */
				}

				/* No death */
				else
				{
					/* Message */
					message_pain(cave_m_idx[y][x], tdam);

					/* Take note */
					if (fear && m_ptr->ml)
					{
						char m_name[80];

						/* Get the monster name (or "it") */
						monster_desc(m_name, sizeof(m_name), m_ptr, 0);

						/* Message */
						message_format(MSG_FLEE, m_ptr->r_idx,
						               "%^s flees in terror!", m_name);
					}
				}
			}

			/* Stop looking */
			break;
		}
	}



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

	/* Obtain a local object */
	object_copy(i_ptr, o_ptr);

	/* Single object */
	i_ptr->number = 1;

	if (item >= 0)
	{
		inven_item_increase(item, -1);
		inven_item_describe(item);
		inven_item_optimize(item);
	}

	/* Reduce and describe floor item */
	else
	{
		floor_item_increase(0 - item, -1);
		floor_item_optimize(0 - item);
	}


	/* Chance of breakage (during attacks) */
	j = (hit_body ? breakage_chance(i_ptr) : 0);

	/* Drop (or break) near that location */
	drop_near(i_ptr, j, y, x, TRUE);
}
コード例 #17
0
ファイル: attack.c プロジェクト: simongre/RePosBand
/*
 * Throw an object from the pack or floor.
 *
 * Note: "unseen" monsters are very hard to hit.
 *
 * Should throwing a weapon do full damage?  Should it allow the magic
 * to hit bonus of the weapon to have an effect?  Should it ever cause
 * the item to be destroyed?  Should it do any damage at all?
 */
void do_cmd_throw(cmd_code code, cmd_arg args[])
{
	int dir, item;
	int i, j, y, x;
	s16b ty, tx;
	int chance, tdam, tdis;
	int weight;

	object_type *o_ptr;

	object_type *i_ptr;
	object_type object_type_body;

	bool hit_body = FALSE;

	byte missile_attr;
	char missile_char;

	char o_name[80];

	u32b msg_type = 0;

	int path_n;
	u16b path_g[256];

	int msec = op_ptr->delay_factor * op_ptr->delay_factor;

	/* Get item to throw and direction in which to throw it. */
	item = args[0].item;
	dir = args[1].direction;

	/* Make sure the player isn't throwing wielded items */
	if (item >= INVEN_WIELD && item < QUIVER_START)
	{
		msg_print("You have cannot throw wielded items.");
		return;
	}

	/* Check the item being thrown is usable by the player. */
	if (!item_is_available(item, NULL, (USE_EQUIP | USE_INVEN | USE_FLOOR)))
	{
		msg_format("That item is not within your reach.");
		return;
	}

	/* Get the object */
	o_ptr = object_from_item_idx(item);
	object_notice_on_firing(o_ptr);

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

	/* Obtain a local object */
	object_copy(i_ptr, o_ptr);

	/* Distribute the charges of rods/wands/staves between the stacks */
	distribute_charges(o_ptr, i_ptr, 1);

	/* Single object */
	i_ptr->number = 1;

	/* Reduce and describe inventory */
	if (item >= 0)
	{
		inven_item_increase(item, -1);
		inven_item_describe(item);
		inven_item_optimize(item);
	}

	/* Reduce and describe floor item */
	else
	{
		floor_item_increase(0 - item, -1);
		floor_item_optimize(0 - item);
	}


	/* Description */
	object_desc(o_name, sizeof(o_name), i_ptr, ODESC_FULL);

	/* Find the color and symbol for the object for throwing */
	missile_attr = object_attr(i_ptr);
	missile_char = object_char(i_ptr);


	/* Enforce a minimum "weight" of one pound */
	weight = ((i_ptr->weight > 10) ? i_ptr->weight : 10);

	/* Hack -- Distance -- Reward strength, penalize weight */
	tdis = (adj_str_blow[p_ptr->state.stat_ind[A_STR]] + 20) * 10 / weight;

	/* Max distance of 10 */
	if (tdis > 10) tdis = 10;

	/* Hack -- Base damage from thrown object */
	tdam = damroll(i_ptr->dd, i_ptr->ds);
	if (!tdam) tdam = 1;
	tdam += i_ptr->to_d;

	/* Chance of hitting */
	chance = (p_ptr->state.skills[SKILL_TO_HIT_THROW] + (p_ptr->state.to_h * BTH_PLUS_ADJ));


	/* Take a turn */
	p_ptr->energy_use = 100;


	/* Start at the player */
	y = p_ptr->py;
	x = p_ptr->px;

	/* Predict the "target" location */
	ty = p_ptr->py + 99 * ddy[dir];
	tx = p_ptr->px + 99 * ddx[dir];

	/* Check for "target request" */
	if ((dir == 5) && target_okay())
	{
		target_get(&tx, &ty);
	}

	/* Calculate the path */
	path_n = project_path(path_g, tdis, p_ptr->py, p_ptr->px, ty, tx, 0);


	/* Hack -- Handle stuff */
	handle_stuff();

	/* Project along the path */
	for (i = 0; i < path_n; ++i)
	{
		int ny = GRID_Y(path_g[i]);
		int nx = GRID_X(path_g[i]);

		/* Hack -- Stop before hitting walls */
		if (!cave_floor_bold(ny, nx)) break;

		/* Advance */
		x = nx;
		y = ny;

		/* Only do visuals if the player can "see" the missile */
		if (player_can_see_bold(y, x))
		{
			/* Visual effects */
			print_rel(missile_char, missile_attr, y, x);
			move_cursor_relative(y, x);

			Term_fresh();
			if (p_ptr->redraw) redraw_stuff();

			Term_xtra(TERM_XTRA_DELAY, msec);
			light_spot(y, x);

			Term_fresh();
			if (p_ptr->redraw) redraw_stuff();
		}

		/* Delay anyway for consistency */
		else
		{
			/* Pause anyway, for consistancy */
			Term_xtra(TERM_XTRA_DELAY, msec);
		}

		/* Handle monster */
		if (cave_m_idx[y][x] > 0)
		{
			monster_type *m_ptr = &mon_list[cave_m_idx[y][x]];
			monster_race *r_ptr = &r_info[m_ptr->r_idx];

			int chance2 = chance - distance(p_ptr->py, p_ptr->px, y, x);

			int visible = m_ptr->ml;

			/* Note the collision */
			hit_body = TRUE;

			/* Did we hit it (penalize range) */
			if (test_hit(chance2, r_ptr->ac, m_ptr->ml))
			{
				const char *hit_verb = "hits";
				bool fear = FALSE;
				const slay_t *best_s_ptr = NULL;

				/* Assume a default death */
				cptr note_dies = " dies.";

				/* Some monsters get "destroyed" */
				if (monster_is_unusual(r_ptr))
				{
					/* Special note at death */
					note_dies = " is destroyed.";
				}

				/* Apply special damage  - brought forward to fill in hit_verb XXX XXX XXX */
				improve_attack_modifier(i_ptr, m_ptr, &best_s_ptr);
				if (best_s_ptr != NULL)
				{
					tdam *= best_s_ptr->mult;
					hit_verb = best_s_ptr->range_verb;
				}
				/* Apply special damage XXX XXX XXX */
				tdam = critical_shot(i_ptr->weight, i_ptr->to_h, tdam, &msg_type);

				/* No negative damage; change verb if no damage done */
				if (tdam <= 0)
				{
					tdam = 0;
					hit_verb = "fail to harm";
				}

				/* Handle unseen monster */
				if (!visible)
				{
					/* Invisible monster */
					msg_format("The %s finds a mark.", o_name);
				}

				/* Handle visible monster */
				else
				{
					char m_name[80];

					/* Get "the monster" or "it" */
					monster_desc(m_name, sizeof(m_name), m_ptr, 0);

					/* Tell the player what happened */
					if (msg_type == MSG_SHOOT_HIT)
						message_format(MSG_SHOOT_HIT, 0, "The %s %s %s.", o_name, hit_verb, m_name);
					else
					{
						if (msg_type == MSG_HIT_GOOD)
						{
							message_format(MSG_HIT_GOOD, 0, "The %s %s %s. %s", o_name, hit_verb, m_name,
										   "It was a good hit!");
						}
						else if (msg_type == MSG_HIT_GREAT)
						{
							message_format(MSG_HIT_GREAT, 0, "The %s %s %s. %s", o_name, hit_verb, m_name,
										   "It was a great hit!");
						}
						else if (msg_type == MSG_HIT_SUPERB)
						{
							message_format(MSG_HIT_SUPERB, 0, "The %s %s %s. %s", o_name, hit_verb, m_name,
										   "It was a superb hit!");
						}
					}
					/* Hack -- Track this monster race */
					if (m_ptr->ml) monster_race_track(m_ptr->r_idx);

					/* Hack -- Track this monster */
					if (m_ptr->ml) health_track(cave_m_idx[y][x]);
				}

				/* Learn the bonuses */
				/* XXX Eddie This is messed up, better done for firing, */
				/* should use that method [split last] instead */
				/* check if inven_optimize removed what o_ptr referenced */
				if (object_similar(i_ptr, o_ptr, OSTACK_PACK))
					object_notice_attack_plusses(o_ptr);
				object_notice_attack_plusses(i_ptr);

				/* Complex message */
				if (p_ptr->wizard)
					msg_format("You do %d (out of %d) damage.",
							   tdam, m_ptr->hp);

				/* Hit the monster, check for death */
				if (mon_take_hit(cave_m_idx[y][x], tdam, &fear, note_dies))
				{
					/* Dead monster */
				}

				/* No death */
				else
				{
					/* Message */
					message_pain(cave_m_idx[y][x], tdam);

					/* Take note */
					if (fear && m_ptr->ml)
					{
						char m_name[80];

						/* Get the monster name (or "it") */
						monster_desc(m_name, sizeof(m_name), m_ptr, 0);

						/* Message */
						message_format(MSG_FLEE, m_ptr->r_idx,
						               "%^s flees in terror!", m_name);
					}
				}
			}

			/* Stop looking */
			break;
		}
	}

	/* Chance of breakage (during attacks) */
	j = (hit_body ? breakage_chance(i_ptr) : 0);

	/* Drop (or break) near that location */
	drop_near(i_ptr, j, y, x, TRUE);
}
コード例 #18
0
ファイル: attack.c プロジェクト: Chiinatso/Anquestria
/**
 * This is a helper function used by do_cmd_throw and do_cmd_fire.
 *
 * It abstracts out the projectile path, display code, identify and clean up
 * logic, while using the 'attack' parameter to do work particular to each
 * kind of attack.
 */
static void ranged_helper(int item, int dir, int range, int shots, ranged_attack attack) {
	/* Get the ammo */
	object_type *o_ptr = object_from_item_idx(item);

	int i, j;
	byte missile_attr = object_attr(o_ptr);
	char missile_char = object_char(o_ptr);

	object_type object_type_body;
	object_type *i_ptr = &object_type_body;

	char o_name[80];

	int path_n;
	u16b path_g[256];

	int msec = op_ptr->delay_factor;

	/* Start at the player */
	int x = p_ptr->px;
	int y = p_ptr->py;

	/* Predict the "target" location */
	s16b ty = y + 99 * ddy[dir];
	s16b tx = x + 99 * ddx[dir];

	bool hit_target = FALSE;

	/* Check for target validity */
	if ((dir == 5) && target_okay()) {
		int taim;
		char msg[80];
		target_get(&tx, &ty);
		taim = distance(y, x, ty, tx);
		if (taim > range) {
			sprintf (msg, "Target out of range by %d squares. Fire anyway? ",
				taim - range);
			if (!get_check(msg)) return;
		}
	}

	/* Sound */
	sound(MSG_SHOOT);

	object_notice_on_firing(o_ptr);

	/* Describe the object */
	object_desc(o_name, sizeof(o_name), o_ptr, ODESC_FULL | ODESC_SINGULAR);

	/* Actually "fire" the object -- Take a partial turn */
	p_ptr->energy_use = (100 / shots);

	/* Calculate the path */
	path_n = project_path(path_g, range, y, x, ty, tx, 0);

	/* Hack -- Handle stuff */
	handle_stuff(p_ptr);

	/* Start at the player */
	x = p_ptr->px;
	y = p_ptr->py;

	/* Project along the path */
	for (i = 0; i < path_n; ++i) {
		int ny = GRID_Y(path_g[i]);
		int nx = GRID_X(path_g[i]);

		/* Hack -- Stop before hitting walls */
		if (!cave_floor_bold(ny, nx)) break;

		/* Advance */
		x = nx;
		y = ny;

		/* Only do visuals if the player can "see" the missile */
		if (player_can_see_bold(y, x)) {
			print_rel(missile_char, missile_attr, y, x);
			move_cursor_relative(y, x);

			Term_fresh();
			if (p_ptr->redraw) redraw_stuff(p_ptr);

			Term_xtra(TERM_XTRA_DELAY, msec);
			cave_light_spot(cave, y, x);

			Term_fresh();
			if (p_ptr->redraw) redraw_stuff(p_ptr);
		} else {
			/* Delay anyway for consistency */
			Term_xtra(TERM_XTRA_DELAY, msec);
		}

		/* Handle monster */
		if (cave->m_idx[y][x] > 0) break;
	}

	/* Try the attack on the monster at (x, y) if any */
	if (cave->m_idx[y][x] > 0) {
		monster_type *m_ptr = cave_monster(cave, cave->m_idx[y][x]);
		monster_race *r_ptr = &r_info[m_ptr->r_idx];
		int visible = m_ptr->ml;

		bool fear = FALSE;
		char m_name[80];
		const char *note_dies = monster_is_unusual(r_ptr) ? " is destroyed." : " dies.";

		struct attack_result result = attack(o_ptr, y, x);
		int dmg = result.dmg;
		u32b msg_type = result.msg_type;
		const char *hit_verb = result.hit_verb;

		if (result.success) {
			hit_target = TRUE;

			/* Get "the monster" or "it" */
			monster_desc(m_name, sizeof(m_name), m_ptr, 0);
		
			object_notice_attack_plusses(o_ptr);
		
			/* No negative damage; change verb if no damage done */
			if (dmg <= 0) {
				dmg = 0;
				hit_verb = "fail to harm";
			}
		
			if (!visible) {
				/* Invisible monster */
				msgt(MSG_SHOOT_HIT, "The %s finds a mark.", o_name);
			} else {
				/* Visible monster */
				if (msg_type == MSG_SHOOT_HIT)
					msgt(MSG_SHOOT_HIT, "The %s %s %s.", o_name, hit_verb, m_name);
				else if (msg_type == MSG_HIT_GOOD) {
					msgt(MSG_HIT_GOOD, "The %s %s %s. %s", o_name, hit_verb, m_name, "It was a good hit!");
				} else if (msg_type == MSG_HIT_GREAT) {
					msgt(MSG_HIT_GREAT, "The %s %s %s. %s", o_name, hit_verb, m_name,
						 "It was a great hit!");
				} else if (msg_type == MSG_HIT_SUPERB) {
					msgt(MSG_HIT_SUPERB, "The %s %s %s. %s", o_name, hit_verb, m_name,
						 "It was a superb hit!");
				}
		
				/* Track this monster */
				if (m_ptr->ml) monster_race_track(m_ptr->r_idx);
				if (m_ptr->ml) health_track(p_ptr, cave->m_idx[y][x]);
			}
		
			/* Complex message */
			if (p_ptr->wizard)
				msg("You do %d (out of %d) damage.", dmg, m_ptr->hp);
		
			/* Hit the monster, check for death */
			if (!mon_take_hit(cave->m_idx[y][x], dmg, &fear, note_dies)) {
				message_pain(cave->m_idx[y][x], dmg);
				if (fear && m_ptr->ml)
					add_monster_message(m_name, cave->m_idx[y][x], MON_MSG_FLEE_IN_TERROR, TRUE);
			}
		}
	}

	/* Obtain a local object */
	object_copy(i_ptr, o_ptr);
	object_split(i_ptr, o_ptr, 1);

	/* See if the ammunition broke or not */
	j = breakage_chance(i_ptr, hit_target);

	/* Drop (or break) near that location */
	drop_near(cave, i_ptr, j, y, x, TRUE);

	if (item >= 0) {
		/* The ammo is from the inventory */
		inven_item_increase(item, -1);
		inven_item_describe(item);
		inven_item_optimize(item);
	} else {
		/* The ammo is from the floor */
		floor_item_increase(0 - item, -1);
		floor_item_optimize(0 - item);
	}
}
コード例 #19
0
ファイル: pathfind.c プロジェクト: EpicMan/angband
/*
 * 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 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;


	/* Look at every newly adjacent square. */
	for (i = -max; i <= max; i++)
	{
		object_type *o_ptr;


		/* 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 = &mon_list[cave_m_idx[row][col]];

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

		/* Visible objects abort running */
		for (o_ptr = get_first_object(row, col); o_ptr; o_ptr = get_next_object(o_ptr))
		{
			/* Visible object */
			if (o_ptr->marked && !squelch_hide_item(o_ptr)) 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:

				/* Secret doors */
				case FEAT_SECRET:

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

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

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

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


	/* Look at every soon to be newly adjacent square. */
	for (i = -max; i <= max; i++)
	{		
		/* New direction */
		new_dir = cycle[chome[prev_dir] + i];
		
		/* New location */
		row = py + ddy[prev_dir] + ddy[new_dir];
		col = px + ddx[prev_dir] + ddx[new_dir];
		
		/* HACK: Ugh. Sometimes we come up with illegal bounds. This will
		 * treat the symptom but not the disease. */
		if (row >= DUNGEON_HGT || col >= DUNGEON_WID) continue;
		if (row < 0 || col < 0) continue;

		/* Visible monsters abort running */
		if (cave_m_idx[row][col] > 0)
		{
			monster_type *m_ptr = &mon_list[cave_m_idx[row][col]];
			
			/* Visible monster */
			if (m_ptr->ml) return (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))
			{
				/* 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))
			{
				/* 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
		{
			/* Primary option */
			p_ptr->run_cur_dir = option;

			/* Hack -- allow curving */
			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);
}