Esempio n. 1
0
/**
 * 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 = square_trap(c, y, x);
	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);
}
Esempio n. 2
0
/**
 * Determine if a trap actually exists in this square.
 *
 * Called with vis = 0 to accept any trap, = 1 to accept only visible
 * traps, and = -1 to accept only invisible traps.
 *
 * Clear the SQUARE_TRAP flag if none exist.
 */
static bool square_verify_trap(struct chunk *c, int y, int x, int vis)
{
    struct trap *trap = square_trap(c, y, x);
    bool trap_exists = false;

    /* Scan the square trap list */
    while (trap) {
		/* Accept any trap */
		if (!vis)
			return true;

		/* Accept traps that match visibility requirements */
		if ((vis == 1) && trf_has(trap->flags, TRF_VISIBLE)) 
			return true;

		if ((vis == -1)  && !trf_has(trap->flags, TRF_VISIBLE)) 
			return true;

		/* Note that a trap does exist */
		trap_exists = true;
    }

    /* No traps in this location. */
    if (!trap_exists) {
		/* No traps */
		sqinfo_off(c->squares[y][x].info, SQUARE_TRAP);

		/* Take note */
		square_note_spot(c, y, x);
    }

    /* Report failure */
    return false;
}
Esempio n. 3
0
/**
 * Free memory for all traps on a grid
 */
void square_free_trap(struct chunk *c, int y, int x)
{
	struct trap *next, *trap = square_trap(c, y, x);

	while (trap) {
		next = trap->next;
		mem_free(trap);
		trap = next;
	}
}
Esempio n. 4
0
/**
 * Reveal some of the player traps in a square
 */
bool square_reveal_trap(struct chunk *c, int y, int x, bool always, bool domsg)
{
    int found_trap = 0;
	struct trap *trap = square_trap(c, y, x);
    
    /* 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;
		}
		
		/* Skip traps the player doesn't notice */
		if (!always && player->state.skills[SKILL_SEARCH] < trap->power) {
			trap = trap->next;
			continue;
		}

		/* Trap is invisible */
		if (!trf_has(trap->flags, TRF_VISIBLE)) {
			/* See the trap */
			trf_on(trap->flags, TRF_VISIBLE);
			square_memorize(c, y, x);

			/* We found a trap */
			found_trap++;
		}
		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 */
		square_memorize(c, y, x);

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

    /* Return true if we found any traps */
    return (found_trap != 0);
}
Esempio n. 5
0
/**
 * 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 = square_trap(c, y, x);
    
    /* 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);
			square_memorize(c, y, x);

			/* 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 */
		square_memorize(c, y, x);

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

    /* Return true if we found any traps */
    return (found_trap != 0);
}
Esempio n. 6
0
/**
 * 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 = square_trap(cave, y, x); 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, NULL, &ident, false, 0, 0, 0);

		/* 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);
}
Esempio n. 7
0
/**
 * Is there a trap with a given flag in this square?
 */
bool square_trap_flag(struct chunk *c, int y, int x, int flag)
{
    struct trap *trap = square_trap(c, y, x);

    /* First, check the trap marker */
    if (!square_istrap(c, y, x))
		return false;
	
    /* Scan the square trap list */
    while (trap) {
		/* We found a trap with the right flag */
		if (trf_has(trap->flags, flag))
			return true;
		trap = trap->next;
    }

    /* Report failure */
    return false;
}
Esempio n. 8
0
/**
 * Is there a specific kind of trap in this square?
 */
bool square_trap_specific(struct chunk *c, int y, int x, int t_idx)
{
    struct trap *trap = square_trap(c, y, x);
	
    /* First, check the trap marker */
    if (!square_istrap(c, y, x))
		return false;
	
    /* Scan the square trap list */
    while (trap) {
		/* We found a trap of the right kind */
		if (trap->t_idx == t_idx)
			return true;
		trap = trap->next;
	}

    /* Report failure */
    return false;
}
Esempio n. 9
0
/**
 * Lock a closed door to a given power
 */
void square_set_door_lock(struct chunk *c, int y, int x, int power)
{
	struct trap_kind *lock = lookup_trap("door lock");
	struct trap *trap;

	/* Verify it's a closed door */
	if (!square_iscloseddoor(c, y, x))
		return;

	/* If there's no lock there, add one */
	if (!square_trap_specific(c, y, x, lock->tidx))
		place_trap(c, y, x, lock->tidx, 0);

	/* Set the power (of all locks - there should be only one) */
	trap = square_trap(c, y, x);
	while (trap) {
		if (trap->kind == lock)
			trap->xtra = power;
		trap = trap->next;
	}
}
Esempio n. 10
0
/**
 * Return the power of the lock on a door
 */
int square_door_power(struct chunk *c, int y, int x)
{
	struct trap_kind *lock = lookup_trap("door lock");
	struct trap *trap;

	/* Verify it's a closed door */
	if (!square_iscloseddoor(c, y, x))
		return 0;

	/* Is there a lock there? */
	if (!square_trap_specific(c, y, x, lock->tidx))
		return 0;

	/* Get the power and return it */
	trap = square_trap(c, y, x);
	while (trap) {
		if (trap->kind == lock)
			return trap->xtra;
		trap = trap->next;
	}

	return 0;
}
Esempio n. 11
0
/**
 * Count the number of player traps in this location.
 *
 * Called with vis = 0 to accept any trap, = 1 to accept only visible
 * traps, and = -1 to accept only invisible traps.
 */
int num_traps(struct chunk *c, int y, int x, int vis)
{
    int num = 0;
	struct trap *trap;

	/* Look at the traps in this grid */
	for (trap = square_trap(c, y, x); trap; trap = trap->next) {
		/* Require that trap be capable of affecting the character */
		if (!trf_has(trap->kind->flags, TRF_TRAP)) continue;
	    
		/* Require correct visibility */
		if (vis >= 1) {
			if (trf_has(trap->flags, TRF_VISIBLE)) num++;
		} else if (vis <= -1) {
			if (!trf_has(trap->flags, TRF_VISIBLE)) num++;
		} else {
			num++;
		}
	}

    /* Return the number of traps */
    return (num);
}
Esempio n. 12
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);
}