예제 #1
0
/**
 * Light or Darken the town
 */
void cave_illuminate(struct chunk *c, bool daytime)
{
	int y, x, i;

	/* Apply light or darkness */
	for (y = 0; y < c->height; y++)
		for (x = 0; x < c->width; x++) {
			int d;
			bool light = FALSE;
			feature_type *f_ptr = &f_info[c->squares[y][x].feat];
			
			/* Skip grids with no surrounding floors or stairs */
			for (d = 0; d < 9; d++) {
				/* Extract adjacent (legal) location */
				int yy = y + ddy_ddd[d];
				int xx = x + ddx_ddd[d];

				/* Paranoia */
				if (!square_in_bounds_fully(c, yy, xx)) continue;

				/* Test */
				if (square_isfloor(c, yy, xx) || square_isstairs(c, yy, xx))
					light = TRUE;
			}

			if (!light) continue;

			/* Only interesting grids at night */
			if (daytime || !tf_has(f_ptr->flags, TF_FLOOR)) {
				sqinfo_on(c->squares[y][x].info, SQUARE_GLOW);
				sqinfo_on(c->squares[y][x].info, SQUARE_MARK);
			} else {
				sqinfo_off(c->squares[y][x].info, SQUARE_GLOW);
				sqinfo_off(c->squares[y][x].info, SQUARE_MARK);
			}
		}
			
			
	/* Light shop doorways */
	for (y = 0; y < c->height; y++) {
		for (x = 0; x < c->width; x++) {
			if (!square_isshop(c, y, x))
				continue;
			for (i = 0; i < 8; i++) {
				int yy = y + ddy_ddd[i];
				int xx = x + ddx_ddd[i];
				sqinfo_on(c->squares[yy][xx].info, SQUARE_GLOW);
				sqinfo_on(c->squares[yy][xx].info, SQUARE_MARK);
			}
		}
	}


	/* Fully update the visuals */
	player->upkeep->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);

	/* Redraw map, monster list */
	player->upkeep->redraw |= (PR_MAP | PR_MONLIST | PR_ITEMLIST);
}
예제 #2
0
파일: trap.c 프로젝트: Daedelus01/angband
/**
 * Reveal some of the player traps in a square
 */
bool square_reveal_trap(struct chunk *c, int y, int x, int chance, bool domsg)
{
    int found_trap = 0;
	struct trap *trap = c->squares[y][x].trap;
    
    /* Check there is a player trap */
    if (!square_isplayertrap(c, y, x))
		return FALSE;

	/* Scan the grid */
	while (trap) {
		/* Skip non-player traps */
		if (!trf_has(trap->flags, TRF_TRAP)) {
			trap = trap->next;
			continue;
		}
		
		/* Trap is invisible */
		if (!trf_has(trap->flags, TRF_VISIBLE)) {
			/* See the trap */
			trf_on(trap->flags, TRF_VISIBLE);
			sqinfo_on(c->squares[y][x].info, SQUARE_MARK);

			/* We found a trap */
			found_trap++;

			/* If chance is < 100, check for further looking */
			if ((chance < 100) && (randint1(100) > chance)) break;
		}
		trap = trap->next;
	}

    /* We found at least one trap */
    if (found_trap) {
		/* We want to talk about it */
		if (domsg) {
			if (found_trap == 1)
				msg("You have found a trap.");
			else
				msg("You have found %d traps.", found_trap);
		}

		/* Memorize */
		sqinfo_on(c->squares[y][x].info, SQUARE_MARK);

		/* Redraw */
		square_light_spot(c, y, x);
    }

    /* Return TRUE if we found any traps */
    return (found_trap != 0);
}
예제 #3
0
파일: generate.c 프로젝트: myshkin/angband
/**
 * Place hidden squares that will be used to generate feeling
 * \param c is the cave struct the feeling squares are being placed in
 */
static void place_feeling(struct chunk *c)
{
	int y,x,i,j;
	int tries = 500;
	
	for (i = 0; i < z_info->feeling_total; i++) {
		for (j = 0; j < tries; j++) {
			/* Pick a random dungeon coordinate */
			y = randint0(c->height);
			x = randint0(c->width);

			/* Check to see if it is not a wall */
			if (square_iswall(c, y, x))
				continue;

			/* Check to see if it is already marked */
			if (square_isfeel(c, y, x))
				continue;

			/* Set the cave square appropriately */
			sqinfo_on(c->squares[y][x].info, SQUARE_FEEL);
			
			break;
		}
	}

	/* Reset number of feeling squares */
	c->feeling_squares = 0;
}
예제 #4
0
파일: trap.c 프로젝트: Daedelus01/angband
/**
 * Hit a trap. 
 */
extern void hit_trap(int y, int x)
{
	bool ident;
	struct trap *trap;
	struct effect *effect;

    /* Count the hidden traps here */
    int num = num_traps(cave, y, x, -1);

    /* Oops.  We've walked right into trouble. */
    if      (num == 1) msg("You stumble upon a trap!");
    else if (num >  1) msg("You stumble upon some traps!");


	/* Look at the traps in this grid */
	for (trap = cave->squares[y][x].trap; trap; trap = trap->next) {
		/* Require that trap be capable of affecting the character */
		if (!trf_has(trap->kind->flags, TRF_TRAP)) continue;
	    
		/* Disturb the player */
		disturb(player, 0);

		/* Fire off the trap */
		effect = trap->kind->effect;
		effect_do(effect, &ident, FALSE, 0, 0, 0);

		/* Trap becomes visible (always XXX) */
		trf_on(trap->flags, TRF_VISIBLE);
		sqinfo_on(cave->squares[y][x].info, SQUARE_MARK);
	}

    /* Verify traps (remove marker if appropriate) */
    (void)square_verify_trap(cave, y, x, 0);
}
예제 #5
0
파일: trap.c 프로젝트: Daedelus01/angband
/**
 * Make a new trap of the given type.  Return TRUE if successful.
 *
 * We choose a player trap at random if the index is not legal. This means that
 * things which are not player traps must be picked by passing a valid index.
 *
 * This should be the only function that places traps in the dungeon
 * except the savefile loading code.
 */
void place_trap(struct chunk *c, int y, int x, int t_idx, int trap_level)
{
	struct trap *new_trap;

    /* We've been called with an illegal index; choose a random trap */
    if ((t_idx <= 0) || (t_idx >= z_info->trap_max)) {
		/* Require the correct terrain */
		if (!square_player_trap_allowed(c, y, x)) return;

		t_idx = pick_trap(c->squares[y][x].feat, trap_level);
    }

    /* Failure */
    if (t_idx < 0) return;

	/* Allocate a new trap for this grid (at the front of the list) */
	new_trap = mem_zalloc(sizeof(*new_trap));
	new_trap->next = c->squares[y][x].trap;
	c->squares[y][x].trap = new_trap;

	/* Set the details */
	new_trap->t_idx = t_idx;
	new_trap->kind = &trap_info[t_idx];
	new_trap->fy = y;
	new_trap->fx = x;
	trf_copy(new_trap->flags, trap_info[t_idx].flags);

	/* Toggle on the trap marker */
	sqinfo_on(c->squares[y][x].info, SQUARE_TRAP);

	/* Redraw the grid */
	square_light_spot(c, y, x);
}
예제 #6
0
/**
 * Light up the dungeon using "claravoyance"
 *
 * This function "illuminates" every grid in the dungeon, memorizes all
 * "objects" (or notes the existence of an object "if" full is TRUE),
 * and memorizes all grids as with magic mapping.
 */
void wiz_light(struct chunk *c, bool full)
{
	int i, y, x;

	/* Scan all grids */
	for (y = 1; y < c->height - 1; y++) {
		for (x = 1; x < c->width - 1; x++) {
			struct object *obj;

			/* Process all non-walls */
			if (!square_seemslikewall(c, y, x)) {
				/* Scan all neighbors */
				for (i = 0; i < 9; i++) {
					int yy = y + ddy_ddd[i];
					int xx = x + ddx_ddd[i];

					/* Perma-light the grid */
					sqinfo_on(c->squares[yy][xx].info, SQUARE_GLOW);

					/* Memorize normal features */
					if (!square_isfloor(c, yy, xx) || 
						square_isvisibletrap(c, yy, xx)) {
						sqinfo_on(c->squares[yy][xx].info, SQUARE_MARK);
						cave_k->squares[yy][xx].feat = c->squares[yy][xx].feat;
					}
				}
			}

			/* Memorize objects */
			for (obj = square_object(cave, y, x); obj; obj = obj->next) {
				/* Skip dead objects */
				assert(obj->kind);

				/* Memorize it */
				if (obj->marked < MARK_SEEN)
					obj->marked = full ? MARK_SEEN : MARK_AWARE;
			}
		}
	}

	/* Fully update the visuals */
	player->upkeep->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);

	/* Redraw whole map, monster list */
	player->upkeep->redraw |= (PR_MAP | PR_MONLIST | PR_ITEMLIST);
}
예제 #7
0
파일: cave-map.c 프로젝트: lhz/angband
/**
 * Light up the dungeon using "claravoyance"
 *
 * This function "illuminates" every grid in the dungeon, memorizes all
 * "objects" (or notes the existence of an object "if" full is true),
 * and memorizes all grids as with magic mapping.
 */
void wiz_light(struct chunk *c, struct player *p, bool full)
{
	int i, y, x;

	/* Scan all grids */
	for (y = 1; y < c->height - 1; y++) {
		for (x = 1; x < c->width - 1; x++) {
			/* Process all non-walls */
			if (!square_seemslikewall(c, y, x)) {
				if (!square_in_bounds_fully(c, y, x)) continue;

				/* Scan all neighbors */
				for (i = 0; i < 9; i++) {
					int yy = y + ddy_ddd[i];
					int xx = x + ddx_ddd[i];

					/* Perma-light the grid */
					sqinfo_on(c->squares[yy][xx].info, SQUARE_GLOW);

					/* Memorize normal features */
					if (!square_isfloor(c, yy, xx) || 
						square_isvisibletrap(c, yy, xx)) {
						square_memorize(c, yy, xx);
						square_mark(c, yy, xx);
					}
				}
			}

			/* Memorize objects */
			if (full) {
				square_know_pile(c, y, x);
			} else {
				square_sense_pile(c, y, x);
			}

			/* Forget unprocessed, unknown grids in the mapping area */
			if (!square_ismark(c, y, x) && square_isnotknown(c, y, x))
				square_forget(c, y, x);
		}
	}

	/* Unmark grids */
	for (y = 1; y < c->height - 1; y++) {
		for (x = 1; x < c->width - 1; x++) {
			if (!square_in_bounds(c, y, x)) continue;
			square_unmark(c, y, x);
		}
	}

	/* Fully update the visuals */
	p->upkeep->update |= (PU_UPDATE_VIEW | PU_MONSTERS);

	/* Redraw whole map, monster list */
	p->upkeep->redraw |= (PR_MAP | PR_MONLIST | PR_ITEMLIST);
}
예제 #8
0
/**
 * This routine will Perma-Light all grids in the set passed in.
 *
 * This routine is used (only) by "light_room()"
 *
 * Dark grids are illuminated.
 *
 * Also, process all affected monsters.
 *
 * SMART monsters always wake up when illuminated
 * NORMAL monsters wake up 1/4 the time when illuminated
 * STUPID monsters wake up 1/10 the time when illuminated
 */
static void cave_light(struct point_set *ps)
{
	int i;

	/* Apply flag changes */
	for (i = 0; i < ps->n; i++)
	{
		int y = ps->pts[i].y;
		int x = ps->pts[i].x;

		/* Perma-Light */
		sqinfo_on(cave->squares[y][x].info, SQUARE_GLOW);
	}

	/* Fully update the visuals */
	player->upkeep->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);

	/* Update stuff */
	update_stuff(player);

	/* Process the grids */
	for (i = 0; i < ps->n; i++)
	{
		int y = ps->pts[i].y;
		int x = ps->pts[i].x;

		/* Redraw the grid */
		square_light_spot(cave, y, x);

		/* Process affected monsters */
		if (cave->squares[y][x].mon > 0)
		{
			int chance = 25;

			monster_type *m_ptr = square_monster(cave, y, x);

			/* Stupid monsters rarely wake up */
			if (rf_has(m_ptr->race->flags, RF_STUPID)) chance = 10;

			/* Smart monsters always wake up */
			if (rf_has(m_ptr->race->flags, RF_SMART)) chance = 100;

			/* Sometimes monsters wake up */
			if (m_ptr->m_timed[MON_TMD_SLEEP] && (randint0(100) < chance))
			{
				/* Wake up! */
				mon_clear_timed(m_ptr, MON_TMD_SLEEP,
					MON_TMD_FLG_NOTIFY, FALSE);

			}
		}
	}
}
예제 #9
0
/**
 * Memorize interesting viewable object/features in the given grid
 *
 * This function should only be called on "legal" grids.
 *
 * This function will memorize the object and/or feature in the given grid,
 * if they are (1) see-able and (2) interesting.  Note that all objects are
 * interesting, all terrain features except floors (and invisible traps) are
 * interesting, and floors (and invisible traps) are interesting sometimes
 * (depending on various options involving the illumination of floor grids).
 *
 * The automatic memorization of all objects and non-floor terrain features
 * as soon as they are displayed allows incredible amounts of optimization
 * in various places, especially "map_info()" and this function itself.
 *
 * Note that the memorization of objects is completely separate from the
 * memorization of terrain features, preventing annoying floor memorization
 * when a detected object is picked up from a dark floor, and object
 * memorization when an object is dropped into a floor grid which is
 * memorized but out-of-sight.
 *
 * This function should be called every time the "memorization" of a grid
 * (or the object in a grid) is called into question, such as when an object
 * is created in a grid, when a terrain feature "changes" from "floor" to
 * "non-floor", and when any grid becomes "see-able" for any reason.
 *
 * This function is called primarily from the "update_view()" function, for
 * each grid which becomes newly "see-able".
 */
void square_note_spot(struct chunk *c, int y, int x)
{
	object_type *obj;

	/* Require "seen" flag */
	if (!square_isseen(c, y, x))
		return;

	for (obj = square_object(c, y, x); obj; obj = obj->next)
		obj->marked = MARK_SEEN;

	if (square_ismark(c, y, x))
		return;

	/* Memorize this grid */
	sqinfo_on(c->squares[y][x].info, SQUARE_MARK);
}
예제 #10
0
/* Light up the grid */
static void project_feature_handler_LIGHT_WEAK(project_feature_handler_context_t *context)
{
	const int x = context->x;
	const int y = context->y;

	/* Turn on the light */
	sqinfo_on(cave->squares[y][x].info, SQUARE_GLOW);

	/* Grid is in line of sight */
	if (square_isview(cave, y, x)) {
		if (!player->timed[TMD_BLIND]) {
			/* Observe */
			context->obvious = true;
		}

		/* Fully update the visuals */
		player->upkeep->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);
	}
}
예제 #11
0
파일: cave-map.c 프로젝트: lhz/angband
/**
 * This routine will Perma-Light all grids in the set passed in.
 *
 * This routine is used (only) by "light_room()"
 *
 * Dark grids are illuminated.
 *
 * Also, process all affected monsters.
 *
 * SMART monsters always wake up when illuminated
 * NORMAL monsters wake up 1/4 the time when illuminated
 * STUPID monsters wake up 1/10 the time when illuminated
 */
static void cave_light(struct point_set *ps)
{
	int i;

	/* Apply flag changes */
	for (i = 0; i < ps->n; i++)	{
		int y = ps->pts[i].y;
		int x = ps->pts[i].x;

		/* Perma-Light */
		sqinfo_on(cave->squares[y][x].info, SQUARE_GLOW);
	}

	/* Process the grids */
	for (i = 0; i < ps->n; i++)	{
		int y = ps->pts[i].y;
		int x = ps->pts[i].x;

		/* Redraw the grid */
		square_light_spot(cave, y, x);

		/* Process affected monsters */
		if (cave->squares[y][x].mon > 0) {
			int chance = 25;

			struct monster *mon = square_monster(cave, y, x);

			/* Stupid monsters rarely wake up */
			if (monster_is_stupid(mon)) chance = 10;

			/* Smart monsters always wake up */
			if (monster_is_smart(mon)) chance = 100;

			/* Sometimes monsters wake up */
			if (mon->m_timed[MON_TMD_SLEEP] && (randint0(100) < chance)) {
				mon_clear_timed(mon, MON_TMD_SLEEP, MON_TMD_FLG_NOTIFY, false);
			}
		}
	}
}
예제 #12
0
/**
 * Perform the basic "close" command
 *
 * Assume there is no monster blocking the destination
 *
 * Returns TRUE if repeated commands may continue
 */
static bool do_cmd_close_aux(int y, int x)
{
	bool more = FALSE;

	/* Verify legality */
	if (!do_cmd_close_test(y, x)) return (FALSE);

	/* Broken door */
	if (square_isbrokendoor(cave, y, x))
	{
		msg("The door appears to be broken.");
	} else {
		/* Close door */
		square_close_door(cave, y, x);
		sqinfo_on(cave->squares[y][x].info, SQUARE_MARK);
		square_light_spot(cave, y, x);
		player->upkeep->update |= (PU_UPDATE_VIEW | PU_MONSTERS);
		sound(MSG_SHUTDOOR);
	}

	/* Result */
	return (more);
}
예제 #13
0
/**
 * 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 = player->py;
	int px = player->px;

	int y = py + ddy[dir];
	int x = px + ddx[dir];

	int m_idx = cave->squares[y][x].mon;
	struct monster *m_ptr = cave_monster(cave, m_idx);
	bool alterable = (square_isknowntrap(cave, y, x) ||
					  square_iscloseddoor(cave, y, x));

	/* Attack monsters, alter traps/doors on movement, hit obstacles or move */
	if (m_idx > 0) {
		/* Mimics surprise the player */
		if (is_mimicking(m_ptr)) {
			become_aware(m_ptr);

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

		} else {
			py_attack(y, x);
		}
	} else if (disarm && square_ismark(cave, y, x) && alterable) {
		/* Auto-repeat if not already repeating */
		if (cmd_get_nrepeats() == 0)
			cmd_set_repeat(99);

		do_cmd_alter_aux(dir);
	} else if (player->upkeep->running && square_isknowntrap(cave, y, x)) {
		/* Stop running before known traps */
		disturb(player, 0);
	} else if (!square_ispassable(cave, y, x)) {
		/* Disturb the player */
		disturb(player, 0);

		/* Notice unknown obstacles, mention known obstacles */
		if (!square_ismark(cave, y, x)) {
			if (square_isrubble(cave, y, x)) {
				msgt(MSG_HITWALL,
					 "You feel a pile of rubble blocking your way.");
				sqinfo_on(cave->squares[y][x].info, SQUARE_MARK);
				square_light_spot(cave, y, x);
			} else if (square_iscloseddoor(cave, y, x)) {
				msgt(MSG_HITWALL, "You feel a door blocking your way.");
				sqinfo_on(cave->squares[y][x].info, SQUARE_MARK);
				square_light_spot(cave, y, x);
			} else {
				msgt(MSG_HITWALL, "You feel a wall blocking your way.");
				sqinfo_on(cave->squares[y][x].info, SQUARE_MARK);
				square_light_spot(cave, y, x);
			}
		} else {
			if (square_isrubble(cave, y, x))
				msgt(MSG_HITWALL,
					 "There is a pile of rubble blocking your way.");
			else if (square_iscloseddoor(cave, y, x))
				msgt(MSG_HITWALL, "There is a door blocking your way.");
			else
				msgt(MSG_HITWALL, "There is a wall blocking your way.");
		}
	} else {
		/* See if trap detection status will change */
		bool old_dtrap = square_isdtrap(cave, py, px);
		bool new_dtrap = square_isdtrap(cave, y, x);

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

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

		/* Move player */
		monster_swap(py, px, y, x);

		/* New location */
		y = py = player->py;
		x = px = player->px;

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

		/* Handle store doors, or notice objects */
		if (square_isshop(cave, player->py, player->px)) {
			/* Disturb */
			disturb(player, 0);
			event_signal(EVENT_ENTER_STORE);
			event_remove_handler_type(EVENT_ENTER_STORE);
			event_signal(EVENT_USE_STORE);
			event_remove_handler_type(EVENT_USE_STORE);
			event_signal(EVENT_LEAVE_STORE);
			event_remove_handler_type(EVENT_LEAVE_STORE);
		} else {
			/* Handle objects (later) */
			cmdq_push(CMD_AUTOPICKUP);
		}


		/* Discover invisible traps, set off visible ones */
		if (square_issecrettrap(cave, y, x)) {
			/* Disturb */
			disturb(player, 0);

			/* Hit the trap. */
			hit_trap(y, x);
		} else if (square_isknowntrap(cave, y, x)) {
			/* Disturb */
			disturb(player, 0);

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

	player->upkeep->running_firststep = FALSE;
}
예제 #14
0
void square_mark(struct chunk *c, int y, int x) {
	sqinfo_on(c->squares[y][x].info, SQUARE_MARK);
}
예제 #15
0
/**
 * Perform the basic "open" command on doors
 *
 * Assume there is no monster blocking the destination
 *
 * Returns TRUE if repeated commands may continue
 */
static bool do_cmd_open_aux(int y, int x)
{
	int i, j;
	bool more = FALSE;

	/* Verify legality */
	if (!do_cmd_open_test(y, x)) return (FALSE);

	/* Locked door */
	if (square_islockeddoor(cave, y, x)) {
		/* Disarm factor */
		i = player->state.skills[SKILL_DISARM];

		/* Penalize some conditions */
		if (player->timed[TMD_BLIND] || no_light())
			i = i / 10;
		if (player->timed[TMD_CONFUSED] || player->timed[TMD_IMAGE])
			i = i / 10;

		/* Extract the lock power */
		j = square_door_power(cave, y, x);

		/* Extract the difficulty XXX XXX XXX */
		j = i - (j * 4);

		/* Always have a small chance of success */
		if (j < 2) j = 2;

		if (randint0(100) < j) {
			/* Message */
			msgt(MSG_LOCKPICK, "You have picked the lock.");

			/* Open the door */
			square_open_door(cave, y, x);

			/* Update the visuals */
			sqinfo_on(cave->squares[y][x].info, SQUARE_MARK);
			square_light_spot(cave, y, x);
			player->upkeep->update |= (PU_UPDATE_VIEW | PU_MONSTERS);

			/* Experience */
			/* Removed to avoid exploit by repeatedly locking and unlocking */
			/* player_exp_gain(player, 1); */
		} else {
			event_signal(EVENT_INPUT_FLUSH);

			/* Message */
			msgt(MSG_LOCKPICK_FAIL, "You failed to pick the lock.");

			/* We may keep trying */
			more = TRUE;
		}
	} else {
		/* Closed door */
		square_open_door(cave, y, x);
		sqinfo_on(cave->squares[y][x].info, SQUARE_MARK);
		square_light_spot(cave, y, x);
		player->upkeep->update |= (PU_UPDATE_VIEW | PU_MONSTERS);
		sound(MSG_OPENDOOR);
	}

	/* Result */
	return (more);
}
예제 #16
0
/**
 * Move player in the given direction, with the given "pickup" flag.
 *
 * 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/etc.
 */
void move_player(int dir)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	byte str_escape, dex_escape;

	/* Permit the player to move? */
	bool can_move = FALSE;

	/* Player is jumping off a cliff */
	bool falling = FALSE;

	/* Player hits a trap (always unless flying) */
	bool trapped = TRUE;

	int temp;
	int y, x;

	feature_type *f_ptr;

	/* Find the result of moving */
	y = py + ddy[dir];
	x = px + ddx[dir];
	f_ptr = &f_info[cave_feat[y][x]];


	/* Hack -- attack monsters */
	if (cave_m_idx[y][x] > 0) {
		/* Attack */
		if (py_attack(y, x, TRUE))
			return;
	}

	/* It takes some dexterity, or failing that strength, to get out of pits */
	if (cave_feat[py][px] == FEAT_PIT) {
		str_escape = adj_dex_dis[p_ptr->state.stat_ind[A_STR]];
		dex_escape = adj_dex_dis[p_ptr->state.stat_ind[A_DEX]];

		/* First attempt to leap out of the pit, */
		if ((dex_escape + 1) * 2 < randint1(16)) {
			/* then attempt to climb out of the pit. */
			if (str_escape + 3 < randint1(16)) {
				/* Failure costs a turn. */
				msg("You remain stuck in the pit.");
				return;
			} else
				msg("You clamber out of the pit.");
		} else
			msg("You leap out of the pit.");
	}


	/* Option to disarm a visible trap. -TNB- */
	/* Hack - Rogues can walk over their own trap - BR */
	if (OPT(easy_alter) && cave_visible_trap(y, x)
		&& cave_player_trap(y, x)) {
		bool more = FALSE;
		/* Auto-repeat if not already repeating */
		if (cmd_get_nrepeats() == 0)
			cmd_set_repeat(99);

		more = do_cmd_disarm_aux(y, x);

		/* Cancel repeat unless we may continue */
		if (!more)
			disturb(0, 0);
		return;
	}

	/* Some terrain is impassable for the player, such as stone walls. */
	else if (!tf_has(f_ptr->flags, TF_PASSABLE)) {
		/* Disturb the player */
		disturb(0, 0);

		/* Notice unknown obstacles */
		if (!sqinfo_has(cave_info[y][x], SQUARE_MARK)) {
			/* Closed door */
			if (tf_has(f_ptr->flags, TF_DOOR_CLOSED)) {
				msgt(MSG_HITWALL, "You feel a door blocking your way.");
				sqinfo_on(cave_info[y][x], SQUARE_MARK);
				light_spot(y, x);
			}

			/* Wall (or secret door) */
			else {
				msgt(MSG_HITWALL, "You feel a wall blocking your way.");
				sqinfo_on(cave_info[y][x], SQUARE_MARK);
				light_spot(y, x);
			}
		}

		/* Mention known obstacles */
		else {
			/* Closed door */
			if (tf_has(f_ptr->flags, TF_DOOR_CLOSED)) {
				/* Option to automatically open doors. -TNB- */
				if (OPT(easy_alter)) {
					bool more = FALSE;

					/* Auto-repeat if not already repeating */
					if (cmd_get_nrepeats() == 0)
						cmd_set_repeat(99);

					/* Open the door */
					more = do_cmd_open_aux(y, x);

					/* Cancel repeat unless we may continue */
					if (!more)
						disturb(0, 0);
					return;
				}

				/* Otherwise, a message. */
				msgt(MSG_HITWALL, "There is a door blocking your way.");
			}

			/* Wall (or secret door) */
			else {
				msgt(MSG_HITWALL, "There is a wall blocking your way.");
			}
		}

		/* Sound */
		sound(MSG_HITWALL);
	}

	/* Normal movement */
	else {
		/* Assume terrain can be traversed normally. */
		can_move = TRUE;

		/*** Handle traversable terrain.  ***/
		if (tf_has(f_ptr->flags, TF_ROCK)) {
			/* Dwarves move easily through rubble */
			if (player_has(PF_DWARVEN))
				can_move = TRUE;

			/* Bats, dragons can fly */
			else if ((p_ptr->schange == SHAPE_BAT)
					 || (p_ptr->schange == SHAPE_WYRM))
				can_move = TRUE;

			/* Require more energy */
			else {
				can_move = TRUE;
				p_ptr->energy_use += 100;
			}
		}

		if (tf_has(f_ptr->flags, TF_TREE)) {
			/* Druids, rangers, elves and ents (SJGU) slip easily under
			 * trees */
			if (((player_has(PF_WOODSMAN)) || (player_has(PF_ELVEN)))
				|| (player_has(PF_WOODEN)))
				can_move = TRUE;

			/* Bats, dragons can fly */
			else if ((p_ptr->schange == SHAPE_BAT)
					 || (p_ptr->schange == SHAPE_WYRM))
				can_move = TRUE;

			/* Require more energy */
			else {
				can_move = TRUE;
				p_ptr->energy_use += 100;
			}
		}

		/* Water now slows rather than stopping -NRM- */
		if (tf_has(f_ptr->flags, TF_WATERY)) {
			/* Stop any run. */
			disturb(0, 0);

			can_move = TRUE;

			/* Speed will need updating */
			p_ptr->update |= PU_BONUS;
		}

		if (tf_has(f_ptr->flags, TF_FIERY)) {
			/* Assume player will continue. */
			temp = TRUE;

			/* Smart enough to stop running. */
			if (p_ptr->running) {
				if (!get_check("Lava blocks your path.  Step into it? ")) {
					temp = FALSE;
					p_ptr->running = 0;
				}
			}

			/* Smart enough to sense trouble. */
			else if ((!p_resist_pos(P_RES_FIRE))
					 || (!p_resist_strong(P_RES_FIRE)
						 && (p_ptr->chp <= 100))
					 || (!p_immune(P_RES_FIRE) && (p_ptr->chp <= 30))) {
				if (!get_check
					("The heat of the lava scalds you! Really enter? ")) {
					temp = FALSE;
				}
			}

			/* Enter if OK or confirmed. */
			if (temp) {
				/* Can always cross. */
				can_move = TRUE;

				/* Feather fall makes one lightfooted. */
				if (p_ptr->state.ffall) {
					notice_obj(OF_FEATHER, 0);
					temp = 49 + randint1(51);
				} else
					temp = 124 + randint1(126);

				/* Will take serious fire damage. */
				fire_dam(temp, "burnt to a cinder in molten lava");
			}
			else
				/* Player refuse to go. */
				can_move = FALSE;
		}

		if (tf_has(f_ptr->flags, TF_FALL)) {
			/* Bats, dragons can fly */
			if (!(p_ptr->schange == SHAPE_BAT) &&
				!(p_ptr->schange == SHAPE_WYRM)) {
				/* Assume player will continue. */
				temp = TRUE;

				/* Smart enough to stop running. */
				if (p_ptr->running) {
					if (!get_check
						("You have come to a cliff.  Step off it? ")) {
						can_move = FALSE;
						temp = FALSE;
						p_ptr->running = 0;
					}
				}

				/* Smart enough to sense trouble. */
				else if (!p_ptr->timed[TMD_BLIND]) {
					if (!get_check("It's a cliff! Really step off it? ")) {
						can_move = FALSE;
						temp = FALSE;
					}
				}

				/* Step off if confirmed. */
				if (temp) {
					/* Will take serious damage. */
					falling = TRUE;
				}
			}
		}
	}

	/* If the player can move, handle various things. */
	if (can_move) {
		/* Move player */
		monster_swap(py, px, y, x);

		/* Update speed if stepping out of water */
		if (tf_has(f_info[cave_feat[py][px]].flags, TF_WATERY))
			p_ptr->update |= PU_BONUS;

		/* Update stealth for Unlight */
		if (player_has(PF_UNLIGHT))
			p_ptr->update |= PU_BONUS;

		/* Update speed for elven woodspersons */
		if (player_has(PF_WOODSMAN) && player_has(PF_ELVEN))
			p_ptr->update |= PU_BONUS;

		/* Superstealth for ents in trees SJGU */
		if ((player_has(PF_WOODEN)) &&
			(tf_has
			 (f_info[cave_feat[p_ptr->py][p_ptr->px]].flags, TF_TREE))) {
			if (!(tf_has(f_info[cave_feat[py][px]].flags, TF_TREE))
				|| !(p_ptr->timed[TMD_SSTEALTH])) {
				(void) inc_timed(TMD_SSTEALTH, 1, FALSE);
				p_ptr->update |= (PU_BONUS);
			}
		} else if ((player_has(PF_WOODEN))
				   && (tf_has(f_info[cave_feat[py][px]].flags, TF_TREE))) {
			if (p_ptr->timed[TMD_SSTEALTH]) {
				(void) dec_timed(TMD_SSTEALTH, 1, FALSE);
				p_ptr->update |= (PU_BONUS);
			}
		}

		/* New location */
		y = py = p_ptr->py;
		x = px = p_ptr->px;
		f_ptr = &f_info[cave_feat[y][x]];

		/* Fall off a cliff */
		if (falling)
			fall_off_cliff();

		/* Spontaneous Searching */
		if (p_ptr->state.skills[SKILL_SEARCH_FREQUENCY] > 49) {
			(void) search(FALSE);
		} else if (0 ==
				   randint0(50 -
							p_ptr->state.skills[SKILL_SEARCH_FREQUENCY])) {
			(void) search(FALSE);
		}

		/* Continuous Searching */
		if (p_ptr->searching) {
			(void) search(FALSE);
		}

		/* Handle "store doors" */
		if (tf_has(f_ptr->flags, TF_SHOP)) {
			/* Disturb */
			disturb(0, 0);
			cmd_insert(CMD_ENTER_STORE);
		}

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

		/* Flying players have a chance to miss traps */
		if ((p_ptr->schange == SHAPE_BAT)
			|| (p_ptr->schange == SHAPE_WYRM)) {
			if (cave_invisible_trap(y, x) && cave_player_trap(y, x)
				&& (randint0(3) != 0))
				trapped = FALSE;
			else if (cave_visible_trap(y, x) && cave_player_trap(y, x) &&
					 (randint0(10) != 0))
				trapped = FALSE;
		}

		/* Discover invisible traps */
		if (cave_invisible_trap(y, x) && trapped) {
			/* Disturb */
			disturb(0, 0);

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

		/* Set off a visible trap */
		else if (cave_visible_trap(y, x) && cave_player_trap(y, x) &&
				 trapped) {
			/* Disturb */
			disturb(0, 0);

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

		/* Walk on a monster trap */
		else if (cave_monster_trap(y, x)) {
			msg("You inspect your cunning trap.");
		}
	}
}
예제 #17
0
파일: cmd1.c 프로젝트: Rydelfox/Ponyband
/**
 * Move player in the given direction, with the given "pickup" flag.
 *
 * 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/etc.
 */
void move_player(int dir, bool no_options)
{
	unsigned int py = p_ptr->py;
	unsigned int px = p_ptr->px;

	byte str_escape, dex_escape;

	/* Permit the player to move? */
	bool can_move = FALSE;

	/* Player is jumping off a cliff */
	bool falling = FALSE;

	/* Player hits a trap (always unless flying) */
	bool trapped = TRUE;
	
	/* Sliding on the ice */
	bool icy_slide = FALSE;

	int temp;
	unsigned int y, x;

	feature_type *f_ptr;

	/* Find the result of moving */
	y = py + ddy[dir];
	x = px + ddx[dir];
	f_ptr = &f_info[cave_feat[y][x]];


	/* Hack -- attack monsters */
	if (cave_m_idx[y][x] > 0) {
		/* Attack */
		if (py_attack(y, x, TRUE))
			return;
	}

	/* It takes some dexterity, or failing that strength, to get out of pits */
	if (cave_feat[py][px] == FEAT_PIT) {
		str_escape = adj_dex_dis[p_ptr->state.stat_ind[A_STR]];
		dex_escape = adj_dex_dis[p_ptr->state.stat_ind[A_DEX]];

		/* First attempt to leap out of the pit, */
		if ((dex_escape + 1) * 2 < randint1(16)) {
			/* then attempt to climb out of the pit. */
			if (str_escape + 3 < randint1(16)) {
				/* Failure costs a turn. */
				msg("You remain stuck in the pit.");
				/* Failure clears movement */
				p_ptr->previous_action[0] = ACTION_NOTHING;
				return;
			} else
				msg("You clamber out of the pit.");
		} else
			msg("You leap out of the pit.");
	}


	/* Rooted players cannot move */
	if (p_ptr->timed[TMD_ROOT])
	{
		can_move = FALSE;
		msg("You are rooted to the ground and can't move.");
		
		/* Prevent repeated attempts */
		disturb(0, 0);
		
		return;
	}
	
	/* Option to disarm a visible trap. -TNB- */
	/* Hack - Rogues can walk over their own trap - BR */
	else if (cave_visible_trap(y, x) && cave_player_trap(y, x)
			&& OPT(easy_alter)) {
		bool more = FALSE;
		/* Auto-repeat if not already repeating */
		if (cmd_get_nrepeats() == 0)
			cmd_set_repeat(99);

		more = do_cmd_disarm_aux(y, x);

		/* Cancel repeat unless we may continue */
		if (!more)
			disturb(0, 0);
		return;
	}

	/* Some terrain is impassable for the player, such as stone walls. */
	else if (!tf_has(f_ptr->flags, TF_PASSABLE)) {
		/* Disturb the player */
		disturb(0, 0);

		/* Notice unknown obstacles */
		if (!sqinfo_has(cave_info[y][x], SQUARE_MARK)) {
			/* Closed door */
			if (tf_has(f_ptr->flags, TF_DOOR_CLOSED)) {
				msgt(MSG_HITWALL, "You feel a door blocking your way.");
				sqinfo_on(cave_info[y][x], SQUARE_MARK);
				light_spot(y, x);
			}

			/* Wall (or secret door) */
			else {
				msgt(MSG_HITWALL, "You feel a wall blocking your way.");
				sqinfo_on(cave_info[y][x], SQUARE_MARK);
				light_spot(y, x);
			}
		}

		/* Mention known obstacles */
		else {
			/* Closed door */
			if (tf_has(f_ptr->flags, TF_DOOR_CLOSED)) {
				/* Option to automatically open doors. -TNB- */
				if (OPT(easy_alter)) {
					bool more = FALSE;

					/* Auto-repeat if not already repeating */
					if (cmd_get_nrepeats() == 0)
						cmd_set_repeat(99);

					/* Open the door */
					more = do_cmd_open_aux(y, x);

					/* Cancel repeat unless we may continue */
					if (!more)
						disturb(0, 0);
					/* Clear action list */
					p_ptr->previous_action[0] = ACTION_NOTHING;
                    return;
				}

				/* Otherwise, a message. */
				msgt(MSG_HITWALL, "There is a door blocking your way.");
			}

			/* Wall (or secret door) */
			else {
				msgt(MSG_HITWALL, "There is a wall blocking your way.");
			}
		}

		/* Sound */
		sound(MSG_HITWALL);
	}

	/* Normal movement */
	else {
		/* Assume terrain can be traversed normally. */
		can_move = TRUE;

		/* Terrain blocked by a friendly monster */
		if (cave_m_idx[y][x] > 0)
		{
		    monster_type *n_ptr = & m_list[cave_m_idx[y][x]];
		    
		    /* Push monster if it doesn't have a target and hasn't been pushed.
			 * This allows the player to move into a corridor with a monster in
			 * front of him, and have the monster move ahead, if it is faster. If its
			 * not faster, the player will push over it on the second move, as the push
			 * flag below will have been set. */
			 if(((n_ptr->mflag & MFLAG_PUSH) == 0) && !(n_ptr->ty) && !(n_ptr->tx) && push_aside_player(p_ptr->py, p_ptr->px, n_ptr))
			 {
			     int dy = n_ptr->fy - y;
			     int dx = n_ptr->fx - x;
			     unsigned int count = 0;
			     
			     n_ptr->ty = n_ptr->fy;
			     n_ptr->tx = n_ptr->fx;
			     
			     /* Hack -- get new target as far as the monster can move in the direction
				 * pushed. We do this with a walking stick approach to prevent us getting
				 * invalid target locations like (0,0) */
				while (in_bounds_fully(n_ptr->ty + dy, n_ptr->tx + dx)
						&& cave_exist_mon(&r_info[n_ptr->r_idx], n_ptr->ty + dy, n_ptr->tx + dx, TRUE)
						&& (count++ < (MAX_SIGHT / 2)))
				{
					n_ptr->ty = n_ptr->ty + dy;
					n_ptr->tx = n_ptr->tx + dx;
				}

				/* Clear target if none available */
				if ((n_ptr->ty == n_ptr->fy) && (n_ptr->tx == n_ptr->fx))
				{
					n_ptr->ty = 0;
					n_ptr->tx = 0;
				}
			}

			/* The other monster cannot switch places */
			else if (!cave_exist_mon(&r_info[n_ptr->r_idx], p_ptr->py, p_ptr->px, TRUE))
			{
				/* Try to push it aside. Allow aborting of move if an ally */
				if ((!push_aside_player(p_ptr->py, p_ptr->px, n_ptr)) && (get_reaction(F_PLAYER, n_ptr->faction) <= REACT_FRIEND))
				{
					/* No warning if sliding */
					if (no_options)	{}
					/* Don't provide more warning */
					else if (!get_check("Are you sure?")) 
					{
					    temp = FALSE;
					    p_ptr->running = 0;
					    can_move = FALSE;
					}
				}
			}

			/* Hack -- we clear the target if we move over a monster */
			else
			{
				n_ptr->ty = 0;
				n_ptr->tx = 0;
			}

			/* Mark monsters as pushed */
			n_ptr->mflag |= (MFLAG_PUSH);
		}
        
        /*** Handle traversable terrain.  ***/
		if (tf_has(f_ptr->flags, TF_ROCK)) {
			/* Dwarves move easily through rubble */
			if (player_has(PF_DWARVEN))
				can_move = TRUE;

			/* Bats, dragons can fly */
			else if ((p_ptr->schange == SHAPE_BAT)
					 || (p_ptr->schange == SHAPE_WYRM))
				can_move = TRUE;

			/* Require more energy */
			else {
				can_move = TRUE;
				p_ptr->energy_use += 100;
			}
		}

		if (tf_has(f_ptr->flags, TF_TREE)) {
			/* Druids, rangers, Plant Cutie Marks slip easily under
			 * trees */
			if ((player_has(PF_WOODSMAN)) || (player_has(PF_PLANT_FRIEND)))
				can_move = TRUE;

			/* Bats, dragons can fly */
			else if ((p_ptr->schange == SHAPE_BAT)
					 || (p_ptr->schange == SHAPE_WYRM))
				can_move = TRUE;

			/* Require more energy */
			else {
				can_move = TRUE;
				p_ptr->energy_use += 100;
			}
		}

		/* Water now slows rather than stopping -NRM- */
		if (tf_has(f_ptr->flags, TF_WATERY)) {
			/* Stop any run. */
			disturb(0, 0);

			can_move = TRUE;

			/* Speed will need updating */
			p_ptr->update |= PU_BONUS;
		}
		
		/* Walking on to ice can cause you to slide an additional square. */
		if (tf_has(f_ptr->flags, TF_ICY)) {
			/* Stop any run */
			disturb(0, 0);
			
			can_move = TRUE;
			
			/* Slide is less likely with Cold Resist. Never slide with Levitation */
			if (!p_ptr->state.ffall && ((!p_immune(P_RES_COLD)) && (randint1((p_resist_pos(P_RES_COLD) || p_resist_strong(P_RES_COLD)) ? 2 : 4) != 1)))
			    icy_slide = TRUE;
			
			/* Speed will need updating */
			p_ptr->update |= PU_BONUS;
		}

		if (tf_has(f_ptr->flags, TF_FIERY)) {
			/* Assume player will continue. */
			temp = TRUE;

			/* Smart enough to stop running. */
			if (p_ptr->running) {
				/* Ice keeps sliding */
				if (no_options) {}
				else if (!get_check("Lava blocks your path.  Step into it? ")) {
					temp = FALSE;
					p_ptr->running = 0;
				}
			}

			/* Smart enough to sense trouble. */
			else if ((!p_resist_pos(P_RES_FIRE))
					 || (!p_resist_strong(P_RES_FIRE)
						 && (p_ptr->chp <= 100))
					 || (!p_immune(P_RES_FIRE) && (p_ptr->chp <= 30))) {
				/* Sliding continues regardless */
				if (no_options) {}
				else if (!get_check
					("The heat of the lava scalds you! Really enter? ")) {
					temp = FALSE;
				}
			}

			/* Enter if OK or confirmed. */
			if (temp) {
				/* Can always cross. */
				can_move = TRUE;

				/* Feather fall makes one lightfooted. */
				if (p_ptr->state.ffall) {
					notice_obj(OF_FEATHER, 0);
					temp = 49 + randint1(51);
				} else
					temp = 124 + randint1(126);

				/* Will take serious fire damage. */
				fire_dam(temp, "burnt to a cinder in molten lava", SOURCE_ENVIRONMENTAL);
			}
			else
				/* Player refuse to go. */
				can_move = FALSE;
		}
		
		if (tf_has(f_ptr->flags, TF_BURNING))
		{
            /* Assume player will continue */
            temp = TRUE;
            
            /* Smart enough to stop running */
            if (p_ptr->running)
            {
            	if (no_options) {}
				else if (!get_check("Your path is block by a burning tree. Step into it? "))
            	{
            		temp = FALSE;
            		p_ptr->running = 9;
            	}
            }
            
            /* Smart enough to sense trouble */
            else if ((!p_resist_pos(P_RES_FIRE))
					 || (!p_resist_strong(P_RES_FIRE)
						 && (p_ptr->chp <= 100))
					 || (!p_immune(P_RES_FIRE) && (p_ptr->chp <= 30))) {
				if (no_options) {}
				else if (!get_check
					("The heat of the fire burns you! Really enter? ")) {
					temp = FALSE;
				}
			}

			/* Enter if OK or confirmed. */
			if (temp) {
				/* Can always cross. */
				can_move = TRUE;

				/* Take light damage from the fire */
				temp = 49 + randint1(51);

				/* Will take serious fire damage. */
				fire_dam(temp, "burnt to death in a fire.", SOURCE_ENVIRONMENTAL);
			}
			else
				/* Player refuse to go. */
				can_move = FALSE;
		}

		if (tf_has(f_ptr->flags, TF_FALL)) {
			/* Bats, dragons can fly */
			if (!(p_ptr->schange == SHAPE_BAT) &&
				!(p_ptr->schange == SHAPE_WYRM)) {
				/* Assume player will continue. */
				temp = TRUE;

				/* Smart enough to stop running. */
				if (p_ptr->running) {
					if (no_options) {}
					else if (!get_check
						("You have come to a cliff.  Step off it? ")) {
						can_move = FALSE;
						temp = FALSE;
						p_ptr->running = 0;
					}
				}

				/* Smart enough to sense trouble. */
				else if (!p_ptr->timed[TMD_BLIND]) {
					if (no_options) {}
					else if (!get_check("It's a cliff! Really step off it? ")) {
						can_move = FALSE;
						temp = FALSE;
					}
				}

				/* Step off if confirmed. */
				if (temp) {
					/* Will take serious damage. */
					falling = TRUE;
				}
			}
		}
	}

	/* If the player can move, handle various things. */
	if (can_move) {
		/* Move player */
		monster_swap(py, px, y, x);

		/* Update speed if stepping out of water */
		if (tf_has(f_info[cave_feat[py][px]].flags, TF_WATERY))
			p_ptr->update |= PU_BONUS;

		/* Update stealth for Unlight */
		if (player_has(PF_UNLIGHT))
			p_ptr->update |= PU_BONUS;

		/* Update speed for Plant cutie mark woodspersons */
		if (player_has(PF_WOODSMAN) && player_has(PF_PLANT_FRIEND))
			p_ptr->update |= PU_BONUS;

		/* New location */
		y = py = p_ptr->py;
		x = px = p_ptr->px;
		f_ptr = &f_info[cave_feat[y][x]];
		    

		/* Fall off a cliff */
		if (falling)
			fall_off_cliff();
			
		
        /* Sliding on ice prevents searching */
        if (!icy_slide)
        {
			/* Spontaneous Searching */
			if (p_ptr->state.skills[SKILL_SEARCH_FREQUENCY] > 49) {
				(void) search(FALSE);
			} else if (0 ==
					   randint0(50 -
								p_ptr->state.skills[SKILL_SEARCH_FREQUENCY])) {
				(void) search(FALSE);
			}
	
			/* Continuous Searching */
			if (p_ptr->searching) {
				(void) search(FALSE);
			}
		}

		/* Handle "store doors" */
		if (tf_has(f_ptr->flags, TF_SHOP)) {
			/* Disturb */
			disturb(0, 0);
			cmd_insert(CMD_ENTER_STORE);
		}

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

		/* Flying players have a chance to miss traps */
		if ((p_ptr->schange == SHAPE_BAT)
			|| (p_ptr->schange == SHAPE_WYRM)) {
			if (cave_invisible_trap(y, x) && cave_player_trap(y, x)
				&& (randint0(3) != 0))
				trapped = FALSE;
			else if (cave_visible_trap(y, x) && cave_player_trap(y, x) &&
					 (randint0(10) != 0))
				trapped = FALSE;
		}

		/* Discover invisible traps */
		if (cave_invisible_trap(y, x) && trapped) {
			/* Disturb */
			disturb(0, 0);

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

		/* Set off a visible trap */
		else if (cave_visible_trap(y, x) && cave_player_trap(y, x) &&
				 trapped) {
			/* Disturb */
			disturb(0, 0);

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

		/* Walk on a monster trap */
		else if (cave_monster_trap(y, x)) {
			msg("You inspect your cunning trap.");
		}
		
		/* Slide an additional square on the ice */
		if (icy_slide)
		    move_player(dir, TRUE);
	}
}