summaryrefslogtreecommitdiff
path: root/src/traps.cc
diff options
context:
space:
mode:
authorBardur Arantsson <bardur@scientician.net>2016-10-05 18:45:09 +0200
committerBardur Arantsson <bardur@scientician.net>2016-10-05 18:49:38 +0200
commitcbafbc638c2e1d5bb40ee6bc419007062e9615e4 (patch)
tree0a4644c9c935a2a54d8b52613c67a09fc2fbf4be /src/traps.cc
parent551339813797a9b274ccf5f3f0c4f0d0b44cbf64 (diff)
Remove traps
Credit goes mostly to "miramor" <danlev@norwoodlight.com> who did most of the actual work. I just did a few minor tweaks and fixes + rebased onto master.
Diffstat (limited to 'src/traps.cc')
-rw-r--r--src/traps.cc3113
1 files changed, 0 insertions, 3113 deletions
diff --git a/src/traps.cc b/src/traps.cc
deleted file mode 100644
index a646d221..00000000
--- a/src/traps.cc
+++ /dev/null
@@ -1,3113 +0,0 @@
-/* the below copyright probably still applies, but it is heavily changed
- * copied, adapted & re-engineered by JK.
- * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
- *
- * This software may be copied and distributed for educational, research, and
- * not for profit purposes provided that this copyright and statement are
- * included in all such copies.
- */
-
-#include "traps.hpp"
-
-#include "artifact_type.hpp"
-#include "cave.hpp"
-#include "cave_type.hpp"
-#include "cmd1.hpp"
-#include "cmd2.hpp"
-#include "dungeon_flag.hpp"
-#include "dungeon_info_type.hpp"
-#include "feature_flag.hpp"
-#include "feature_type.hpp"
-#include "files.hpp"
-#include "game.hpp"
-#include "gods.hpp"
-#include "monster2.hpp"
-#include "monster_race.hpp"
-#include "monster_race_flag.hpp"
-#include "monster_type.hpp"
-#include "object1.hpp"
-#include "object2.hpp"
-#include "object_flag.hpp"
-#include "object_kind.hpp"
-#include "player_race.hpp"
-#include "player_race_mod.hpp"
-#include "player_spec.hpp"
-#include "player_type.hpp"
-#include "spells1.hpp"
-#include "spells2.hpp"
-#include "stats.hpp"
-#include "tables.hpp"
-#include "trap_type.hpp"
-#include "util.hpp"
-#include "variable.hpp"
-#include "xtra1.hpp"
-#include "xtra2.hpp"
-#include "z-rand.hpp"
-
-bool_ do_player_trap_call_out(void)
-{
- s16b i, sn, cx, cy;
- s16b h_index = 0;
- s16b h_level = 0;
- monster_type *m_ptr;
- char m_name[80];
- bool_ ident = FALSE;
-
- for (i = 1; i < m_max; i++)
- {
- m_ptr = &m_list[i];
-
- /* Paranoia -- Skip dead monsters */
- if (!m_ptr->r_idx) continue;
-
- if (m_ptr->level >= h_level)
- {
- h_level = m_ptr->level;
- h_index = i;
- }
- }
-
- /* if the level is empty of monsters, h_index will be 0 */
- if (!h_index) return (FALSE);
-
- m_ptr = &m_list[h_index];
-
- sn = 0;
- for (i = 0; i < 8; i++)
- {
- cx = p_ptr->px + ddx[i];
- cy = p_ptr->py + ddy[i];
-
- /* Skip non-empty grids */
- if (!cave_valid_bold(cy, cx)) continue;
- if (cave[cy][cx].feat == FEAT_GLYPH) continue;
- if ((cx == p_ptr->px) && (cy == p_ptr->py)) continue;
- sn++;
-
- /* Randomize choice */
- if (rand_int(sn) > 0) continue;
- cave[cy][cx].m_idx = h_index;
- cave[m_ptr->fy][m_ptr->fx].m_idx = 0;
- m_ptr->fx = cx;
- m_ptr->fy = cy;
-
- /* we do not change the sublevel! */
- ident = TRUE;
- update_mon(h_index, TRUE);
- monster_desc(m_name, m_ptr, 0x08);
- msg_format("You hear a rapid-shifting wail, and %s appears!", m_name);
- break;
- }
-
- return (ident);
-}
-
-static bool_ do_trap_teleport_away(object_type *i_ptr, s16b y, s16b x)
-{
- auto const &f_info = game->edit_data.f_info;
-
- bool_ ident = FALSE;
- char o_name[80];
-
- s16b o_idx = 0;
- object_type *o_ptr;
- cave_type *c_ptr;
-
- s16b x1;
- s16b y1;
-
- if (i_ptr == NULL) return (FALSE);
-
- if (i_ptr->name1 == ART_POWER) return (FALSE);
-
- while (o_idx == 0)
- {
- x1 = rand_int(cur_wid);
- y1 = rand_int(cur_hgt);
-
- /* Obtain grid */
- c_ptr = &cave[y1][x1];
-
- /* Require floor space (or shallow terrain) -KMW- */
- if (!(f_info[c_ptr->feat].flags & FF_FLOOR)) continue;
-
- o_idx = drop_near(i_ptr, 0, y1, x1);
- }
-
- o_ptr = &o_list[o_idx];
-
- x1 = o_ptr->ix;
- y1 = o_ptr->iy;
-
- if (!p_ptr->blind)
- {
- note_spot(y, x);
- lite_spot(y, x);
- ident = TRUE;
- object_desc(o_name, i_ptr, FALSE, 0);
- if (player_has_los_bold(y1, x1))
- {
- lite_spot(y1, x1);
- msg_format("The %s suddenly stands elsewhere.", o_name);
-
- }
- else
- {
- msg_format("You suddenly don't see the %s any more!", o_name);
- }
- }
- else
- {
- msg_print("You hear something move.");
- }
- return (ident);
-}
-
-/*
- * this handles a trap that places walls around the player
- */
-static bool_ player_handle_trap_of_walls(void)
-{
- auto const &f_info = game->edit_data.f_info;
-
- bool_ ident;
-
- s16b dx, dy, cx, cy;
- s16b sx = 0, sy = 0, sn, i;
- cave_type *cv_ptr;
- bool_ map[5][5] =
- {
- {FALSE, FALSE, FALSE, FALSE, FALSE},
- {FALSE, FALSE, FALSE, FALSE, FALSE},
- {FALSE, FALSE, FALSE, FALSE, FALSE},
- {FALSE, FALSE, FALSE, FALSE, FALSE},
- {FALSE, FALSE, FALSE, FALSE, FALSE}
- };
-
- for (dy = -2; dy <= 2; dy++)
- for (dx = -2; dx <= 2; dx++)
- {
- /* Extract the location */
- cx = p_ptr->px + dx;
- cy = p_ptr->py + dy;
-
- if (!in_bounds(cy, cx)) continue;
-
- cv_ptr = &cave[cy][cx];
-
- if (cv_ptr->m_idx) continue;
-
- /* Lose room and vault */
- cv_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY);
- /* Lose light and knowledge */
- cv_ptr->info &= ~(CAVE_GLOW | CAVE_MARK);
-
- /* Skip the center */
- if (!dx && !dy) continue;
-
- /* test for dungeon level */
- if (randint(100) > 10 + max_dlv[dungeon_type]) continue;
-
- /* Damage this grid */
- map[2 + dx][2 + dy] = TRUE;
- }
-
- for (dy = -2; dy <= 2; dy++)
- for (dx = -2; dx <= 2; dx++)
- {
- /* Extract the location */
- cx = p_ptr->px + dx;
- cy = p_ptr->py + dy;
-
- /* Skip unaffected grids */
- if (!map[2 + dx][2 + dy]) continue;
-
- cv_ptr = &cave[cy][cx];
-
- if (cv_ptr->m_idx)
- {
- monster_type *m_ptr = &m_list[cv_ptr->m_idx];
- auto const r_ptr = m_ptr->race();
-
- /* Most monsters cannot co-exist with rock */
- if ((!(r_ptr->flags & RF_KILL_WALL)) &&
- (!(r_ptr->flags & RF_PASS_WALL)))
- {
- char m_name[80];
-
- /* Assume not safe */
- sn = 0;
-
- /* Monster can move to escape the wall */
- if (!(r_ptr->flags & RF_NEVER_MOVE))
- {
- /* Look for safety */
- for (i = 0; i < 8; i++)
- {
- /* Access the grid */
- cy = p_ptr->py + ddy[i];
- cx = p_ptr->px + ddx[i];
-
- /* Skip non-empty grids */
- if (!cave_clean_bold(cy, cx)) continue;
-
- /* Hack -- no safety on glyph of warding */
- if (cave[cy][cx].feat == FEAT_GLYPH) continue;
-
- /* Important -- Skip "quake" grids */
- if (map[2 + (cx - p_ptr->px)][2 + (cy - p_ptr->py)]) continue;
-
- /* Count "safe" grids */
- sn++;
-
- /* Randomize choice */
- if (rand_int(sn) > 0) continue;
-
- /* Save the safe grid */
- sx = cx;
- sy = cy;
-
- ident = TRUE;
-
- break; /* discontinue for loop - safe grid found */
- }
- }
-
- /* Describe the monster */
- monster_desc(m_name, m_ptr, 0);
-
- /* Scream in pain */
- msg_format("%^s wails out in pain!", m_name);
-
- /* Monster is certainly awake */
- m_ptr->csleep = 0;
-
- /* Apply damage directly */
- m_ptr->hp -= (sn ? damroll(4, 8) : 200);
-
- /* Delete (not kill) "dead" monsters */
- if (m_ptr->hp < 0)
- {
- /* Message */
- msg_format("%^s is entombed in the rock!", m_name);
-
- /* Delete the monster */
- delete_monster_idx(cave[cy][cx].m_idx);
-
- /* No longer safe */
- sn = 0;
- }
-
- /* Hack -- Escape from the rock */
- if (sn)
- {
- s16b m_idx = cave[cy][cx].m_idx;
-
- /* Update the new location */
- cave[sy][sx].m_idx = m_idx;
-
- /* Update the old location */
- cave[cy][cx].m_idx = 0;
-
- /* Move the monster */
- m_ptr->fy = sy;
- m_ptr->fx = sx;
-
- /* do not change fz */
- /* don't make rock on that square! */
- if ((sx >= (p_ptr->px - 2)) && (sx <= (p_ptr->px + 2)) &&
- (sy >= (p_ptr->py - 2)) && (sy <= (p_ptr->py + 2)))
- {
- map[2 + (sx - p_ptr->px)][2 + (sy - p_ptr->py)] = FALSE;
- }
-
- /* Update the monster (new location) */
- update_mon(m_idx, TRUE);
-
- /* Redraw the old grid */
- lite_spot(cy, cx);
-
- /* Redraw the new grid */
- lite_spot(sy, sx);
- } /* if sn */
- } /* if monster can co-exist with rock */
- } /* if monster on square */
- }
-
- /* Examine the quaked region */
- for (dy = -2; dy <= 2; dy++)
- for (dx = -2; dx <= 2; dx++)
- {
- /* Extract the location */
- cx = p_ptr->px + dx;
- cy = p_ptr->py + dy;
-
- /* Skip unaffected grids */
- if (!map[2 + dx][2 + dy]) continue;
-
- /* Access the cave grid */
- cv_ptr = &cave[cy][cx];
-
- /* Paranoia -- never affect player */
- if (!dy && !dx) continue;
-
- /* Destroy location (if valid) */
- if ((cx < cur_wid) && (cy < cur_hgt) && cave_valid_bold(cy, cx))
- {
- bool floor = bool(f_info[cave[cy][cx].feat].flags & FF_FLOOR);
-
- /* Delete any object that is still there */
- delete_object(cy, cx);
-
- if (floor)
- {
- cave_set_feat(cy, cx, FEAT_WALL_OUTER);
- }
- else
- {
- /* Clear previous contents, add floor */
- cave_set_feat(cy, cx, FEAT_FLOOR);
- }
- }
- }
-
- /* Mega-Hack -- Forget the view and lite */
- p_ptr->update |= PU_UN_VIEW;
-
- /* Update stuff */
- p_ptr->update |= (PU_VIEW | PU_FLOW | PU_MON_LITE);
-
- /* Update the monsters */
- p_ptr->update |= (PU_DISTANCE);
-
- /* Update the health bar */
- p_ptr->redraw |= (PR_FRAME);
-
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD);
- handle_stuff();
-
- msg_print("Suddenly the cave shifts around you. The air is getting stale!");
-
- ident = TRUE;
-
- return (ident);
-}
-
-
-/*
- * this function handles arrow & dagger traps, in various types.
- * num = number of missiles
- * tval, sval = kind of missiles
- * dd,ds = damage roll for missiles
- * poison_dam = additional poison damage
- * name = name given if you should die from it...
- *
- * return value = ident (always TRUE)
- */
-static bool_ player_handle_missile_trap(s16b num, s16b tval, s16b sval, s16b dd, s16b ds,
- s16b pdam, cptr name)
-{
- object_type *o_ptr, forge;
- s16b i, k_idx = lookup_kind(tval, sval);
- char i_name[80];
-
- o_ptr = &forge;
- object_prep(o_ptr, k_idx);
- o_ptr->number = num;
- apply_magic(o_ptr, max_dlv[dungeon_type], FALSE, FALSE, FALSE);
- object_desc(i_name, o_ptr, TRUE, 0);
-
- msg_format("Suddenly %s hit%s you!", i_name,
- ((num == 1) ? "" : "s"));
-
- for (i = 0; i < num; i++)
- {
- take_hit(damroll(dd, ds), name);
-
- redraw_stuff();
-
- if (pdam > 0)
- {
- if (!(p_ptr->resist_pois || p_ptr->oppose_pois))
- {
- (void)set_poisoned(p_ptr->poisoned + pdam);
- }
- }
- }
-
- drop_near(o_ptr, -1, p_ptr->py, p_ptr->px);
-
- return TRUE;
-}
-
-/*
- * this function handles a "breath" type trap - acid bolt, lightning balls etc.
- */
-static bool_ player_handle_breath_trap(s16b rad, s16b type, u16b trap)
-{
- auto const &t_info = game->edit_data.t_info;
-
- auto t_ptr = &t_info[trap];
- bool_ ident;
- s16b my_dd, my_ds, dam;
-
- my_dd = t_ptr->dd;
- my_ds = t_ptr->ds;
-
- /* these traps gets nastier as levels progress */
- if (max_dlv[dungeon_type] > (2 * t_ptr->minlevel))
- {
- my_dd += (max_dlv[dungeon_type] / 15);
- my_ds += (max_dlv[dungeon_type] / 15);
- }
- dam = damroll(my_dd, my_ds);
-
- ident = project( -2, rad, p_ptr->py, p_ptr->px, dam, type, PROJECT_KILL | PROJECT_JUMP);
-
- return (ident);
-}
-
-/*
- * this function activates one trap type, and returns
- * a bool_ indicating if this trap is now identified
- */
-bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item)
-{
- auto const &a_info = game->edit_data.a_info;
-
- bool_ ident = FALSE;
- s16b trap;
-
- s16b k, l;
-
- trap = cave[y][x].t_idx;
-
- if (i_ptr != NULL)
- {
- trap = i_ptr->pval;
- }
-
- switch (trap)
- {
- /* stat traps */
- case TRAP_OF_WEAKNESS_I:
- ident = do_dec_stat(A_STR, STAT_DEC_TEMPORARY);
- break;
- case TRAP_OF_WEAKNESS_II:
- ident = do_dec_stat(A_STR, STAT_DEC_NORMAL);
- break;
- case TRAP_OF_WEAKNESS_III:
- ident = do_dec_stat(A_STR, STAT_DEC_PERMANENT);
- break;
- case TRAP_OF_INTELLIGENCE_I:
- ident = do_dec_stat(A_INT, STAT_DEC_TEMPORARY);
- break;
- case TRAP_OF_INTELLIGENCE_II:
- ident = do_dec_stat(A_INT, STAT_DEC_NORMAL);
- break;
- case TRAP_OF_INTELLIGENCE_III:
- ident = do_dec_stat(A_INT, STAT_DEC_PERMANENT);
- break;
- case TRAP_OF_WISDOM_I:
- ident = do_dec_stat(A_WIS, STAT_DEC_TEMPORARY);
- break;
- case TRAP_OF_WISDOM_II:
- ident = do_dec_stat(A_WIS, STAT_DEC_NORMAL);
- break;
- case TRAP_OF_WISDOM_III:
- ident = do_dec_stat(A_WIS, STAT_DEC_PERMANENT);
- break;
- case TRAP_OF_FUMBLING_I:
- ident = do_dec_stat(A_DEX, STAT_DEC_TEMPORARY);
- break;
- case TRAP_OF_FUMBLING_II:
- ident = do_dec_stat(A_DEX, STAT_DEC_NORMAL);
- break;
- case TRAP_OF_FUMBLING_III:
- ident = do_dec_stat(A_DEX, STAT_DEC_PERMANENT);
- break;
- case TRAP_OF_WASTING_I:
- ident = do_dec_stat(A_CON, STAT_DEC_TEMPORARY);
- break;
- case TRAP_OF_WASTING_II:
- ident = do_dec_stat(A_CON, STAT_DEC_NORMAL);
- break;
- case TRAP_OF_WASTING_III:
- ident = do_dec_stat(A_CON, STAT_DEC_PERMANENT);
- break;
- case TRAP_OF_BEAUTY_I:
- ident = do_dec_stat(A_CHR, STAT_DEC_TEMPORARY);
- break;
- case TRAP_OF_BEAUTY_II:
- ident = do_dec_stat(A_CHR, STAT_DEC_NORMAL);
- break;
- case TRAP_OF_BEAUTY_III:
- ident = do_dec_stat(A_CHR, STAT_DEC_PERMANENT);
- break;
-
- /* Trap of Curse Weapon */
- case TRAP_OF_CURSE_WEAPON:
- {
- ident = curse_weapon();
- break;
- }
-
- /* Trap of Curse Armor */
- case TRAP_OF_CURSE_ARMOR:
- {
- ident = curse_armor();
- break;
- }
-
- /* Earthquake Trap */
- case TRAP_OF_EARTHQUAKE:
- {
- msg_print("As you touch the trap, the ground starts to shake.");
- earthquake(y, x, 10);
- ident = TRUE;
- break;
- }
-
- /* Poison Needle Trap */
- case TRAP_OF_POISON_NEEDLE:
- {
- if (!(p_ptr->resist_pois || p_ptr->oppose_pois))
- {
- msg_print("You prick yourself on a poisoned needle.");
- (void)set_poisoned(p_ptr->poisoned + rand_int(15) + 10);
- ident = TRUE;
- }
- else
- {
- msg_print("You prick yourself on a needle.");
- }
- break;
- }
-
- /* Summon Monster Trap */
- case TRAP_OF_SUMMON_MONSTER:
- {
- msg_print("A spell hangs in the air.");
- for (k = 0; k < randint(3); k++)
- {
- ident |= summon_specific(y, x, max_dlv[dungeon_type], 0);
- }
- break;
- }
-
- /* Summon Undead Trap */
- case TRAP_OF_SUMMON_UNDEAD:
- {
- msg_print("A mighty spell hangs in the air.");
- for (k = 0; k < randint(3); k++)
- {
- ident |= summon_specific(y, x, max_dlv[dungeon_type],
- SUMMON_UNDEAD);
- }
- break;
- }
-
- /* Summon Greater Undead Trap */
- case TRAP_OF_SUMMON_GREATER_UNDEAD:
- {
- msg_print("An old and evil spell hangs in the air.");
- for (k = 0; k < randint(3); k++)
- {
- ident |= summon_specific(y, x, max_dlv[dungeon_type],
- SUMMON_HI_UNDEAD);
- }
- break;
- }
-
- /* Teleport Trap */
- case TRAP_OF_TELEPORT:
- {
- msg_print("The world whirls around you.");
- teleport_player(RATIO * 67);
- ident = TRUE;
- break;
- }
-
- /* Paralyzing Trap */
- case TRAP_OF_PARALYZING:
- {
- if (!p_ptr->free_act)
- {
- msg_print("You touch a poisoned part and can't move.");
- (void)set_paralyzed(rand_int(10) + 10);
- ident = TRUE;
- }
- else
- {
- msg_print("You prick yourself on a needle.");
- }
- break;
- }
-
- /* Explosive Device */
- case TRAP_OF_EXPLOSIVE_DEVICE:
- {
- msg_print("A hidden explosive device explodes in your face.");
- take_hit(damroll(5, 8), "an explosion");
- ident = TRUE;
- break;
- }
-
- /* Teleport Away Trap */
- case TRAP_OF_TELEPORT_AWAY:
- {
- /* teleport away all items */
- while (!cave[y][x].o_idxs.empty())
- {
- auto item = cave[y][x].o_idxs.front();
-
- object_type *o_ptr = &o_list[item];
-
- int amt = o_ptr->number;
-
- ident = do_trap_teleport_away(o_ptr, y, x);
-
- floor_item_increase(item, -amt);
- floor_item_optimize(item);
- }
- break;
- }
-
- /* Lose Memory Trap */
- case TRAP_OF_LOSE_MEMORY:
- {
- lose_exp(p_ptr->exp / 4);
-
- ident |= dec_stat(A_WIS, rand_int(20) + 10, STAT_DEC_NORMAL);
- ident |= dec_stat(A_INT, rand_int(20) + 10, STAT_DEC_NORMAL);
-
- if (!p_ptr->resist_conf)
- {
- ident |= set_confused(p_ptr->confused + rand_int(100) + 50);
- }
-
- if (ident)
- {
- msg_print("You suddenly don't remember what you were doing.");
- }
- else
- {
- msg_print("You feel an alien force probing your mind.");
- }
- break;
- }
- /* Bitter Regret Trap */
- case TRAP_OF_BITTER_REGRET:
- {
- msg_print("An age-old and hideous-sounding spell reverberates off the walls.");
-
- ident |= dec_stat(A_DEX, 25, TRUE);
- ident |= dec_stat(A_WIS, 25, TRUE);
- ident |= dec_stat(A_CON, 25, TRUE);
- ident |= dec_stat(A_STR, 25, TRUE);
- ident |= dec_stat(A_CHR, 25, TRUE);
- ident |= dec_stat(A_INT, 25, TRUE);
- break;
- }
-
- /* Bowel Cramps Trap */
- case TRAP_OF_BOWEL_CRAMPS:
- {
- msg_print("A wretched-smelling gas cloud upsets your stomach.");
-
- (void)set_food(PY_FOOD_STARVE - 1);
- (void)set_poisoned(0);
-
- if (!p_ptr->free_act)
- {
- (void)set_paralyzed(rand_int(dun_level) + 6);
- }
- ident = TRUE;
- break;
- }
-
- /* Blindness/Confusion Trap */
- case TRAP_OF_BLINDNESS_CONFUSION:
- {
- msg_print("A powerful magic protected this.");
-
- if (!p_ptr->resist_blind)
- {
- ident |= set_blind(p_ptr->blind + rand_int(100) + 100);
- }
- if (!p_ptr->resist_conf)
- {
- ident |= set_confused(p_ptr->confused + rand_int(20) + 15);
- }
- break;
- }
-
- /* Aggravation Trap */
- case TRAP_OF_AGGRAVATION:
- {
- msg_print("You hear a hollow noise echoing through the dungeons.");
- aggravate_monsters(1);
- break;
- }
-
- /* Multiplication Trap */
- case TRAP_OF_MULTIPLICATION:
- {
- msg_print("You hear a loud click.");
- for (k = -1; k <= 1; k++)
- for (l = -1; l <= 1; l++)
- {
- if ((in_bounds(p_ptr->py + l, p_ptr->px + k)) &&
- (!cave[p_ptr->py + l][p_ptr->px + k].t_idx))
- {
- place_trap(p_ptr->py + l, p_ptr->px + k);
- }
- }
- ident = TRUE;
- break;
- }
-
- /* Steal Item Trap */
- case TRAP_OF_STEAL_ITEM:
- {
- /*
- * please note that magical stealing is not so
- * easily circumvented
- */
- if (!p_ptr->paralyzed &&
- (rand_int(160) < (adj_dex_safe[p_ptr->stat_ind[A_DEX]] +
- p_ptr->lev)))
- {
- /* Saving throw message */
- msg_print("Your backpack seems to vibrate strangely!");
- break;
- }
-
- /* Find an item */
- for (k = 0; k < rand_int(10); k++)
- {
- char i_name[80];
- object_type *j_ptr, *q_ptr, forge;
-
- /* Pick an item */
- s16b i = rand_int(INVEN_PACK);
-
- /* Obtain the item */
- j_ptr = &p_ptr->inventory[i];
-
- /* Accept real items */
- if (!j_ptr->k_idx) continue;
-
- /* Don't steal artifacts -CFT */
- if (artifact_p(j_ptr)) continue;
-
- /* Get a description */
- object_desc(i_name, j_ptr, FALSE, 3);
-
- /* Message */
- msg_format("%sour %s (%c) was stolen!",
- ((j_ptr->number > 1) ? "One of y" : "Y"),
- i_name, index_to_label(i));
-
- /* Create the item */
- q_ptr = &forge;
- object_copy(q_ptr, j_ptr);
- q_ptr->number = 1;
-
- /* Drop it somewhere */
- do_trap_teleport_away(q_ptr, y, x);
-
- inc_stack_size_ex(i, -1, OPTIMIZE, NO_DESCRIBE);
-
- ident = TRUE;
- }
- break;
- }
-
- /* Summon Fast Quylthulgs Trap */
- case TRAP_OF_SUMMON_FAST_QUYLTHULGS:
- {
- for (k = 0; k < randint(3); k++)
- {
- ident |= summon_specific(y, x, max_dlv[dungeon_type], SUMMON_QUYLTHULG);
- }
-
- if (ident)
- {
- msg_print("You suddenly have company.");
- (void)set_slow(p_ptr->slow + randint(25) + 15);
- }
- break;
- }
-
- /* Trap of Sinking */
- case TRAP_OF_SINKING:
- {
- msg_print("You fell through a trap door!");
-
- if (p_ptr->ffall)
- {
- if (dungeon_flags & DF_TOWER)
- {
- msg_print("You float gently down to the previous level.");
- }
- else
- {
- msg_print("You float gently down to the next level.");
- }
- }
- else
- {
- take_hit(damroll(2, 8), "a trap door");
- }
-
- /* Still alive and autosave enabled */
- if (p_ptr->chp >= 0)
- {
- autosave_checkpoint();
- }
-
- if (dungeon_flags & DF_TOWER) dun_level--;
- else dun_level++;
-
- /* Leaving */
- p_ptr->leaving = TRUE;
- break;
- }
-
- /* Trap of Mana Drain */
- case TRAP_OF_MANA_DRAIN:
- {
- if (p_ptr->csp > 0)
- {
- p_ptr->csp = 0;
- p_ptr->csp_frac = 0;
- p_ptr->redraw |= (PR_FRAME);
- msg_print("You sense a great loss.");
- ident = TRUE;
- }
- else if (p_ptr->msp == 0)
- {
- /* no sense saying this unless you never have mana */
- msg_format("Suddenly you feel glad you're a mere %s",
- spp_ptr->title);
- }
- else
- {
- msg_print("Your head feels dizzy for a moment.");
- }
- break;
- }
- /* Trap of Missing Money */
- case TRAP_OF_MISSING_MONEY:
- {
- s32b gold = (p_ptr->au / 10) + randint(25);
-
- if (gold < 2) gold = 2;
- if (gold > 5000) gold = (p_ptr->au / 20) + randint(3000);
- if (gold > p_ptr->au) gold = p_ptr->au;
-
- p_ptr->au -= gold;
- if (gold <= 0)
- {
- msg_print("You feel something touching you.");
- }
- else if (p_ptr->au)
- {
- msg_print("Your purse feels lighter.");
- msg_format("%ld coins were stolen!", (long)gold);
- ident = TRUE;
- }
- else
- {
- msg_print("Your purse feels empty.");
- msg_print("All of your coins were stolen!");
- ident = TRUE;
- }
- p_ptr->redraw |= (PR_FRAME);
- break;
- }
-
- /* Trap of No Return */
- case TRAP_OF_NO_RETURN:
- {
- object_type *j_ptr;
- s16b j;
-
- for (j = 0; j < INVEN_WIELD; j++)
- {
- if (!p_ptr->inventory[j].k_idx) continue;
-
- j_ptr = &p_ptr->inventory[j];
-
- if ((j_ptr->tval == TV_SCROLL) &&
- (j_ptr->sval == SV_SCROLL_WORD_OF_RECALL))
- {
- inc_stack_size_ex(j, -j_ptr->number, OPTIMIZE, NO_DESCRIBE);
-
- combine_pack();
- reorder_pack();
-
- if (!ident)
- {
- msg_print("A small fire works its way through your backpack. "
- "Some scrolls are burnt.");
- }
- else
- {
- msg_print("The fire hasn't finished.");
- }
- ident = TRUE;
- }
- else if ((j_ptr->tval == TV_ROD_MAIN) &&
- (j_ptr->pval == SV_ROD_RECALL))
- {
- j_ptr->timeout = 0; /* a long time */
- if (!ident) msg_print("You feel the air stabilise around you.");
- ident = TRUE;
- }
- }
- if ((!ident) && (p_ptr->word_recall))
- {
- msg_print("You feel like staying around.");
- p_ptr->word_recall = 0;
- ident = TRUE;
- }
- break;
- }
-
- /* Trap of Silent Switching */
- case TRAP_OF_SILENT_SWITCHING:
- {
- s16b i, j, slot1, slot2;
- object_type *j_ptr, *k_ptr;
-
- for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
- {
- j_ptr = &p_ptr->inventory[i];
-
- if (!j_ptr->k_idx) continue;
-
- /* Do not allow this trap to touch the One Ring */
- auto const j_flags = object_flags(j_ptr);
- if(j_flags & TR_PERMA_CURSE) continue;
-
- slot1 = wield_slot(j_ptr);
-
- for (j = 0; j < INVEN_WIELD; j++)
- {
- k_ptr = &p_ptr->inventory[j];
-
- if (!k_ptr->k_idx) continue;
-
- /* Do not allow this trap to touch the One Ring */
- auto const k_flags = object_flags(k_ptr);
- if(k_flags & TR_PERMA_CURSE) continue;
-
- /* this is a crude hack, but it prevent wielding 6 torches... */
- if (k_ptr->number > 1) continue;
-
- slot2 = wield_slot(k_ptr);
-
- /* a chance of 4 in 5 of switching something, then 2 in 5 to do it again */
- if ((slot1 == slot2) &&
- (rand_int(100) < (80 - (ident * 40))))
- {
- object_type tmp_obj;
-
- if (p_ptr->inventory[j].name1)
- wield_set(p_ptr->inventory[j].name1, a_info[p_ptr->inventory[j].name1].set, FALSE);
- if (p_ptr->inventory[i].name1)
- takeoff_set(p_ptr->inventory[i].name1, a_info[p_ptr->inventory[i].name1].set);
-
- tmp_obj = p_ptr->inventory[j];
- p_ptr->inventory[j] = p_ptr->inventory[i];
- p_ptr->inventory[i] = tmp_obj;
- ident = TRUE;
- }
- }
- }
-
- if (ident)
- {
- p_ptr->update |= (PU_BONUS);
- p_ptr->update |= (PU_TORCH);
- p_ptr->update |= (PU_MANA);
- msg_print("You somehow feel like another person.");
- }
- else
- {
- msg_print("You feel a lack of useful items.");
- }
- break;
- }
-
- /* Trap of Walls */
- case TRAP_OF_WALLS:
- {
- ident = player_handle_trap_of_walls();
- break;
- }
-
- /* Trap of Calling Out */
- case TRAP_OF_CALLING_OUT:
- {
- ident = do_player_trap_call_out();
-
- if (!ident)
- {
- /* Increase "afraid" */
- if (p_ptr->resist_fear)
- {
- msg_print("You feel as if you had a nightmare!");
- }
- else if (rand_int(100) < p_ptr->skill_sav)
- {
- msg_print("You remember having a nightmare!");
- }
- else
- {
- if (set_afraid(p_ptr->afraid + 3 + randint(40)))
- {
- msg_print("You have a vision of a powerful enemy.");
- }
- }
- }
- break;
- }
-
- /* Trap of Sliding */
- case TRAP_OF_SLIDING:
- break;
-
- /* Trap of Charges Drain */
- case TRAP_OF_CHARGES_DRAIN:
- {
- /* Find an item */
- for (k = 0; k < 10; k++)
- {
- s16b i = rand_int(INVEN_PACK);
-
- object_type *j_ptr = &p_ptr->inventory[i];
-
- /* Drain charged wands/staffs
- Hack -- don't let artifacts get drained */
- if (((j_ptr->tval == TV_STAFF) ||
- (j_ptr->tval == TV_WAND)) &&
- (j_ptr->pval) &&
- !artifact_p(j_ptr))
- {
- ident = TRUE;
- j_ptr->pval = j_ptr->pval / (randint(4) + 1);
-
- /* 60% chance of only 1 */
- if (randint(10) > 3) break;
- }
- }
-
- if (ident)
- {
- /* Window stuff */
- p_ptr->window |= PW_INVEN;
- /* Combine / Reorder the pack */
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
-
- msg_print("Your backpack seems to be turned upside down.");
- }
- else
- {
- msg_print("You hear a wail of great disappointment.");
- }
- break;
- }
-
- /* Trap of Stair Movement */
- case TRAP_OF_STAIR_MOVEMENT:
- {
- s16b cx, cy, i, j;
- s16b cnt = 0;
- s16b cnt_seen = 0;
- s16b tmps, tmpx;
- s16b tmpspecial, tmpspecial2;
- u32b tmpf;
- bool_ seen = FALSE;
- s16b index_x[20], index_y[20]; /* 20 stairs per level is enough? */
- cave_type *cv_ptr;
-
- if (max_dlv[dungeon_type] == 99)
- {
- /* no sense in relocating that stair! */
- msg_print("You have a feeling that this trap could be dangerous.");
- break;
- }
-
- for (cx = 0; cx < cur_wid; cx++)
- for (cy = 0; cy < cur_hgt; cy++)
- {
- cv_ptr = &cave[cy][cx];
-
- if ((cv_ptr->feat != FEAT_LESS) &&
- (cv_ptr->feat != FEAT_MORE) &&
- (cv_ptr->feat != FEAT_SHAFT_UP) &&
- (cv_ptr->feat != FEAT_SHAFT_DOWN)) continue;
-
- index_x[cnt] = cx;
- index_y[cnt] = cy;
- cnt++;
- }
-
- if (cnt == 0)
- {
- if (wizard) msg_print("Executing moving stairs trap on level with no stairs!");
- break;
- }
-
- for (i = 0; i < cnt; i++)
- {
- seen = FALSE;
-
- for (j = 0; j < 10; j++) /* try 10 times to relocate */
- {
- cave_type *cv_ptr = &cave[index_y[i]][index_x[i]];
- cave_type *cv_ptr2;
-
- cx = rand_int(cur_wid);
- cy = rand_int(cur_hgt);
-
- if ((cx == index_x[i]) || (cy == index_y[i])) continue;
-
- cv_ptr2 = &cave[cy][cx];
-
- if (!cave_valid_bold(cy, cx) || (!cv_ptr2->o_idxs.empty())) continue;
-
- /* don't put anything in vaults */
- if (cv_ptr2->info & CAVE_ICKY) continue;
-
- tmpx = cv_ptr2->mimic;
- tmps = cv_ptr2->info;
- tmpf = cv_ptr2->feat;
- tmpspecial = cv_ptr2->special;
- tmpspecial2 = cv_ptr2->special2;
- cave[cy][cx].mimic = cv_ptr->mimic;
- cave[cy][cx].info = cv_ptr->info;
- cave[cy][cx].special = cv_ptr->special;
- cave[cy][cx].special2 = cv_ptr->special2;
- cave_set_feat(cy, cx, cv_ptr->feat);
- cv_ptr->mimic = tmpx;
- cv_ptr->info = tmps;
- cv_ptr->special = tmpspecial;
- cv_ptr->special2 = tmpspecial2;
- cave_set_feat(index_y[i], index_x[i], tmpf);
-
- /* if we are placing walls in rooms, make them rubble instead */
- if ((cv_ptr->info & CAVE_ROOM) &&
- (cv_ptr->feat >= FEAT_WALL_EXTRA) &&
- (cv_ptr->feat <= FEAT_PERM_SOLID))
- {
- cave_set_feat(index_y[i], index_x[i], FEAT_RUBBLE);
- }
-
- if (player_has_los_bold(cy, cx))
- {
- note_spot(cy, cx);
- lite_spot(cy, cx);
- seen = TRUE;
- }
- else
- {
- cv_ptr2->info &= ~CAVE_MARK;
- }
-
- if (player_has_los_bold(index_y[i], index_x[i]))
- {
- note_spot(index_y[i], index_x[i]);
- lite_spot(index_y[i], index_x[i]);
- seen = TRUE;
- }
- else
- {
- cv_ptr->info &= ~CAVE_MARK;
- }
- break;
- }
-
- if (seen) cnt_seen++;
- }
-
- ident = (cnt_seen > 0);
-
- if ((ident) && (cnt_seen > 1))
- {
- msg_print("You see some stairs move.");
- }
- else if (ident)
- {
- msg_print("You see a stair move.");
- }
- else
- {
- msg_print("You hear distant scraping noises.");
- }
- p_ptr->redraw |= PR_MAP;
- break;
- }
-
- /* Trap of New Trap */
- case TRAP_OF_NEW:
- {
- /* if we're on a floor or on a door, place a new trap */
- if ((item == -1) || (item == -2))
- {
- place_trap(y, x);
- if (player_has_los_bold(y, x))
- {
- note_spot(y, x);
- lite_spot(y, x);
- }
- }
- else
- {
- /* re-trap the chest */
- place_trap(y, x);
- }
- msg_print("You hear a noise, and then its echo.");
- ident = FALSE;
- break;
- }
-
- /* Trap of Acquirement */
- case TRAP_OF_ACQUIREMENT:
- {
- /* Get a nice thing */
- msg_print("You notice something falling off the trap.");
- acquirement(y, x, 1, TRUE, FALSE);
-
- /* If we're on a floor or on a door, place a new trap */
- if ((item == -1) || (item == -2))
- {
- place_trap(y, x);
- if (player_has_los_bold(y, x))
- {
- note_spot(y, x);
- lite_spot(y, x);
- }
- }
- else
- {
- /* Re-trap the chest */
- place_trap(y, x);
- }
- msg_print("You hear a noise, and then its echo.");
-
- /* Never known */
- ident = FALSE;
- }
- break;
-
- /* Trap of Scatter Items */
- case TRAP_OF_SCATTER_ITEMS:
- {
- s16b i, j;
- bool_ message = FALSE;
-
- for (i = 0; i < INVEN_PACK; i++)
- {
-
- if (!p_ptr->inventory[i].k_idx) continue;
-
- if (rand_int(10) < 3) continue;
-
- for (j = 0; j < 10; j++)
- {
- object_type tmp_obj, *j_ptr = &tmp_obj;
- s16b cx = x + 15 - rand_int(30);
- s16b cy = y + 15 - rand_int(30);
-
- if (!in_bounds(cy, cx)) continue;
-
- if (!cave_floor_bold(cy, cx)) continue;
-
- object_copy(j_ptr, &p_ptr->inventory[i]);
-
- inc_stack_size_ex(i, -999, OPTIMIZE, NO_DESCRIBE);
-
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
-
- (void)floor_carry(cy, cx, j_ptr);
-
- if (!message)
- {
- msg_print("You feel light-footed.");
- message = TRUE;
- }
-
- if (player_has_los_bold(cy, cx))
- {
- char i_name[80];
-
- object_desc(i_name, &tmp_obj, TRUE, 3);
- note_spot(cy, cx);
- lite_spot(cy, cx);
- ident = TRUE;
- msg_format("Suddenly %s appear%s!", i_name,
- (j_ptr->number > 1) ? "" : "s");
- }
- break;
- }
- }
- ident = message;
- break;
- }
-
- /* Trap of Decay */
- case TRAP_OF_DECAY:
- break;
-
- /* Trap of Wasting Wands */
- case TRAP_OF_WASTING_WANDS:
- {
- s16b i;
- object_type *j_ptr;
-
- for (i = 0; i < INVEN_PACK; i++)
- {
- if (!p_ptr->inventory[i].k_idx) continue;
-
- j_ptr = &p_ptr->inventory[i];
-
- if ((j_ptr->tval == TV_WAND) && (rand_int(5) == 1))
- {
- if (object_known_p(j_ptr)) ident = TRUE;
-
- /* Create a Wand of Nothing */
- object_prep(j_ptr, lookup_kind(TV_WAND, SV_WAND_NOTHING));
- apply_magic(j_ptr, 0, FALSE, FALSE, FALSE, boost::make_optional(0));
- j_ptr->ident &= ~IDENT_KNOWN;
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
- }
- else if ((j_ptr->tval == TV_STAFF) && (rand_int(5) == 1))
- {
- if (object_known_p(j_ptr)) ident = TRUE;
-
- /* Create a Staff of Nothing */
- object_prep(j_ptr, lookup_kind(TV_STAFF, SV_STAFF_NOTHING));
- apply_magic(j_ptr, 0, FALSE, FALSE, FALSE, boost::make_optional(0));
- j_ptr->ident &= ~IDENT_KNOWN;
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
- }
- }
- if (ident)
- {
- msg_print("You have lost trust in your backpack!");
- }
- else
- {
- msg_print("You hear an echoing cry of rage.");
- }
- break;
- }
-
- /* Trap of Filling */
- case TRAP_OF_FILLING:
- {
- s16b nx, ny;
-
- for (nx = x - 8; nx <= x + 8; nx++)
- for (ny = y - 8; ny <= y + 8; ny++)
- {
- if (!in_bounds (ny, nx)) continue;
-
- if (rand_int(distance(ny, nx, y, x)) > 3)
- {
- place_trap(ny, nx);
- }
- }
-
- msg_print("The floor vibrates in a strange way.");
- ident = FALSE;
- break;
- }
-
- case TRAP_OF_DRAIN_SPEED:
- {
- s16b j, chance = 75;
-
- for (j = 0; j < INVEN_TOTAL; j++)
- {
- /* don't bother the overflow slot */
- if (j == INVEN_PACK) continue;
-
- if (!p_ptr->inventory[j].k_idx) continue;
-
- auto j_ptr = &p_ptr->inventory[j];
- auto const flags = object_flags(j_ptr);
-
- /* is it a non-artifact speed item? */
- if ((!j_ptr->name1) && (flags & TR_SPEED))
- {
- if (randint(100) < chance)
- {
- j_ptr->pval = j_ptr->pval / 2;
- if (j_ptr->pval == 0)
- {
- j_ptr->pval--;
- }
- chance /= 2;
- ident = TRUE;
- }
- inven_item_optimize(j);
- }
- }
- if (!ident)
- {
- msg_print("You feel some things in your pack vibrating.");
- }
- else
- {
- combine_pack();
- reorder_pack();
- msg_print("You suddenly feel you have time for self-reflection.");
-
- /* Recalculate bonuses */
- p_ptr->update |= (PU_BONUS);
-
- /* Recalculate mana */
- p_ptr->update |= (PU_MANA);
-
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
- }
- break;
- }
-
- /*
- * single missile traps
- */
- case TRAP_OF_ARROW_I:
- ident = player_handle_missile_trap(1, TV_ARROW, SV_AMMO_NORMAL, 4, 8, 0, "Arrow Trap");
- break;
- case TRAP_OF_ARROW_II:
- ident = player_handle_missile_trap(1, TV_BOLT, SV_AMMO_NORMAL, 5, 8, 0, "Bolt Trap");
- break;
- case TRAP_OF_ARROW_III:
- ident = player_handle_missile_trap(1, TV_ARROW, SV_AMMO_HEAVY, 6, 8, 0, "Seeker Arrow Trap");
- break;
- case TRAP_OF_ARROW_IV:
- ident = player_handle_missile_trap(1, TV_BOLT, SV_AMMO_HEAVY, 8, 10, 0, "Seeker Bolt Trap");
- break;
- case TRAP_OF_POISON_ARROW_I:
- ident = player_handle_missile_trap(1, TV_ARROW, SV_AMMO_NORMAL, 4, 8, 10 + randint(20), "Poison Arrow Trap");
- break;
- case TRAP_OF_POISON_ARROW_II:
- ident = player_handle_missile_trap(1, TV_BOLT, SV_AMMO_NORMAL, 5, 8, 15 + randint(30), "Poison Bolt Trap");
- break;
- case TRAP_OF_POISON_ARROW_III:
- ident = player_handle_missile_trap(1, TV_ARROW, SV_AMMO_HEAVY, 6, 8, 30 + randint(50), "Poison Seeker Arrow Trap");
- break;
- case TRAP_OF_POISON_ARROW_IV:
- ident = player_handle_missile_trap(1, TV_BOLT, SV_AMMO_HEAVY, 8, 10, 40 + randint(70), "Poison Seeker Bolt Trap");
- break;
- case TRAP_OF_DAGGER_I:
- ident = player_handle_missile_trap(1, TV_SWORD, SV_BROKEN_DAGGER, 2, 8, 0, "Dagger Trap");
- break;
- case TRAP_OF_DAGGER_II:
- ident = player_handle_missile_trap(1, TV_SWORD, SV_DAGGER, 3, 8, 0, "Dagger Trap");
- break;
- case TRAP_OF_POISON_DAGGER_I:
- ident = player_handle_missile_trap(1, TV_SWORD, SV_BROKEN_DAGGER, 2, 8, 15 + randint(20), "Poison Dagger Trap");
- break;
- case TRAP_OF_POISON_DAGGER_II:
- ident = player_handle_missile_trap(1, TV_SWORD, SV_DAGGER, 3, 8, 20 + randint(30), "Poison Dagger Trap");
- break;
-
- /*
- * multiple missile traps
- * numbers range from 2 (level 0 to 14) to 10 (level 120 and up)
- */
- case TRAP_OF_ARROWS_I:
- ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_ARROW, SV_AMMO_NORMAL, 4, 8, 0, "Arrow Trap");
- break;
- case TRAP_OF_ARROWS_II:
- ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_BOLT, SV_AMMO_NORMAL, 5, 8, 0, "Bolt Trap");
- break;
- case TRAP_OF_ARROWS_III:
- ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_ARROW, SV_AMMO_HEAVY, 6, 8, 0, "Seeker Arrow Trap");
- break;
- case TRAP_OF_ARROWS_IV:
- ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_BOLT, SV_AMMO_HEAVY, 8, 10, 0, "Seeker Bolt Trap");
- break;
- case TRAP_OF_POISON_ARROWS_I:
- ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_ARROW, SV_AMMO_NORMAL, 4, 8, 10 + randint(20), "Poison Arrow Trap");
- break;
- case TRAP_OF_POISON_ARROWS_II:
- ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_BOLT, SV_AMMO_NORMAL, 5, 8, 15 + randint(30), "Poison Bolt Trap");
- break;
- case TRAP_OF_POISON_ARROWS_III:
- ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_ARROW, SV_AMMO_HEAVY, 6, 8, 30 + randint(50), "Poison Seeker Arrow Trap");
- break;
- case TRAP_OF_POISON_ARROWS_IV:
- ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_BOLT, SV_AMMO_HEAVY, 8, 10, 40 + randint(70), "Poison Seeker Bolt Trap");
- break;
- case TRAP_OF_DAGGERS_I:
- ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_SWORD, SV_BROKEN_DAGGER, 2, 8, 0, "Dagger Trap");
- break;
- case TRAP_OF_DAGGERS_II:
- ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_SWORD, SV_DAGGER, 3, 8, 0, "Dagger Trap");
- break;
- case TRAP_OF_POISON_DAGGERS_I:
- ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_SWORD, SV_BROKEN_DAGGER, 2, 8, 15 + randint(20), "Poison Dagger Trap");
- break;
- case TRAP_OF_POISON_DAGGERS_II:
- ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_SWORD, SV_DAGGER, 3, 8, 20 + randint(30), "Poison Dagger Trap");
- break;
-
- case TRAP_OF_DROP_ITEMS:
- {
- s16b i;
- bool_ message = FALSE;
-
- for (i = 0; i < INVEN_PACK; i++)
- {
- object_type tmp_obj;
-
- if (!p_ptr->inventory[i].k_idx) continue;
- if (randint(100) < 80) continue;
- if (p_ptr->inventory[i].name1 == ART_POWER) continue;
-
- tmp_obj = p_ptr->inventory[i];
-
- /* drop carefully */
- drop_near(&tmp_obj, 0, y, x);
-
- inc_stack_size_ex(i, -999, OPTIMIZE, NO_DESCRIBE);
-
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
-
- if (!message)
- {
- msg_print("You are startled by a sudden sound.");
- message = TRUE;
- }
- ident = TRUE;
- }
- if (!ident)
- {
- msg_print("You hear a sudden, strange sound.");
- }
- break;
- }
-
- case TRAP_OF_DROP_ALL_ITEMS:
- {
- s16b i;
- bool_ message = FALSE;
-
- for (i = 0; i < INVEN_PACK; i++)
- {
- object_type tmp_obj;
-
- if (!p_ptr->inventory[i].k_idx) continue;
- if (randint(100) < 10) continue;
- if (p_ptr->inventory[i].name1 == ART_POWER) continue;
-
- tmp_obj = p_ptr->inventory[i];
-
- /* drop carefully */
- drop_near(&tmp_obj, 0, y, x);
-
- inc_stack_size_ex(i, -999, OPTIMIZE, NO_DESCRIBE);
-
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
-
- if (!message)
- {
- msg_print("You are greatly startled by a sudden sound.");
- message = TRUE;
- }
- ident = TRUE;
- }
- if (!ident)
- {
- msg_print("You hear a sudden, strange sound.");
- }
- break;
- }
-
- case TRAP_OF_DROP_EVERYTHING:
- {
- s16b i;
- bool_ message = FALSE;
-
- for (i = 0; i < INVEN_TOTAL; i++)
- {
- object_type tmp_obj;
- if (!p_ptr->inventory[i].k_idx) continue;
- if (randint(100) < 30) continue;
- if (p_ptr->inventory[i].name1 == ART_POWER) continue;
-
- tmp_obj = p_ptr->inventory[i];
- /* drop carefully */
-
- drop_near(&tmp_obj, 0, y, x);
-
- inc_stack_size_ex(i, -999, OPTIMIZE, NO_DESCRIBE);
-
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
-
- if (!message)
- {
- msg_print("You are completely startled by a sudden sound.");
- message = TRUE;
- }
- ident = TRUE;
- }
- if (!ident)
- {
- msg_print("You hear a sudden, strange sound.");
- }
- break;
- }
-
- /* Bolt Trap */
- case TRAP_G_ELEC_BOLT:
- ident = player_handle_breath_trap(1, GF_ELEC, TRAP_G_ELEC_BOLT);
- break;
- case TRAP_G_POIS_BOLT:
- ident = player_handle_breath_trap(1, GF_POIS, TRAP_G_POIS_BOLT);
- break;
- case TRAP_G_ACID_BOLT:
- ident = player_handle_breath_trap(1, GF_ACID, TRAP_G_ACID_BOLT);
- break;
- case TRAP_G_COLD_BOLT:
- ident = player_handle_breath_trap(1, GF_COLD, TRAP_G_COLD_BOLT);
- break;
- case TRAP_G_FIRE_BOLT:
- ident = player_handle_breath_trap(1, GF_FIRE, TRAP_G_FIRE_BOLT);
- break;
- case TRAP_OF_ELEC_BOLT:
- ident = player_handle_breath_trap(1, GF_ELEC, TRAP_OF_ELEC_BOLT);
- break;
- case TRAP_OF_POIS_BOLT:
- ident = player_handle_breath_trap(1, GF_POIS, TRAP_OF_POIS_BOLT);
- break;
- case TRAP_OF_ACID_BOLT:
- ident = player_handle_breath_trap(1, GF_ACID, TRAP_OF_ACID_BOLT);
- break;
- case TRAP_OF_COLD_BOLT:
- ident = player_handle_breath_trap(1, GF_COLD, TRAP_OF_COLD_BOLT);
- break;
- case TRAP_OF_FIRE_BOLT:
- ident = player_handle_breath_trap(1, GF_FIRE, TRAP_OF_FIRE_BOLT);
- break;
- case TRAP_OF_PLASMA_BOLT:
- ident = player_handle_breath_trap(1, GF_PLASMA, TRAP_OF_PLASMA_BOLT);
- break;
- case TRAP_OF_WATER_BOLT:
- ident = player_handle_breath_trap(1, GF_WATER, TRAP_OF_WATER_BOLT);
- break;
- case TRAP_OF_LITE_BOLT:
- ident = player_handle_breath_trap(1, GF_LITE, TRAP_OF_LITE_BOLT);
- break;
- case TRAP_OF_DARK_BOLT:
- ident = player_handle_breath_trap(1, GF_DARK, TRAP_OF_DARK_BOLT);
- break;
- case TRAP_OF_SHARDS_BOLT:
- ident = player_handle_breath_trap(1, GF_SHARDS, TRAP_OF_SHARDS_BOLT);
- break;
- case TRAP_OF_SOUND_BOLT:
- ident = player_handle_breath_trap(1, GF_SOUND, TRAP_OF_SOUND_BOLT);
- break;
- case TRAP_OF_CONFUSION_BOLT:
- ident = player_handle_breath_trap(1, GF_CONFUSION, TRAP_OF_CONFUSION_BOLT);
- break;
- case TRAP_OF_FORCE_BOLT:
- ident = player_handle_breath_trap(1, GF_FORCE, TRAP_OF_FORCE_BOLT);
- break;
- case TRAP_OF_INERTIA_BOLT:
- ident = player_handle_breath_trap(1, GF_INERTIA, TRAP_OF_INERTIA_BOLT);
- break;
- case TRAP_OF_MANA_BOLT:
- ident = player_handle_breath_trap(1, GF_MANA, TRAP_OF_MANA_BOLT);
- break;
- case TRAP_OF_ICE_BOLT:
- ident = player_handle_breath_trap(1, GF_ICE, TRAP_OF_ICE_BOLT);
- break;
- case TRAP_OF_CHAOS_BOLT:
- ident = player_handle_breath_trap(1, GF_CHAOS, TRAP_OF_CHAOS_BOLT);
- break;
- case TRAP_OF_NETHER_BOLT:
- ident = player_handle_breath_trap(1, GF_NETHER, TRAP_OF_NETHER_BOLT);
- break;
- case TRAP_OF_DISENCHANT_BOLT:
- ident = player_handle_breath_trap(1, GF_DISENCHANT, TRAP_OF_DISENCHANT_BOLT);
- break;
- case TRAP_OF_NEXUS_BOLT:
- ident = player_handle_breath_trap(1, GF_NEXUS, TRAP_OF_NEXUS_BOLT);
- break;
- case TRAP_OF_TIME_BOLT:
- ident = player_handle_breath_trap(1, GF_TIME, TRAP_OF_TIME_BOLT);
- break;
- case TRAP_OF_GRAVITY_BOLT:
- ident = player_handle_breath_trap(1, GF_GRAVITY, TRAP_OF_GRAVITY_BOLT);
- break;
-
- /* Ball Trap */
- case TRAP_OF_ELEC_BALL:
- ident = player_handle_breath_trap(3, GF_ELEC, TRAP_OF_ELEC_BALL);
- break;
- case TRAP_OF_POIS_BALL:
- ident = player_handle_breath_trap(3, GF_POIS, TRAP_OF_POIS_BALL);
- break;
- case TRAP_OF_ACID_BALL:
- ident = player_handle_breath_trap(3, GF_ACID, TRAP_OF_ACID_BALL);
- break;
- case TRAP_OF_COLD_BALL:
- ident = player_handle_breath_trap(3, GF_COLD, TRAP_OF_COLD_BALL);
- break;
- case TRAP_OF_FIRE_BALL:
- ident = player_handle_breath_trap(3, GF_FIRE, TRAP_OF_FIRE_BALL);
- break;
- case TRAP_OF_PLASMA_BALL:
- ident = player_handle_breath_trap(3, GF_PLASMA, TRAP_OF_PLASMA_BALL);
- break;
- case TRAP_OF_WATER_BALL:
- ident = player_handle_breath_trap(3, GF_WATER, TRAP_OF_WATER_BALL);
- break;
- case TRAP_OF_LITE_BALL:
- ident = player_handle_breath_trap(3, GF_LITE, TRAP_OF_LITE_BALL);
- break;
- case TRAP_OF_DARK_BALL:
- ident = player_handle_breath_trap(3, GF_DARK, TRAP_OF_DARK_BALL);
- break;
- case TRAP_OF_SHARDS_BALL:
- ident = player_handle_breath_trap(3, GF_SHARDS, TRAP_OF_SHARDS_BALL);
- break;
- case TRAP_OF_SOUND_BALL:
- ident = player_handle_breath_trap(3, GF_SOUND, TRAP_OF_SOUND_BALL);
- break;
- case TRAP_OF_CONFUSION_BALL:
- ident = player_handle_breath_trap(3, GF_CONFUSION, TRAP_OF_CONFUSION_BALL);
- break;
- case TRAP_OF_FORCE_BALL:
- ident = player_handle_breath_trap(3, GF_FORCE, TRAP_OF_FORCE_BALL);
- break;
- case TRAP_OF_INERTIA_BALL:
- ident = player_handle_breath_trap(3, GF_INERTIA, TRAP_OF_INERTIA_BALL);
- break;
- case TRAP_OF_MANA_BALL:
- ident = player_handle_breath_trap(3, GF_MANA, TRAP_OF_MANA_BALL);
- break;
- case TRAP_OF_ICE_BALL:
- ident = player_handle_breath_trap(3, GF_ICE, TRAP_OF_ICE_BALL);
- break;
- case TRAP_OF_CHAOS_BALL:
- ident = player_handle_breath_trap(3, GF_CHAOS, TRAP_OF_CHAOS_BALL);
- break;
- case TRAP_OF_NETHER_BALL:
- ident = player_handle_breath_trap(3, GF_NETHER, TRAP_OF_NETHER_BALL);
- break;
- case TRAP_OF_DISENCHANT_BALL:
- ident = player_handle_breath_trap(3, GF_DISENCHANT, TRAP_OF_DISENCHANT_BALL);
- break;
- case TRAP_OF_NEXUS_BALL:
- ident = player_handle_breath_trap(3, GF_NEXUS, TRAP_OF_NEXUS_BALL);
- break;
- case TRAP_OF_TIME_BALL:
- ident = player_handle_breath_trap(3, GF_TIME, TRAP_OF_TIME_BALL);
- break;
- case TRAP_OF_GRAVITY_BALL:
- ident = player_handle_breath_trap(3, GF_GRAVITY, TRAP_OF_GRAVITY_BALL);
- break;
-
- /* Trap of Divine Anger */
- case TRAP_OF_DIVINE_ANGER:
- {
- if (p_ptr->pgod == 0)
- {
- msg_format("Suddenly you feel glad you're a mere %s", spp_ptr->title);
- }
- else
- {
- cptr name;
-
- name = deity_info[p_ptr->pgod].name;
- msg_format("You feel you have angered %s.", name);
- inc_piety(p_ptr->pgod, -3000);
- }
- break;
- }
-
- /* Trap of Divine Wrath */
- case TRAP_OF_DIVINE_WRATH:
- {
- if (p_ptr->pgod == 0)
- {
- msg_format("Suddenly you feel glad you're a mere %s", spp_ptr->title);
- }
- else
- {
- cptr name;
-
- name = deity_info[p_ptr->pgod].name;
-
- msg_format("%s quakes in rage: ``Thou art supremely insolent, mortal!!''", name);
- inc_piety(p_ptr->pgod, -500 * p_ptr->lev);
- }
- break;
- }
-
- /* Trap of hallucination */
- case TRAP_OF_HALLUCINATION:
- {
- msg_print("Scintillating colors hypnotise you for a moment.");
-
- set_image(80);
- }
- break;
-
- /* Bolt Trap */
- case TRAP_OF_ROCKET:
- ident = player_handle_breath_trap(1, GF_ROCKET, trap);
- break;
- case TRAP_OF_NUKE_BOLT:
- ident = player_handle_breath_trap(1, GF_NUKE, trap);
- break;
- case TRAP_OF_HOLY_FIRE:
- ident = player_handle_breath_trap(1, GF_HOLY_FIRE, trap);
- break;
- case TRAP_OF_HELL_FIRE:
- ident = player_handle_breath_trap(1, GF_HELL_FIRE, trap);
- break;
- case TRAP_OF_PSI_BOLT:
- ident = player_handle_breath_trap(1, GF_PSI, trap);
- break;
- case TRAP_OF_PSI_DRAIN:
- ident = player_handle_breath_trap(1, GF_PSI_DRAIN, trap);
- break;
-
- /* Ball Trap */
- case TRAP_OF_NUKE_BALL:
- ident = player_handle_breath_trap(3, GF_NUKE, TRAP_OF_NUKE_BALL);
- break;
- case TRAP_OF_PSI_BALL:
- ident = player_handle_breath_trap(3, GF_PSI, TRAP_OF_NUKE_BALL);
- break;
-
- default:
- {
- msg_print(format("Executing unknown trap %d", trap));
- }
- }
- return ident;
-}
-
-void player_activate_door_trap(s16b y, s16b x)
-{
- auto const &f_info = game->edit_data.f_info;
- auto &t_info = game->edit_data.t_info;
-
- cave_type *c_ptr;
- bool_ ident = FALSE;
-
- c_ptr = &cave[y][x];
-
- /* Return if trap or door not found */
- if ((c_ptr->t_idx == 0) ||
- !(f_info[c_ptr->feat].flags & FF_DOOR)) return;
-
- /* Disturb */
- disturb(0);
-
- /* Message */
- msg_print("You found a trap!");
-
- /* Pick a trap */
- pick_trap(y, x);
-
- /* Hit the trap */
- ident = player_activate_trap_type(y, x, NULL, -1);
- if (ident)
- {
- t_info[c_ptr->t_idx].ident = TRUE;
- msg_format("You identified that trap as %s.",
- t_info[c_ptr->t_idx].name);
- }
-}
-
-
-/*
- * Places a random trap at the given location.
- *
- * The location must be a valid, empty, clean, floor grid.
- */
-void place_trap(int y, int x)
-{
- auto const &d_info = game->edit_data.d_info;
- auto const &f_info = game->edit_data.f_info;
- auto const &t_info = game->edit_data.t_info;
-
- int cnt;
- u32b flags;
- cave_type *c_ptr = &cave[y][x];
- auto d_ptr = &d_info[dungeon_type];
-
- /* No traps in town or on first level */
- if (dun_level <= 1) return;
-
- /*
- * Avoid open doors -- because DOOR flag is added to make much more
- * important processing faster
- */
- if (c_ptr->feat == FEAT_OPEN) return;
- if (c_ptr->feat == FEAT_BROKEN) return;
-
- /* Traps only appears on empty floor */
- if (!cave_floor_grid(c_ptr) &&
- !(f_info[c_ptr->feat].flags & FF_DOOR)) return;
-
- /* Set flags */
- if (f_info[c_ptr->feat].flags & FF_DOOR) flags = FTRAP_DOOR;
- else flags = FTRAP_FLOOR;
-
- /* Try 100 times */
- cnt = 100;
- while (cnt--)
- {
- std::size_t trap = rand_int(t_info.size());
- auto t_ptr = &t_info[trap];
-
- /* No traps below their minlevel */
- if (t_ptr->minlevel > dun_level) continue;
-
- /* is this a correct trap now? */
- if (!(t_ptr->flags & flags)) continue;
-
- /*
- * Hack -- No trap door at the bottom of dungeon or in flat
- * (non dungeon) places or on quest levels
- */
- if ((trap == TRAP_OF_SINKING) &&
- ((d_ptr->maxdepth == dun_level) ||
- (dungeon_flags & DF_FLAT) || is_quest(dun_level)) )
- {
- continue;
- }
-
- /* How probable is this trap */
- if (rand_int(100) < t_ptr->probability)
- {
- c_ptr->t_idx = trap;
- break;
- }
- }
-
- return;
-}
-
-
-/*
- * Place a leveled trap at given position
- */
-void place_trap_leveled(int y, int x, int lev)
-{
- int prev_dun_level = dun_level;
- dun_level = lev;
- place_trap(y,x);
- dun_level = prev_dun_level;
-}
-
-/*
- * Places a random trap on the given chest.
- *
- * The object must be a valid chest.
- */
-void place_trap_object(object_type *o_ptr)
-{
- auto const &t_info = game->edit_data.t_info;
-
- int cnt;
-
- /* No traps in town or on first level */
- if (dun_level <= 1)
- {
- /* empty chest were already looted, therefore known */
- o_ptr->ident |= IDENT_KNOWN;
- return;
- }
-
- /* Try 100 times */
- cnt = 100;
- while (cnt--)
- {
- std::size_t trap = rand_int(t_info.size());
- auto t_ptr = &t_info[trap];
-
- /* no traps below their minlevel */
- if (t_ptr->minlevel > dun_level) continue;
-
- /* Is this a correct trap now? */
- if (!(t_ptr->flags & FTRAP_CHEST)) continue;
-
- /* How probable is this trap */
- if (rand_int(100) < t_ptr->probability)
- {
- o_ptr->pval = trap;
- break;
- }
- }
-
- return;
-}
-
-/* Dangerous trap placing function */
-void wiz_place_trap(int y, int x, int idx)
-{
- auto const &f_info = game->edit_data.f_info;
-
- cave_type *c_ptr = &cave[y][x];
-
- /* Dangerous enough as it is... */
- if (!cave_floor_grid(c_ptr) && (!(f_info[c_ptr->feat].flags & FF_DOOR))) return;
-
- c_ptr->t_idx = idx;
-}
-
-/*
- * Here begin monster traps code
- */
-
-/*
- * Hook to determine if an object is a device
- */
-static bool item_tester_hook_device(object_type const *o_ptr)
-{
- return (((o_ptr->tval == TV_ROD_MAIN) && (o_ptr->pval != 0)) ||
- (o_ptr->tval == TV_STAFF) ||
- (o_ptr->tval == TV_WAND));
-}
-
-/*
- * The trap setting code for rogues -MWK-
- *
- * Also, it will fail or give weird results if the tvals are resorted!
- */
-void do_cmd_set_trap(void)
-{
- int item_kit, item_load, i;
- int num;
-
- object_type *o_ptr, *j_ptr, *i_ptr;
-
- cptr q, s, c;
-
- object_type object_type_body;
-
- /* Check some conditions */
- if (p_ptr->blind)
- {
- msg_print("You can't see anything.");
- return;
- }
- if (no_lite())
- {
- msg_print("You don't dare to set a trap in the darkness.");
- return;
- }
- if (p_ptr->confused)
- {
- msg_print("You are too confused!");
- return;
- }
-
- /* Only set traps on clean floor grids */
- if (!cave_clean_bold(p_ptr->py, p_ptr->px))
- {
- msg_print("You cannot set a trap on this.");
- return;
- }
-
- /* Get an item */
- q = "Use which trapping kit? ";
- s = "You have no trapping kits.";
- if (!get_item(&item_kit,
- q, s,
- USE_INVEN,
- object_filter::TVal(TV_TRAPKIT)))
- {
- return;
- }
-
- o_ptr = &p_ptr->inventory[item_kit];
-
- /* Trap kits need a second object */
- object_filter_t object_filter = object_filter::Or(
- object_filter::And(
- object_filter::SVal(SV_TRAPKIT_BOW),
- object_filter::TVal(TV_ARROW)),
- object_filter::And(
- object_filter::SVal(SV_TRAPKIT_XBOW),
- object_filter::TVal(TV_BOLT)),
- object_filter::And(
- object_filter::SVal(SV_TRAPKIT_SLING),
- object_filter::TVal(TV_SHOT)),
- object_filter::And(
- object_filter::SVal(SV_TRAPKIT_POTION),
- object_filter::Or(
- object_filter::TVal(TV_POTION),
- object_filter::TVal(TV_POTION2))),
- object_filter::And(
- object_filter::SVal(SV_TRAPKIT_SCROLL),
- object_filter::TVal(TV_SCROLL)),
- object_filter::And(
- object_filter::SVal(SV_TRAPKIT_DEVICE),
- &item_tester_hook_device));
-
- /* Get the second item */
- q = "Load with what? ";
- s = "You have nothing to load that trap with.";
- if (!get_item(&item_load, q, s, USE_INVEN, object_filter)) return;
-
- /* Get the second object */
- j_ptr = &p_ptr->inventory[item_load];
-
- /* Assume a single object */
- num = 1;
-
- /* In some cases, take multiple objects to load */
- if (o_ptr->sval != SV_TRAPKIT_DEVICE)
- {
- auto const flags = object_flags(o_ptr);
-
- if ((flags & TR_XTRA_SHOTS) && (o_ptr->pval > 0)) num += o_ptr->pval;
-
- if (flags & (TR_AUTOMATIC_5 | TR_AUTOMATIC_99)) num = 99;
-
- if (num > j_ptr->number) num = j_ptr->number;
-
- c = format("How many (1-%d)? ", num);
-
- /* Ask for number of items to use */
- num = get_quantity(c, num);
- }
-
- /* Canceled */
- if (!num) return;
-
- /* Take a turn */
- energy_use = 100;
-
- /* Get local object */
- i_ptr = &object_type_body;
-
- /* Obtain local object for trap content */
- object_copy(i_ptr, j_ptr);
-
- /* Set number */
- i_ptr->number = num;
-
- /* Drop it here */
- cave[p_ptr->py][p_ptr->px].special = floor_carry(p_ptr->py, p_ptr->px, i_ptr);
-
- /* Obtain local object for trap trigger kit */
- object_copy(i_ptr, o_ptr);
-
- /* Set number */
- i_ptr->number = 1;
-
- /* Drop it here */
- cave[p_ptr->py][p_ptr->px].special2 = floor_carry(p_ptr->py, p_ptr->px, i_ptr);
-
- /* Modify, Describe, Optimize */
- inc_stack_size_ex(item_kit, -1, NO_OPTIMIZE, DESCRIBE);
- inc_stack_size_ex(item_load, -num, NO_OPTIMIZE, DESCRIBE);
-
- for (i = 0; i < INVEN_WIELD; i++)
- {
- if (inven_item_optimize(i)) break;
- }
- for (i = 0; i < INVEN_WIELD; i++)
- {
- inven_item_optimize(i);
- }
-
- /* Actually set the trap */
- cave_set_feat(p_ptr->py, p_ptr->px, FEAT_MON_TRAP);
-}
-
-/*
- * Monster hitting a rod trap -MWK-
- *
- * Return TRUE if the monster died
- */
-bool_ mon_hit_trap_aux_rod(int m_idx, object_type *o_ptr)
-{
- int dam = 0, typ = 0;
- int rad = 0;
- monster_type *m_ptr = &m_list[m_idx];
- int y = m_ptr->fy;
- int x = m_ptr->fx;
-
- /* Depend on rod type */
- switch (o_ptr->pval)
- {
- case SV_ROD_DETECT_TRAP:
- m_ptr->smart |= SM_NOTE_TRAP;
- break;
- case SV_ROD_DETECTION:
- m_ptr->smart |= SM_NOTE_TRAP;
- break;
- case SV_ROD_ILLUMINATION:
- typ = GF_LITE_WEAK;
- dam = damroll(2, 15);
- rad = 3;
- lite_room(y, x);
- break;
- case SV_ROD_CURING:
- typ = GF_OLD_HEAL;
- dam = damroll(3, 4); /* and heal conf? */
- break;
- case SV_ROD_HEALING:
- typ = GF_OLD_HEAL;
- dam = 300;
- break;
- case SV_ROD_SPEED:
- typ = GF_OLD_SPEED;
- dam = 50;
- break;
- case SV_ROD_TELEPORT_AWAY:
- typ = GF_AWAY_ALL;
- dam = MAX_SIGHT * 5;
- break;
- case SV_ROD_DISARMING:
- break;
- case SV_ROD_LITE:
- typ = GF_LITE_WEAK;
- dam = damroll(6, 8);
- break;
- case SV_ROD_SLEEP_MONSTER:
- typ = GF_OLD_SLEEP;
- dam = 50;
- break;
- case SV_ROD_SLOW_MONSTER:
- typ = GF_OLD_SLOW;
- dam = 50;
- break;
- case SV_ROD_DRAIN_LIFE:
- typ = GF_OLD_DRAIN;
- dam = 75;
- break;
- case SV_ROD_POLYMORPH:
- typ = GF_OLD_POLY;
- dam = 50;
- break;
- case SV_ROD_ACID_BOLT:
- typ = GF_ACID;
- dam = damroll(6, 8);
- break;
- case SV_ROD_ELEC_BOLT:
- typ = GF_ELEC;
- dam = damroll(3, 8);
- break;
- case SV_ROD_FIRE_BOLT:
- typ = GF_FIRE;
- dam = damroll(8, 8);
- break;
- case SV_ROD_COLD_BOLT:
- typ = GF_COLD;
- dam = damroll(5, 8);
- break;
- case SV_ROD_ACID_BALL:
- typ = GF_ACID;
- dam = 60;
- rad = 2;
- break;
- case SV_ROD_ELEC_BALL:
- typ = GF_ELEC;
- dam = 32;
- rad = 2;
- break;
- case SV_ROD_FIRE_BALL:
- typ = GF_FIRE;
- dam = 72;
- rad = 2;
- break;
- case SV_ROD_COLD_BALL:
- typ = GF_COLD;
- dam = 48;
- rad = 2;
- break;
- default:
- return (FALSE);
- }
-
- /* Actually hit the monster */
- if (typ) (void) project( -2, rad, y, x, dam, typ, PROJECT_KILL | PROJECT_ITEM | PROJECT_JUMP);
- return (cave[y][x].m_idx == 0 ? TRUE : FALSE);
-}
-
-/*
- * Monster hitting a staff trap -MWK-
- *
- * Return TRUE if the monster died
- */
-bool_ mon_hit_trap_aux_staff(int m_idx, object_type *o_ptr)
-{
- return (FALSE);
-}
-
-/*
- * Monster hitting a scroll trap -MWK-
- *
- * Return TRUE if the monster died
- */
-bool_ mon_hit_trap_aux_scroll(int m_idx, int sval)
-{
- auto const &r_info = game->edit_data.r_info;
-
- monster_type *m_ptr = &m_list[m_idx];
- int dam = 0, typ = 0;
- int rad = 0;
- int y = m_ptr->fy;
- int x = m_ptr->fx;
- int k;
-
- /* Depend on scroll type */
- switch (sval)
- {
- case SV_SCROLL_CURSE_ARMOR:
- case SV_SCROLL_CURSE_WEAPON:
- case SV_SCROLL_TRAP_CREATION: /* these don't work :-( */
- case SV_SCROLL_WORD_OF_RECALL: /* should these? */
- case SV_SCROLL_IDENTIFY:
- case SV_SCROLL_STAR_IDENTIFY:
- case SV_SCROLL_MAPPING:
- case SV_SCROLL_DETECT_GOLD:
- case SV_SCROLL_DETECT_ITEM:
- case SV_SCROLL_REMOVE_CURSE:
- case SV_SCROLL_STAR_REMOVE_CURSE:
- case SV_SCROLL_ENCHANT_ARMOR:
- case SV_SCROLL_ENCHANT_WEAPON_TO_HIT:
- case SV_SCROLL_ENCHANT_WEAPON_TO_DAM:
- case SV_SCROLL_STAR_ENCHANT_ARMOR:
- case SV_SCROLL_STAR_ENCHANT_WEAPON:
- case SV_SCROLL_RECHARGING:
- case SV_SCROLL_DETECT_DOOR:
- case SV_SCROLL_DETECT_INVIS:
- case SV_SCROLL_SATISFY_HUNGER:
- case SV_SCROLL_RUNE_OF_PROTECTION:
- case SV_SCROLL_TRAP_DOOR_DESTRUCTION:
- case SV_SCROLL_PROTECTION_FROM_EVIL:
- return (FALSE);
- case SV_SCROLL_DARKNESS:
- unlite_room(y, x);
- typ = GF_DARK_WEAK;
- dam = 10;
- rad = 3;
- break;
- case SV_SCROLL_AGGRAVATE_MONSTER:
- aggravate_monsters(m_idx);
- return (FALSE);
- case SV_SCROLL_SUMMON_MONSTER:
- for (k = 0; k < randint(3) ; k++) summon_specific(y, x, dun_level, 0);
- return (FALSE);
- case SV_SCROLL_SUMMON_UNDEAD:
- for (k = 0; k < randint(3) ; k++) summon_specific(y, x, dun_level, SUMMON_UNDEAD);
- return (FALSE);
- case SV_SCROLL_PHASE_DOOR:
- typ = GF_AWAY_ALL;
- dam = 10;
- break;
- case SV_SCROLL_TELEPORT:
- typ = GF_AWAY_ALL;
- dam = 100;
- break;
- case SV_SCROLL_TELEPORT_LEVEL:
- delete_monster(y, x);
- return (TRUE);
- case SV_SCROLL_LIGHT:
- lite_room(y, x);
- typ = GF_LITE_WEAK;
- dam = damroll(2, 8);
- rad = 2;
- break;
- case SV_SCROLL_DETECT_TRAP:
- m_ptr->smart |= SM_NOTE_TRAP;
- return (FALSE);
- case SV_SCROLL_BLESSING:
- typ = GF_HOLY_FIRE;
- dam = damroll(1, 4);
- break;
- case SV_SCROLL_HOLY_CHANT:
- typ = GF_HOLY_FIRE;
- dam = damroll(2, 4);
- break;
- case SV_SCROLL_HOLY_PRAYER:
- typ = GF_HOLY_FIRE;
- dam = damroll(4, 4);
- break;
- case SV_SCROLL_MONSTER_CONFUSION:
- typ = GF_OLD_CONF;
- dam = damroll(5, 10);
- break;
- case SV_SCROLL_STAR_DESTRUCTION:
- destroy_area(y, x, 15);
- return (FALSE);
- case SV_SCROLL_DISPEL_UNDEAD:
- typ = GF_DISP_UNDEAD;
- rad = 5;
- dam = 60;
- break;
- case SV_SCROLL_GENOCIDE:
- {
- auto r_ptr = &r_info[m_ptr->r_idx];
- genocide_aux(FALSE, r_ptr->d_char);
- /* although there's no point in a multiple genocide trap... */
- return (!(r_ptr->flags & RF_UNIQUE));
- }
- case SV_SCROLL_MASS_GENOCIDE:
- for (k = 0; k < 8; k++)
- delete_monster(y + ddy[k], x + ddx[k]);
- delete_monster(y, x);
- return (TRUE);
- case SV_SCROLL_ACQUIREMENT:
- acquirement(y, x, 1, TRUE, FALSE);
- return (FALSE);
- case SV_SCROLL_STAR_ACQUIREMENT:
- acquirement(y, x, randint(2) + 1, TRUE, FALSE);
- return (FALSE);
- default:
- return (FALSE);
- }
-
- /* Actually hit the monster */
- (void) project( -2, rad, y, x, dam, typ, PROJECT_KILL | PROJECT_ITEM | PROJECT_JUMP);
- return (cave[y][x].m_idx == 0 ? TRUE : FALSE);
-}
-
-/*
- * Monster hitting a wand trap -MWK-
- *
- * Return TRUE if the monster died
- */
-bool_ mon_hit_trap_aux_wand(int m_idx, object_type *o_ptr)
-{
- return (FALSE);
-}
-
-/*
- * Monster hitting a potions trap -MWK-
- *
- * Return TRUE if the monster died
- */
-bool_ mon_hit_trap_aux_potion(int m_idx, object_type *o_ptr)
-{
- auto const &r_info = game->edit_data.r_info;
-
- monster_type *m_ptr = &m_list[m_idx];
- int dam = 0, typ = 0;
- int y = m_ptr->fy;
- int x = m_ptr->fx;
- int sval = o_ptr->sval;
-
- /* Depend on potion type */
- if (o_ptr->tval == TV_POTION)
- {
- switch (sval)
- {
- /* Nothing happens */
- case SV_POTION_WATER:
- case SV_POTION_APPLE_JUICE:
- case SV_POTION_SLIME_MOLD:
- case SV_POTION_SALT_WATER:
- case SV_POTION_DEC_STR:
- case SV_POTION_DEC_INT:
- case SV_POTION_DEC_WIS:
- case SV_POTION_DEC_DEX:
- case SV_POTION_DEC_CON:
- case SV_POTION_DEC_CHR:
- case SV_POTION_INFRAVISION:
- case SV_POTION_DETECT_INVIS:
- case SV_POTION_SLOW_POISON:
- case SV_POTION_CURE_POISON:
- case SV_POTION_RESIST_HEAT:
- case SV_POTION_RESIST_COLD:
- case SV_POTION_RESTORE_MANA:
- case SV_POTION_RESTORE_EXP:
- case SV_POTION_RES_STR:
- case SV_POTION_RES_INT:
- case SV_POTION_RES_WIS:
- case SV_POTION_RES_DEX:
- case SV_POTION_RES_CON:
- case SV_POTION_RES_CHR:
- case SV_POTION_INC_STR:
- case SV_POTION_INC_INT:
- case SV_POTION_INC_WIS:
- case SV_POTION_INC_DEX:
- case SV_POTION_INC_CON:
- case SV_POTION_INC_CHR:
- case SV_POTION_AUGMENTATION:
- case SV_POTION_RUINATION: /* ??? */
- case SV_POTION_ENLIGHTENMENT:
- case SV_POTION_STAR_ENLIGHTENMENT:
- case SV_POTION_SELF_KNOWLEDGE:
- return (FALSE);
-
- case SV_POTION_EXPERIENCE:
- if (m_ptr->level < MONSTER_LEVEL_MAX)
- {
- m_ptr->exp = monster_exp(m_ptr->level + 1);
- monster_check_experience(m_idx, FALSE);
- }
- return (FALSE);
- case SV_POTION_SLOWNESS:
- typ = GF_OLD_SLOW;
- dam = damroll(4, 6);
- break;
- case SV_POTION_POISON:
- typ = GF_POIS;
- dam = damroll(8, 6);
- break;
- case SV_POTION_CONFUSION:
- typ = GF_CONFUSION;
- dam = damroll(4, 6);
- break;
- case SV_POTION_BLINDNESS:
- typ = GF_DARK;
- dam = 10;
- break;
- case SV_POTION_SLEEP:
- typ = GF_OLD_SLEEP;
- dam = damroll (4, 6);
- break;
- case SV_POTION_LOSE_MEMORIES:
- typ = GF_OLD_CONF;
- dam = damroll(10, 10);
- break;
- case SV_POTION_DETONATIONS:
- typ = GF_DISINTEGRATE;
- dam = damroll(20, 20);
- break;
- case SV_POTION_DEATH:
- typ = GF_NETHER;
- dam = damroll(100, 20);
- break;
- case SV_POTION_BOLDNESS:
- m_ptr->monfear = 0;
- return (FALSE);
- case SV_POTION_SPEED:
- typ = GF_OLD_SPEED;
- dam = damroll(5, 10);
- break;
- case SV_POTION_HEROISM:
- case SV_POTION_BESERK_STRENGTH:
- m_ptr->monfear = 0;
- typ = GF_OLD_HEAL;
- dam = damroll(2, 10);
- break;
- case SV_POTION_CURE_LIGHT:
- typ = GF_OLD_HEAL;
- dam = damroll(3, 4);
- break;
- case SV_POTION_CURE_SERIOUS:
- typ = GF_OLD_HEAL;
- dam = damroll(4, 6);
- break;
- case SV_POTION_CURE_CRITICAL:
- typ = GF_OLD_HEAL;
- dam = damroll(6, 8);
- break;
- case SV_POTION_HEALING:
- typ = GF_OLD_HEAL;
- dam = 300;
- break;
- case SV_POTION_STAR_HEALING:
- typ = GF_OLD_HEAL;
- dam = 1000;
- break;
- case SV_POTION_LIFE:
- {
- auto r_ptr = &r_info[m_ptr->r_idx];
- if (r_ptr->flags & RF_UNDEAD)
- {
- typ = GF_HOLY_FIRE;
- dam = damroll(20, 20);
- }
- else
- {
- typ = GF_OLD_HEAL;
- dam = 5000;
- }
- break;
- }
- default:
- return (FALSE);
-
- }
- }
- else
- {}
-
- /* Actually hit the monster */
- (void) project_m( -2, 0, y, x, dam, typ);
- return (cave[y][x].m_idx == 0 ? TRUE : FALSE);
-}
-
-/*
- * Monster hitting a monster trap -MWK-
- * Returns True if the monster died, false otherwise
- */
-bool_ mon_hit_trap(int m_idx)
-{
- auto const &r_info = game->edit_data.r_info;
- auto const &k_info = game->edit_data.k_info;
-
- monster_type *m_ptr = &m_list[m_idx];
- auto r_ptr = &r_info[m_ptr->r_idx];
-
- object_type object_type_body;
-
- int mx = m_ptr->fx;
- int my = m_ptr->fy;
-
- int difficulty;
- int smartness;
-
- char m_name[80];
-
- bool_ notice = FALSE;
- bool_ disarm = FALSE;
- bool_ remove = FALSE;
- bool_ dead = FALSE;
- bool_ fear = FALSE;
- s32b special = 0;
-
- int dam, chance, shots;
- int mul = 0;
- int breakage = -1;
-
- int cost = 0;
-
- /* Get the trap objects */
- auto kit_o_idx = cave[my][mx].special2;
- auto kit_o_ptr = &o_list[kit_o_idx];
- auto load_o_ptr = &o_list[cave[my][mx].special];
- auto j_ptr = &object_type_body;
-
- /* Get trap properties */
- auto const flags = object_flags(kit_o_ptr);
-
- /* Can set off check */
- /* Ghosts only set off Ghost traps */
- if ((r_ptr->flags & RF_PASS_WALL) && !(flags & TR_KILL_GHOST)) return (FALSE);
-
- /* Some traps are specialized to some creatures */
- if (flags & (TR_ONLY_DRAGON | TR_ONLY_DEMON | TR_ONLY_ANIMAL | TR_ONLY_UNDEAD | TR_ONLY_EVIL))
- {
- bool_ affect = FALSE;
- if ((flags & TR_ONLY_DRAGON) && (r_ptr->flags & RF_DRAGON)) affect = TRUE;
- if ((flags & TR_ONLY_DEMON) && (r_ptr->flags & RF_DEMON)) affect = TRUE;
- if ((flags & TR_ONLY_UNDEAD) && (r_ptr->flags & RF_UNDEAD)) affect = TRUE;
- if ((flags & TR_ONLY_EVIL) && (r_ptr->flags & RF_EVIL)) affect = TRUE;
- if ((flags & TR_ONLY_ANIMAL) && (r_ptr->flags & RF_ANIMAL)) affect = TRUE;
-
- /* Don't set it off if forbidden */
- if (!affect) return (FALSE);
- }
-
- /* Get detection difficulty */
- difficulty = 25;
-
- /* Some traps are well-hidden */
- if (flags & TR_STEALTH)
- {
- difficulty += 10 * (kit_o_ptr->pval);
- }
-
- /* Get monster smartness for trap detection */
- /* Higher level monsters are smarter */
- smartness = r_ptr->level;
-
- /* Smart monsters are better at detecting traps */
- if (r_ptr->flags & RF_SMART) smartness += 10;
-
- /* Some monsters have already noticed one of out traps */
- if (m_ptr->smart & SM_NOTE_TRAP) smartness += 20;
-
- /* Stupid monsters are no good at detecting traps */
- if (r_ptr->flags & (RF_STUPID | RF_EMPTY_MIND)) smartness = -150;
-
- /* Check if the monster notices the trap */
- if (randint(300) > (difficulty - smartness + 150)) notice = TRUE;
-
- /* Disarm check */
- if (notice)
- {
- /* The next traps will be easier to spot! */
- m_ptr->smart |= SM_NOTE_TRAP;
-
- /* Get trap disarming difficulty */
- difficulty = (kit_o_ptr->ac + kit_o_ptr->to_a);
-
- /* Get monster disarming ability */
- /* Higher level monsters are better */
- smartness = r_ptr->level / 5;
-
- /* Smart monsters are better at disarming */
- if (r_ptr->flags & RF_SMART) smartness *= 2;
-
- /* Stupid monsters never disarm traps */
- if (r_ptr->flags & RF_STUPID) smartness = -150;
-
- /* Nonsmart animals never disarm traps */
- if ((r_ptr->flags & RF_ANIMAL) && !(r_ptr->flags & RF_SMART)) smartness = -150;
-
- /* Check if the monster disarms the trap */
- if (randint(120) > (difficulty - smartness + 80)) disarm = TRUE;
- }
-
- /* If disarmed, remove the trap and print a message */
- if (disarm)
- {
- remove = TRUE;
-
- if (m_ptr->ml)
- {
- /* Get the name */
- monster_desc(m_name, m_ptr, 0);
-
- /* Print a message */
- msg_format("%^s disarms a trap!", m_name);
- }
- }
-
- /* Otherwise, activate the trap! */
- else
- {
- /* Message for visible monster */
- if (m_ptr->ml)
- {
- /* Get the name */
- monster_desc(m_name, m_ptr, 0);
-
- /* Print a message */
- msg_format("%^s sets off a trap!", m_name);
- }
- else
- {
- /* No message if monster isn't visible ? */
- }
-
- /* Next time be more careful */
- if (randint(100) < 80) m_ptr->smart |= SM_NOTE_TRAP;
-
- /* Actually activate the trap */
- switch (kit_o_ptr->sval)
- {
- case SV_TRAPKIT_BOW:
- case SV_TRAPKIT_XBOW:
- case SV_TRAPKIT_SLING:
- {
- /* Get number of shots */
- shots = 1;
- if (flags & TR_XTRA_SHOTS) shots += kit_o_ptr->pval;
- if (shots <= 0) shots = 1;
- if (shots > load_o_ptr->number) shots = load_o_ptr->number;
-
- while (shots-- && !dead)
- {
- /* Total base damage */
- dam = damroll(load_o_ptr->dd, load_o_ptr->ds) + load_o_ptr->to_d + kit_o_ptr->to_d;
-
- /* Total hit probability */
- chance = (kit_o_ptr->to_h + load_o_ptr->to_h + 20) * BTH_PLUS_ADJ;
-
- /* Damage multiplier */
- if (kit_o_ptr->sval == SV_TRAPKIT_BOW) mul = 3;
- if (kit_o_ptr->sval == SV_TRAPKIT_XBOW) mul = 4;
- if (kit_o_ptr->sval == SV_TRAPKIT_SLING) mul = 2;
- if (flags & TR_XTRA_MIGHT) mul += kit_o_ptr->pval;
- if (mul < 0) mul = 0;
-
- /* Multiply damage */
- dam *= mul;
-
- /* Check if we hit the monster */
- if (test_hit_fire(chance, r_ptr->ac, TRUE))
- {
- /* Assume a default death */
- cptr note_dies = " dies.";
-
- /* Some monsters get "destroyed" */
- if ((r_ptr->flags & RF_DEMON) ||
- (r_ptr->flags & RF_UNDEAD) ||
- (r_ptr->flags & RF_STUPID) ||
- (strchr("Evg", r_ptr->d_char)))
- {
- /* Special note at death */
- note_dies = " is destroyed.";
- }
-
- /* Message if visible */
- if (m_ptr->ml)
- {
- /* describe the monster (again, just in case :-) */
- monster_desc(m_name, m_ptr, 0);
-
- /* Print a message */
- msg_format("%^s is hit by a missile.", m_name);
- }
-
- /* Apply slays, brand, critical hits */
- dam = tot_dam_aux(load_o_ptr, dam, m_ptr, &special);
- dam = critical_shot(load_o_ptr->weight, load_o_ptr->to_h, dam, SKILL_ARCHERY);
-
- /* No negative damage */
- if (dam < 0) dam = 0;
-
- /* Hit the monster, check for death */
- if (mon_take_hit(m_idx, dam, &fear, note_dies))
- {
- /* Dead monster */
- dead = TRUE;
- }
-
- /* No death */
- else
- {
- /* Message */
- message_pain(m_idx, dam);
-
- if (special) attack_special(m_ptr, special, dam);
-
- /* Take note */
- if (fear && m_ptr->ml)
- {
- /* Message */
- msg_format("%^s flees in terror!", m_name);
- }
- }
-
- }
-
- /* Exploding ammo */
- if (load_o_ptr->pval2 != 0)
- {
- int rad = 0;
- int dam = (damroll(load_o_ptr->dd, load_o_ptr->ds) + load_o_ptr->to_d)*2;
- int flag = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL |
- PROJECT_JUMP;
-
- switch (load_o_ptr->sval)
- {
- case SV_AMMO_LIGHT:
- rad = 2;
- dam /= 2;
- break;
- case SV_AMMO_NORMAL:
- rad = 3;
- break;
- case SV_AMMO_HEAVY:
- rad = 4;
- dam *= 2;
- break;
- }
-
- project(0, rad, my, mx, dam, load_o_ptr->pval2, flag);
-
- breakage = 100;
- }
- else
- {
- breakage = breakage_chance(load_o_ptr);
- }
-
- /* Copy and decrease ammo */
- object_copy(j_ptr, load_o_ptr);
-
- j_ptr->number = 1;
-
- load_o_ptr->number--;
-
- if (load_o_ptr->number <= 0)
- {
- remove = TRUE;
- delete_object_idx(kit_o_idx);
- }
-
- /* Drop (or break) near that location */
- drop_near(j_ptr, breakage, my, mx);
-
- }
-
- break;
- }
-
- case SV_TRAPKIT_POTION:
- {
- /* Get number of shots */
- shots = 1;
- if (flags & TR_XTRA_SHOTS) shots += kit_o_ptr->pval;
- if (shots <= 0) shots = 1;
- if (shots > load_o_ptr->number) shots = load_o_ptr->number;
-
- while (shots-- && !dead)
- {
-
- /* Message if visible */
- if (m_ptr->ml)
- {
- /* describe the monster (again, just in case :-) */
- monster_desc(m_name, m_ptr, 0);
-
- /* Print a message */
- msg_format("%^s is hit by fumes.", m_name);
- }
-
- /* Get the potion effect */
- dead = mon_hit_trap_aux_potion(m_idx, load_o_ptr);
-
- /* Copy and decrease ammo */
- object_copy(j_ptr, load_o_ptr);
-
- j_ptr->number = 1;
-
- load_o_ptr->number--;
-
- if (load_o_ptr->number <= 0)
- {
- remove = TRUE;
- delete_object_idx(kit_o_idx);
- }
- }
-
- break;
- }
-
- case SV_TRAPKIT_SCROLL:
- {
- /* Get number of shots */
- shots = 1;
- if (flags & TR_XTRA_SHOTS) shots += kit_o_ptr->pval;
- if (shots <= 0) shots = 1;
- if (shots > load_o_ptr->number) shots = load_o_ptr->number;
-
- while (shots-- && !dead)
- {
-
- /* Message if visible */
- if (m_ptr->ml)
- {
- /* describe the monster (again, just in case :-) */
- monster_desc(m_name, m_ptr, 0);
-
- /* Print a message */
- msg_format("%^s activates a spell!", m_name);
- }
-
- /* Get the potion effect */
- dead = mon_hit_trap_aux_scroll(m_idx, load_o_ptr->sval);
-
- /* Copy and decrease ammo */
- object_copy(j_ptr, load_o_ptr);
-
- j_ptr->number = 1;
-
- load_o_ptr->number--;
-
- if (load_o_ptr->number <= 0)
- {
- remove = TRUE;
- delete_object_idx(kit_o_idx);
- }
- }
-
- break;
- }
-
- case SV_TRAPKIT_DEVICE:
- {
- if (load_o_ptr->tval == TV_ROD_MAIN)
- {
- /* Extract mana cost of the rod tip */
- auto tip_o_ptr = &k_info[lookup_kind(TV_ROD, load_o_ptr->pval)];
- auto const tflags = object_flags(load_o_ptr);
- cost = (tflags & TR_CHEAPNESS) ? tip_o_ptr->pval / 2 : tip_o_ptr->pval;
- if (cost <= 0) cost = 1;
- }
-
- /* Get number of shots */
- shots = 1;
- if (flags & TR_XTRA_SHOTS) shots += kit_o_ptr->pval;
- if (shots <= 0) shots = 1;
-
- if (load_o_ptr->tval == TV_ROD_MAIN)
- {
- if (shots > load_o_ptr->timeout / cost) shots = load_o_ptr->timeout / cost;
- }
- else
- {
- if (shots > load_o_ptr->pval) shots = load_o_ptr->pval;
- }
-
- while (shots-- && !dead)
- {
- /* Get the effect effect */
- switch (load_o_ptr->tval)
- {
- case TV_ROD_MAIN:
- dead = mon_hit_trap_aux_rod(m_idx, load_o_ptr);
- break;
- case TV_WAND:
- dead = mon_hit_trap_aux_wand(m_idx, load_o_ptr);
- break;
- case TV_STAFF:
- dead = mon_hit_trap_aux_staff(m_idx, load_o_ptr);
- break;
- }
-
- if (load_o_ptr->tval == TV_ROD_MAIN)
- {
- /* decrease stored mana (timeout) for rods */
- load_o_ptr->timeout -= cost;
- }
- else
- {
- /* decrease charges for wands and staves */
- load_o_ptr->pval--;
- }
- }
-
- break;
- }
-
- default:
- msg_print("oops! nonexistant trap!");
-
- }
-
- /* Non-automatic traps are removed */
- if (!(flags & (TR_AUTOMATIC_5 | TR_AUTOMATIC_99)))
- {
- remove = TRUE;
- }
- else if (flags & TR_AUTOMATIC_5) remove = (randint(5) == 1);
-
- }
-
- /* Special trap effect -- teleport to */
- if ((flags & TR_TELEPORT_TO) && (!disarm) && (!dead))
- {
- teleport_monster_to(m_idx, p_ptr->py, p_ptr->px);
- }
-
- /* Remove the trap if inactive now */
- if (remove) place_floor_convert_glass(my, mx);
-
- /* did it die? */
- return (dead);
-}
-