Exemplo n.º 1
0
void monk_double_attack_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Double Attack");
        break;
    case SPELL_DESC:
        var_set_string(res, "Attack twice at an adjacent enemy. This action consumes double the normal energy.");
        break;
    case SPELL_CAST:
        var_set_bool(res, FALSE);
        if (_monk_check_spell())
        {
            int x, y, dir = 0;

            if (!get_rep_dir(&dir, FALSE)) return;

            y = py + ddy[dir];
            x = px + ddx[dir];
            if (cave[y][x].m_idx)
            {
                if (one_in_(2)) msg_print("Ahhhtatatatatatatatatatatatatatataatatatatattaaaaa!!!!");
                else msg_print("Oraoraoraoraoraoraoraoraoraoraoraoraoraoraoraoraora!!!!");

                py_attack(y, x, 0);
                if (cave[y][x].m_idx)
                {
                    handle_stuff();
                    py_attack(y, x, 0);
                }
            }
            else
            {
                msg_print("You don't see any monster in this direction");
                msg_print(NULL);
            }
            var_set_bool(res, TRUE);
        }
        break;
    case SPELL_ENERGY:
        var_set_int(res, 100 + ENERGY_NEED());
        break;
    default:
        default_spell(cmd, res);
        break;
    }
}
Exemplo n.º 2
0
void _scatter_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Scatter");
        break;
    case SPELL_DESC:
        var_set_string(res, "Attack all adjacent monsters with a single strike. If landed, your enemies will be scattered away from you.");
        break;
    case SPELL_CAST:
    {
        int              dir, x, y;
        cave_type       *c_ptr;
        monster_type    *m_ptr;

        for (dir = 0; dir < 8; dir++)
        {
            y = py + ddy_ddd[dir];
            x = px + ddx_ddd[dir];
            c_ptr = &cave[y][x];

            m_ptr = &m_list[c_ptr->m_idx];

            if (c_ptr->m_idx && (m_ptr->ml || cave_have_flag_bold(y, x, FF_PROJECT)))
                py_attack(y, x, MAULER_SCATTER);
        }
        var_set_bool(res, TRUE);
        break;
    }
    default:
        default_spell(cmd, res);
        break;
    }
}
Exemplo n.º 3
0
/*
 * Tunnel through "walls" (including rubble and secret doors)
 *
 * Digging is very difficult without a "digger" weapon, but can be
 * accomplished by strong players using heavy weapons.
 */
void do_cmd_tunnel(cmd_code code, cmd_arg args[])
{
	int y, x, dir;
	bool more = FALSE;

	dir = args[0].direction;

	/* Get location */
	y = p_ptr->py + ddy[dir];
	x = p_ptr->px + ddx[dir];


	/* Oops */
	if (!do_cmd_tunnel_test(y, x))
	{
		/* Cancel repeat */
		disturb(0, 0);
		return;
	}

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

	/* Apply confusion */
	if (confuse_dir(&dir))
	{
		/* Get location */
		y = p_ptr->py + ddy[dir];
		x = p_ptr->px + ddx[dir];
	}


	/* Monster */
	if (cave_m_idx[y][x] > 0)
	{
		if (mon_list[cave_m_idx[y][x]].align & (AL_PET_MASK))
		{
			msg_print("There is a friendly monster in the way!");
		}
		else
		{
			/* Message */
			msg_print("There is a monster in the way!");

			/* Attack */
			py_attack(y, x);
		}
	}

	/* Walls */
	else
	{
		/* Tunnel through walls */
		more = do_cmd_tunnel_aux(y, x);
	}

	/* Cancel repetition unless we can continue */
	if (!more) disturb(0, 0);
}
Exemplo n.º 4
0
/*
 * Close an open door.
 */
void do_cmd_close(cmd_code code, cmd_arg args[])
{
	int y, x, dir;

	bool more = FALSE;

	dir = args[0].direction;

	/* Get location */
	y = p_ptr->py + ddy[dir];
	x = p_ptr->px + ddx[dir];

	/* Verify legality */
	if (!do_cmd_close_test(y, x))
	{
		/* Cancel repeat */
		disturb(0, 0);
		return;
	}

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

	/* Apply confusion */
	if (confuse_dir(&dir))
	{
		/* Get location */
		y = p_ptr->py + ddy[dir];
		x = p_ptr->px + ddx[dir];
	}


	/* Monster */
	if (cave_m_idx[y][x] > 0)
	{
		if (mon_list[cave_m_idx[y][x]].align & (AL_PET_MASK))
			msg_print("There is a friendly monster in the way!");
		else
		{
			/* Message */
			msg_print("There is a monster in the way!");

			/* Attack */
			py_attack(y, x);
		}
	}

	/* Door */
	else
	{
		/* Close door */
		more = do_cmd_close_aux(y, x);
	}

	/* Cancel repeat unless told not to */
	if (!more) disturb(0, 0);
}
Exemplo n.º 5
0
/**
 * Close an open door.
 */
void do_cmd_close(struct command *cmd)
{
	int y, x, dir;
	int err;

	bool more = false;

	/* Get arguments */
	err = cmd_get_arg_direction(cmd, "direction", &dir);
	if (err || dir == DIR_UNKNOWN) {
		int y2, x2;

		/* Count open doors */
		if (count_feats(&y2, &x2, square_isopendoor, false) == 1) {
			dir = coords_to_dir(y2, x2);
			cmd_set_arg_direction(cmd, "direction", dir);
		} else if (cmd_get_direction(cmd, "direction", &dir, false)) {
			return;
		}
	}

	/* Get location */
	y = player->py + ddy[dir];
	x = player->px + ddx[dir];

	/* Verify legality */
	if (!do_cmd_close_test(y, x)) {
		/* Cancel repeat */
		disturb(player, 0);
		return;
	}

	/* Take a turn */
	player->upkeep->energy_use = z_info->move_energy;

	/* Apply confusion */
	if (player_confuse_dir(player, &dir, false)) {
		/* Get location */
		y = player->py + ddy[dir];
		x = player->px + ddx[dir];
	}

	/* Monster - alert, then attack */
	if (cave->squares[y][x].mon > 0) {
		msg("There is a monster in the way!");
		py_attack(y, x);
	} else
		/* Door - close it */
		more = do_cmd_close_aux(y, x);

	/* Cancel repeat unless told not to */
	if (!more) disturb(player, 0);
}
Exemplo n.º 6
0
/*
 * Tunnel through "walls" (including rubble and secret doors)
 *
 * Digging is very difficult without a "digger" weapon, but can be
 * accomplished by strong players using heavy weapons.
 */
void do_cmd_tunnel(cmd_code code, cmd_arg args[])
{
	int y, x, dir;
	bool more = FALSE;

	dir = args[0].direction;

	/* Get location */
	y = p_ptr->py + ddy[dir];
	x = p_ptr->px + ddx[dir];


	/* Oops */
	if (!do_cmd_tunnel_test(y, x))
	{
		/* Cancel repeat */
		disturb(p_ptr, 0, 0);
		return;
	}

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

	/* Apply confusion */
	if (player_confuse_dir(p_ptr, &dir, FALSE))
	{
		/* Get location */
		y = p_ptr->py + ddy[dir];
		x = p_ptr->px + ddx[dir];
	}


	/* Monster */
	if (cave->m_idx[y][x] > 0)
	{
		/* Message */
		msg("There is a monster in the way!");

		/* Attack */
		py_attack(y, x);
	}

	/* Walls */
	else
	{
		/* Tunnel through walls */
		more = do_cmd_tunnel_aux(y, x);
	}

	/* Cancel repetition unless we can continue */
	if (!more) disturb(p_ptr, 0, 0);
}
static void _charge_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Charge");
        break;
    case SPELL_DESC:
        var_set_string(res, "Attacks monster with your weapons normally, then move through counter side of the monster.");
        break;
    case SPELL_CAST:
    {
        int dir, x, y;
        var_set_bool(res, FALSE);
        if (p_ptr->riding)
        {
            msg_print("You cannot do it when riding.");
            return;
        }

        if (!get_rep_dir2(&dir)) return;
        if (dir == 5) return;

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

        if (!cave[y][x].m_idx)
        {
            msg_print("There is no monster there.");
            return;
        }

        py_attack(y, x, 0);

        if (player_can_enter(cave[y][x].feat, 0) && !is_trap(cave[y][x].feat))
        {
            y += ddy[dir];
            x += ddx[dir];
            if (player_can_enter(cave[y][x].feat, 0) && !is_trap(cave[y][x].feat) && !cave[y][x].m_idx)
            {
                msg_print(NULL);
                move_player_effect(y, x, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP);
            }
        }
        var_set_bool(res, TRUE);
        break;
    }
    default:
        default_spell(cmd, res);
        break;
    }
}
Exemplo n.º 8
0
/*
 * Close an open door.
 */
void do_cmd_close(cmd_code code, cmd_arg args[])
{
	int y, x, dir;

	bool more = FALSE;

	dir = args[0].direction;

	/* Get location */
	y = p_ptr->py + ddy[dir];
	x = p_ptr->px + ddx[dir];

	/* Verify legality */
	if (!do_cmd_close_test(y, x))
	{
		/* Cancel repeat */
		disturb(p_ptr, 0, 0);
		return;
	}

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

	/* Apply confusion */
	if (player_confuse_dir(p_ptr, &dir, FALSE))
	{
		/* Get location */
		y = p_ptr->py + ddy[dir];
		x = p_ptr->px + ddx[dir];
	}


	/* Monster */
	if (cave->m_idx[y][x] > 0)
	{
		/* Message */
		msg("There is a monster in the way!");

		/* Attack */
		py_attack(y, x);
	}

	/* Door */
	else
	{
		/* Close door */
		more = do_cmd_close_aux(y, x);
	}

	/* Cancel repeat unless told not to */
	if (!more) disturb(p_ptr, 0, 0);
}
Exemplo n.º 9
0
bool do_blow(int type)
{
    int x = 0, y = 0;
    int dir;
    int m_idx = 0;

    /* For ergonomics sake, use currently targeted monster. This allows
       a macro of \e*tmaa or similar to pick an adjacent foe, while
       \emaa*t won't work, since get_rep_dir2() won't allow a target. */
    if (use_old_target && target_okay())
    {
        y = target_row;
        x = target_col;
        m_idx = cave[y][x].m_idx;
        if (m_idx)
        {
            if (m_list[m_idx].cdis > 1)
                m_idx = 0;
            else
                dir = 5;
        }
    }

    if (!m_idx)
    {
        if (!get_rep_dir2(&dir)) return FALSE;
        if (dir == 5) return FALSE;

        y = py + ddy[dir];
        x = px + ddx[dir];
        m_idx = cave[y][x].m_idx;

        if (!m_idx)
        {
            msg_print("There is no monster there.");
            return FALSE;
        }

    }

    if (m_idx)
        py_attack(y, x, type);

    return TRUE;
}
Exemplo n.º 10
0
/*
 * Manipulate an adjacent grid in some way
 *
 * Attack monsters, tunnel through walls, disarm traps, open doors.
 *
 * This command must always take energy, to prevent free detection
 * of invisible monsters.
 *
 * The "semantics" of this command must be chosen before the player
 * is confused, and it must be verified against the new grid.
 */
void do_cmd_alter_aux(int dir)
{
	int y, x;
	bool more = FALSE;

	/* Get location */
	y = p_ptr->py + ddy[dir];
	x = p_ptr->px + ddx[dir];

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

	/* Apply confusion */
	if (player_confuse_dir(p_ptr, &dir, FALSE)) {
		/* Get location */
		y = p_ptr->py + ddy[dir];
		x = p_ptr->px + ddx[dir];
	}

	/* Attack monsters */
	if (cave->m_idx[y][x] > 0)
		py_attack(y, x);

	/* Tunnel through walls and rubble */
	else if (cave_isdiggable(cave, y, x))
		more = do_cmd_tunnel_aux(y, x);

	/* Open closed doors */
	else if (cave_iscloseddoor(cave, y, x))
		more = do_cmd_open_aux(y, x);

	/* Disarm traps */
	else if (cave_isknowntrap(cave, y, x))
		more = do_cmd_disarm_aux(y, x);

	/* Oops */
	else
		msg("You spin around.");

	/* Cancel repetition unless we can continue */
	if (!more) disturb(p_ptr, 0, 0);
}
Exemplo n.º 11
0
/**
 * Tunnel through "walls" (including rubble and doors, secret or otherwise)
 *
 * Digging is very difficult without a "digger" weapon, but can be
 * accomplished by strong players using heavy weapons.
 */
void do_cmd_tunnel(struct command *cmd)
{
	int y, x, dir;
	bool more = false;

	/* Get arguments */
	if (cmd_get_direction(cmd, "direction", &dir, false))
		return;

	/* Get location */
	y = player->py + ddy[dir];
	x = player->px + ddx[dir];

	/* Oops */
	if (!do_cmd_tunnel_test(y, x)) {
		/* Cancel repeat */
		disturb(player, 0);
		return;
	}

	/* Take a turn */
	player->upkeep->energy_use = z_info->move_energy;

	/* Apply confusion */
	if (player_confuse_dir(player, &dir, false)) {
		/* Get location */
		y = player->py + ddy[dir];
		x = player->px + ddx[dir];
	}

	/* Attack any monster we run into */
	if (cave->squares[y][x].mon > 0) {
		msg("There is a monster in the way!");
		py_attack(y, x);
	} else {
		/* Tunnel through walls */
		more = do_cmd_tunnel_aux(y, x);
	}

	/* Cancel repetition unless we can continue */
	if (!more) disturb(player, 0);
}
Exemplo n.º 12
0
/**
 * Manipulate an adjacent grid in some way
 *
 * Attack monsters, tunnel through walls, disarm traps, open doors.
 *
 * This command must always take energy, to prevent free detection
 * of invisible monsters.
 *
 * The "semantics" of this command must be chosen before the player
 * is confused, and it must be verified against the new grid.
 */
void do_cmd_alter_aux(int dir)
{
	int y, x;
	bool more = false;

	/* Get location */
	y = player->py + ddy[dir];
	x = player->px + ddx[dir];

	/* Take a turn */
	player->upkeep->energy_use = z_info->move_energy;

	/* Apply confusion */
	if (player_confuse_dir(player, &dir, false)) {
		/* Get location */
		y = player->py + ddy[dir];
		x = player->px + ddx[dir];
	}

	/* Action depends on what's there */
	if (cave->squares[y][x].mon > 0)
		/* Attack monsters */
		py_attack(y, x);
	else if (square_isdiggable(cave, y, x))
		/* Tunnel through walls and rubble */
		more = do_cmd_tunnel_aux(y, x);
	else if (square_iscloseddoor(cave, y, x))
		/* Open closed doors */
		more = do_cmd_open_aux(y, x);
	else if (square_isknowntrap(cave, y, x))
		/* Disarm traps */
		more = do_cmd_disarm_aux(y, x);
	else
		/* Oops */
		msg("You spin around.");

	/* Cancel repetition unless we can continue */
	if (!more) disturb(player, 0);
}
Exemplo n.º 13
0
void awesome_blow_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Awesome Blow");
        break;
    case SPELL_DESC:
        var_set_string(res, "Attack a monster with a single melee blow. If blow hits, does normal melee damage and propels the monster backwards.");
        break;
    case SPELL_CAST:
    {
        int y, x, dir;
        var_set_bool(res, FALSE);

        if (!get_rep_dir2(&dir)) return;
        if (dir == 5) return;

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

        if (cave[y][x].m_idx)
        {
            py_attack(y, x, MELEE_AWESOME_BLOW);
        }
        else
        {
            msg_print("There is no monster.");
            return;
        }

        var_set_bool(res, TRUE);
        break;
    }
    default:
        default_spell(cmd, res);
        break;
    }
}
Exemplo n.º 14
0
/*
 * Open a closed/locked/jammed door or a closed/locked chest.
 *
 * Unlocking a locked door/chest is worth one experience point.
 */
void do_cmd_open(cmd_code code, cmd_arg args[])
{
	int y, x, dir;

	s16b o_idx;

	bool more = FALSE;

	dir = args[0].direction;

	/* Get location */
	y = p_ptr->py + ddy[dir];
	x = p_ptr->px + ddx[dir];

	/* Check for chests */
	o_idx = chest_check(y, x);


	/* Verify legality */
	if (!o_idx && !do_cmd_open_test(y, x))
	{
		/* Cancel repeat */
		disturb(0, 0);
		return;
	}

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

	/* Apply confusion */
	if (confuse_dir(&dir))
	{
		/* Get location */
		y = p_ptr->py + ddy[dir];
		x = p_ptr->px + ddx[dir];

		/* Check for chest */
		o_idx = chest_check(y, x);
	}


	/* Monster */
	if (cave_m_idx[y][x] > 0)
	{
		if (mon_list[cave_m_idx[y][x]].align & (AL_PET_MASK))
			msg_print("There is a friendly monster in the way!");
		else
		{
			/* Message */
			msg_print("There is a monster in the way!");

			/* Attack */
			py_attack(y, x);
		}
	}

	/* Chest */
	else if (o_idx)
	{
		/* Open the chest */
		more = do_cmd_open_chest(y, x, o_idx);
	}

	/* Door */
	else
	{
		/* Open the door */
		more = do_cmd_open_aux(y, x);
	}

	/* Cancel repeat unless we may continue */
	if (!more) disturb(0, 0);
}
Exemplo n.º 15
0
/*
 * Bash open a door, success based on character strength
 *
 * For a closed door, pval is positive if locked; negative if stuck.
 *
 * For an open door, pval is positive for a broken door.
 *
 * A closed door can be opened - harder if locked. Any door might be
 * bashed open (and thereby broken). Bashing a door is (potentially)
 * faster! You move into the door way. To open a stuck door, it must
 * be bashed. A closed door can be jammed (see do_cmd_spike()).
 *
 * Creatures can also open or bash doors, see elsewhere.
 */
void do_cmd_bash(void)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int y, x, dir;

	bool more = FALSE;


	/* Get a direction (or abort) */
	if (!get_rep_dir(&dir)) return;

	/* Get location */
	y = py + ddy[dir];
	x = px + ddx[dir];


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


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

	/* Apply confusion */
	if (confuse_dir(&dir))
	{
		/* Get location */
		y = py + ddy[dir];
		x = px + ddx[dir];
	}


	/* Allow repeated command */
	if (p_ptr->command_arg)
	{
		/* Set repeat count */
		p_ptr->command_rep = p_ptr->command_arg - 1;

		/* Redraw the state */
		p_ptr->redraw |= (PR_STATE);

		/* Cancel the arg */
		p_ptr->command_arg = 0;
	}

	/* Monster */
	if (cave_m_idx[y][x] > 0)
	{
		/* Message */
		msg_print("There is a monster in the way!");

		/* Attack */
		py_attack(y, x);

		/* Done */
		return;
	}

	/* Door */
	else
	{
		/* Bash the door */
		more = do_cmd_bash_aux(y, x);
	}

	/* Cancel repeat unless told not to */
	if (!more) disturb(0, 0);
}
Exemplo n.º 16
0
/**
 * Open a closed/locked/jammed door or a closed/locked chest.
 *
 * Unlocking a locked chest is worth one experience point; since doors are
 * player lockable, there is no experience for unlocking doors.
 */
void do_cmd_open(struct command *cmd)
{
	int y, x, dir;
	struct object *obj;
	bool more = false;
	int err;
	struct monster *m;

	/* Get arguments */
	err = cmd_get_arg_direction(cmd, "direction", &dir);
	if (err || dir == DIR_UNKNOWN) {
		int y2, x2;
		int n_closed_doors, n_locked_chests;

		n_closed_doors = count_feats(&y2, &x2, square_iscloseddoor, false);
		n_locked_chests = count_chests(&y2, &x2, CHEST_OPENABLE);

		if (n_closed_doors + n_locked_chests == 1) {
			dir = coords_to_dir(y2, x2);
			cmd_set_arg_direction(cmd, "direction", dir);
		} else if (cmd_get_direction(cmd, "direction", &dir, false)) {
			return;
		}
	}

	/* Get location */
	y = player->py + ddy[dir];
	x = player->px + ddx[dir];

	/* Check for chest */
	obj = chest_check(y, x, CHEST_OPENABLE);

	/* Check for door */
	if (!obj && !do_cmd_open_test(y, x)) {
		/* Cancel repeat */
		disturb(player, 0);
		return;
	}

	/* Take a turn */
	player->upkeep->energy_use = z_info->move_energy;

	/* Apply confusion */
	if (player_confuse_dir(player, &dir, false)) {
		/* Get location */
		y = player->py + ddy[dir];
		x = player->px + ddx[dir];

		/* Check for chest */
		obj = chest_check(y, x, CHEST_OPENABLE);
	}

	/* Monster */
	m = square_monster(cave, y, x);
	if (m) {
		/* Mimics surprise the player */
		if (is_mimicking(m)) {
			become_aware(m);

			/* Mimic wakes up */
			mon_clear_timed(m, MON_TMD_SLEEP, MON_TMD_FLG_NOMESSAGE, false);
		} else {
			/* Message */
			msg("There is a monster in the way!");

			/* Attack */
			py_attack(y, x);
		}
	} else if (obj) {
		/* Chest */
		more = do_cmd_open_chest(y, x, obj);
	} else {
		/* Door */
		more = do_cmd_open_aux(y, x);
	}

	/* Cancel repeat unless we may continue */
	if (!more) disturb(player, 0);
}
Exemplo n.º 17
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 = 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;
}
Exemplo n.º 18
0
/*
 * Manipulate an adjacent grid in some way
 *
 * Attack monsters, tunnel through walls, disarm traps, open doors,
 * or, for rogues, set traps and steal money.
 *
 * This command must always take energy, to prevent free detection
 * of invisible monsters.
 *
 * The "semantics" of this command must be chosen before the player
 * is confused, and it must be verified against the new grid.
 */
void do_cmd_alter(void)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int y, x, dir;

	int feat;

	bool did_nothing = TRUE;
	bool more = FALSE;

	monster_type *m_ptr;

	/* Get a direction */
	if (!get_rep_dir(&dir)) return;

	/* Get location */
	y = py + ddy[dir];
	x = px + ddx[dir];


	/* Original feature */
	feat = cave_feat[y][x];

	/* Must have knowledge to know feature XXX XXX */
	if (!(cave_info[y][x] & (CAVE_MARK))) feat = FEAT_NONE;


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

	/* Apply confusion */
	if (confuse_dir(&dir))
	{
		/* Get location */
		y = py + ddy[dir];
		x = px + ddx[dir];
	}


	/* Allow repeated command */
	if (p_ptr->command_arg)
	{
		/* Set repeat count */
		p_ptr->command_rep = p_ptr->command_arg - 1;

		/* Redraw the state */
		p_ptr->redraw |= (PR_STATE);

		/* Cancel the arg */
		p_ptr->command_arg = 0;
	}

	/* If a monster is present, and visible, Rogues may steal from it.
	 * Otherwise, the player will simply attack. -LM-
	 */
	if (cave_m_idx[y][x] > 0)
	{
		if ((check_ability(SP_STEAL)) && (!SCHANGE))
		{
			m_ptr = &m_list[cave_m_idx[y][x]];
			if (m_ptr->ml) py_steal(y, x);
			else py_attack(y, x);
		}
		else py_attack(y, x);
		did_nothing = FALSE;
	}

	/*
	 * Some players can set traps.  Total number is checked in py_set_trap.
	 */
	else if ((check_ability(SP_TRAP)) && (cave_naked_bold(y, x)))
	{
		py_set_trap(y, x);
		did_nothing = FALSE;
	}

	/* Disarm advanced monster traps */
	else if (feat > FEAT_MTRAP_HEAD)
	{
		/* Disarm */
		more = do_cmd_disarm_aux(y, x);
	}

	/* Modify basic monster traps */
	else if (feat == FEAT_MTRAP_HEAD)
	{
		/* Modify */
		py_modify_trap(y, x);
	}

	/* Tunnel through walls */
	else if (feat >= FEAT_SECRET)
	{
		/* Tunnel */
		more = do_cmd_tunnel_aux(y, x);
	}

	/* Bash jammed doors */
	else if (feat >= FEAT_DOOR_HEAD + 0x08)
	{
		/* Bash */
		more = do_cmd_bash_aux(y, x);
	}

	/* Open closed doors */
	else if (feat >= FEAT_DOOR_HEAD)
	{
		/* Close */
		more = do_cmd_open_aux(y, x);
	}

	/* Disarm traps */
	else if (feat >= FEAT_TRAP_HEAD)
	{
		/* Disarm */
		more = do_cmd_disarm_aux(y, x);
	}

	/* Oops */
	else if (did_nothing)
	{
		/* Oops */
		msg_print("You spin around.");
	}

	/* Cancel repetition unless we can continue */
	if (!more) disturb(0, 0);
}
Exemplo n.º 19
0
/*
 * Open a closed/locked/jammed door or a closed/locked chest.
 *
 * Unlocking a locked door/chest is worth one experience point.
 */
void do_cmd_open(cmd_code code, cmd_arg args[])
{
	int y, x, dir;

	s16b o_idx;

	bool more = FALSE;

	dir = args[0].direction;

	/* Get location */
	y = p_ptr->py + ddy[dir];
	x = p_ptr->px + ddx[dir];

	/* Check for chests */
	o_idx = chest_check(y, x);


	/* Verify legality */
	if (!o_idx && !do_cmd_open_test(y, x))
	{
		/* Cancel repeat */
		disturb(p_ptr, 0, 0);
		return;
	}

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

	/* Apply confusion */
	if (player_confuse_dir(p_ptr, &dir, FALSE))
	{
		/* Get location */
		y = p_ptr->py + ddy[dir];
		x = p_ptr->px + ddx[dir];

		/* Check for chest */
		o_idx = chest_check(y, x);
	}


	/* Monster */
	if (cave->m_idx[y][x] > 0)
	{
		int m_idx = cave->m_idx[y][x];

		/* 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 {
			/* Message */
			msg("There is a monster in the way!");

			/* Attack */
			py_attack(y, x);
		}
	}

	/* Chest */
	else if (o_idx)
	{
		/* Open the chest */
		more = do_cmd_open_chest(y, x, o_idx);
	}

	/* Door */
	else
	{
		/* Open the door */
		more = do_cmd_open_aux(y, x);
	}

	/* Cancel repeat unless we may continue */
	if (!more) disturb(p_ptr, 0, 0);
}
Exemplo n.º 20
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 y = player->py + ddy[dir];
	int x = player->px + ddx[dir];

	int m_idx = cave->squares[y][x].mon;
	struct monster *mon = 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(mon)) {
			become_aware(mon);

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

		} else {
			py_attack(y, x);
		}
	} else if (disarm && square_isknown(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(player, 0);

		/* Notice unknown obstacles, mention known obstacles */
		if (!square_isknown(cave, y, x)) {
			if (square_isrubble(cave, y, x)) {
				msgt(MSG_HITWALL,
					 "You feel a pile of rubble blocking your way.");
				square_memorize(cave, y, x);
				square_light_spot(cave, y, x);
			} else if (square_iscloseddoor(cave, y, x)) {
				msgt(MSG_HITWALL, "You feel a door blocking your way.");
				square_memorize(cave, y, x);
				square_light_spot(cave, y, x);
			} else {
				msgt(MSG_HITWALL, "You feel a wall blocking your way.");
				square_memorize(cave, y, x);
				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 {
		/* Move player */
		monster_swap(player->py, player->px, y, x);

		/* Handle store doors, or notice objects */
		if (square_isshop(cave, y, x)) {
			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 {
			square_know_pile(cave, y, x);
			cmdq_push(CMD_AUTOPICKUP);
		}

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

		/* Update view and search */
		update_view(cave, player);
		search();
	}

	player->upkeep->running_firststep = false;
}
Exemplo n.º 21
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;

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


    /* 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[p_ptr->py][p_ptr->px] == (FEAT_TRAP_HEAD + 0x01)) {
	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_print("You remain stuck in the pit.");
		return;
	    } else
		msg_print("You clamber out of the pit.");
	} else
	    msg_print("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_feat[y][x] >= FEAT_TRAP_HEAD)
	&& (cave_feat[y][x] <= FEAT_TRAP_TAIL)) 
    {
	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 (!cave_passable_bold(y, x)) {
	/* Disturb the player */
	disturb(0, 0);

	/* Notice unknown obstacles */
	if (!(cave_info[y][x] & (CAVE_MARK))) {
	    /* Closed door */
	    if (cave_feat[y][x] < FEAT_SECRET) {
		message(MSG_HITWALL, 0, "You feel a door blocking your way.");
		cave_info[y][x] |= (CAVE_MARK);
		light_spot(y, x);
	    }

	    /* Wall (or secret door) */
	    else {
		message(MSG_HITWALL, 0, "You feel a wall blocking your way.");
		cave_info[y][x] |= (CAVE_MARK);
		light_spot(y, x);
	    }
	}

	/* Mention known obstacles */
	else {
	    /* Closed door */
	    if (cave_feat[y][x] < FEAT_SECRET) {
		/* 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. */
		message(MSG_HITWALL, 0, "There is a door blocking your way.");
	    }

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

	/* Sound */
	sound(MSG_HITWALL);
    }

    /* Normal movement */
    else 
    {
	/*** Handle traversable terrain.  ***/
	switch (cave_feat[y][x]) {
	case FEAT_RUBBLE:
	    {
		/* 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;

		else if (player_is_crossing == dir)
		{
		    can_move = TRUE;
		    player_is_crossing = 0;
		}
		else 
		{
		    player_is_crossing = dir;
		    cmd_insert(CMD_WALK);
		}

		break;
	    }
	case FEAT_TREE:
	case FEAT_TREE2:
	    {
		/* 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;

		/* Allow movement only if partway through already. */
		else if (player_is_crossing == dir)
		{
		    can_move = TRUE;
		    player_is_crossing = 0;
		}
		else 
		{
		    player_is_crossing = dir;
		    cmd_insert(CMD_WALK);
		}
		
		break;
	    }
	case FEAT_WATER:	/* Water now slows rather than stopping -NRM- */
	    {
		/* Stop any run. */
		disturb(0, 0);

		can_move = TRUE;

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

		break;
	    }
	case FEAT_LAVA:
	    {
		/* 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");
		}
		break;
	    }
	case FEAT_VOID:
	    {
		/* Bats, dragons can fly */
		if ((p_ptr->schange == SHAPE_BAT)
		    || (p_ptr->schange == SHAPE_WYRM))
		    can_move = TRUE;
		else {
		    /* 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? ")) {
			    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? ")) {
			    temp = FALSE;
			}
		    }

		    /* Step off if confirmed. */
		    if (temp) {
			/* Can always jump. */
			can_move = TRUE;

			/* Will take serious damage. */
			falling = TRUE;
		    }
		}
		break;
	    }
	default:
	    {
		/* All other terrain can be traversed normally. */
		can_move = 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 (cave_feat[py][px] == FEAT_WATER)
		p_ptr->update |= PU_BONUS;

	    /* Update stealth for Unlight */
	    if (player_has(PF_UNLIGHT))
		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;

	    /* No longer traversing. */
	    player_is_crossing = 0;

	    /* 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 ((cave_feat[y][x] >= FEAT_SHOP_HEAD)
		&& (cave_feat[y][x] <= FEAT_SHOP_TAIL)) {
		/* 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_feat[y][x] == FEAT_INVIS)
		     || (cave_feat[y][x] == FEAT_GRASS_INVIS))
		    && (randint0(3) != 0))
		    trapped = FALSE;
		else if ((cave_feat[y][x] >= FEAT_TRAP_HEAD)
			 && (cave_feat[y][x] <= FEAT_TRAP_TAIL)
			 && (randint0(10) != 0))
		    trapped = FALSE;
	    }

	    /* Discover invisible traps */
	    else if (((cave_feat[y][x] == FEAT_INVIS)
		      || (cave_feat[y][x] == FEAT_GRASS_INVIS)
		      || (cave_feat[y][x] == FEAT_TREE_INVIS)
		      || (cave_feat[y][x] == FEAT_TREE2_INVIS)) && trapped) {
		/* Disturb */
		disturb(0, 0);

		/* Message */
		msg_print("You stumble upon a trap!");

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

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

	    /* Set off a visible trap */
	    else if ((cave_feat[y][x] >= FEAT_TRAP_HEAD)
		     && (cave_feat[y][x] <= FEAT_TRAP_TAIL) && trapped) {
		/* Disturb */
		disturb(0, 0);

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

	    /* Walk on a monster trap */
	    else if ((cave_feat[y][x] >= FEAT_MTRAP_HEAD)
		     && (cave_feat[y][x] <= FEAT_MTRAP_TAIL)) {
		msg_print("You inspect your cunning trap.");
	    }
	}
    }
}
Exemplo n.º 22
0
/**
 * Disarms a trap, or a chest
 *
 * Traps must be visible, chests must be known trapped
 */
void do_cmd_disarm(struct command *cmd)
{
	int y, x, dir;
	int err;

	struct object *obj;
	bool more = false;

	/* Get arguments */
	err = cmd_get_arg_direction(cmd, "direction", &dir);
	if (err || dir == DIR_UNKNOWN) {
		int y2, x2;
		int n_traps, n_chests;

		n_traps = count_feats(&y2, &x2, square_isknowntrap, true);
		n_chests = count_chests(&y2, &x2, CHEST_TRAPPED);

		if (n_traps + n_chests == 1) {
			dir = coords_to_dir(y2, x2);
			cmd_set_arg_direction(cmd, "direction", dir);
		} else if (cmd_get_direction(cmd, "direction", &dir, n_chests > 0)) {
			/* If there are chests to disarm, 5 is allowed as a direction */
			return;
		}
	}

	/* Get location */
	y = player->py + ddy[dir];
	x = player->px + ddx[dir];

	/* Check for chests */
	obj = chest_check(y, x, CHEST_TRAPPED);

	/* Verify legality */
	if (!obj && !do_cmd_disarm_test(y, x)) {
		/* Cancel repeat */
		disturb(player, 0);
		return;
	}

	/* Take a turn */
	player->upkeep->energy_use = z_info->move_energy;

	/* Apply confusion */
	if (player_confuse_dir(player, &dir, false)) {
		/* Get location */
		y = player->py + ddy[dir];
		x = player->px + ddx[dir];

		/* Check for chests */
		obj = chest_check(y, x, CHEST_TRAPPED);
	}


	/* Monster */
	if (cave->squares[y][x].mon > 0) {
		msg("There is a monster in the way!");
		py_attack(y, x);
	} else if (obj)
		/* Chest */
		more = do_cmd_disarm_chest(y, x, obj);
	else if (square_iscloseddoor(cave, y, x) &&
			 !square_islockeddoor(cave, y, x))
		/* Door to lock */
		more = do_cmd_lock_door(y, x);
	else
		/* Disarm trap */
		more = do_cmd_disarm_aux(y, x);

	/* Cancel repeat unless told not to */
	if (!more) disturb(player, 0);
}
Exemplo n.º 23
0
/*
 * Disarms a trap, a glyph, or a chest.
 */
void do_cmd_disarm(void)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int y, x, dir;

	s16b o_idx;

	bool more = FALSE;

	/* Option: Pick a direction -TNB- */
	if (easy_disarm)
	{
		int num_traps, num_chests;

		/* Count visible traps */
		num_traps = count_feats(&y, &x, is_trap, TRUE);

		/* Count chests (trapped) */
		num_chests = count_chests(&y, &x, TRUE);

		/* See if there's only one target */
		if (num_traps || num_chests)
		{
			if (num_traps + num_chests <= 1)
				p_ptr->command_dir = coords_to_dir(y, x);
		}

	}

	/* Get a direction (or abort) */
	if (!get_rep_dir(&dir)) return;

	/* Get location */
	y = py + ddy[dir];
	x = px + ddx[dir];

	/* Check for chests */
	o_idx = chest_check(y, x);


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


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

	/* Apply confusion */
	if (confuse_dir(&dir))
	{
		/* Get location */
		y = py + ddy[dir];
		x = px + ddx[dir];

		/* Check for chests */
		o_idx = chest_check(y, x);
	}


	/* Allow repeated command */
	if (p_ptr->command_arg)
	{
		/* Set repeat count */
		p_ptr->command_rep = p_ptr->command_arg - 1;

		/* Redraw the state */
		p_ptr->redraw |= (PR_STATE);

		/* Cancel the arg */
		p_ptr->command_arg = 0;
	}

	/* Monster */
	if (cave_m_idx[y][x] > 0)
	{
		/* Message */
		msg_print("There is a monster in the way!");

		/* Attack */
		py_attack(y, x);
	}

	/* Chest */
	else if (o_idx)
	{
		/* Disarm the chest */
		more = do_cmd_disarm_chest(y, x, o_idx);
	}

	/* Disarm trap */
	else
	{
		/* Disarm the trap */
		more = do_cmd_disarm_aux(y, x);
	}

	/* Cancel repeat unless told not to */
	if (!more) disturb(0, 0);
}
Exemplo n.º 24
0
/*
 * Manipulate an adjacent grid in some way
 *
 * Attack monsters, tunnel through walls, disarm traps, open doors.
 *
 * This command must always take energy, to prevent free detection
 * of invisible monsters.
 *
 * The "semantics" of this command must be chosen before the player
 * is confused, and it must be verified against the new grid.
 */
void do_cmd_alter_aux(int dir)
{
	int y, x;

	int feat;

	bool more = FALSE;

	/* Get location */
	y = p_ptr->py + ddy[dir];
	x = p_ptr->px + ddx[dir];


	/* Original feature */
	feat = cave_feat[y][x];

	/* Must have knowledge to know feature XXX XXX */
	if (!(cave_info[y][x] & (CAVE_MARK))) feat = FEAT_NONE;


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

	/* Apply confusion */
	if (confuse_dir(&dir))
	{
		/* Get location */
		y = p_ptr->py + ddy[dir];
		x = p_ptr->px + ddx[dir];
	}


	/* Attack monsters */
	if (cave_m_idx[y][x] > 0)
	{
		if (mon_list[cave_m_idx[y][x]].align & (AL_PET_MASK))
		{
			msg_print("There is a friendly monster in the way!");
		}
		else
		{
			/* Attack */
			py_attack(y, x);
		}
	}

	/* Tunnel through walls */
	else if (feat >= FEAT_SECRET)
	{
		more = do_cmd_tunnel_aux(y, x);
	}

#if 0
	/* Bash jammed doors */
	else if (feat >= FEAT_DOOR_HEAD + 0x08)
	{
		more = do_cmd_bash_aux(y, x);
	}
#endif

	/* Open closed doors */
	else if (feat >= FEAT_DOOR_HEAD)
	{
		more = do_cmd_open_aux(y, x);
	}

	/* Disarm traps */
	else if (feat >= FEAT_TRAP_HEAD)
	{
		more = do_cmd_disarm_aux(y, x);
	}

#if 0
	/* Close open doors */
	else if (feat == FEAT_OPEN)
	{
		more = do_cmd_close_aux(y, x);
	}
#endif

	/* Oops */
	else
	{
		msg_print("You spin around.");
	}

	/* Cancel repetition unless we can continue */
	if (!more) disturb(0, 0);
}
Exemplo n.º 25
0
/*
 * Disarms a trap, or a chest
 */
void do_cmd_disarm(cmd_code code, cmd_arg args[])
{
	int y, x, dir;

	s16b o_idx;

	bool more = FALSE;

	dir = args[0].direction;

	/* Get location */
	y = p_ptr->py + ddy[dir];
	x = p_ptr->px + ddx[dir];

	/* Check for chests */
	o_idx = chest_check(y, x);


	/* Verify legality */
	if (!o_idx && !do_cmd_disarm_test(y, x))
	{
		/* Cancel repeat */
		disturb(0, 0);
		return;
	}

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

	/* Apply confusion */
	if (confuse_dir(&dir))
	{
		/* Get location */
		y = p_ptr->py + ddy[dir];
		x = p_ptr->px + ddx[dir];

		/* Check for chests */
		o_idx = chest_check(y, x);
	}


	/* Monster */
	if (cave_m_idx[y][x] > 0)
	{
		/* Message */
		msg_print("There is a monster in the way!");

		/* Attack */
		py_attack(y, x);
	}

	/* Chest */
	else if (o_idx)
	{
		/* Disarm the chest */
		more = do_cmd_disarm_chest(y, x, o_idx);
	}

	/* Disarm trap */
	else
	{
		/* Disarm the trap */
		more = do_cmd_disarm_aux(y, x);
	}

	/* Cancel repeat unless told not to */
	if (!more) disturb(0, 0);
}
Exemplo n.º 26
0
/**
 * Rogues may steal gold from monsters.  The monster needs to have
 * something to steal (it must drop some form of loot), and should
 * preferably be asleep.  Humanoids and dragons are a rogue's favorite
 * targets.  Steal too often on a level, and monsters will be more wary,
 * and the hue and cry will be eventually be raised.  Having every
 * monster on the level awake and aggravated is not pleasant. -LM-
 */
extern void py_steal(int y, int x)
{
    cptr act = NULL;

    monster_type *m_ptr = &m_list[cave_m_idx[y][x]];
    monster_race *r_ptr = &r_info[m_ptr->r_idx];

    char m_name[80];

    int i;
    int effect, theft_protection;
    int filching_power = 0;
    int purse = 0;

    bool thief = FALSE;
    bool success = FALSE;

    /* Check intent */
    if ((m_ptr->hostile != -1)
            && !get_check("Do you want to steal from this being?")) {
        py_attack(y, x, FALSE);
        return;
    }

    /* Hard limit on theft. */
    if (number_of_thefts_on_level > 4) {
        msg_print
        ("Everyone is keeping a lookout for you.  You can steal nothing here.");
        return;
    }

    /* Determine the cunning of the thief. */
    filching_power = 2 * p_ptr->lev;

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

    /* Determine how much protection the monster has. */
    theft_protection = (7 * (r_ptr->level + 2) / 4);
    theft_protection += (m_ptr->mspeed - p_ptr->state.pspeed);
    if (theft_protection < 1)
        theft_protection = 1;

    /* Send a thief to catch a thief. */
    for (i = 0; i < 4; i++) {
        /* Extract infomation about the blow effect */
        effect = r_ptr->blow[i].effect;
        if (effect == RBE_EAT_GOLD)
            thief = TRUE;
        if (effect == RBE_EAT_ITEM)
            thief = TRUE;
    }
    if (thief)
        theft_protection += 30;

    if (m_ptr->csleep)
        theft_protection = 3 * theft_protection / 5;

    /* Special player stealth magics aid stealing, but are lost in the process */
    if (p_ptr->timed[TMD_SSTEALTH]) {
        theft_protection = 3 * theft_protection / 5;
        (void) clear_timed(TMD_SSTEALTH, TRUE);
    }

    /* The more you steal on a level, the more wary the monsters. */
    theft_protection += number_of_thefts_on_level * 15;

    /* Did the theft succeed? */
    if (randint1(theft_protection) < filching_power)
        success = TRUE;


    /* If the theft succeeded, determine the value of the purse. */
    if (success) {
        purse = (r_ptr->level + 1) + randint1(3 * (r_ptr->level + 1) / 2);

        /* Uniques are juicy targets. */
        if (rf_has(r_ptr->flags, RF_UNIQUE))
            purse *= 3;

        /* But some monsters are dirt poor. */
        if (!(rf_has(r_ptr->flags, RF_DROP_60))
                || rf_has(r_ptr->flags, RF_DROP_90)
                || rf_has(r_ptr->flags, RF_DROP_1D2)
                || rf_has(r_ptr->flags, RF_DROP_2D2)
                || rf_has(r_ptr->flags, RF_DROP_3D2)
                || rf_has(r_ptr->flags, RF_DROP_4D2))
            purse = 0;

        /* Some monster races are far better to steal from than others. */
        if ((r_ptr->d_char == 'D') || (r_ptr->d_char == 'd')
                || (r_ptr->d_char == 'p') || (r_ptr->d_char == 'h'))
            purse *= 2 + randint1(3) + randint1(r_ptr->level / 20);
        else if ((r_ptr->d_char == 'P') || (r_ptr->d_char == 'o')
                 || (r_ptr->d_char == 'O') || (r_ptr->d_char == 'T')
                 || (r_ptr->d_char == 'n') || (r_ptr->d_char == 'W')
                 || (r_ptr->d_char == 'k') || (r_ptr->d_char == 'L')
                 || (r_ptr->d_char == 'V') || (r_ptr->d_char == 'y'))
            purse *= 1 + randint1(3) + randint1(r_ptr->level / 30);

        /* Pickings are scarce in a land of many thieves. */
        purse = purse * (p_ptr->depth + 5) / (p_ptr->recall[0] + 5);

        /* Increase player gold. */
        p_ptr->au += purse;

        /* Limit to avoid buffer overflow */
        if (p_ptr->au > PY_MAX_GOLD)
            p_ptr->au = PY_MAX_GOLD;

        /* Redraw gold */
        p_ptr->redraw |= (PR_GOLD);

        /* Announce the good news. */
        if (purse)
            msg_format("You burgle %d gold.", purse);

        /* Pockets are empty. */
        else
            msg_print("You burgle only dust.");
    }

    /* The victim normally, but not always, wakes up and is aggravated. */
    if (randint1(4) != 1) {
        m_ptr->csleep = 0;
        m_ptr->mflag |= (MFLAG_ACTV);
        if (m_ptr->mspeed < r_ptr->speed + 3)
            m_ptr->mspeed += 10;

        /* Become hostile */
        m_ptr->hostile = -1;

        /* Occasionally, amuse the player with a message. */
        if ((randint1(5) == 1) && (purse) && (rf_has(r_ptr->flags, RF_SMART))) {
            monster_desc(m_name, sizeof(m_name), m_ptr, 0);
            act = desc_victim_outcry[randint0(20)];
            msg_format("%^s cries out %s", m_name, act);
        }
        /* Otherwise, simply explain what happened. */
        else {
            monster_desc(m_name, sizeof(m_name), m_ptr, 0);
            msg_format("You have aroused %s.", m_name);
        }
    }

    /* The thief also speeds up, but only for just long enough to escape. */
    if (!p_ptr->timed[TMD_FAST])
        p_ptr->timed[TMD_FAST] += 2;

    /* Recalculate bonuses */
    p_ptr->update |= (PU_BONUS);

    /* Handle stuff */
    handle_stuff();


    /* Increment the number of thefts, and possibly raise the hue and cry. */
    number_of_thefts_on_level++;

    if (number_of_thefts_on_level > 4) {
        /* Notify the player of the trouble he's in. */
        msg_print("All the level is in an uproar over your misdeeds!");

        /* Aggravate and speed up all monsters on level. */
        (void) aggravate_monsters(1, TRUE);
    }

    else if ((number_of_thefts_on_level > 2) || (randint1(8) == 1)) {
        msg_print
        ("You hear hunting parties scouring the area for a notorious burgler.");

        /* Aggravate monsters nearby. */
        (void) aggravate_monsters(1, FALSE);
    }

    /* Rogue "Hit and Run" attack. */
    if (p_ptr->special_attack & (ATTACK_FLEE)) {
        /* Cancel the fleeing spell */
        p_ptr->special_attack &= ~(ATTACK_FLEE);

        /* Message */
        msg_print("You escape into the shadows!");

        /* Teleport. */
        teleport_player(6 + p_ptr->lev / 5, TRUE);

        /* Redraw the state */
        p_ptr->redraw |= (PR_STATUS);
    }
}
Exemplo n.º 27
0
/*
 * Jam a closed door with a spike.  Now takes only 4/10ths normal energy
 * if no monster is in the way. -LM-
 *
 * This command may NOT be repeated
 */
void do_cmd_spike(void)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int y, x, dir, item;


	/* Get a spike */
	if (!get_spike(&item))
	{
		/* Message */
		msg_print("You have no spikes!");

		/* Done */
		return;
	}


	/* Get a direction (or abort) */
	if (!get_rep_dir(&dir)) return;

	/* Get location */
	y = py + ddy[dir];
	x = px + ddx[dir];


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


	/* Take a partial turn.   Now jamming is more useful. */
	p_ptr->energy_use = 40;

	/* Confuse direction */
	if (confuse_dir(&dir))
	{
		/* Get location */
		y = py + ddy[dir];
		x = px + ddx[dir];
	}


	/* Monster.  Make the action now take a full turn */
	if (cave_m_idx[y][x] > 0)
	{
		/* Message */
		msg_print("There is a monster in the way!");

			p_ptr->energy_use += 60;

		/* Attack */
		py_attack(y, x);
	}

	/* Go for it */
	else
	{
		/* Verify legality */
		if (!do_cmd_spike_test(y, x)) return;

		/* Successful jamming */
		msg_print("You jam the door with a spike.");

		/* Convert "locked" to "stuck" XXX XXX XXX */
		if (cave_feat[y][x] < FEAT_DOOR_HEAD + 0x08)
		{
			cave_feat[y][x] += 0x08;
		}

		/* Add one spike to the door */
		if (cave_feat[y][x] < FEAT_DOOR_TAIL)
		{
			cave_feat[y][x] += 0x01;
		}

		/* Use up, and describe, a single spike, from the bottom */
		inven_item_increase(item, -1);
		inven_item_describe(item);
		inven_item_optimize(item);
	}
}
Exemplo n.º 28
0
static void _double_crack_spell(int cmd, variant *res)
{
    switch (cmd)
    {
    case SPELL_NAME:
        var_set_string(res, "Double Crack");
        break;
    case SPELL_DESC:
        var_set_string(res, "Attack a monster normally with your whip, and then randomly attack an adjacent monster.");
        break;
    case SPELL_CAST:
        if (_whip_check())
        {
            int dir = 5;
            bool b = FALSE;

            if ( get_rep_dir2(&dir)
              && dir != 5 )
            {
                int x, y;
                int num = 1;
                int attempts = 0;

                /* First we attack where the player selected */
                y = py + ddy[dir];
                x = px + ddx[dir];
                if (in_bounds(y, x) && cave[y][x].m_idx)
                    py_attack(y, x, 0);
                else
                    msg_print("Your whip cracks in empty air.");

                /* Now the whip cracks randomly!
                   Note that we favor fighting in hallways, or
                   with ones back up against the wall. */
                while (num > 0)
                {
                    if (attempts > 3 * num)
                    {
                        while (num > 0)
                        {
                            msg_print("Your whip cracks in empty air.");
                            num--;
                        }
                        break;
                    }

                    /* random direction, but we don't penalize for choosing the player (5) */
                    dir = randint0(9);
                    if (dir == 5) continue;
                    
                    attempts++;
                    y = py + ddy[dir];
                    x = px + ddx[dir];

                    if ( !in_bounds(y, x) 
                      || cave_have_flag_bold(y, x, FF_WALL)
                      || cave_have_flag_bold(y, x, FF_TREE) 
                      || cave_have_flag_bold(y, x, FF_CAN_DIG) )
                    {
                        continue;
                    }

                    
                    if (cave[y][x].m_idx)
                        py_attack(y, x, 0);
                    else
                        msg_print("Your whip cracks in empty air.");

                    num--;
                }

                b = TRUE;
            }
            var_set_bool(res, b);
        }
        else
        {
            msg_print("Whip techniques can only be used if you are fighting with whips.");
            var_set_bool(res, FALSE);
        }
        break;
    default:
        default_spell(cmd, res);
        break;
    }
}
Exemplo n.º 29
0
/*
 * Jam a closed door with a spike
 *
 * This command may NOT be repeated
 */
void do_cmd_spike(cmd_code code, cmd_arg args[])
{
	int y, x, dir, item = 0;

	dir = args[0].direction;

	/* Get a spike */
	if (!get_spike(&item))
	{
		/* Message */
		msg_print("You have no spikes!");

		/* Done */
		return;
	}

	/* Get location */
	y = p_ptr->py + ddy[dir];
	x = p_ptr->px + ddx[dir];


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


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

	/* Confuse direction */
	if (confuse_dir(&dir))
	{
		/* Get location */
		y = p_ptr->py + ddy[dir];
		x = p_ptr->px + ddx[dir];
	}


	/* Monster */
	if (cave_m_idx[y][x] > 0)
	{
		if (mon_list[cave_m_idx[y][x]].align & (AL_PET_MASK))
		{
			msg_print("There is a friendly monster in the way!");
		}
		else
		{
			/* Message */
			msg_print("There is a monster in the way!");

			/* Attack */
			py_attack(y, x);
		}
	}

	/* Go for it */
	else
	{
		/* Verify legality */
		if (!do_cmd_spike_test(y, x)) return;

		/* Successful jamming */
		msg_print("You jam the door with a spike.");

		/* Convert "locked" to "stuck" XXX XXX XXX */
		if (cave_feat[y][x] < FEAT_DOOR_HEAD + 0x08)
		{
			cave_feat[y][x] += 0x08;
		}

		/* Add one spike to the door */
		if (cave_feat[y][x] < FEAT_DOOR_TAIL)
		{
			cave_feat[y][x] += 0x01;
		}

		/* Use up, and describe, a single spike, from the bottom */
		inven_item_increase(item, -1);
		inven_item_describe(item);
		inven_item_optimize(item);
	}
}
Exemplo n.º 30
0
/*
 * Disarms a trap, or a chest
 */
void do_cmd_disarm(cmd_code code, cmd_arg args[])
{
	int y, x, dir;

	s16b o_idx;

	bool more = FALSE;

	dir = args[0].direction;

	/* Get location */
	y = p_ptr->py + ddy[dir];
	x = p_ptr->px + ddx[dir];

	/* Check for chests */
	o_idx = chest_check(y, x);


	/* Verify legality */
	if (!o_idx && !do_cmd_disarm_test(y, x))
	{
		/* Cancel repeat */
		disturb(p_ptr, 0, 0);
		return;
	}

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

	/* Apply confusion */
	if (player_confuse_dir(p_ptr, &dir, FALSE))
	{
		/* Get location */
		y = p_ptr->py + ddy[dir];
		x = p_ptr->px + ddx[dir];

		/* Check for chests */
		o_idx = chest_check(y, x);
	}


	/* Monster */
	if (cave->m_idx[y][x] > 0) {
		msg("There is a monster in the way!");
		py_attack(y, x);
	}

	/* Chest */
	else if (o_idx)
		more = do_cmd_disarm_chest(y, x, o_idx);

	/* Door to lock */
	else if (cave->feat[y][x] == FEAT_DOOR_HEAD)
		more = do_cmd_lock_door(y, x);

	/* Disarm trap */
	else
		more = do_cmd_disarm_aux(y, x);

	/* Cancel repeat unless told not to */
	if (!more) disturb(p_ptr, 0, 0);
}