Example #1
0
/**
 * Perform the basic "disarm" command
 *
 * Assume there is no monster blocking the destination
 *
 * Returns true if repeated commands may continue
 */
static bool do_cmd_disarm_aux(int y, int x)
{
	int skill, power, chance;
    struct trap *trap = cave->squares[y][x].trap;
	bool more = false;

	/* Verify legality */
	if (!do_cmd_disarm_test(y, x)) return (false);

    /* Choose first player trap */
	while (trap) {
		if (trf_has(trap->flags, TRF_TRAP))
			break;
		trap = trap->next;
	}
	if (!trap)
		return false;

	/* Get the base disarming skill */
	if (trf_has(trap->flags, TRF_MAGICAL))
		skill = player->state.skills[SKILL_DISARM_MAGIC];
	else
		skill = player->state.skills[SKILL_DISARM_PHYS];

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

	/* Extract trap power */
	power = cave->depth / 5;

	/* Extract the percentage success */
	chance = skill - power;

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

	/* Two chances - one to disarm, one not to set the trap off */
	if (randint0(100) < chance) {
		msgt(MSG_DISARM, "You have disarmed the %s.", trap->kind->name);
		player_exp_gain(player, power);

		/* Trap is gone */
		square_forget(cave, y, x);
		square_destroy_trap(cave, y, x);
	} else if (randint0(100) < chance) {
		event_signal(EVENT_INPUT_FLUSH);
		msg("You failed to disarm the %s.", trap->kind->name);

		/* Player can try again */
		more = true;
	} else {
		msg("You set off the %s!", trap->kind->name);
		hit_trap(y, x);
	}

	/* Result */
	return (more);
}
Example #2
0
/* Destroy Doors (and traps) */
static void project_feature_handler_KILL_DOOR(project_feature_handler_context_t *context)
{
	const int x = context->x;
	const int y = context->y;

	/* Destroy all doors and traps */
	if (square_isplayertrap(cave, y, x) || square_isdoor(cave, y, x)) {
		/* Check line of sight */
		if (square_isview(cave, y, x)) {
			/* Message */
			msg("There is a bright flash of light!");
			context->obvious = true;

			/* Visibility change */
			if (square_isdoor(cave, y, x))
				player->upkeep->update |= (PU_UPDATE_VIEW | PU_MONSTERS);

			/* Forget the door */
			square_forget(cave, y, x);
		}

		/* Destroy the feature */
		if (square_isdoor(cave, y, x))
			square_destroy_door(cave, y, x);
		else
			square_destroy_trap(cave, y, x);
	}
}
Example #3
0
/**
 * This routine will "darken" all grids in the set passed in.
 *
 * In addition, some of these grids will be "unmarked".
 *
 * This routine is used (only) by "light_room()"
 */
static void cave_unlight(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;

		/* Darken the grid */
		if (!square_isbright(cave, y, x)) {
			sqinfo_off(cave->squares[y][x].info, SQUARE_GLOW);
		}

		/* Hack -- Forget "boring" grids */
		if (square_isfloor(cave, y, x))
			square_forget(cave, y, x);
	}

	/* 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);
	}
}
Example #4
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;
			
			/* 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 || !square_isfloor(c, y, x)) {
				sqinfo_on(c->squares[y][x].info, SQUARE_GLOW);
				square_memorize(c, y, x);
			} else if (!square_isbright(c, y, x)) {
				sqinfo_off(c->squares[y][x].info, SQUARE_GLOW);
				square_forget(c, y, x);
			}
		}
	}
			
			
	/* 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);
				square_memorize(c, yy, xx);
			}
		}
	}


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

	/* Redraw map, monster list */
	player->upkeep->redraw |= (PR_MAP | PR_MONLIST | PR_ITEMLIST);
}
Example #5
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, 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);
}
Example #6
0
/**
 * 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 (!(square_isdiggable(cave, y, x) || square_iscloseddoor(cave, y, x)))
		return (false);

	/* Sound */
	sound(MSG_DIG);

	/* Forget the wall */
	square_forget(cave, y, x);

	/* Remove the feature */
	square_tunnel_wall(cave, y, x);

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

	/* Fully update the flow */
	player->upkeep->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW);

	/* Result */
	return (true);
}
Example #7
0
/**
 * Try to break a glyph.
 */
static bool process_monster_glyph(struct chunk *c, struct monster *mon,
								  int nx, int ny)
{
	assert(square_iswarded(c, ny, nx));

	/* Break the ward */
	if (randint1(z_info->glyph_hardness) < mon->race->level) {
		/* Describe observable breakage */
		if (square_isseen(c, ny, nx)) {
			msg("The rune of protection is broken!");

			/* Forget the rune */
			square_forget(c, ny, nx);
		}

		/* Break the rune */
		square_remove_ward(c, ny, nx);

		return true;
	}

	/* Unbroken ward - can't move */
	return false;
}
Example #8
0
/* Destroy walls (and doors) */
static void project_feature_handler_KILL_WALL(project_feature_handler_context_t *context)
{
	const int x = context->x;
	const int y = context->y;

	/* Non-walls (etc) */
	if (square_ispassable(cave, y, x)) return;

	/* Permanent walls */
	if (square_isperm(cave, y, x)) return;

	/* Different treatment for different walls */
	if (square_iswall(cave, y, x) && !square_hasgoldvein(cave, y, x)) {
		/* Message */
		if (square_isseen(cave, y, x)) {
			msg("The wall turns into mud!");
			context->obvious = true;

			/* Forget the wall */
			square_forget(cave, y, x);
		}

		/* Destroy the wall */
		square_destroy_wall(cave, y, x);
	} else if (square_iswall(cave, y, x) && square_hasgoldvein(cave, y, x)) {
		/* Message */
		if (square_isseen(cave, y, x)) {
			msg("The vein turns into mud!");
			msg("You have found something!");
			context->obvious = true;

			/* Forget the wall */
			square_forget(cave, y, x);
		}

		/* Destroy the wall */
		square_destroy_wall(cave, y, x);

		/* Place some gold */
		place_gold(cave, y, x, player->depth, ORIGIN_FLOOR);
	} else if (square_ismagma(cave, y, x) || square_isquartz(cave, y, x)) {
		/* Message */
		if (square_isseen(cave, y, x)) {
			msg("The vein turns into mud!");
			context->obvious = true;

			/* Forget the wall */
			square_forget(cave, y, x);
		}

		/* Destroy the wall */
		square_destroy_wall(cave, y, x);
	} else if (square_isrubble(cave, y, x)) {
		/* Message */
		if (square_isseen(cave, y, x)) {
			msg("The rubble turns into mud!");
			context->obvious = true;

			/* Forget the wall */
			square_forget(cave, y, x);
		}

		/* Destroy the rubble */
		square_destroy_rubble(cave, y, x);

		/* Hack -- place an object */
		if (randint0(100) < 10){
			if (square_isseen(cave, y, x)) {
				msg("There was something buried in the rubble!");
				context->obvious = true;
			}
			place_object(cave, y, x, player->depth, false, false,
						 ORIGIN_RUBBLE, 0);
		}
	} else if (square_isdoor(cave, y, x)) {
		/* Hack -- special message */
		if (square_isseen(cave, y, x)) {
			msg("The door turns into mud!");
			context->obvious = true;

			/* Forget the wall */
			square_forget(cave, y, x);
		}

		/* Destroy the feature */
		square_destroy_door(cave, y, x);
	}

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

	/* Fully update the flow */
	player->upkeep->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW);
}
Example #9
0
/**
 * Perform the basic "disarm" command
 *
 * Assume there is no monster blocking the destination
 *
 * Returns true if repeated commands may continue
 */
static bool do_cmd_disarm_aux(int y, int x)
{
	int i, j, power;
    struct trap *trap = cave->squares[y][x].trap;
	bool more = false;


	/* Verify legality */
	if (!do_cmd_disarm_test(y, x)) return (false);


    /* Choose first player trap */
	while (trap) {
		if (trf_has(trap->flags, TRF_TRAP))
			break;
		trap = trap->next;
	}
	if (!trap)
		return false;

	/* Get the "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;

	/* XXX XXX XXX Variable power? */

	/* Extract trap "power" */
	power = 5;

	/* Extract the difficulty */
	j = i - power;

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

	/* Success */
	if (randint0(100) < j) {
		/* Message */
		msgt(MSG_DISARM, "You have disarmed the %s.", trap->kind->name);

		/* Reward */
		player_exp_gain(player, power);

		/* Forget the trap */
		square_forget(cave, y, x);

		/* Remove the trap */
		square_destroy_trap(cave, y, x);
	} else if ((i > 5) && (randint1(i) > 5)) {
		/* Failure -- Keep trying */
		event_signal(EVENT_INPUT_FLUSH);
		msg("You failed to disarm the %s.", trap->kind->name);
		more = true;
	} else {
		/* Failure -- Set off the trap */
		msg("You set off the %s!", trap->kind->name);
		hit_trap(y, x);
	}

	/* Result */
	return (more);
}
Example #10
0
/**
 * Hit a trap. 
 */
extern void hit_trap(int y, int x)
{
	bool ident = false;
	struct trap *trap;
	struct effect *effect;

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

	/* The player is safe from all traps */
	if (player_is_trapsafe(player)) return;

    /* 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 = square_trap(cave, y, x); trap; trap = trap->next) {
		int flag;
		bool saved = false;

		/* Require that trap be capable of affecting the character */
		if (!trf_has(trap->kind->flags, TRF_TRAP)) continue;
		if (trap->timeout) continue;

		/* Disturb the player */
		disturb(player, 0);

		/* Give a message */
		if (trap->kind->msg)
			msg(trap->kind->msg);

		/* Test for save due to flag */
		for (flag = of_next(trap->kind->save_flags, FLAG_START);
			 flag != FLAG_END;
			 flag = of_next(trap->kind->save_flags, flag + 1))
			if (player_of_has(player, flag)) {
				saved = true;
				equip_learn_flag(player, flag);
			}

		/* Test for save due to armor */
		if (trf_has(trap->kind->flags, TRF_SAVE_ARMOR) && !trap_check_hit(125))
			saved = true;

		/* Test for save due to saving throw */
		if (trf_has(trap->kind->flags, TRF_SAVE_THROW) &&
			(randint0(100) < player->state.skills[SKILL_SAVE]))
			saved = true;

		/* Save, or fire off the trap */
		if (saved) {
			if (trap->kind->msg_good)
				msg(trap->kind->msg_good);
		} else {
			if (trap->kind->msg_bad)
				msg(trap->kind->msg_bad);
			effect = trap->kind->effect;
			effect_do(effect, source_trap(trap), NULL, &ident, false, 0, 0, 0);

			/* Do any extra effects */
			if (trap->kind->effect_xtra && one_in_(2)) {
				if (trap->kind->msg_xtra)
					msg(trap->kind->msg_xtra);
				effect = trap->kind->effect_xtra;
				effect_do(effect, source_trap(trap), NULL, &ident, false, 0, 0, 0);
			}
		}

		/* Some traps drop you a dungeon level */
		if (trf_has(trap->kind->flags, TRF_DOWN))
			dungeon_change_level(player,
								 dungeon_get_next_level(player->depth, 1));

		/* Some traps drop you onto them */
		if (trf_has(trap->kind->flags, TRF_PIT))
			monster_swap(player->py, player->px, trap->fy, trap->fx);

		/* Some traps disappear after activating, all have a chance to */
		if (trf_has(trap->kind->flags, TRF_ONETIME) || one_in_(3)) {
			square_destroy_trap(cave, y, x);
			square_forget(cave, y, x);
		}

		/* Trap may have gone */
		if (!square_trap(cave, y, x)) break;

		/* Trap becomes visible (always XXX) */
		trf_on(trap->flags, TRF_VISIBLE);
		square_memorize(cave, y, x);
	}

    /* Verify traps (remove marker if appropriate) */
    (void)square_verify_trap(cave, y, x, 0);
}