示例#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);
}
/**
 * Set the terrain type for a square.
 *
 * This should be the only function that sets terrain, apart from the savefile
 * loading code.
 */
void square_set_feat(struct chunk *c, int y, int x, int feat)
{
	int current_feat = c->squares[y][x].feat;

	assert(c);
	assert(y >= 0 && y < c->height);
	assert(x >= 0 && x < c->width);

	/* Track changes */
	if (current_feat) c->feat_count[current_feat]--;
	if (feat) c->feat_count[feat]++;

	/* Make the change */
	c->squares[y][x].feat = feat;

	/* Make the new terrain feel at home */
	if (character_dungeon) {
		/* Remove traps if necessary */
		if (!square_player_trap_allowed(c, y, x))
			square_destroy_trap(c, y, x);

		square_note_spot(c, y, x);
		square_light_spot(c, y, x);
	} else {
		/* Make sure no incorrect wall flags set for dungeon generation */
		sqinfo_off(c->squares[y][x].info, SQUARE_WALL_INNER);
		sqinfo_off(c->squares[y][x].info, SQUARE_WALL_OUTER);
		sqinfo_off(c->squares[y][x].info, SQUARE_WALL_SOLID);
	}
}
示例#3
0
/* Destroy Traps (and Locks) */
static void project_feature_handler_KILL_TRAP(project_feature_handler_context_t *context)
{
	const int x = context->x;
	const int y = context->y;

	/* Reveal secret doors */
	if (square_issecretdoor(cave, y, x)) {
		place_closed_door(cave, y, x);

		/* Check line of sight */
		if (square_isseen(cave, y, x))
			context->obvious = true;
	}

	/* Destroy traps, unlock doors */
	if (square_istrap(cave, y, x)) {
		/* Check line of sight */
		if (square_isview(cave, y, x)) {
			msg("There is a bright flash of light!");
			context->obvious = true;
		}

		/* Destroy the trap */
		square_destroy_trap(cave, y, x);
	} else if (square_islockeddoor(cave, y, x)) {
		/* Unlock the door */
		square_unlock_door(cave, y, x);

		/* Check line of sound */
		if (square_isview(cave, y, x)) {
			msg("Click!");
			context->obvious = true;
		}
	}
}
示例#4
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);
	}
}
示例#5
0
void square_add_stairs(struct chunk *c, int y, int x, int depth) {
	int down = randint0(100) < 50;
	if (depth == 0)
		down = 1;
	else if (is_quest(depth) || depth >= z_info->max_depth - 1)
		down = 0;

	/* Remove any traps */
	square_destroy_trap(c, y, x);

	square_set_feat(c, y, x, down ? FEAT_MORE : FEAT_LESS);
}
示例#6
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);
}
示例#7
0
文件: trap.c 项目: magnate/angband
/**
 * 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);
}