示例#1
0
文件: cmd2.c 项目: CJNyfalt/Oangband
/*
 * Determine if a given grid may be "walked"
 */
static bool do_cmd_walk_test(int y, int x)
{
	/* Assume no monster. */
	monster_type *m_ptr = 0;

	/* Access the monster, if any is present. */
	if (cave_m_idx[y][x] != 0) m_ptr = &m_list[cave_m_idx[y][x]];

	/* If a monster can be seen, it can be attacked normally.  Code in cmd1.c
	 * controls whether a player can actually move to the destination grid.
	 */
	if ((m_ptr) && (m_ptr->ml)) return (TRUE);


	/* Hack -- walking obtains knowledge XXX XXX */
	if (!(cave_info[y][x] & (CAVE_MARK))) return (TRUE);

	/* Require open space */
	if (!cave_passable_bold(y, x))
	{
		/* Door */
		if (cave_feat[y][x] < FEAT_SECRET)
		{
			/* If easy_open_door option is on, doors are legal. */
			if (easy_open) return (TRUE);

			/* Otherwise, let the player know of the door. */
			else msg_print("There is a door in the way!");
		}

		/* Wall */
		else
		{
			/* Message */
			msg_print("There is a wall in the way!");
		}

		/* Nope */
		return (FALSE);
	}

	/* Okay */
	return (TRUE);
}
示例#2
0
/*
 * Determine is a monster makes a reasonable target
 *
 * The concept of "targetting" was stolen from "Morgul" (?)
 *
 * The player can target any location, or any "target-able" monster.
 *
 * Currently, a monster is "target_able" if it is visible, and if
 * the player can hit it with a projection, and the player is not
 * hallucinating.  This allows use of "use closest target" macros.
 *
 * Future versions may restrict the ability to target "trappers"
 * and "mimics", but the semantics is a little bit weird.
 */
bool target_able(int m_idx)
{

	monster_type *m_ptr;

	/* No monster */
	if (m_idx <= 0) return (FALSE);

	/* Get monster */
	m_ptr = &mon_list[m_idx];

	/* Monster must be alive */
	if (!m_ptr->r_idx) return (FALSE);

	/* Monster must be visible */
	if (!m_ptr->ml) return (FALSE);

	/*monster is an undiscovered mimic*/
	if (m_ptr->mimic_k_idx) return (FALSE);

	/* Monster must be projectable */
	if (!m_ptr->project) return (FALSE);

	/* Walls protect monsters */
	if (!cave_project_bold(m_ptr->fy, m_ptr->fx) &&
		!cave_passable_bold(m_ptr->fy, m_ptr->fx)) return (FALSE);

	/* Hack -- no targeting hallucinations */
	if (p_ptr->timed[TMD_IMAGE]) return (FALSE);

	/* Hack -- Never target trappers XXX XXX XXX */
	/* if (CLEAR_ATTR && (CLEAR_CHAR)) return (FALSE); */

	/* Hidden monsters cannot be targets */
	if (m_ptr->mflag & (MFLAG_HIDE)) return (FALSE);

	/* Assume okay */
	return (TRUE);
}
示例#3
0
/**
 * Hack -- Teleport to the target.  Oangband asks for a target after
 * the command.
 */
static void do_cmd_wiz_bamf(void)
{
    /* target starts at player. */
    s16b ny = 0;
    s16b nx = 0;

    /* Use the targeting function. */
    if (!target_set_interactive(TARGET_LOOK, -1, -1))
        return;

    /* grab the target coords. */
    target_get(&nx, &ny);

    /* Test for passable terrain. */
    if (!cave_passable_bold(ny, nx)) {
        msg_print("The square you are aiming for is impassable.");
    }

    /* The simple act of controlled teleport. */
    else
        teleport_player_to(ny, nx, TRUE);
}
示例#4
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.");
	    }
	}
    }
}
示例#5
0
/**
 * Handle player hitting a real trap.  Rewritten in Oangband to allow a
 * greater variety of traps, with effects controlled by dungeon level.
 * To allow a trap to choose one of a variety of effects consistantly,
 * the quick RNG is often used, and xy coordinates input as a seed value.
 */
extern void hit_trap(int y, int x)
{
    int i, j, k, num;
    int dam = 0;

    int nastyness, selection;

    feature_type *f_ptr = &f_info[cave_feat[y][x]];

    cptr name = f_ptr->name;

    /* Use the "simple" RNG to insure that traps are consistant. */
    Rand_quick = TRUE;

    /* Use the coordinates of the trap to seed the RNG. */
    Rand_value = y * x;

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

    /* Analyze XXX XXX XXX */
    switch (cave_feat[y][x]) {
    /* trap door. */
    case FEAT_TRAP_HEAD + 0x00:
    {
        Rand_quick = FALSE;

        /* Paranoia -NRM- */
        if (((stage_map[p_ptr->stage][STAGE_TYPE] == CAVE)
                || (stage_map[p_ptr->stage][STAGE_TYPE] == VALLEY))
                && (!stage_map[p_ptr->stage][DOWN])) {
            cave_info[y][x] &= ~(CAVE_MARK);
            cave_set_feat(y, x, FEAT_FLOOR);
            msg_print("The trap fails!");
            break;
        }


        msg_print("You fall through a trap door!");
        if (p_ptr->state.ffall) {
            notice_obj(OF_FEATHER, 0);
            msg_print("You float gently down to the next level.");
        } else {
            dam = damroll(2, 8);
            take_hit(dam, name);
        }
        /* Remember where we came from */
        p_ptr->last_stage = p_ptr->stage;

        if (!stage_map[p_ptr->stage][DOWN]) {
            /* Set the ways forward and back */
            stage_map[255][UP] = p_ptr->stage;
            stage_map[p_ptr->stage][DOWN] = 255;
            stage_map[255][DEPTH] = p_ptr->depth + 1;
        }

        /* New stage */
        p_ptr->stage = stage_map[p_ptr->stage][DOWN];

        /* New depth */
        p_ptr->depth = stage_map[p_ptr->stage][DEPTH];

        /* Leaving */
        p_ptr->leaving = TRUE;

        Rand_quick = TRUE;

        break;
    }

    /* pits. */
    case FEAT_TRAP_HEAD + 0x01:
    {
        /* determine how dangerous the trap is allowed to be. */
        nastyness = randint1(p_ptr->depth);
        if (randint1(20) == 1)
            nastyness += 20;
        else if (randint1(5) == 1)
            nastyness += 10;

        /* Player is now in pit. */
        monster_swap(p_ptr->py, p_ptr->px, y, x);

        /* Center on player. */
        y = p_ptr->py;
        x = p_ptr->px;

        /* pit of daggers. */
        if ((nastyness > 80) && (randint1(3) != 3)) {
            msg_print("You fall into a pit of daggers!");

            if (p_ptr->state.ffall) {
                notice_obj(OF_FEATHER, 0);
                msg_print("You float gently to the floor of the pit.");
                msg_print("You carefully avoid setting off the daggers.");
            }

            else {
                /* a trap of morgul. */
                if (randint1(6) == 1) {
                    Rand_quick = FALSE;


                    msg_print
                    ("A single coldly gleaming dagger pierces you deeply!");
                    msg_print
                    ("You feel a deadly chill slowly withering your soul.");

                    /* activate the Black Breath. */
                    p_ptr->black_breath = TRUE;

                    /* lots of damage. */
                    dam = damroll(20, 15);

                    /* undead may be attracted. */
                    if (randint1(2) == 1) {
                        msg_print
                        ("Undead suddenly appear and call you to them!");

                        k = randint1(3) + 2;
                        for (i = 0; i < k; i++) {
                            summon_specific(y, x, FALSE, p_ptr->depth,
                                            SUMMON_UNDEAD);
                        }
                    }

                    /* morgul-traps are one-time only. */
                    cave_info[y][x] &= ~(CAVE_MARK);
                    cave_set_feat(y, x, FEAT_FLOOR);

                    Rand_quick = TRUE;
                }

                else {
                    Rand_quick = FALSE;

                    /* activate the ordinary daggers. */
                    msg_print("Daggers pierce you everywhere!");

                    k = randint1(10) + 5;
                    for (i = 0; i < k; i++) {
                        dam += damroll(3, 4);
                    }

                    Rand_quick = TRUE;
                }

                /* cut the player. */
                (void) inc_timed(TMD_CUT, randint1(dam), TRUE);

                /* Take the damage. */
                take_hit(dam, name);
            }
        }

        /* poisoned spiked pit. */
        else if ((nastyness > 55) && (randint1(3) != 3)) {
            msg_print("You fall into a spiked pit!");

            if (p_ptr->state.ffall) {
                notice_obj(OF_FEATHER, 0);
                msg_print("You float gently to the floor of the pit.");
                msg_print("You carefully avoid touching the spikes.");
            }

            else {
                Rand_quick = FALSE;

                /* Base damage */
                dam = damroll(2, 6);

                /* Extra spike damage */
                if (randint0(100) < 85) {
                    bool was_poisoned;

                    msg_print("You are impaled on poisonous spikes!");

                    dam = dam * (randint1(6) + 3);
                    (void) inc_timed(TMD_CUT, randint1(dam), TRUE);

                    was_poisoned = pois_hit(dam);

                    if (!was_poisoned)
                        msg_print("The poison does not affect you!");
                }

                /* Take the damage */
                take_hit(dam, name);

                Rand_quick = TRUE;
            }
        }

        /* spiked pit. */
        else if ((nastyness > 30) && (randint1(3) != 3)) {
            msg_print("You fall into a spiked pit!");

            if (p_ptr->state.ffall) {
                notice_obj(OF_FEATHER, 0);
                msg_print("You float gently to the floor of the pit.");
                msg_print("You carefully avoid touching the spikes.");
            }

            else {
                Rand_quick = FALSE;

                /* Base damage */
                dam = damroll(2, 6);

                /* Extra spike damage */
                if (randint0(100) < 85) {
                    msg_print("You are impaled!");

                    dam = dam * (2 + randint1(4));
                    (void) inc_timed(TMD_CUT, randint1(dam), TRUE);
                }

                /* Take the damage */
                take_hit(dam, name);

                Rand_quick = TRUE;
            }
        }

        /* ordinary pit in all other cases. */
        else {
            msg_print("You fall into a pit!");
            if (p_ptr->state.ffall) {
                notice_obj(OF_FEATHER, 0);
                msg_print("You float gently to the bottom of the pit.");
            } else {
                Rand_quick = FALSE;

                dam = damroll(2, 6);
                take_hit(dam, name);

                Rand_quick = TRUE;
            }
        }

        break;
    }

    /* stat-reducing dart traps. */
    case FEAT_TRAP_HEAD + 0x02:
    {
        /* decide if the dart hits. */
        if (check_trap_hit(50 + p_ptr->depth)) {
            /* select a stat to drain. */
            selection = randint0(6);

            Rand_quick = FALSE;

            msg_print("A small dart hits you!");
            dam = damroll(1, 4);
            take_hit(dam, name);

            /* Determine how dangerous the trap is allowed to be. */
            nastyness = randint1(p_ptr->depth);

            /* decide how much to drain the stat by. */
            if ((nastyness > 50) && (randint1(3) == 1)) {
                num = randint1(4);
            } else
                num = 1;

            /* drain the stat. */
            for (i = 0; i < num; i++) {
                (void) do_dec_stat(selection);
            }

            Rand_quick = TRUE;
        } else {
            msg_print("A small dart barely misses you.");
        }
        break;
    }

    /* discolored spots. */
    case FEAT_TRAP_HEAD + 0x03:
    {
        /* determine how dangerous the trap is allowed to be. */
        nastyness = randint1(p_ptr->depth);
        if (randint1(5) == 1)
            nastyness += 10;

        /* pick a elemental attack type. */
        selection = randint1(4);


        /* electicity trap. */
        if (selection == 1) {
            if ((nastyness >= 50) && (randint1(2) == 1)) {
                Rand_quick = FALSE;

                msg_print("You are struck by lightning!");
                dam = damroll(6, 30);

                Rand_quick = TRUE;
            } else {
                Rand_quick = FALSE;

                msg_print("You get zapped!");
                dam = damroll(4, 8);

                Rand_quick = TRUE;
            }
            Rand_quick = FALSE;
            elec_dam(dam, "an electricity trap");
            Rand_quick = TRUE;

        }

        /* frost trap. */
        if (selection == 2) {
            if ((nastyness >= 50) && (randint1(2) == 1)) {
                Rand_quick = FALSE;

                msg_print("You are lost within a blizzard!");
                dam = damroll(6, 30);

                Rand_quick = TRUE;
            } else {
                Rand_quick = FALSE;

                msg_print("You are coated in frost!");
                dam = damroll(4, 8);

                Rand_quick = TRUE;
            }
            Rand_quick = FALSE;
            cold_dam(dam, "a frost trap");
            Rand_quick = TRUE;
        }

        /* fire trap. */
        if (selection == 3) {
            if ((nastyness >= 50) && (randint1(2) == 1)) {
                Rand_quick = FALSE;

                msg_print("You are enveloped in a column of fire!");
                dam = damroll(6, 30);

                Rand_quick = TRUE;
            } else {
                Rand_quick = FALSE;

                msg_print("You are surrounded by flames!");
                dam = damroll(4, 8);

                Rand_quick = TRUE;
            }
            Rand_quick = FALSE;
            fire_dam(dam, "a fire trap");
            Rand_quick = TRUE;
        }

        /* acid trap. */
        if (selection == 4) {
            if ((nastyness >= 50) && (randint1(2) == 1)) {
                Rand_quick = FALSE;

                msg_print("A cauldron of acid is tipped over your head!");
                dam = damroll(6, 30);

                Rand_quick = TRUE;
            } else {
                Rand_quick = FALSE;

                msg_print("You are splashed with acid!");
                dam = damroll(4, 8);

                Rand_quick = TRUE;
            }
            Rand_quick = FALSE;
            acid_dam(dam, "an acid trap");
            Rand_quick = TRUE;
        }

        break;
    }

    /* gas traps. */
    case FEAT_TRAP_HEAD + 0x04:
    {
        selection = randint1(4);

        /* blinding trap. */
        if (selection == 1) {
            msg_print("You are surrounded by a black gas!");
            if (!p_ptr->state.no_blind) {
                Rand_quick = FALSE;

                (void) inc_timed(TMD_BLIND, randint0(30) + 15, TRUE);

                Rand_quick = TRUE;
            }
        } else
            notice_obj(OF_SEEING, 0);

        /* confusing trap. */
        if (selection == 2) {
            msg_print
            ("You are surrounded by a gas of scintillating colors!");
            if (!p_resist_good(P_RES_CONFU)) {
                Rand_quick = FALSE;

                (void) inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE);

                Rand_quick = TRUE;
            } else
                notice_other(IF_RES_CONFU, 0);
        }

        /* poisoning trap. */
        if (selection == 3) {
            msg_print("You are surrounded by a pungent green gas!");

            Rand_quick = FALSE;

            pois_hit(25);

            Rand_quick = TRUE;
        }

        /* sleeping trap. */
        if (selection == 4) {
            msg_print("You are surrounded by a strange white mist!");
            if (!p_ptr->state.free_act) {
                (void) inc_timed(TMD_PARALYZED, randint0(10) + 5, TRUE);
            } else
                notice_obj(OF_FREE_ACT, 0);
        }

        break;
    }

    /* summoning traps. */
    case FEAT_TRAP_HEAD + 0x05:
    {
        sound(MSG_SUM_MONSTER);
        /* sometimes summon thieves. */
        if ((p_ptr->depth > 8) && (randint1(5) == 1)) {
            msg_print("You have aroused a den of thieves!");

            Rand_quick = FALSE;

            num = 2 + randint1(3);
            for (i = 0; i < num; i++) {
                (void) summon_specific(y, x, FALSE, p_ptr->depth,
                                       SUMMON_THIEF);
            }

            Rand_quick = TRUE;
        }

        /* sometimes summon a nasty unique. */
        else if (randint1(8) == 1) {
            msg_print("You are enveloped in a cloud of smoke!");

            Rand_quick = FALSE;

            (void) summon_specific(y, x, FALSE, p_ptr->depth + 5,
                                   SUMMON_UNIQUE);

            Rand_quick = TRUE;
        }

        /* otherwise, the ordinary summon monsters. */
        else {
            msg_print("You are enveloped in a cloud of smoke!");

            Rand_quick = FALSE;

            num = 2 + randint1(3);
            for (i = 0; i < num; i++) {
                (void) summon_specific(y, x, FALSE, p_ptr->depth, 0);
            }

            Rand_quick = TRUE;
        }

        /* these are all one-time traps. */
        cave_info[y][x] &= ~(CAVE_MARK);
        cave_set_feat(y, x, FEAT_FLOOR);

        break;
    }

    /* dungeon alteration traps. */
    case FEAT_TRAP_HEAD + 0x06:
    {
        /* determine how dangerous the trap is allowed to be. */
        nastyness = randint1(p_ptr->depth);
        if (randint1(5) == 1)
            nastyness += 10;

        /* make room for alterations. */
        cave_info[y][x] &= ~(CAVE_MARK);
        cave_set_feat(y, x, FEAT_FLOOR);

        /* Everything truely random from here on. */
        Rand_quick = FALSE;

        /* dungeon destruction trap. */
        if ((nastyness > 60) && (randint1(12) == 1)) {
            msg_print
            ("A ear-splitting howl shatters your mind as the dungeon is smashed by hammer blows!");

            (void) destroy_level(FALSE);

            /* the player is hard-hit. */
            (void) inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE);
            (void) inc_timed(TMD_BLIND, randint0(30) + 15, TRUE);
            (void) inc_timed(TMD_STUN, randint1(50) + 50, TRUE);
            dam = damroll(15, 15);
            take_hit(dam, name);
        }

        /* earthquake trap. */
        else if ((nastyness > 20) && (randint1(4) == 1)) {
            msg_print("A tremor shakes the earth around you");
            earthquake(y, x, 10, FALSE);
        }

        /* falling rock trap. */
        else if ((nastyness > 4) && (randint1(2) == 1)) {
            msg_print("A rock falls on your head.");
            dam = damroll(2, 10);
            take_hit(dam, name);

            (void) inc_timed(TMD_STUN, randint1(10) + 10, TRUE);
        }

        /* a few pebbles. */
        else {
            msg_print("A bunch of pebbles rain down on you.");
            dam = damroll(1, 8);
            take_hit(dam, name);
        }

        Rand_quick = TRUE;

        break;
    }

    /* various char and equipment-alteration traps, lumped together to
     * avoid any one effect being too common (some of them can be rather
     * nasty). */
    case FEAT_TRAP_HEAD + 0x07:
    {
        /* determine how dangerous the trap is allowed to be. */
        nastyness = randint0(100);

        /* these are all one-time traps. */
        cave_info[y][x] &= ~(CAVE_MARK);
        cave_set_feat(y, x, FEAT_FLOOR);

        /* Everything truely random from here on. */
        Rand_quick = FALSE;

        /* trap of drain wands. */
        if (nastyness < 15) {
            /* Hold the object information. */
            object_type *o_ptr;

            /* Find an item */
            for (i = 0; i < 20; i++) {
                /* Pick an item */
                i = randint0(INVEN_PACK - p_ptr->pack_size_reduce);

                /* Obtain the item */
                o_ptr = &p_ptr->inventory[i];

                /* use "num" to decide if a item can be uncharged.  By
                 * default, assume it can't. */
                num = 0;

                /* Skip non-objects */
                if (!o_ptr->k_idx)
                    continue;

                /* Drain charged wands/staffs/rods */
                if ((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)
                        || (o_ptr->tval == TV_ROD)) {
                    /* case of charged wands/staffs. */
                    if (((o_ptr->tval == TV_STAFF)
                            || (o_ptr->tval == TV_WAND)) && (o_ptr->pval))
                        num = 1;

                    /* case of charged rods. */
                    if ((o_ptr->tval == TV_ROD)
                            && (o_ptr->timeout < randcalc(o_ptr->time, 0,
                                                          MINIMISE)))
                        num = 1;


                    if (num == 1) {
                        /* Message */
                        msg_print("Energy drains from your pack!");

                        /* Uncharge */
                        if ((o_ptr->tval == TV_STAFF)
                                || (o_ptr->tval == TV_WAND))
                            o_ptr->pval = 0;

                        if (o_ptr->tval == TV_ROD)
                            o_ptr->timeout = randcalc(o_ptr->time, 0, RANDOMISE) * o_ptr->number * 2;


                        /* Combine / Reorder the pack */
                        p_ptr->notice |= (PN_COMBINE | PN_REORDER);

                        /* not more than one inventory slot effected. */
                        break;
                    } else
                        continue;
                }
            }
        }

        /* trap of forgetting. */
        else if (nastyness < 35) {
            if (check_save(100)) {
                msg_print("You hang on to your memories!");
            } else if (lose_all_info()) {
                msg_print("Your memories fade away.");
            }
        }

        /* trap of alter reality. */
        else if (nastyness < 50) {
            if (OPT(adult_ironman))
                msg_print("Nothing happens.");
            else {
                msg_print("The world changes!");

                /* Leaving */
                p_ptr->leaving = TRUE;
            }
        }

        /* trap of remold player. */
        else if (nastyness < 75) {
            int max1, cur1, max2, cur2, ii, jj;

            msg_print("You feel yourself being twisted by wild magic!");

            if (check_save(100)) {
                msg_print("You resist the effects!");
            } else {
                msg_print("Your body starts to scramble...");

                /* Pick a pair of stats */
                ii = randint0(6);
                for (jj = ii; jj == ii; jj = randint0(6))	/* loop */
                    ;

                max1 = p_ptr->stat_max[ii];
                cur1 = p_ptr->stat_cur[ii];
                max2 = p_ptr->stat_max[jj];
                cur2 = p_ptr->stat_cur[jj];

                p_ptr->stat_max[ii] = max2;
                p_ptr->stat_cur[ii] = cur2;
                p_ptr->stat_max[jj] = max1;
                p_ptr->stat_cur[jj] = cur1;

                p_ptr->update |= (PU_BONUS);
            }
        }

        /* time ball trap. */
        else if (nastyness < 90) {
            msg_print("You feel time itself assault you!");

            /* Target the player with a radius 0 ball attack. */
            fire_meteor(0, GF_TIME, p_ptr->py, p_ptr->px, 75, 0, TRUE);
        }

        /* trap of bugs gone berserk. */
        else {
            /* explain what the dickens is going on. */
            msg_print("GRUESOME Gnawing Bugs leap out at you!");

            if (!p_resist_good(P_RES_CONFU)) {
                (void) inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE);
            } else
                notice_other(IF_RES_CONFU, 0);

            if (!p_resist_good(P_RES_CHAOS)) {
                (void) inc_timed(TMD_IMAGE, randint1(40), TRUE);
            } else
                notice_other(IF_RES_CHAOS, 0);

            /* XXX (hard coded) summon 3-6 bugs. */
            k = randint1(4) + 2;
            for (i = 0; i < k; ++i) {
                /* Look for a location */
                for (j = 0; j < 20; ++j) {
                    /* Pick a (scattered) distance. */
                    int d = (j / 10) + randint1(3);

                    /* Pick a location */
                    scatter(&y, &x, y, x, d, 0);

                    /* Require passable terrain */
                    if (!cave_passable_bold(y, x))
                        continue;

                    /* Hack -- no summon on glyph of warding */
                    if (cave_feat[y][x] == FEAT_RUNE_PROTECT)
                        continue;

                    /* Okay */
                    break;
                }

                /* Attempt to place the awake bug */
                place_monster_aux(y, x, 453, FALSE, TRUE);
            }

            /* herald the arrival of bugs. */
            msg_print("AAAAAAAHHHH! THEY'RE EVERYWHERE!");
        }

        Rand_quick = TRUE;

        break;
    }

    /* teleport trap */
    case FEAT_TRAP_HEAD + 0x08:
    {
        if (stage_map[p_ptr->stage][STAGE_TYPE] >= CAVE)
            msg_print("You teleport across the dungeon.");
        else
            msg_print("You teleport across the wilderness.");

        Rand_quick = FALSE;

        teleport_player(250, FALSE);

        Rand_quick = TRUE;

        break;
    }

    /* murder holes. */
    case FEAT_TRAP_HEAD + 0x09:
    {
        /* hold the object info. */
        object_type *o_ptr;
        object_type object_type_body;

        /* hold the missile type and name. */
        int sval = 0;
        int tval = 0;
        cptr missile_name = "";



        /* Determine the missile type and base damage. */
        if (randint1(3) == 1) {
            if (p_ptr->depth < 40) {
                missile_name = "shot";
                dam = damroll(2, 3);
                tval = TV_SHOT;
                sval = SV_AMMO_NORMAL;
            } else {
                missile_name = "seeker shot";
                dam = damroll(3, 7);
                tval = TV_SHOT;
                sval = SV_AMMO_HEAVY;
            }
        }

        else if (randint1(2) == 1) {
            if (p_ptr->depth < 55) {
                missile_name = "arrow";
                dam = damroll(2, 4);
                tval = TV_ARROW;
                sval = SV_AMMO_NORMAL;
            } else {
                missile_name = "seeker arrow";
                dam = damroll(3, 9);
                tval = TV_ARROW;
                sval = SV_AMMO_HEAVY;
            }
        }

        else {
            if (p_ptr->depth < 65) {
                missile_name = "bolt";
                dam = damroll(2, 5);
                tval = TV_BOLT;
                sval = SV_AMMO_NORMAL;
            } else {
                missile_name = "seeker bolt";
                dam = damroll(3, 11);
                tval = TV_BOLT;
                sval = SV_AMMO_HEAVY;
            }
        }

        /* determine if the missile hits. */
        if (check_trap_hit(75 + p_ptr->depth)) {
            msg_format("A %s hits you from above.", missile_name);

            Rand_quick = FALSE;

            /* critical hits. */
            if (randint1(2) == 1) {
                msg_print("It was well-aimed!");
                dam *= 1 + randint1(2);
            }
            if (randint1(2) == 1) {
                msg_print("It gouges you!");
                dam = 3 * dam / 2;

                /* cut the player. */
                (void) inc_timed(TMD_CUT, randint1(dam), TRUE);
            }

            Rand_quick = TRUE;

            take_hit(dam, name);
        }

        /* Explain what just happened. */
        else
            msg_format("A %s wizzes by your head.", missile_name);

        /* these will eventually run out of ammo. */

        Rand_quick = FALSE;

        if (randint0(8) == 0) {
            cave_info[y][x] &= ~(CAVE_MARK);
            cave_set_feat(y, x, FEAT_FLOOR);
        }

        Rand_quick = TRUE;

        /* Get local object */
        o_ptr = &object_type_body;

        /* Make a missile, identify it, and drop it near the player. */
        object_prep(o_ptr, lookup_kind(tval, sval), MINIMISE);
        object_aware(o_ptr);
        object_known(o_ptr);
        drop_near(o_ptr, -1, y, x, TRUE);

        break;
    }

    /* falling tree branch */
    case FEAT_TRAP_HEAD + 0x0A:
    {
        /* determine if the missile hits. */
        if (check_trap_hit(75 + p_ptr->depth)) {
            /* Take damage */
            dam = damroll(3, 5);
            msg_print("A branch hits you from above.");

            Rand_quick = FALSE;

            /* critical hits. */
            if (randint1(2) == 1) {
                msg_print("It was heavy!");
                dam = 3 * dam / 2;

                /* stun the player. */
                (void) inc_timed(TMD_STUN, randint1(dam), TRUE);
            }

            Rand_quick = TRUE;

            take_hit(dam, name);
        }

        /* Explain what just happened. */
        else
            msg_print("A falling branch just misses you.");

        /* No more */
        cave_info[y][x] &= ~(CAVE_MARK);
        cave_set_feat(y, x, FEAT_TREE);

        break;
    }

    /* falling tree branch */
    case FEAT_TRAP_HEAD + 0x0B:
    {
        /* determine if the missile hits. */
        if (check_trap_hit(75 + p_ptr->depth)) {
            /* Take damage */
            dam = damroll(3, 5);
            msg_print("A branch hits you from above.");

            Rand_quick = FALSE;

            /* critical hits. */
            if (randint1(2) == 1) {
                msg_print("It was heavy!");
                dam = 3 * dam / 2;

                /* stun the player. */
                (void) inc_timed(TMD_STUN, randint1(dam), TRUE);
            }

            Rand_quick = TRUE;

            take_hit(dam, name);
        }

        /* Explain what just happened. */
        else
            msg_print("A falling branch just misses you.");

        /* No more */
        cave_info[y][x] &= ~(CAVE_MARK);
        cave_set_feat(y, x, FEAT_TREE2);

        break;
    }

    /* undefined trap. */
    case FEAT_TRAP_HEAD + 0x0C:
    {
        msg_print("A dagger is thrown at you from the shadows!");
        dam = damroll(3, 4);
        take_hit(dam, name);

        break;
    }

    /* undefined trap. */
    case FEAT_TRAP_HEAD + 0x0D:
    {
        msg_print("A dagger is thrown at you from the shadows!");
        dam = damroll(3, 4);
        take_hit(dam, name);

        break;
    }

    /* undefined trap. */
    case FEAT_TRAP_HEAD + 0x0E:
    {
        msg_print("A dagger is thrown at you from the shadows!");
        dam = damroll(3, 4);
        take_hit(dam, name);

        break;
    }

    /* undefined trap. */
    case FEAT_TRAP_HEAD + 0x0F:
    {
        msg_print("A dagger is thrown at you from the shadows!");
        dam = damroll(3, 4);
        take_hit(dam, name);

        break;
    }

    }

    /* Revert to usage of the complex RNG. */
    Rand_quick = FALSE;
}