/* * Do an effect, given an object. * Boost is the extent to which skill surpasses difficulty, used as % boost. It * ranges from 0 to 138. */ bool effect_do(effect_type effect, bool *ident, bool aware, int dir, int beam, int boost) { int py = p_ptr->py; int px = p_ptr->px; int dam, chance, dur; if (effect < 1 || effect > EF_MAX) { msg("Bad effect passed to do_effect(). Please report this bug."); return FALSE; } switch (effect) { case EF_POISON: { inc_timed(TMD_POISONED, damroll(2, 7) + 10, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_BLIND: { inc_timed(TMD_BLIND, damroll(4, 25) + 75, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_SCARE: { inc_timed(TMD_AFRAID, randint0(10) + 10, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_CONFUSE: { inc_timed(TMD_CONFUSED, damroll(4, 5) + 10, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_HALLUC: { inc_timed(TMD_IMAGE, randint0(250) + 250, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_PARALYZE: { inc_timed(TMD_PARALYZED, randint0(5) + 5, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_SLOW: { if (inc_timed(TMD_SLOW, randint1(25) + 15, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_POISON: { if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_BLINDNESS: { if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_PARANOIA: { if (clear_timed(TMD_AFRAID, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_CONFUSION: { if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_MIND: { if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; if (clear_timed(TMD_AFRAID, TRUE)) *ident = TRUE; if (clear_timed(TMD_IMAGE, TRUE)) *ident = TRUE; if (!of_has(p_ptr->state.flags, OF_RES_CONFU) && inc_timed(TMD_OPP_CONF, damroll(4, 10), TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_BODY: { if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_LIGHT: { if (hp_player(20)) *ident = TRUE; if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (dec_timed(TMD_CUT, 20, TRUE)) *ident = TRUE; if (dec_timed(TMD_CONFUSED, 20, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_SERIOUS: { if (hp_player(40)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_CRITICAL: { if (hp_player(60)) *ident = TRUE; if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; if (clear_timed(TMD_AMNESIA, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_FULL: { int amt = (p_ptr->mhp * 35) / 100; if (amt < 300) amt = 300; if (hp_player(amt)) *ident = TRUE; if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; if (clear_timed(TMD_AMNESIA, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_FULL2: { if (hp_player(1200)) *ident = TRUE; if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; if (clear_timed(TMD_AMNESIA, TRUE)) *ident = TRUE; return TRUE; } case EF_CURE_TEMP: { if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; if (clear_timed(TMD_CONFUSED, TRUE)) *ident = TRUE; if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; return TRUE; } case EF_HEAL1: { if (hp_player(500)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; return TRUE; } case EF_HEAL2: { if (hp_player(1000)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; return TRUE; } case EF_HEAL3: { if (hp_player(500)) *ident = TRUE; if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; return TRUE; } case EF_GAIN_EXP: { if (p_ptr->exp < PY_MAX_EXP) { msg("You feel more experienced."); player_exp_gain(p_ptr, 100000L); *ident = TRUE; } return TRUE; } case EF_LOSE_EXP: { if (!check_state(OF_HOLD_LIFE, p_ptr->state.flags) && (p_ptr->exp > 0)) { msg("You feel your memories fade."); player_exp_lose(p_ptr, p_ptr->exp / 4, FALSE); *ident = TRUE; } *ident = TRUE; wieldeds_notice_flag(OF_HOLD_LIFE); return TRUE; } case EF_RESTORE_EXP: { if (restore_level()) *ident = TRUE; return TRUE; } case EF_RESTORE_MANA: { if (p_ptr->csp < p_ptr->msp) { p_ptr->csp = p_ptr->msp; p_ptr->csp_frac = 0; msg("Your feel your head clear."); p_ptr->redraw |= (PR_MANA); *ident = TRUE; } return TRUE; } case EF_GAIN_STR: case EF_GAIN_INT: case EF_GAIN_WIS: case EF_GAIN_DEX: case EF_GAIN_CON: case EF_GAIN_CHR: { int stat = effect - EF_GAIN_STR; if (do_inc_stat(stat)) *ident = TRUE; return TRUE; } case EF_GAIN_ALL: { if (do_inc_stat(A_STR)) *ident = TRUE; if (do_inc_stat(A_INT)) *ident = TRUE; if (do_inc_stat(A_WIS)) *ident = TRUE; if (do_inc_stat(A_DEX)) *ident = TRUE; if (do_inc_stat(A_CON)) *ident = TRUE; if (do_inc_stat(A_CHR)) *ident = TRUE; return TRUE; } case EF_BRAWN: { /* Pick a random stat to decrease other than strength */ int stat = randint0(A_MAX-1) + 1; if (do_dec_stat(stat, TRUE)) { do_inc_stat(A_STR); *ident = TRUE; } return TRUE; } case EF_INTELLECT: { /* Pick a random stat to decrease other than intelligence */ int stat = randint0(A_MAX-1); if (stat >= A_INT) stat++; if (do_dec_stat(stat, TRUE)) { do_inc_stat(A_INT); *ident = TRUE; } return TRUE; } case EF_CONTEMPLATION: { /* Pick a random stat to decrease other than wisdom */ int stat = randint0(A_MAX-1); if (stat >= A_WIS) stat++; if (do_dec_stat(stat, TRUE)) { do_inc_stat(A_WIS); *ident = TRUE; } return TRUE; } case EF_TOUGHNESS: { /* Pick a random stat to decrease other than constitution */ int stat = randint0(A_MAX-1); if (stat >= A_CON) stat++; if (do_dec_stat(stat, TRUE)) { do_inc_stat(A_CON); *ident = TRUE; } return TRUE; } case EF_NIMBLENESS: { /* Pick a random stat to decrease other than dexterity */ int stat = randint0(A_MAX-1); if (stat >= A_DEX) stat++; if (do_dec_stat(stat, TRUE)) { do_inc_stat(A_DEX); *ident = TRUE; } return TRUE; } case EF_PLEASING: { /* Pick a random stat to decrease other than charisma */ int stat = randint0(A_MAX-1); if (do_dec_stat(stat, TRUE)) { do_inc_stat(A_CHR); *ident = TRUE; } return TRUE; } case EF_LOSE_STR: case EF_LOSE_INT: case EF_LOSE_WIS: case EF_LOSE_DEX: case EF_LOSE_CON: case EF_LOSE_CHR: { int stat = effect - EF_LOSE_STR; take_hit(damroll(5, 5), "stat drain"); (void)do_dec_stat(stat, FALSE); *ident = TRUE; return TRUE; } case EF_LOSE_CON2: { take_hit(damroll(10, 10), "poisonous food"); (void)do_dec_stat(A_CON, FALSE); *ident = TRUE; return TRUE; } case EF_RESTORE_STR: case EF_RESTORE_INT: case EF_RESTORE_WIS: case EF_RESTORE_DEX: case EF_RESTORE_CON: case EF_RESTORE_CHR: { int stat = effect - EF_RESTORE_STR; if (do_res_stat(stat)) *ident = TRUE; return TRUE; } case EF_CURE_NONORLYBIG: { msg("You feel life flow through your body!"); restore_level(); (void)clear_timed(TMD_POISONED, TRUE); (void)clear_timed(TMD_BLIND, TRUE); (void)clear_timed(TMD_CONFUSED, TRUE); (void)clear_timed(TMD_IMAGE, TRUE); (void)clear_timed(TMD_STUN, TRUE); (void)clear_timed(TMD_CUT, TRUE); (void)clear_timed(TMD_AMNESIA, TRUE); if (do_res_stat(A_STR)) *ident = TRUE; if (do_res_stat(A_INT)) *ident = TRUE; if (do_res_stat(A_WIS)) *ident = TRUE; if (do_res_stat(A_DEX)) *ident = TRUE; if (do_res_stat(A_CON)) *ident = TRUE; if (do_res_stat(A_CHR)) *ident = TRUE; /* Recalculate max. hitpoints */ update_stuff(); hp_player(5000); *ident = TRUE; return TRUE; } case EF_RESTORE_ALL: { /* Life, above, also gives these effects */ if (do_res_stat(A_STR)) *ident = TRUE; if (do_res_stat(A_INT)) *ident = TRUE; if (do_res_stat(A_WIS)) *ident = TRUE; if (do_res_stat(A_DEX)) *ident = TRUE; if (do_res_stat(A_CON)) *ident = TRUE; if (do_res_stat(A_CHR)) *ident = TRUE; return TRUE; } case EF_RESTORE_ST_LEV: { if (restore_level()) *ident = TRUE; if (do_res_stat(A_STR)) *ident = TRUE; if (do_res_stat(A_INT)) *ident = TRUE; if (do_res_stat(A_WIS)) *ident = TRUE; if (do_res_stat(A_DEX)) *ident = TRUE; if (do_res_stat(A_CON)) *ident = TRUE; if (do_res_stat(A_CHR)) *ident = TRUE; return TRUE; } case EF_TMD_INFRA: { if (inc_timed(TMD_SINFRA, 100 + damroll(4, 25), TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_TMD_SINVIS: { if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (inc_timed(TMD_SINVIS, 12 + damroll(2, 6), TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_TMD_ESP: { if (clear_timed(TMD_BLIND, TRUE)) *ident = TRUE; if (inc_timed(TMD_TELEPATHY, 12 + damroll(6, 6), TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_ENLIGHTENMENT: { msg("An image of your surroundings forms in your mind..."); wiz_light(); *ident = TRUE; return TRUE; } case EF_ENLIGHTENMENT2: { msg("You begin to feel more enlightened..."); message_flush(); wiz_light(); (void)do_inc_stat(A_INT); (void)do_inc_stat(A_WIS); (void)detect_traps(TRUE); (void)detect_doorstairs(TRUE); (void)detect_treasure(TRUE); identify_pack(); *ident = TRUE; return TRUE; } case EF_HERO: { dur = randint1(25) + 25; if (hp_player(10)) *ident = TRUE; if (clear_timed(TMD_AFRAID, TRUE)) *ident = TRUE; if (inc_timed(TMD_BOLD, dur, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_HERO, dur, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_SHERO: { dur = randint1(25) + 25; if (hp_player(30)) *ident = TRUE; if (clear_timed(TMD_AFRAID, TRUE)) *ident = TRUE; if (inc_timed(TMD_BOLD, dur, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_SHERO, dur, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RESIST_ACID: { if (inc_timed(TMD_OPP_ACID, randint1(10) + 10, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RESIST_ELEC: { if (inc_timed(TMD_OPP_ELEC, randint1(10) + 10, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RESIST_FIRE: { if (inc_timed(TMD_OPP_FIRE, randint1(10) + 10, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RESIST_COLD: { if (inc_timed(TMD_OPP_COLD, randint1(10) + 10, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RESIST_POIS: { if (inc_timed(TMD_OPP_POIS, randint1(10) + 10, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RESIST_ALL: { if (inc_timed(TMD_OPP_ACID, randint1(20) + 20, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_OPP_ELEC, randint1(20) + 20, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_OPP_FIRE, randint1(20) + 20, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_OPP_COLD, randint1(20) + 20, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_OPP_POIS, randint1(20) + 20, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_DETECT_TREASURE: { if (detect_treasure(aware)) *ident = TRUE; return TRUE; } case EF_DETECT_TRAP: { if (detect_traps(aware)) *ident = TRUE; return TRUE; } case EF_DETECT_DOORSTAIR: { if (detect_doorstairs(aware)) *ident = TRUE; return TRUE; } case EF_DETECT_INVIS: { if (detect_monsters_invis(aware)) *ident = TRUE; return TRUE; } case EF_DETECT_EVIL: { if (detect_monsters_evil(aware)) *ident = TRUE; return TRUE; } case EF_DETECT_ALL: { if (detect_all(aware)) *ident = TRUE; return TRUE; } case EF_ENCHANT_TOHIT: { *ident = TRUE; return enchant_spell(1, 0, 0); } case EF_ENCHANT_TODAM: { *ident = TRUE; return enchant_spell(0, 1, 0); } case EF_ENCHANT_WEAPON: { *ident = TRUE; return enchant_spell(randint1(3), randint1(3), 0); } case EF_ENCHANT_ARMOR: { *ident = TRUE; return enchant_spell(0, 0, 1); } case EF_ENCHANT_ARMOR2: { *ident = TRUE; return enchant_spell(0, 0, randint1(3) + 2); } case EF_RESTORE_ITEM: { *ident = TRUE; return restore_item(); } case EF_IDENTIFY: { *ident = TRUE; if (!ident_spell()) return FALSE; return TRUE; } case EF_REMOVE_CURSE: { if (remove_curse()) { if (!p_ptr->timed[TMD_BLIND]) msg("The air around your body glows blue for a moment..."); else msg("You feel as if someone is watching over you."); *ident = TRUE; } return TRUE; } case EF_REMOVE_CURSE2: { remove_all_curse(); *ident = TRUE; return TRUE; } case EF_LIGHT: { if (light_area(damroll(2, 8), 2)) *ident = TRUE; return TRUE; } case EF_SUMMON_MON: { int i; sound(MSG_SUM_MONSTER); for (i = 0; i < randint1(3); i++) { if (summon_specific(py, px, p_ptr->depth, 0, 1)) *ident = TRUE; } return TRUE; } case EF_SUMMON_UNDEAD: { int i; sound(MSG_SUM_UNDEAD); for (i = 0; i < randint1(3); i++) { if (summon_specific(py, px, p_ptr->depth, S_UNDEAD, 1)) *ident = TRUE; } return TRUE; } case EF_TELE_PHASE: { teleport_player(10); *ident = TRUE; return TRUE; } case EF_TELE_LONG: { teleport_player(100); *ident = TRUE; return TRUE; } case EF_TELE_LEVEL: { (void)teleport_player_level(); *ident = TRUE; return TRUE; } case EF_CONFUSING: { if (p_ptr->confusing == 0) { msg("Your hands begin to glow."); p_ptr->confusing = TRUE; *ident = TRUE; } return TRUE; } case EF_MAPPING: { map_area(); *ident = TRUE; return TRUE; } case EF_RUNE: { warding_glyph(); *ident = TRUE; return TRUE; } case EF_ACQUIRE: { acquirement(py, px, p_ptr->depth, 1, TRUE); *ident = TRUE; return TRUE; } case EF_ACQUIRE2: { acquirement(py, px, p_ptr->depth, randint1(2) + 1, TRUE); *ident = TRUE; return TRUE; } case EF_ANNOY_MON: { msg("There is a high pitched humming noise."); aggravate_monsters(0); *ident = TRUE; return TRUE; } case EF_CREATE_TRAP: { /* Hack -- no traps in the town */ if (p_ptr->depth == 0) return TRUE; trap_creation(); msg("You hear a low-pitched whistling sound."); *ident = TRUE; return TRUE; } case EF_DESTROY_TDOORS: { if (destroy_doors_touch()) *ident = TRUE; return TRUE; } case EF_RECHARGE: { *ident = TRUE; if (!recharge(60)) return FALSE; return TRUE; } case EF_BANISHMENT: { *ident = TRUE; if (!banishment()) return FALSE; return TRUE; } case EF_DARKNESS: { if (!check_state(OF_RES_DARK, p_ptr->state.flags)) (void)inc_timed(TMD_BLIND, 3 + randint1(5), TRUE, TRUE); unlight_area(10, 3); wieldeds_notice_flag(OF_RES_DARK); *ident = TRUE; return TRUE; } case EF_PROTEVIL: { if (inc_timed(TMD_PROTEVIL, randint1(25) + 3 * p_ptr->lev, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_SATISFY: { if (set_food(PY_FOOD_MAX - 1)) *ident = TRUE; return TRUE; } case EF_CURSE_WEAPON: { if (curse_weapon()) *ident = TRUE; return TRUE; } case EF_CURSE_ARMOR: { if (curse_armor()) *ident = TRUE; return TRUE; } case EF_BLESSING: { if (inc_timed(TMD_BLESSED, randint1(12) + 6, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_BLESSING2: { if (inc_timed(TMD_BLESSED, randint1(24) + 12, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_BLESSING3: { if (inc_timed(TMD_BLESSED, randint1(48) + 24, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_RECALL: { set_recall(); *ident = TRUE; return TRUE; } case EF_DEEP_DESCENT: { int i, target_depth = p_ptr->depth; /* Calculate target depth */ for (i = 2; i > 0; i--) { if (is_quest(target_depth)) break; if (target_depth >= MAX_DEPTH - 1) break; target_depth++; } if (target_depth > p_ptr->depth) { msgt(MSG_TPLEVEL, "You sink through the floor..."); dungeon_change_level(target_depth); *ident = TRUE; return TRUE; } else { msgt(MSG_TPLEVEL, "You sense a malevolent presence blocking passage to the levels below."); *ident = TRUE; return FALSE; } } case EF_LOSHASTE: { if (speed_monsters()) *ident = TRUE; return TRUE; } case EF_LOSSLEEP: { if (sleep_monsters(aware)) *ident = TRUE; return TRUE; } case EF_LOSSLOW: { if (slow_monsters()) *ident = TRUE; return TRUE; } case EF_LOSCONF: { if (confuse_monsters(aware)) *ident = TRUE; return TRUE; } case EF_LOSKILL: { (void)mass_banishment(); *ident = TRUE; return TRUE; } case EF_EARTHQUAKES: { earthquake(py, px, 10); *ident = TRUE; return TRUE; } case EF_DESTRUCTION2: { destroy_area(py, px, 15, TRUE); *ident = TRUE; return TRUE; } case EF_ILLUMINATION: { if (light_area(damroll(2, 15), 3)) *ident = TRUE; return TRUE; } case EF_CLAIRVOYANCE: { *ident = TRUE; wiz_light(); (void)detect_traps(TRUE); (void)detect_doorstairs(TRUE); return TRUE; } case EF_PROBING: { *ident = probing(); return TRUE; } case EF_STONE_TO_MUD: { if (wall_to_mud(dir)) *ident = TRUE; return TRUE; } case EF_CONFUSE2: { *ident = TRUE; confuse_monster(dir, 20, aware); return TRUE; } case EF_BIZARRE: { *ident = TRUE; ring_of_power(dir); return TRUE; } case EF_STAR_BALL: { int i; *ident = TRUE; for (i = 0; i < 8; i++) fire_ball(GF_ELEC, ddd[i], (150 * (100 + boost) / 100), 3); return TRUE; } case EF_RAGE_BLESS_RESIST: { dur = randint1(50) + 50; *ident = TRUE; (void)hp_player(30); (void)clear_timed(TMD_AFRAID, TRUE); (void)inc_timed(TMD_BOLD, dur, TRUE, TRUE); (void)inc_timed(TMD_SHERO, dur, TRUE, TRUE); (void)inc_timed(TMD_BLESSED, randint1(50) + 50, TRUE, TRUE); (void)inc_timed(TMD_OPP_ACID, randint1(50) + 50, TRUE, TRUE); (void)inc_timed(TMD_OPP_ELEC, randint1(50) + 50, TRUE, TRUE); (void)inc_timed(TMD_OPP_FIRE, randint1(50) + 50, TRUE, TRUE); (void)inc_timed(TMD_OPP_COLD, randint1(50) + 50, TRUE, TRUE); (void)inc_timed(TMD_OPP_POIS, randint1(50) + 50, TRUE, TRUE); return TRUE; } case EF_SLEEPII: { *ident = TRUE; sleep_monsters_touch(aware); return TRUE; } case EF_RESTORE_LIFE: { *ident = TRUE; restore_level(); return TRUE; } case EF_MISSILE: { *ident = TRUE; dam = damroll(3, 4) * (100 + boost) / 100; fire_bolt_or_beam(beam, GF_MISSILE, dir, dam); return TRUE; } case EF_DISPEL_EVIL: { *ident = TRUE; dam = p_ptr->lev * 5 * (100 + boost) / 100; dispel_evil(dam); return TRUE; } case EF_DISPEL_EVIL60: { dam = 60 * (100 + boost) / 100; if (dispel_evil(dam)) *ident = TRUE; return TRUE; } case EF_DISPEL_UNDEAD: { dam = 60 * (100 + boost) / 100; if (dispel_undead(dam)) *ident = TRUE; return TRUE; } case EF_DISPEL_ALL: { dam = 120 * (100 + boost) / 100; if (dispel_monsters(dam)) *ident = TRUE; return TRUE; } case EF_HASTE: { if (!p_ptr->timed[TMD_FAST]) { if (set_timed(TMD_FAST, damroll(2, 10) + 20, TRUE)) *ident = TRUE; } else { (void)inc_timed(TMD_FAST, 5, TRUE, TRUE); } return TRUE; } case EF_HASTE1: { if (!p_ptr->timed[TMD_FAST]) { if (set_timed(TMD_FAST, randint1(20) + 20, TRUE)) *ident = TRUE; } else { (void)inc_timed(TMD_FAST, 5, TRUE, TRUE); } return TRUE; } case EF_HASTE2: { if (!p_ptr->timed[TMD_FAST]) { if (set_timed(TMD_FAST, randint1(75) + 75, TRUE)) *ident = TRUE; } else { (void)inc_timed(TMD_FAST, 5, TRUE, TRUE); } return TRUE; } case EF_FIRE_BOLT: { *ident = TRUE; dam = damroll(9, 8) * (100 + boost) / 100; fire_bolt(GF_FIRE, dir, dam); return TRUE; } case EF_FIRE_BOLT2: { dam = damroll(12, 8) * (100 + boost) / 100; fire_bolt_or_beam(beam, GF_FIRE, dir, dam); *ident = TRUE; return TRUE; } case EF_FIRE_BOLT3: { dam = damroll(16, 8) * (100 + boost) / 100; fire_bolt_or_beam(beam, GF_FIRE, dir, dam); *ident = TRUE; return TRUE; } case EF_FIRE_BOLT72: { dam = 72 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_FIRE, dir, dam, 2); return TRUE; } case EF_FIRE_BALL: { dam = 144 * (100 + boost) / 100; fire_ball(GF_FIRE, dir, dam, 2); *ident = TRUE; return TRUE; } case EF_FIRE_BALL2: { dam = 120 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_FIRE, dir, dam, 3); return TRUE; } case EF_FIRE_BALL200: { dam = 200 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_FIRE, dir, dam, 3); return TRUE; } case EF_COLD_BOLT: { dam = damroll(6, 8) * (100 + boost) / 100; *ident = TRUE; fire_bolt_or_beam(beam, GF_COLD, dir, dam); return TRUE; } case EF_COLD_BOLT2: { dam = damroll(12, 8) * (100 + boost) / 100; *ident = TRUE; fire_bolt(GF_COLD, dir, dam); return TRUE; } case EF_COLD_BALL2: { dam = 200 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_COLD, dir, dam, 3); return TRUE; } case EF_COLD_BALL50: { dam = 50 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_COLD, dir, dam, 2); return TRUE; } case EF_COLD_BALL100: { dam = 100 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_COLD, dir, dam, 2); return TRUE; } case EF_COLD_BALL160: { dam = 160 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_COLD, dir, dam, 3); return TRUE; } case EF_ACID_BOLT: { dam = damroll(5, 8) * (100 + boost) / 100; *ident = TRUE; fire_bolt(GF_ACID, dir, dam); return TRUE; } case EF_ACID_BOLT2: { dam = damroll(10, 8) * (100 + boost) / 100; fire_bolt_or_beam(beam, GF_ACID, dir, dam); *ident = TRUE; return TRUE; } case EF_ACID_BOLT3: { dam = damroll(12, 8) * (100 + boost) / 100; fire_bolt_or_beam(beam, GF_ACID, dir, dam); *ident = TRUE; return TRUE; } case EF_ACID_BALL: { dam = 120 * (100 + boost) / 100; fire_ball(GF_ACID, dir, dam, 2); *ident = TRUE; return TRUE; } case EF_ELEC_BOLT: { dam = damroll(6, 6) * (100 + boost) / 100; *ident = TRUE; fire_beam(GF_ELEC, dir, dam); return TRUE; } case EF_ELEC_BALL: { dam = 64 * (100 + boost) / 100; fire_ball(GF_ELEC, dir, dam, 2); *ident = TRUE; return TRUE; } case EF_ELEC_BALL2: { dam = 250 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_ELEC, dir, dam, 3); return TRUE; } case EF_ARROW: { dam = 150 * (100 + boost) / 100; *ident = TRUE; fire_bolt(GF_ARROW, dir, dam); return TRUE; } case EF_REM_FEAR_POIS: { *ident = TRUE; (void)clear_timed(TMD_AFRAID, TRUE); (void)clear_timed(TMD_POISONED, TRUE); return TRUE; } case EF_STINKING_CLOUD: { dam = 12 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_POIS, dir, dam, 3); return TRUE; } case EF_DRAIN_LIFE1: { dam = 90 * (100 + boost) / 100; if (drain_life(dir, dam)) *ident = TRUE; return TRUE; } case EF_DRAIN_LIFE2: { dam = 120 * (100 + boost) / 100; if (drain_life(dir, dam)) *ident = TRUE; return TRUE; } case EF_DRAIN_LIFE3: { dam = 150 * (100 + boost) / 100; if (drain_life(dir, dam)) *ident = TRUE; return TRUE; } case EF_DRAIN_LIFE4: { dam = 250 * (100 + boost) / 100; if (drain_life(dir, dam)) *ident = TRUE; return TRUE; } case EF_FIREBRAND: { *ident = TRUE; if (!brand_bolts()) return FALSE; return TRUE; } case EF_MANA_BOLT: { dam = damroll(12, 8) * (100 + boost) / 100; fire_bolt(GF_MANA, dir, dam); *ident = TRUE; return TRUE; } case EF_MON_HEAL: { if (heal_monster(dir)) *ident = TRUE; return TRUE; } case EF_MON_HASTE: { if (speed_monster(dir)) *ident = TRUE; return TRUE; } case EF_MON_SLOW: { if (slow_monster(dir)) *ident = TRUE; return TRUE; } case EF_MON_CONFUSE: { if (confuse_monster(dir, 10, aware)) *ident = TRUE; return TRUE; } case EF_MON_SLEEP: { if (sleep_monster(dir, aware)) *ident = TRUE; return TRUE; } case EF_MON_CLONE: { if (clone_monster(dir)) *ident = TRUE; return TRUE; } case EF_MON_SCARE: { if (fear_monster(dir, 10, aware)) *ident = TRUE; return TRUE; } case EF_LIGHT_LINE: { msg("A line of shimmering blue light appears."); light_line(dir); *ident = TRUE; return TRUE; } case EF_TELE_OTHER: { if (teleport_monster(dir)) *ident = TRUE; return TRUE; } case EF_DISARMING: { if (disarm_trap(dir)) *ident = TRUE; return TRUE; } case EF_TDOOR_DEST: { if (destroy_door(dir)) *ident = TRUE; return TRUE; } case EF_POLYMORPH: { if (poly_monster(dir)) *ident = TRUE; return TRUE; } case EF_STARLIGHT: { int i; if (!p_ptr->timed[TMD_BLIND]) msg("Light shoots in all directions!"); for (i = 0; i < 8; i++) light_line(ddd[i]); *ident = TRUE; return TRUE; } case EF_STARLIGHT2: { int k; for (k = 0; k < 8; k++) strong_light_line(ddd[k]); *ident = TRUE; return TRUE; } case EF_BERSERKER: { dur = randint1(50) + 50; if (inc_timed(TMD_BOLD, dur, TRUE, TRUE)) *ident = TRUE; if (inc_timed(TMD_SHERO, dur, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_WONDER: { if (effect_wonder(dir, randint1(100) + p_ptr->lev / 5, beam)) *ident = TRUE; return TRUE; } case EF_WAND_BREATH: { /* table of random ball effects and their damages */ const int breath_types[] = { GF_ACID, 200, GF_ELEC, 160, GF_FIRE, 200, GF_COLD, 160, GF_POIS, 120 }; /* pick a random (type, damage) tuple in the table */ int which = 2 * randint0(sizeof(breath_types) / (2 * sizeof(int))); fire_ball(breath_types[which], dir, breath_types[which + 1], 3); *ident = TRUE; return TRUE; } case EF_STAFF_MAGI: { if (do_res_stat(A_INT)) *ident = TRUE; if (p_ptr->csp < p_ptr->msp) { p_ptr->csp = p_ptr->msp; p_ptr->csp_frac = 0; *ident = TRUE; msg("Your feel your head clear."); p_ptr->redraw |= (PR_MANA); } return TRUE; } case EF_STAFF_HOLY: { dam = 120 * (100 + boost) / 100; if (dispel_evil(dam)) *ident = TRUE; if (inc_timed(TMD_PROTEVIL, randint1(25) + 3 * p_ptr->lev, TRUE, TRUE)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; if (clear_timed(TMD_AFRAID, TRUE)) *ident = TRUE; if (hp_player(50)) *ident = TRUE; if (clear_timed(TMD_STUN, TRUE)) *ident = TRUE; if (clear_timed(TMD_CUT, TRUE)) *ident = TRUE; return TRUE; } case EF_DRINK_BREATH: { const int breath_types[] = { GF_FIRE, 80, GF_COLD, 80, }; int which = 2 * randint0(N_ELEMENTS(breath_types) / 2); fire_ball(breath_types[which], dir, breath_types[which + 1], 2); *ident = TRUE; return TRUE; } case EF_DRINK_GOOD: { msg("You feel less thirsty."); *ident = TRUE; return TRUE; } case EF_DRINK_DEATH: { msg("A feeling of Death flows through your body."); take_hit(5000, "a potion of Death"); *ident = TRUE; return TRUE; } case EF_DRINK_RUIN: { msg("Your nerves and muscles feel weak and lifeless!"); take_hit(damroll(10, 10), "a potion of Ruination"); player_stat_dec(p_ptr, A_DEX, TRUE); player_stat_dec(p_ptr, A_WIS, TRUE); player_stat_dec(p_ptr, A_CON, TRUE); player_stat_dec(p_ptr, A_STR, TRUE); player_stat_dec(p_ptr, A_CHR, TRUE); player_stat_dec(p_ptr, A_INT, TRUE); *ident = TRUE; return TRUE; } case EF_DRINK_DETONATE: { msg("Massive explosions rupture your body!"); take_hit(damroll(50, 20), "a potion of Detonation"); (void)inc_timed(TMD_STUN, 75, TRUE, TRUE); (void)inc_timed(TMD_CUT, 5000, TRUE, TRUE); *ident = TRUE; return TRUE; } case EF_DRINK_SALT: { msg("The potion makes you vomit!"); (void)set_food(PY_FOOD_STARVE - 1); (void)clear_timed(TMD_POISONED, TRUE); (void)inc_timed(TMD_PARALYZED, 4, TRUE, FALSE); *ident = TRUE; return TRUE; } case EF_FOOD_GOOD: { msg("That tastes good."); *ident = TRUE; return TRUE; } case EF_FOOD_WAYBREAD: { msg("That tastes good."); (void)clear_timed(TMD_POISONED, TRUE); (void)hp_player(damroll(4, 8)); *ident = TRUE; return TRUE; } case EF_SHROOM_EMERGENCY: { (void)set_timed(TMD_IMAGE, rand_spread(250, 50), TRUE); (void)set_timed(TMD_OPP_FIRE, rand_spread(30, 10), TRUE); (void)set_timed(TMD_OPP_COLD, rand_spread(30, 10), TRUE); (void)hp_player(200); *ident = TRUE; return TRUE; } case EF_SHROOM_TERROR: { if (set_timed(TMD_TERROR, rand_spread(100, 20), TRUE)) *ident = TRUE; return TRUE; } case EF_SHROOM_STONE: { if (set_timed(TMD_STONESKIN, rand_spread(80, 20), TRUE)) *ident = TRUE; return TRUE; } case EF_SHROOM_DEBILITY: { int stat = one_in_(2) ? A_STR : A_CON; if (p_ptr->csp < p_ptr->msp) { p_ptr->csp = p_ptr->msp; p_ptr->csp_frac = 0; msg("Your feel your head clear."); p_ptr->redraw |= (PR_MANA); *ident = TRUE; } (void)do_dec_stat(stat, FALSE); *ident = TRUE; return TRUE; } case EF_SHROOM_SPRINTING: { if (inc_timed(TMD_SPRINT, 100, TRUE, TRUE)) *ident = TRUE; return TRUE; } case EF_SHROOM_PURGING: { (void)set_food(PY_FOOD_FAINT - 1); if (do_res_stat(A_STR)) *ident = TRUE; if (do_res_stat(A_CON)) *ident = TRUE; if (clear_timed(TMD_POISONED, TRUE)) *ident = TRUE; return TRUE; } case EF_RING_ACID: { dam = 70 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_ACID, dir, dam, 2); inc_timed(TMD_OPP_ACID, randint1(20) + 20, TRUE, TRUE); return TRUE; } case EF_RING_FLAMES: { dam = 80 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_FIRE, dir, dam, 2); inc_timed(TMD_OPP_FIRE, randint1(20) + 20, TRUE, TRUE); return TRUE; } case EF_RING_ICE: { dam = 75 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_COLD, dir, dam, 2); inc_timed(TMD_OPP_COLD, randint1(20) + 20, TRUE, TRUE); return TRUE; } case EF_RING_LIGHTNING: { dam = 85 * (100 + boost) / 100; *ident = TRUE; fire_ball(GF_ELEC, dir, dam, 2); inc_timed(TMD_OPP_ELEC, randint1(20) + 20, TRUE, TRUE); return TRUE; } case EF_DRAGON_BLUE: { dam = 100 * (100 + boost) / 100; msgt(MSG_BR_ELEC, "You breathe lightning."); fire_ball(GF_ELEC, dir, dam, 2); return TRUE; } case EF_DRAGON_GREEN: { dam = 150 * (100 + boost) / 100; msgt(MSG_BR_GAS, "You breathe poison gas."); fire_ball(GF_POIS, dir, dam, 2); return TRUE; } case EF_DRAGON_RED: { dam = 200 * (100 + boost) / 100; msgt(MSG_BR_FIRE, "You breathe fire."); fire_ball(GF_FIRE, dir, dam, 2); return TRUE; } case EF_DRAGON_MULTIHUED: { static const struct { int msg_sound; const char *msg; int typ; } mh[] = { { MSG_BR_ELEC, "lightning", GF_ELEC }, { MSG_BR_FROST, "frost", GF_COLD }, { MSG_BR_ACID, "acid", GF_ACID }, { MSG_BR_GAS, "poison gas", GF_POIS }, { MSG_BR_FIRE, "fire", GF_FIRE } }; int chance = randint0(5); dam = 250 * (100 + boost) / 100; msgt(mh[chance].msg_sound, "You breathe %s.", mh[chance].msg); fire_ball(mh[chance].typ, dir, dam, 2); return TRUE; } case EF_DRAGON_BRONZE: { dam = 120 * (100 + boost) / 100; msgt(MSG_BR_CONF, "You breathe confusion."); fire_ball(GF_CONFU, dir, dam, 2); return TRUE; } case EF_DRAGON_GOLD: { dam = 130 * (100 + boost) / 100; msgt(MSG_BR_SOUND, "You breathe sound."); fire_ball(GF_SOUND, dir, dam, 2); return TRUE; } case EF_DRAGON_CHAOS: { dam = 220 * (100 + boost) / 100; chance = randint0(2); msgt((chance == 1 ? MSG_BR_CHAOS : MSG_BR_DISEN), "You breathe %s.", ((chance == 1 ? "chaos" : "disenchantment"))); fire_ball((chance == 1 ? GF_CHAOS : GF_DISEN), dir, dam, 2); return TRUE; } case EF_DRAGON_LAW: { dam = 230 * (100 + boost) / 100; chance = randint0(2); msgt((chance == 1 ? MSG_BR_SOUND : MSG_BR_SHARDS), "You breathe %s.", ((chance == 1 ? "sound" : "shards"))); fire_ball((chance == 1 ? GF_SOUND : GF_SHARD), dir, dam, 2); return TRUE; } case EF_DRAGON_BALANCE: { dam = 250 * (100 + boost) / 100; chance = randint0(4); msg("You breathe %s.", ((chance == 1) ? "chaos" : ((chance == 2) ? "disenchantment" : ((chance == 3) ? "sound" : "shards")))); fire_ball(((chance == 1) ? GF_CHAOS : ((chance == 2) ? GF_DISEN : ((chance == 3) ? GF_SOUND : GF_SHARD))), dir, dam, 2); return TRUE; } case EF_DRAGON_SHINING: { dam = 200 * (100 + boost) / 100; chance = randint0(2); msgt((chance == 0 ? MSG_BR_LIGHT : MSG_BR_DARK), "You breathe %s.", ((chance == 0 ? "light" : "darkness"))); fire_ball((chance == 0 ? GF_LIGHT : GF_DARK), dir, dam, 2); return TRUE; } case EF_DRAGON_POWER: { dam = 300 * (100 + boost) / 100; msgt(MSG_BR_ELEMENTS, "You breathe the elements."); fire_ball(GF_MISSILE, dir, dam, 2); return TRUE; } case EF_TRAP_DOOR: { msg("You fall through a trap door!"); if (check_state(OF_FEATHER, p_ptr->state.flags)) { msg("You float gently down to the next level."); } else { take_hit(damroll(2, 8), "a trap"); } wieldeds_notice_flag(OF_FEATHER); dungeon_change_level(p_ptr->depth + 1); return TRUE; } case EF_TRAP_PIT: { msg("You fall into a pit!"); if (check_state(OF_FEATHER, p_ptr->state.flags)) { msg("You float gently to the bottom of the pit."); } else { take_hit(damroll(2, 6), "a trap"); } wieldeds_notice_flag(OF_FEATHER); return TRUE; } case EF_TRAP_PIT_SPIKES: { msg("You fall into a spiked pit!"); if (check_state(OF_FEATHER, p_ptr->state.flags)) { msg("You float gently to the floor of the pit."); msg("You carefully avoid touching the spikes."); } else { int dam = damroll(2, 6); /* Extra spike damage */ if (one_in_(2)) { msg("You are impaled!"); dam *= 2; (void)inc_timed(TMD_CUT, randint1(dam), TRUE, TRUE); } take_hit(dam, "a trap"); } wieldeds_notice_flag(OF_FEATHER); return TRUE; } case EF_TRAP_PIT_POISON: { msg("You fall into a spiked pit!"); if (check_state(OF_FEATHER, p_ptr->state.flags)) { msg("You float gently to the floor of the pit."); msg("You carefully avoid touching the spikes."); } else { int dam = damroll(2, 6); /* Extra spike damage */ if (one_in_(2)) { msg("You are impaled on poisonous spikes!"); (void)inc_timed(TMD_CUT, randint1(dam * 2), TRUE, TRUE); (void)inc_timed(TMD_POISONED, randint1(dam * 4), TRUE, TRUE); } take_hit(dam, "a trap"); } wieldeds_notice_flag(OF_FEATHER); return TRUE; } case EF_TRAP_RUNE_SUMMON: { int i; int num = 2 + randint1(3); msgt(MSG_SUM_MONSTER, "You are enveloped in a cloud of smoke!"); /* Remove trap */ cave->info[py][px] &= ~(CAVE_MARK); cave_set_feat(cave, py, px, FEAT_FLOOR); for (i = 0; i < num; i++) (void)summon_specific(py, px, p_ptr->depth, 0, 1); break; } case EF_TRAP_RUNE_TELEPORT: { msg("You hit a teleport trap!"); teleport_player(100); return TRUE; } case EF_TRAP_SPOT_FIRE: { int dam; msg("You are enveloped in flames!"); dam = damroll(4, 6); dam = adjust_dam(GF_FIRE, dam, RANDOMISE, check_for_resist(GF_FIRE, p_ptr->state.flags, TRUE)); if (dam) { take_hit(dam, "a fire trap"); inven_damage(GF_FIRE, MIN(dam * 5, 300)); } return TRUE; } case EF_TRAP_SPOT_ACID: { int dam; msg("You are splashed with acid!"); dam = damroll(4, 6); dam = adjust_dam(GF_ACID, dam, RANDOMISE, check_for_resist(GF_ACID, p_ptr->state.flags, TRUE)); if (dam) { take_hit(dam, "an acid trap"); inven_damage(GF_ACID, MIN(dam * 5, 300)); } return TRUE; } case EF_TRAP_DART_SLOW: { if (trap_check_hit(125)) { msg("A small dart hits you!"); take_hit(damroll(1, 4), "a trap"); (void)inc_timed(TMD_SLOW, randint0(20) + 20, TRUE, FALSE); } else { msg("A small dart barely misses you."); } return TRUE; } case EF_TRAP_DART_LOSE_STR: { if (trap_check_hit(125)) { msg("A small dart hits you!"); take_hit(damroll(1, 4), "a trap"); (void)do_dec_stat(A_STR, FALSE); } else { msg("A small dart barely misses you."); } return TRUE; } case EF_TRAP_DART_LOSE_DEX: { if (trap_check_hit(125)) { msg("A small dart hits you!"); take_hit(damroll(1, 4), "a trap"); (void)do_dec_stat(A_DEX, FALSE); } else { msg("A small dart barely misses you."); } return TRUE; } case EF_TRAP_DART_LOSE_CON: { if (trap_check_hit(125)) { msg("A small dart hits you!"); take_hit(damroll(1, 4), "a trap"); (void)do_dec_stat(A_CON, FALSE); } else { msg("A small dart barely misses you."); } return TRUE; } case EF_TRAP_GAS_BLIND: { msg("You are surrounded by a black gas!"); (void)inc_timed(TMD_BLIND, randint0(50) + 25, TRUE, TRUE); return TRUE; } case EF_TRAP_GAS_CONFUSE: { msg("You are surrounded by a gas of scintillating colors!"); (void)inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE, TRUE); return TRUE; } case EF_TRAP_GAS_POISON: { msg("You are surrounded by a pungent green gas!"); (void)inc_timed(TMD_POISONED, randint0(20) + 10, TRUE, TRUE); return TRUE; } case EF_TRAP_GAS_SLEEP: { msg("You are surrounded by a strange white mist!"); (void)inc_timed(TMD_PARALYZED, randint0(10) + 5, TRUE, TRUE); return TRUE; } case EF_XXX: case EF_MAX: break; } /* Not used */ msg("Effect not handled."); return FALSE; }
static bool cast_mage_spell(int spell, int dir) { int py = p_ptr->py; int px = p_ptr->px; int plev = p_ptr->lev; /* Hack -- chance of "beam" instead of "bolt" */ int beam = beam_chance(); /* Spells. */ switch (spell) { case SPELL_MAGIC_MISSILE: { fire_bolt_or_beam(beam-10, GF_MISSILE, dir, damroll(3 + ((plev - 1) / 5), 4)); break; } case SPELL_DETECT_MONSTERS: { (void)detect_monsters_normal(TRUE); break; } case SPELL_PHASE_DOOR: { teleport_player(10); break; } case SPELL_LIGHT_AREA: { (void)light_area(damroll(2, (plev / 2)), (plev / 10) + 1); break; } case SPELL_TREASURE_DETECTION: { (void)detect_treasure(TRUE); break; } case SPELL_CURE_LIGHT_WOUNDS: { (void)heal_player(15, 15); (void)dec_timed(TMD_CUT, 20, TRUE); (void)dec_timed(TMD_CONFUSED, 20, TRUE); (void)clear_timed(TMD_BLIND, TRUE); break; } case SPELL_FIND_TRAPS_DOORS: { (void)detect_traps(TRUE); (void)detect_doorstairs(TRUE); break; } case SPELL_STINKING_CLOUD: { fire_ball(GF_POIS, dir, 10 + (plev / 2), 2); break; } case SPELL_CONFUSE_MONSTER: { (void)confuse_monster(dir, plev, TRUE); break; } case SPELL_LIGHTNING_BOLT: { fire_beam(GF_ELEC, dir, damroll(3+((plev-5)/6), 6)); break; } case SPELL_TRAP_DOOR_DESTRUCTION: { (void)destroy_doors_touch(); break; } case SPELL_SLEEP_MONSTER: { (void)sleep_monster(dir, TRUE); break; } case SPELL_CURE_POISON: { (void)clear_timed(TMD_POISONED, TRUE); break; } case SPELL_TELEPORT_SELF: { teleport_player(plev * 5); break; } case SPELL_SPEAR_OF_LIGHT: { msg("A line of blue shimmering light appears."); light_line(dir); break; } case SPELL_FROST_BOLT: { fire_bolt_or_beam(beam-10, GF_COLD, dir, damroll(5+((plev-5)/4), 8)); break; } case SPELL_TURN_STONE_TO_MUD: { (void)wall_to_mud(dir); break; } case SPELL_SATISFY_HUNGER: { (void)set_food(PY_FOOD_MAX - 1); break; } case SPELL_RECHARGE_ITEM_I: { return recharge(2 + plev / 5); } case SPELL_WONDER: { (void)spell_wonder(dir); break; } case SPELL_POLYMORPH_OTHER: { (void)poly_monster(dir); break; } case SPELL_IDENTIFY: { return ident_spell(); } case SPELL_MASS_SLEEP: { (void)sleep_monsters(TRUE); break; } case SPELL_FIRE_BOLT: { fire_bolt_or_beam(beam, GF_FIRE, dir, damroll(6+((plev-5)/4), 8)); break; } case SPELL_SLOW_MONSTER: { (void)slow_monster(dir); break; } case SPELL_FROST_BALL: { fire_ball(GF_COLD, dir, 30 + (plev), 2); break; } case SPELL_RECHARGE_ITEM_II: /* greater recharging */ { return recharge(50 + plev); } case SPELL_TELEPORT_OTHER: { (void)teleport_monster(dir); break; } case SPELL_BEDLAM: { fire_ball(GF_OLD_CONF, dir, plev, 4); break; } case SPELL_FIRE_BALL: { fire_ball(GF_FIRE, dir, 55 + (plev), 2); break; } case SPELL_WORD_OF_DESTRUCTION: { destroy_area(py, px, 15, TRUE); break; } case SPELL_BANISHMENT: { return banishment(); break; } case SPELL_DOOR_CREATION: { (void)door_creation(); break; } case SPELL_STAIR_CREATION: { (void)stair_creation(); break; } case SPELL_TELEPORT_LEVEL: { (void)teleport_player_level(); break; } case SPELL_EARTHQUAKE: { earthquake(py, px, 10); break; } case SPELL_WORD_OF_RECALL: { set_recall(); break; } case SPELL_ACID_BOLT: { fire_bolt_or_beam(beam, GF_ACID, dir, damroll(8+((plev-5)/4), 8)); break; } case SPELL_CLOUD_KILL: { fire_ball(GF_POIS, dir, 40 + (plev / 2), 3); break; } case SPELL_ACID_BALL: { fire_ball(GF_ACID, dir, 40 + (plev), 2); break; } case SPELL_ICE_STORM: { fire_ball(GF_ICE, dir, 50 + (plev * 2), 3); break; } case SPELL_METEOR_SWARM: { fire_swarm(2 + plev / 20, GF_METEOR, dir, 30 + plev / 2, 1); break; } case SPELL_MANA_STORM: { fire_ball(GF_MANA, dir, 300 + (plev * 2), 3); break; } case SPELL_DETECT_INVISIBLE: { (void)detect_monsters_normal(TRUE); (void)detect_monsters_invis(TRUE); break; } case SPELL_DETECT_ENCHANTMENT: { (void)detect_objects_magic(TRUE); break; } case SPELL_SHOCK_WAVE: { fire_ball(GF_SOUND, dir, 10 + plev, 2); break; } case SPELL_EXPLOSION: { fire_ball(GF_SHARD, dir, 20 + (plev * 2), 2); break; } case SPELL_MASS_BANISHMENT: { (void)mass_banishment(); break; } case SPELL_RESIST_FIRE: { (void)inc_timed(TMD_OPP_FIRE, randint1(20) + 20, TRUE); break; } case SPELL_RESIST_COLD: { (void)inc_timed(TMD_OPP_COLD, randint1(20) + 20, TRUE); break; } case SPELL_ELEMENTAL_BRAND: /* elemental brand */ { return brand_ammo(); } case SPELL_RESIST_POISON: { (void)inc_timed(TMD_OPP_POIS, randint1(20) + 20, TRUE); break; } case SPELL_RESISTANCE: { int time = randint1(20) + 20; (void)inc_timed(TMD_OPP_ACID, time, TRUE); (void)inc_timed(TMD_OPP_ELEC, time, TRUE); (void)inc_timed(TMD_OPP_FIRE, time, TRUE); (void)inc_timed(TMD_OPP_COLD, time, TRUE); (void)inc_timed(TMD_OPP_POIS, time, TRUE); break; } case SPELL_HEROISM: { (void)hp_player(10); (void)inc_timed(TMD_HERO, randint1(25) + 25, TRUE); (void)clear_timed(TMD_AFRAID, TRUE); break; } case SPELL_SHIELD: { (void)inc_timed(TMD_SHIELD, randint1(20) + 30, TRUE); break; } case SPELL_BERSERKER: { (void)hp_player(30); (void)inc_timed(TMD_SHERO, randint1(25) + 25, TRUE); (void)clear_timed(TMD_AFRAID, TRUE); break; } case SPELL_HASTE_SELF: { if (!p_ptr->timed[TMD_FAST]) { (void)set_timed(TMD_FAST, randint1(20) + plev, TRUE); } else { (void)inc_timed(TMD_FAST, randint1(5), TRUE); } break; } case SPELL_RIFT: { fire_beam(GF_GRAVITY, dir, 40 + damroll(plev, 7)); break; } case SPELL_REND_SOUL: /* rend soul */ { fire_bolt_or_beam(beam / 4, GF_NETHER, dir, damroll(11, plev)); break; } case SPELL_CHAOS_STRIKE: /* chaos strike */ { fire_bolt_or_beam(beam, GF_CHAOS, dir, damroll(13, plev)); break; } case SPELL_RUNE_OF_PROTECTION: /* rune of protection */ { (void)warding_glyph(); break; } case SPELL_ENCHANT_ARMOR: /* enchant armor */ { return enchant_spell(0, 0, randint0(3) + plev / 20); } case SPELL_ENCHANT_WEAPON: /* enchant weapon */ { return enchant_spell(randint0(4) + plev / 20, randint0(4) + plev / 20, 0); } } /* Success */ return (TRUE); }
static bool zap_rod(object_type *o_ptr, bool *ident) { int chance, dir, lev; /* Get a direction (unless KNOWN not to need it) */ if ((o_ptr->sval >= SV_ROD_MIN_DIRECTION) || !object_aware_p(o_ptr)) { /* Get a direction, allow cancel */ if (!get_aim_dir(&dir)) return FALSE; } /* Take a turn */ p_ptr->energy_use = 100; /* Not identified yet */ *ident = FALSE; /* Extract the item level */ lev = k_info[o_ptr->k_idx].level; /* Base chance of success */ chance = p_ptr->skill_dev; /* Confusion hurts skill */ if (p_ptr->confused) chance = chance / 2; /* High level objects are harder */ chance = chance - ((lev > 50) ? 50 : lev); /* Give everyone a (slight) chance */ if ((chance < USE_DEVICE) && (rand_int(USE_DEVICE - chance + 1) == 0)) { chance = USE_DEVICE; } /* Roll for usage */ if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE)) { if (flush_failure) flush(); msg_print("You failed to use the rod properly."); return FALSE; } /* Still charging */ if (o_ptr->pval) { if (flush_failure) flush(); msg_print("The rod is still charging."); return FALSE; } /* Sound */ sound(MSG_ZAP); /* Analyze the rod */ switch (o_ptr->sval) { case SV_ROD_DETECT_TRAP: { if (detect_traps()) *ident = TRUE; o_ptr->pval = 50; break; } case SV_ROD_DETECT_DOOR: { if (detect_doors()) *ident = TRUE; if (detect_stairs()) *ident = TRUE; o_ptr->pval = 70; break; } case SV_ROD_IDENTIFY: { *ident = TRUE; if (ident_spell()) o_ptr->pval = 10; break; } case SV_ROD_RECALL: { set_recall(); *ident = TRUE; o_ptr->pval = 60; break; } case SV_ROD_ILLUMINATION: { if (lite_area(damroll(2, 8), 2)) *ident = TRUE; o_ptr->pval = 30; break; } case SV_ROD_MAPPING: { map_area(); *ident = TRUE; o_ptr->pval = 99; break; } case SV_ROD_DETECTION: { detect_all(); *ident = TRUE; o_ptr->pval = 99; break; } case SV_ROD_PROBING: { probing(); *ident = TRUE; o_ptr->pval = 50; break; } case SV_ROD_CURING: { if (set_blind(0)) *ident = TRUE; if (set_poisoned(0)) *ident = TRUE; if (set_confused(0)) *ident = TRUE; if (set_stun(0)) *ident = TRUE; if (set_cut(0)) *ident = TRUE; o_ptr->pval = 999; break; } case SV_ROD_HEALING: { if (hp_player(500)) *ident = TRUE; if (set_stun(0)) *ident = TRUE; if (set_cut(0)) *ident = TRUE; o_ptr->pval = 999; break; } case SV_ROD_RESTORATION: { if (restore_level()) *ident = TRUE; if (do_res_stat(A_STR)) *ident = TRUE; if (do_res_stat(A_INT)) *ident = TRUE; if (do_res_stat(A_WIS)) *ident = TRUE; if (do_res_stat(A_DEX)) *ident = TRUE; if (do_res_stat(A_CON)) *ident = TRUE; if (do_res_stat(A_CHR)) *ident = TRUE; o_ptr->pval = 999; break; } case SV_ROD_SPEED: { if (!p_ptr->fast) { if (set_fast(randint(30) + 15)) *ident = TRUE; } else { (void)set_fast(p_ptr->fast + 5); } o_ptr->pval = 99; break; } case SV_ROD_TELEPORT_AWAY: { if (teleport_monster(dir)) *ident = TRUE; o_ptr->pval = 25; break; } case SV_ROD_DISARMING: { if (disarm_trap(dir)) *ident = TRUE; o_ptr->pval = 30; break; } case SV_ROD_LITE: { msg_print("A line of blue shimmering light appears."); lite_line(dir); *ident = TRUE; o_ptr->pval = 9; break; } case SV_ROD_SLEEP_MONSTER: { if (sleep_monster(dir)) *ident = TRUE; o_ptr->pval = 18; break; } case SV_ROD_SLOW_MONSTER: { if (slow_monster(dir)) *ident = TRUE; o_ptr->pval = 20; break; } case SV_ROD_DRAIN_LIFE: { if (drain_life(dir, 150)) *ident = TRUE; o_ptr->pval = 23; break; } case SV_ROD_POLYMORPH: { if (poly_monster(dir)) *ident = TRUE; o_ptr->pval = 25; break; } case SV_ROD_ACID_BOLT: { fire_bolt_or_beam(10, GF_ACID, dir, damroll(12, 8)); *ident = TRUE; o_ptr->pval = 12; break; } case SV_ROD_ELEC_BOLT: { fire_bolt_or_beam(10, GF_ELEC, dir, damroll(6, 6)); *ident = TRUE; o_ptr->pval = 11; break; } case SV_ROD_FIRE_BOLT: { fire_bolt_or_beam(10, GF_FIRE, dir, damroll(16, 8)); *ident = TRUE; o_ptr->pval = 15; break; } case SV_ROD_COLD_BOLT: { fire_bolt_or_beam(10, GF_COLD, dir, damroll(10, 8)); *ident = TRUE; o_ptr->pval = 13; break; } case SV_ROD_ACID_BALL: { fire_ball(GF_ACID, dir, 120, 2); *ident = TRUE; o_ptr->pval = 27; break; } case SV_ROD_ELEC_BALL: { fire_ball(GF_ELEC, dir, 64, 2); *ident = TRUE; o_ptr->pval = 23; break; } case SV_ROD_FIRE_BALL: { fire_ball(GF_FIRE, dir, 144, 2); *ident = TRUE; o_ptr->pval = 30; break; } case SV_ROD_COLD_BALL: { fire_ball(GF_COLD, dir, 96, 2); *ident = TRUE; o_ptr->pval = 25; break; } } return TRUE; }
static bool cast_mage_spell(int Ind, int spell) { player_type *p_ptr = Players[Ind]; object_type *o_ptr; int py = p_ptr->py; int px = p_ptr->px; int Depth = p_ptr->dun_depth; int dir; int plev = p_ptr->lev; /* Hack -- chance of "beam" instead of "bolt" */ int beam = beam_chance(Ind); /* MAngband-specific: Projected */ if (spell >= SPELL_PROJECTED) { if (!get_aim_dir(Ind, &dir)) return (FALSE); (void)project_spell_ball(Ind, dir, spell - SPELL_PROJECTED); return (TRUE); } /* Spells. */ switch (spell) { case SPELL_MAGIC_MISSILE: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s fires a magic missile."); fire_bolt_or_beam(Ind, beam-10, GF_MISSILE, dir, damroll(3 + ((plev - 1) / 5), 4)); break; } case SPELL_DETECT_MONSTERS: { (void)detect_creatures(Ind, TRUE); break; } case SPELL_PHASE_DOOR: { msg_spell("%s blinks away!"); teleport_player(Ind, 10); break; } case SPELL_LIGHT_AREA: { (void)lite_area(Ind, damroll(2, (plev / 2)), (plev / 10) + 1); break; } case SPELL_TREASURE_DETECTION: { (void)detect_treasure(Ind); //(void)detect_objects_gold(Ind); break; } case SPELL_CURE_LIGHT_WOUNDS: { (void)hp_player(Ind, damroll(2, 8)); (void)set_cut(Ind, p_ptr->cut - 15); break; } case SPELL_OBJECT_DETECTION: { (void)detect_objects_normal(Ind); break; } case SPELL_FIND_TRAPS_DOORS: { (void)detect_trap(Ind);//detect_traps(Ind); (void)detect_sdoor(Ind);//detect_doors(Ind); //(void)detect_stairs(Ind); break; } case SPELL_STINKING_CLOUD: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts a stinking cloud."); fire_ball(Ind, GF_POIS, dir, 10 + (plev / 2), 2); break; } case SPELL_CONFUSE_MONSTER: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s makes a complicated gesture."); (void)confuse_monster(Ind, dir, plev); break; } case SPELL_LIGHTNING_BOLT: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts a lightning bolt."); fire_beam(Ind, GF_ELEC, dir, damroll(3+((plev-5)/6), 6)); break; } case SPELL_TRAP_DOOR_DESTRUCTION: { (void)destroy_doors_touch(Ind); break; } case SPELL_SLEEP_MONSTER: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s gestures and mumbles calmly."); (void)sleep_monster(Ind, dir); break; } case SPELL_CURE_POISON: { (void)set_poisoned(Ind, 0); break; } case SPELL_TELEPORT_SELF: { msg_spell("%s teleports away!"); teleport_player(Ind, plev * 5); break; } case SPELL_SPEAR_OF_LIGHT: /* spear of light */ { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_print(Ind, "A line of blue shimmering light appears."); msg_spell("A line of blue shimmering light appears out of %s's hands."); lite_line(Ind, dir); break; } case SPELL_FROST_BOLT: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts a frost bolt."); fire_bolt_or_beam(Ind, beam-10, GF_COLD, dir, damroll(5+((plev-5)/4), 8)); break; } case SPELL_TURN_STONE_TO_MUD: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s makes a moving gesture."); (void)wall_to_mud(Ind, dir); break; } case SPELL_SATISFY_HUNGER: { (void)set_food(Ind, PY_FOOD_MAX - 1); break; } case SPELL_RECHARGE_ITEM_I: { return recharge(Ind, 2 + plev / 5); } case SPELL_WONDER: /* wonder */ { if (!get_aim_dir(Ind, &dir)) return (FALSE); (void)spell_wonder(Ind, dir); break; } case SPELL_POLYMORPH_OTHER: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s discharges an everchanging blast of energy."); (void)poly_monster(Ind, dir); break; } case SPELL_IDENTIFY: { return ident_spell(Ind); } case SPELL_MASS_SLEEP: { (void)sleep_monsters(Ind); break; } case SPELL_FIRE_BOLT: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts a fire bolt."); fire_bolt_or_beam(Ind, beam, GF_FIRE, dir, damroll(6+((plev-5)/4), 8)); break; } case SPELL_SLOW_MONSTER: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s makes a lengthy gesture."); (void)slow_monster(Ind, dir); break; } case SPELL_FROST_BALL: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts a frost ball."); fire_ball(Ind, GF_COLD, dir, 30 + (plev), 2); break; } case SPELL_RECHARGE_ITEM_II: /* greater recharging */ { return recharge(Ind, 50 + plev); } case SPELL_TELEPORT_OTHER: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s makes a rush gesture."); (void)teleport_monster(Ind, dir); break; } case SPELL_BEDLAM: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s creates confusion."); fire_ball(Ind, GF_OLD_CONF, dir, plev, 4); break; } case SPELL_FIRE_BALL: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts a fire ball."); fire_ball(Ind, GF_FIRE, dir, 55 + (plev), 2); break; } case SPELL_WORD_OF_DESTRUCTION: { msg_spell("%s unleashes great power!"); destroy_area(Depth, py, px, 15, TRUE); break; } case SPELL_BANISHMENT: { return banishment(Ind); break; } case SPELL_DOOR_CREATION: { (void)door_creation(Ind); break; } case SPELL_STAIR_CREATION: { (void)stair_creation(Ind); break; } case SPELL_TELEPORT_LEVEL: { (void)teleport_player_level(Ind); break; } case SPELL_EARTHQUAKE: { msg_spell("%s casts a spell, and the ground shakes!"); earthquake(Depth, py, px, 10); break; } case SPELL_WORD_OF_RECALL: { o_ptr = &p_ptr->inventory[get_spell_book(Ind, spell)]; set_recall(Ind, o_ptr); break; } case SPELL_ACID_BOLT: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts an acid bolt."); fire_bolt_or_beam(Ind, beam, GF_ACID, dir, damroll(8+((plev-5)/4), 8)); break; } case SPELL_CLOUD_KILL: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts a cloud of death."); fire_ball(Ind, GF_POIS, dir, 40 + (plev / 2), 3); break; } case SPELL_ACID_BALL: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts an acid ball."); fire_ball(Ind, GF_ACID, dir, 40 + (plev), 2); break; } case SPELL_ICE_STORM: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s invokes an ice storm."); fire_ball(Ind, GF_ICE, dir, 50 + (plev * 2), 3); break; } case SPELL_METEOR_SWARM: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts a meteor shower."); fire_swarm(Ind, 2 + plev / 20, GF_METEOR, dir, 30 + plev / 2, 1); break; } case SPELL_MANA_STORM: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts a mana ball."); fire_ball(Ind, GF_MANA, dir, 300 + (plev * 2), 3); break; } case SPELL_DETECT_INVISIBLE: { (void)detect_invisible(Ind, TRUE); break; } case SPELL_DETECT_ENCHANTMENT: { (void)detect_objects_magic(Ind); break; } case SPELL_SHOCK_WAVE: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts a shock wave."); fire_ball(Ind, GF_SOUND, dir, 10 + plev, 2); break; } case SPELL_EXPLOSION: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts an explosion."); fire_ball(Ind, GF_SHARDS, dir, 20 + (plev * 2), 2); break; } case SPELL_MASS_BANISHMENT: { (void)mass_banishment(Ind); break; } case SPELL_RESIST_FIRE: { (void)set_oppose_fire(Ind, p_ptr->oppose_fire + randint(20) + 20); break; } case SPELL_RESIST_COLD: { (void)set_oppose_cold(Ind, p_ptr->oppose_cold + randint(20) + 20); break; } case SPELL_ELEMENTAL_BRAND: /* elemental brand */ { if (!get_item(Ind, &dir, item_test(AMMO))) return (FALSE); (void)brand_ammo(Ind, dir); break; } case SPELL_RESIST_POISON: { (void)set_oppose_pois(Ind, p_ptr->oppose_pois + randint(20) + 20); break; } case SPELL_RESISTANCE: { int time = randint(20) + 20; (void)set_oppose_acid(Ind, p_ptr->oppose_acid + time); (void)set_oppose_elec(Ind, p_ptr->oppose_elec + time); (void)set_oppose_fire(Ind, p_ptr->oppose_fire + time); (void)set_oppose_cold(Ind, p_ptr->oppose_cold + time); (void)set_oppose_pois(Ind, p_ptr->oppose_pois + time); break; } case SPELL_HEROISM: { (void)hp_player(Ind, 10); (void)set_hero(Ind, p_ptr->hero + randint(25) + 25); (void)set_afraid(Ind, 0); break; } case SPELL_SHIELD: { msg_spell("%s forms a mystic shield."); (void)set_shield(Ind, p_ptr->shield + randint(20) + 30); break; } case SPELL_BERSERKER: { msg_spell("%s enters a battle rage!"); (void)hp_player(Ind, 30); (void)set_shero(Ind, p_ptr->shero + randint(25) + 25); (void)set_afraid(Ind, 0); break; } case SPELL_HASTE_SELF: { msg_spell("%s starts moving faster."); if (!p_ptr->fast) { (void)set_fast(Ind, randint(20) + plev); } else { (void)set_fast(Ind, p_ptr->fast + randint(5)); } break; } case SPELL_RIFT: { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("Space warps in a beam from %s."); fire_beam(Ind, GF_GRAVITY, dir, 40 + damroll(plev, 7)); break; } case SPELL_REND_SOUL: /* rend soul */ { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts a nether ball."); fire_bolt_or_beam(Ind, beam / 4, GF_NETHER, dir, damroll(11, plev)); break; } case SPELL_CHAOS_STRIKE: /* chaos strike */ { if (!get_aim_dir(Ind, &dir)) return (FALSE); msg_spell("%s casts a ball of chaos."); fire_bolt_or_beam(Ind, beam, GF_CHAOS, dir, damroll(13, plev)); break; } case SPELL_RUNE_OF_PROTECTION: /* rune of protection */ { if (warding_glyph(Ind)) { msg_spell("%s lays down a rune of protection."); } break; } case SPELL_ENCHANT_ARMOR: /* enchant armor */ { return enchant_spell(Ind, 0, 0, rand_int(3) + plev / 20); } case SPELL_ENCHANT_WEAPON: /* enchant weapon */ { return enchant_spell(Ind, rand_int(4) + plev / 20, rand_int(4) + plev / 20, 0); } } /* Success */ return (TRUE); }
static bool aim_wand(object_type *o_ptr, bool *ident) { int lev, chance, dir, sval; /* Allow direction to be cancelled for free */ if (!get_aim_dir(&dir)) return (FALSE); /* Take a turn */ p_ptr->energy_use = 100; /* Not identified yet */ *ident = FALSE; /* Get the level */ lev = k_info[o_ptr->k_idx].level; /* Base chance of success */ chance = p_ptr->skill_dev; /* Confusion hurts skill */ if (p_ptr->confused) chance = chance / 2; /* High level objects are harder */ chance = chance - ((lev > 50) ? 50 : lev); /* Give everyone a (slight) chance */ if ((chance < USE_DEVICE) && (rand_int(USE_DEVICE - chance + 1) == 0)) { chance = USE_DEVICE; } /* Roll for usage */ if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE)) { if (flush_failure) flush(); msg_print("You failed to use the wand properly."); return (FALSE); } /* The wand is already empty! */ if (o_ptr->pval <= 0) { if (flush_failure) flush(); msg_print("The wand has no charges left."); o_ptr->ident |= (IDENT_EMPTY); p_ptr->notice |= (PN_COMBINE | PN_REORDER); p_ptr->window |= (PW_INVEN); return (FALSE); } /* Sound */ sound(MSG_ZAP); /* XXX Hack -- Extract the "sval" effect */ sval = o_ptr->sval; /* XXX Hack -- Wand of wonder can do anything before it */ if (sval == SV_WAND_WONDER) sval = rand_int(SV_WAND_WONDER); /* Analyze the wand */ switch (sval) { case SV_WAND_HEAL_MONSTER: { if (heal_monster(dir)) *ident = TRUE; break; } case SV_WAND_HASTE_MONSTER: { if (speed_monster(dir)) *ident = TRUE; break; } case SV_WAND_CLONE_MONSTER: { if (clone_monster(dir)) *ident = TRUE; break; } case SV_WAND_TELEPORT_AWAY: { if (teleport_monster(dir)) *ident = TRUE; break; } case SV_WAND_DISARMING: { if (disarm_trap(dir)) *ident = TRUE; break; } case SV_WAND_TRAP_DOOR_DEST: { if (destroy_door(dir)) *ident = TRUE; break; } case SV_WAND_STONE_TO_MUD: { if (wall_to_mud(dir)) *ident = TRUE; break; } case SV_WAND_LITE: { msg_print("A line of blue shimmering light appears."); lite_line(dir); *ident = TRUE; break; } case SV_WAND_SLEEP_MONSTER: { if (sleep_monster(dir)) *ident = TRUE; break; } case SV_WAND_SLOW_MONSTER: { if (slow_monster(dir)) *ident = TRUE; break; } case SV_WAND_CONFUSE_MONSTER: { if (confuse_monster(dir, 10)) *ident = TRUE; break; } case SV_WAND_FEAR_MONSTER: { if (fear_monster(dir, 10)) *ident = TRUE; break; } case SV_WAND_DRAIN_LIFE: { if (drain_life(dir, 150)) *ident = TRUE; break; } case SV_WAND_POLYMORPH: { if (poly_monster(dir)) *ident = TRUE; break; } case SV_WAND_STINKING_CLOUD: { fire_ball(GF_POIS, dir, 12, 2); *ident = TRUE; break; } case SV_WAND_MAGIC_MISSILE: { fire_bolt_or_beam(20, GF_MISSILE, dir, damroll(3, 4)); *ident = TRUE; break; } case SV_WAND_ACID_BOLT: { fire_bolt_or_beam(20, GF_ACID, dir, damroll(10, 8)); *ident = TRUE; break; } case SV_WAND_ELEC_BOLT: { fire_bolt_or_beam(20, GF_ELEC, dir, damroll(6, 6)); *ident = TRUE; break; } case SV_WAND_FIRE_BOLT: { fire_bolt_or_beam(20, GF_FIRE, dir, damroll(12, 8)); *ident = TRUE; break; } case SV_WAND_COLD_BOLT: { fire_bolt_or_beam(20, GF_COLD, dir, damroll(6, 8)); *ident = TRUE; break; } case SV_WAND_ACID_BALL: { fire_ball(GF_ACID, dir, 120, 2); *ident = TRUE; break; } case SV_WAND_ELEC_BALL: { fire_ball(GF_ELEC, dir, 64, 2); *ident = TRUE; break; } case SV_WAND_FIRE_BALL: { fire_ball(GF_FIRE, dir, 144, 2); *ident = TRUE; break; } case SV_WAND_COLD_BALL: { fire_ball(GF_COLD, dir, 96, 2); *ident = TRUE; break; } case SV_WAND_WONDER: { msg_print("Oops. Wand of wonder activated."); break; } case SV_WAND_DRAGON_FIRE: { fire_ball(GF_FIRE, dir, 200, 3); *ident = TRUE; break; } case SV_WAND_DRAGON_COLD: { fire_ball(GF_COLD, dir, 160, 3); *ident = TRUE; break; } case SV_WAND_DRAGON_BREATH: { switch (randint(5)) { case 1: { fire_ball(GF_ACID, dir, 200, 3); break; } case 2: { fire_ball(GF_ELEC, dir, 160, 3); break; } case 3: { fire_ball(GF_FIRE, dir, 200, 3); break; } case 4: { fire_ball(GF_COLD, dir, 160, 3); break; } default: { fire_ball(GF_POIS, dir, 120, 3); break; } } *ident = TRUE; break; } case SV_WAND_ANNIHILATION: { if (drain_life(dir, 250)) *ident = TRUE; break; } } return (TRUE); }
/*! * @brief 青魔法の発動 / * do_cmd_cast calls this function if the player's class is 'blue-mage'. * @param spell 発動するモンスター攻撃のID * @param success TRUEは成功時、FALSEは失敗時の処理を行う * @return 処理を実行したらTRUE、キャンセルした場合FALSEを返す。 */ static bool cast_learned_spell(int spell, bool success) { int dir; int plev = pseudo_plev(); int summon_lev = p_ptr->lev * 2 / 3 + randint1(p_ptr->lev/2); int damage = 0; bool pet = success; bool no_trump = FALSE; u32b p_mode, u_mode = 0L, g_mode; if (pet) { p_mode = PM_FORCE_PET; g_mode = 0; } else { p_mode = PM_NO_PET; g_mode = PM_ALLOW_GROUP; } if (!success || (randint1(50+plev) < plev/10)) u_mode = PM_ALLOW_UNIQUE; /* spell code */ switch (spell) { case MS_SHRIEK: msg_print(_("かん高い金切り声をあげた。", "You make a high pitched shriek.")); aggravate_monsters(0); break; case MS_XXX1: break; case MS_DISPEL: { int m_idx; if (!target_set(TARGET_KILL)) return FALSE; m_idx = cave[target_row][target_col].m_idx; if (!m_idx) break; if (!player_has_los_bold(target_row, target_col)) break; if (!projectable(p_ptr->y, p_ptr->x, target_row, target_col)) break; dispel_monster_status(m_idx); break; } case MS_ROCKET: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("ロケットを発射した。", "You fire a rocket.")); damage = monspell_bluemage_damage((MS_ROCKET), plev, DAM_ROLL); fire_rocket(GF_ROCKET, dir, damage, 2); break; case MS_SHOOT: { if (!get_aim_dir(&dir)) return FALSE; msg_print(_("矢を放った。", "You fire an arrow.")); damage = monspell_bluemage_damage((MS_SHOOT), plev, DAM_ROLL); fire_bolt(GF_ARROW, dir, damage); break; } case MS_XXX2: break; case MS_XXX3: break; case MS_XXX4: break; case MS_BR_ACID: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("酸のブレスを吐いた。", "You breathe acid.")); damage = monspell_bluemage_damage((MS_BR_ACID), plev, DAM_ROLL); fire_ball(GF_ACID, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_ELEC: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("稲妻のブレスを吐いた。", "You breathe lightning.")); damage = monspell_bluemage_damage((MS_BR_ELEC), plev, DAM_ROLL); fire_ball(GF_ELEC, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_FIRE: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("火炎のブレスを吐いた。", "You breathe fire.")); damage = monspell_bluemage_damage((MS_BR_FIRE), plev, DAM_ROLL); fire_ball(GF_FIRE, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_COLD: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("冷気のブレスを吐いた。", "You breathe frost.")); damage = monspell_bluemage_damage((MS_BR_COLD), plev, DAM_ROLL); fire_ball(GF_COLD, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_POIS: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("ガスのブレスを吐いた。", "You breathe gas.")); damage = monspell_bluemage_damage((MS_BR_POIS), plev, DAM_ROLL); fire_ball(GF_POIS, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_NETHER: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("地獄のブレスを吐いた。", "You breathe nether.")); damage = monspell_bluemage_damage((MS_BR_NETHER), plev, DAM_ROLL); fire_ball(GF_NETHER, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_LITE: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("閃光のブレスを吐いた。", "You breathe light.")); damage = monspell_bluemage_damage((MS_BR_LITE), plev, DAM_ROLL); fire_ball(GF_LITE, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_DARK: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("暗黒のブレスを吐いた。", "You breathe darkness.")); damage = monspell_bluemage_damage((MS_BR_DARK), plev, DAM_ROLL); fire_ball(GF_DARK, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_CONF: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("混乱のブレスを吐いた。", "You breathe confusion.")); damage = monspell_bluemage_damage((MS_BR_CONF), plev, DAM_ROLL); fire_ball(GF_CONFUSION, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_SOUND: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("轟音のブレスを吐いた。", "You breathe sound.")); damage = monspell_bluemage_damage((MS_BR_SOUND), plev, DAM_ROLL); fire_ball(GF_SOUND, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_CHAOS: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("カオスのブレスを吐いた。", "You breathe chaos.")); damage = monspell_bluemage_damage((MS_BR_CHAOS), plev, DAM_ROLL); fire_ball(GF_CHAOS, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_DISEN: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("劣化のブレスを吐いた。", "You breathe disenchantment.")); damage = monspell_bluemage_damage((MS_BR_DISEN), plev, DAM_ROLL); fire_ball(GF_DISENCHANT, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_NEXUS: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("因果混乱のブレスを吐いた。", "You breathe nexus.")); damage = monspell_bluemage_damage((MS_BR_NEXUS), plev, DAM_ROLL); fire_ball(GF_NEXUS, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_TIME: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("時間逆転のブレスを吐いた。", "You breathe time.")); damage = monspell_bluemage_damage((MS_BR_TIME), plev, DAM_ROLL); fire_ball(GF_TIME, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_INERTIA: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("遅鈍のブレスを吐いた。", "You breathe inertia.")); damage = monspell_bluemage_damage((MS_BR_INERTIA), plev, DAM_ROLL); fire_ball(GF_INERTIAL, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_GRAVITY: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("重力のブレスを吐いた。", "You breathe gravity.")); damage = monspell_bluemage_damage((MS_BR_GRAVITY), plev, DAM_ROLL); fire_ball(GF_GRAVITY, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_SHARDS: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("破片のブレスを吐いた。", "You breathe shards.")); damage = monspell_bluemage_damage((MS_BR_SHARDS), plev, DAM_ROLL); fire_ball(GF_SHARDS, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_PLASMA: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("プラズマのブレスを吐いた。", "You breathe plasma.")); damage = monspell_bluemage_damage((MS_BR_PLASMA), plev, DAM_ROLL); fire_ball(GF_PLASMA, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_FORCE: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("フォースのブレスを吐いた。", "You breathe force.")); damage = monspell_bluemage_damage((MS_BR_FORCE), plev, DAM_ROLL); fire_ball(GF_FORCE, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BR_MANA: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("魔力のブレスを吐いた。", "You breathe mana.")); damage = monspell_bluemage_damage((MS_BR_MANA), plev, DAM_ROLL); fire_ball(GF_MANA, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BALL_NUKE: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("放射能球を放った。", "You cast a ball of radiation.")); damage = monspell_bluemage_damage((MS_BALL_NUKE), plev, DAM_ROLL); fire_ball(GF_NUKE, dir, damage, 2); break; case MS_BR_NUKE: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("放射性廃棄物のブレスを吐いた。", "You breathe toxic waste.")); damage = monspell_bluemage_damage((MS_BR_NUKE), plev, DAM_ROLL); fire_ball(GF_NUKE, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BALL_CHAOS: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("純ログルスを放った。", "You invoke a raw Logrus.")); damage = monspell_bluemage_damage((MS_BALL_CHAOS), plev, DAM_ROLL); fire_ball(GF_CHAOS, dir, damage, 4); break; case MS_BR_DISI: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("分解のブレスを吐いた。", "You breathe disintegration.")); damage = monspell_bluemage_damage((MS_BR_DISI), plev, DAM_ROLL); fire_ball(GF_DISINTEGRATE, dir, damage, (plev > 40 ? -3 : -2)); break; case MS_BALL_ACID: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("アシッド・ボールの呪文を唱えた。", "You cast an acid ball.")); damage = monspell_bluemage_damage((MS_BALL_ACID), plev, DAM_ROLL); fire_ball(GF_ACID, dir, damage, 2); break; case MS_BALL_ELEC: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("サンダー・ボールの呪文を唱えた。", "You cast a lightning ball.")); damage = monspell_bluemage_damage((MS_BALL_ELEC), plev, DAM_ROLL); fire_ball(GF_ELEC, dir, damage, 2); break; case MS_BALL_FIRE: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("ファイア・ボールの呪文を唱えた。", "You cast a fire ball.")); damage = monspell_bluemage_damage((MS_BALL_FIRE), plev, DAM_ROLL); fire_ball(GF_FIRE, dir, damage, 2); break; case MS_BALL_COLD: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("アイス・ボールの呪文を唱えた。", "You cast a frost ball.")); damage = monspell_bluemage_damage((MS_BALL_COLD), plev, DAM_ROLL); fire_ball(GF_COLD, dir, damage, 2); break; case MS_BALL_POIS: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("悪臭雲の呪文を唱えた。", "You cast a stinking cloud.")); damage = monspell_bluemage_damage((MS_BALL_POIS), plev, DAM_ROLL); fire_ball(GF_POIS, dir, damage, 2); break; case MS_BALL_NETHER: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("地獄球の呪文を唱えた。", "You cast a nether ball.")); damage = monspell_bluemage_damage((MS_BALL_NETHER), plev, DAM_ROLL); fire_ball(GF_NETHER, dir, damage, 2); break; case MS_BALL_WATER: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("流れるような身振りをした。", "You gesture fluidly.")); damage = monspell_bluemage_damage((MS_BALL_WATER), plev, DAM_ROLL); fire_ball(GF_WATER, dir, damage, 4); break; case MS_BALL_MANA: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("魔力の嵐の呪文を念じた。", "You invoke a mana storm.")); damage = monspell_bluemage_damage((MS_BALL_MANA), plev, DAM_ROLL); fire_ball(GF_MANA, dir, damage, 4); break; case MS_BALL_DARK: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("暗黒の嵐の呪文を念じた。", "You invoke a darkness storm.")); damage = monspell_bluemage_damage((MS_BALL_DARK), plev, DAM_ROLL); fire_ball(GF_DARK, dir, damage, 4); break; case MS_DRAIN_MANA: if (!get_aim_dir(&dir)) return FALSE; damage = monspell_bluemage_damage((MS_DRAIN_MANA), plev, DAM_ROLL); fire_ball_hide(GF_DRAIN_MANA, dir, damage, 0); break; case MS_MIND_BLAST: if (!get_aim_dir(&dir)) return FALSE; damage = monspell_bluemage_damage((MS_MIND_BLAST), plev, DAM_ROLL); fire_ball_hide(GF_MIND_BLAST, dir, damage, 0); break; case MS_BRAIN_SMASH: if (!get_aim_dir(&dir)) return FALSE; damage = monspell_bluemage_damage((MS_BRAIN_SMASH), plev, DAM_ROLL); fire_ball_hide(GF_BRAIN_SMASH, dir, damage, 0); break; case MS_CAUSE_1: if (!get_aim_dir(&dir)) return FALSE; damage = monspell_bluemage_damage((MS_CAUSE_1), plev, DAM_ROLL); fire_ball_hide(GF_CAUSE_1, dir, damage, 0); break; case MS_CAUSE_2: if (!get_aim_dir(&dir)) return FALSE; damage = monspell_bluemage_damage((MS_CAUSE_2), plev, DAM_ROLL); fire_ball_hide(GF_CAUSE_2, dir, damage, 0); break; case MS_CAUSE_3: if (!get_aim_dir(&dir)) return FALSE; damage = monspell_bluemage_damage((MS_CAUSE_3), plev, DAM_ROLL); fire_ball_hide(GF_CAUSE_3, dir, damage, 0); break; case MS_CAUSE_4: if (!get_aim_dir(&dir)) return FALSE; damage = monspell_bluemage_damage((MS_CAUSE_4), plev, DAM_ROLL); fire_ball_hide(GF_CAUSE_4, dir, damage, 0); break; case MS_BOLT_ACID: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("アシッド・ボルトの呪文を唱えた。", "You cast an acid bolt.")); damage = monspell_bluemage_damage((MS_BOLT_ACID), plev, DAM_ROLL); fire_bolt(GF_ACID, dir, damage); break; case MS_BOLT_ELEC: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("サンダー・ボルトの呪文を唱えた。", "You cast a lightning bolt.")); damage = monspell_bluemage_damage((MS_BOLT_ELEC), plev, DAM_ROLL); fire_bolt(GF_ELEC, dir, damage); break; case MS_BOLT_FIRE: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("ファイア・ボルトの呪文を唱えた。", "You cast a fire bolt.")); damage = monspell_bluemage_damage((MS_BOLT_FIRE), plev, DAM_ROLL); fire_bolt(GF_FIRE, dir, damage); break; case MS_BOLT_COLD: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("アイス・ボルトの呪文を唱えた。", "You cast a frost bolt.")); damage = monspell_bluemage_damage((MS_BOLT_COLD), plev, DAM_ROLL); fire_bolt(GF_COLD, dir, damage); break; case MS_STARBURST: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("スターバーストの呪文を念じた。", "You invoke a starburst.")); damage = monspell_bluemage_damage((MS_STARBURST), plev, DAM_ROLL); fire_ball(GF_LITE, dir, damage, 4); break; case MS_BOLT_NETHER: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("地獄の矢の呪文を唱えた。", "You cast a nether bolt.")); damage = monspell_bluemage_damage((MS_BOLT_NETHER), plev, DAM_ROLL); fire_bolt(GF_NETHER, dir, damage); break; case MS_BOLT_WATER: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("ウォーター・ボルトの呪文を唱えた。", "You cast a water bolt.")); damage = monspell_bluemage_damage((MS_BOLT_WATER), plev, DAM_ROLL); fire_bolt(GF_WATER, dir, damage); break; case MS_BOLT_MANA: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("魔力の矢の呪文を唱えた。", "You cast a mana bolt.")); damage = monspell_bluemage_damage((MS_BOLT_MANA), plev, DAM_ROLL); fire_bolt(GF_MANA, dir, damage); break; case MS_BOLT_PLASMA: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("プラズマ・ボルトの呪文を唱えた。", "You cast a plasma bolt.")); damage = monspell_bluemage_damage((MS_BOLT_PLASMA), plev, DAM_ROLL); fire_bolt(GF_PLASMA, dir, damage); break; case MS_BOLT_ICE: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("極寒の矢の呪文を唱えた。", "You cast a ice bolt.")); damage = monspell_bluemage_damage((MS_BOLT_ICE), plev, DAM_ROLL); fire_bolt(GF_ICE, dir, damage); break; case MS_MAGIC_MISSILE: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("マジック・ミサイルの呪文を唱えた。", "You cast a magic missile.")); damage = monspell_bluemage_damage((MS_MAGIC_MISSILE), plev, DAM_ROLL); fire_bolt(GF_MISSILE, dir, damage); break; case MS_SCARE: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("恐ろしげな幻覚を作り出した。", "You cast a fearful illusion.")); fear_monster(dir, plev+10); break; case MS_BLIND: if (!get_aim_dir(&dir)) return FALSE; confuse_monster(dir, plev * 2); break; case MS_CONF: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("誘惑的な幻覚をつくり出した。", "You cast a mesmerizing illusion.")); confuse_monster(dir, plev * 2); break; case MS_SLOW: if (!get_aim_dir(&dir)) return FALSE; slow_monster(dir, plev); break; case MS_SLEEP: if (!get_aim_dir(&dir)) return FALSE; sleep_monster(dir, plev); break; case MS_SPEED: (void)set_fast(randint1(20 + plev) + plev, FALSE); break; case MS_HAND_DOOM: { if (!get_aim_dir(&dir)) return FALSE; msg_print(_("<破滅の手>を放った!", "You invoke the Hand of Doom!")); fire_ball_hide(GF_HAND_DOOM, dir, plev * 3, 0); break; } case MS_HEAL: msg_print(_("自分の傷に念を集中した。", "You concentrate on your wounds!")); (void)hp_player(plev*4); (void)set_stun(0); (void)set_cut(0); break; case MS_INVULNER: msg_print(_("無傷の球の呪文を唱えた。", "You cast a Globe of Invulnerability.")); (void)set_invuln(randint1(4) + 4, FALSE); break; case MS_BLINK: teleport_player(10, 0L); break; case MS_TELEPORT: teleport_player(plev * 5, 0L); break; case MS_WORLD: world_player = TRUE; msg_print(_("「時よ!」", "'Time!'")); msg_print(NULL); /* Hack */ p_ptr->energy_need -= 1000 + (100 + randint1(200)+200)*TURNS_PER_TICK/10; /* Redraw map */ p_ptr->redraw |= (PR_MAP); /* Update monsters */ p_ptr->update |= (PU_MONSTERS); /* Window stuff */ p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON); handle_stuff(); break; case MS_SPECIAL: break; case MS_TELE_TO: { monster_type *m_ptr; monster_race *r_ptr; char m_name[80]; if (!target_set(TARGET_KILL)) return FALSE; if (!cave[target_row][target_col].m_idx) break; if (!player_has_los_bold(target_row, target_col)) break; if (!projectable(p_ptr->y, p_ptr->x, target_row, target_col)) break; m_ptr = &m_list[cave[target_row][target_col].m_idx]; r_ptr = &r_info[m_ptr->r_idx]; monster_desc(m_name, m_ptr, 0); if (r_ptr->flagsr & RFR_RES_TELE) { if ((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flagsr & RFR_RES_ALL)) { if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE; msg_format(_("%sには効果がなかった!", "%s is unaffected!"), m_name); break; } else if (r_ptr->level > randint1(100)) { if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE; msg_format(_("%sには耐性がある!", "%s resists!"), m_name); break; } } msg_format(_("%sを引き戻した。", "You command %s to return."), m_name); teleport_monster_to(cave[target_row][target_col].m_idx, p_ptr->y, p_ptr->x, 100, TELEPORT_PASSIVE); break; } case MS_TELE_AWAY: if (!get_aim_dir(&dir)) return FALSE; (void)fire_beam(GF_AWAY_ALL, dir, 100); break; case MS_TELE_LEVEL: { int target_m_idx; monster_type *m_ptr; monster_race *r_ptr; char m_name[80]; if (!target_set(TARGET_KILL)) return FALSE; target_m_idx = cave[target_row][target_col].m_idx; if (!target_m_idx) break; if (!player_has_los_bold(target_row, target_col)) break; if (!projectable(p_ptr->y, p_ptr->x, target_row, target_col)) break; m_ptr = &m_list[target_m_idx]; r_ptr = &r_info[m_ptr->r_idx]; monster_desc(m_name, m_ptr, 0); msg_format(_("%^sの足を指さした。", "You gesture at %^s's feet."), m_name); if ((r_ptr->flagsr & (RFR_EFF_RES_NEXU_MASK | RFR_RES_TELE)) || (r_ptr->flags1 & RF1_QUESTOR) || (r_ptr->level + randint1(50) > plev + randint1(60))) { msg_format(_("しかし効果がなかった!", "%^s is unaffected!"), m_name); } else teleport_level(target_m_idx); break; } case MS_PSY_SPEAR: if (!get_aim_dir(&dir)) return FALSE; msg_print(_("光の剣を放った。", "You throw a psycho-spear.")); damage = monspell_bluemage_damage((MS_PSY_SPEAR), plev, DAM_ROLL); (void)fire_beam(GF_PSY_SPEAR, dir, damage); break; case MS_DARKNESS: msg_print(_("暗闇の中で手を振った。", "You gesture in shadow.")); (void)unlite_area(10, 3); break; case MS_MAKE_TRAP: if (!target_set(TARGET_KILL)) return FALSE; msg_print(_("呪文を唱えて邪悪に微笑んだ。", "You cast a spell and cackle evilly.")); trap_creation(target_row, target_col); break; case MS_FORGET: msg_print(_("しかし何も起きなかった。", "Nothing happen.")); break; case MS_RAISE_DEAD: msg_print(_("死者復活の呪文を唱えた。", "You cast a animate dead.")); (void)animate_dead(0, p_ptr->y, p_ptr->x); break; case MS_S_KIN: { int k; msg_print(_("援軍を召喚した。", "You summon minions.")); for (k = 0;k < 1; k++) { if (summon_kin_player(summon_lev, p_ptr->y, p_ptr->x, (pet ? PM_FORCE_PET : 0L))) { if (!pet) msg_print(_("召喚された仲間は怒っている!", "Summoned fellows are angry!")); } else { no_trump = TRUE; } } break; } case MS_S_CYBER: { int k; msg_print(_("サイバーデーモンを召喚した!", "You summon a Cyberdemon!")); for (k = 0 ;k < 1 ; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_CYBER, p_mode)) { if (!pet) msg_print(_("召喚されたサイバーデーモンは怒っている!", "The summoned Cyberdemon are angry!")); } else { no_trump = TRUE; } break; } case MS_S_MONSTER: { int k; msg_print(_("仲間を召喚した。", "You summon help.")); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, 0, p_mode)) { if (!pet) msg_print(_("召喚されたモンスターは怒っている!", "The summoned monster is angry!")); } else { no_trump = TRUE; } break; } case MS_S_MONSTERS: { int k; msg_print(_("モンスターを召喚した!", "You summon monsters!")); for (k = 0;k < plev / 15 + 2; k++) if(summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, 0, (p_mode | u_mode))) { if (!pet) msg_print(_("召喚されたモンスターは怒っている!", "The summoned monsters are angry!")); } else { no_trump = TRUE; } break; } case MS_S_ANT: { int k; msg_print(_("アリを召喚した。", "You summon ants.")); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_ANT, (PM_ALLOW_GROUP | p_mode))) { if (!pet) msg_print(_("召喚されたアリは怒っている!", "The summoned ants are angry!")); } else { no_trump = TRUE; } break; } case MS_S_SPIDER: { int k; msg_print(_("蜘蛛を召喚した。", "You summon spiders.")); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_SPIDER, (PM_ALLOW_GROUP | p_mode))) { if (!pet) msg_print(_("召喚された蜘蛛は怒っている!", "Summoned spiders are angry!")); } else { no_trump = TRUE; } break; } case MS_S_HOUND: { int k; msg_print(_("ハウンドを召喚した。", "You summon hounds.")); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_HOUND, (PM_ALLOW_GROUP | p_mode))) { if (!pet) msg_print(_("召喚されたハウンドは怒っている!", "Summoned hounds are angry!")); } else { no_trump = TRUE; } break; } case MS_S_HYDRA: { int k; msg_print(_("ヒドラを召喚した。", "You summon a hydras.")); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_HYDRA, (g_mode | p_mode))) { if (!pet) msg_print(_("召喚されたヒドラは怒っている!", "Summoned hydras are angry!")); } else { no_trump = TRUE; } break; } case MS_S_ANGEL: { int k; msg_print(_("天使を召喚した!", "You summon an angel!")); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_ANGEL, (g_mode | p_mode))) { if (!pet) msg_print(_("召喚された天使は怒っている!", "Summoned angels are angry!")); } else { no_trump = TRUE; } break; } case MS_S_DEMON: { int k; msg_print(_("混沌の宮廷から悪魔を召喚した!", "You summon a demon from the Courts of Chaos!")); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_DEMON, (g_mode | p_mode))) { if (!pet) msg_print(_("召喚されたデーモンは怒っている!", "Summoned demons are angry!")); } else { no_trump = TRUE; } break; } case MS_S_UNDEAD: { int k; msg_print(_("アンデッドの強敵を召喚した!", "You summon an undead adversary!")); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_UNDEAD, (g_mode | p_mode))) { if (!pet) msg_print(_("召喚されたアンデッドは怒っている!", "Summoned undeads are angry!")); } else { no_trump = TRUE; } break; } case MS_S_DRAGON: { int k; msg_print(_("ドラゴンを召喚した!", "You summon a dragon!")); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_DRAGON, (g_mode | p_mode))) { if (!pet) msg_print(_("召喚されたドラゴンは怒っている!", "Summoned dragons are angry!")); } else { no_trump = TRUE; } break; } case MS_S_HI_UNDEAD: { int k; msg_print(_("強力なアンデッドを召喚した!", "You summon a greater undead!")); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_HI_UNDEAD, (g_mode | p_mode | u_mode))) { if (!pet) msg_print(_("召喚された上級アンデッドは怒っている!", "Summoned greater undeads are angry!")); } else { no_trump = TRUE; } break; } case MS_S_HI_DRAGON: { int k; msg_print(_("古代ドラゴンを召喚した!", "You summon an ancient dragon!")); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_HI_DRAGON, (g_mode | p_mode | u_mode))) { if (!pet) msg_print(_("召喚された古代ドラゴンは怒っている!", "Summoned ancient dragons are angry!")); } else { no_trump = TRUE; } break; } case MS_S_AMBERITE: { int k; msg_print(_("アンバーの王族を召喚した!", "You summon a Lord of Amber!")); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_AMBERITES, (g_mode | p_mode | u_mode))) { if (!pet) msg_print(_("召喚されたアンバーの王族は怒っている!", "Summoned Lords of Amber are angry!")); } else { no_trump = TRUE; } break; } case MS_S_UNIQUE: { int k, count = 0; msg_print(_("特別な強敵を召喚した!", "You summon a special opponent!")); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_UNIQUE, (g_mode | p_mode | PM_ALLOW_UNIQUE))) { count++; if (!pet) msg_print(_("召喚されたユニーク・モンスターは怒っている!", "Summoned special opponents are angry!")); } for (k = count;k < 1; k++) if (summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, summon_lev, SUMMON_HI_UNDEAD, (g_mode | p_mode | PM_ALLOW_UNIQUE))) { count++; if (!pet) msg_print(_("召喚された上級アンデッドは怒っている!", "Summoned greater undeads are angry!")); } if (!count) { no_trump = TRUE; } break; } default: msg_print("hoge?"); } if (no_trump) { msg_print(_("何も現れなかった。", "No one have appeared.")); } return TRUE; }
/* * do_cmd_cast calls this function if the player's class * is 'imitator'. */ static bool cast_learned_spell(int spell, bool success) { int dir; int plev = pseudo_plev(); int summon_lev = p_ptr->lev * 2 / 3 + randint1(p_ptr->lev/2); int hp = p_ptr->chp; int damage = 0; bool pet = success; bool no_trump = FALSE; u32b p_mode, u_mode = 0L, g_mode; if (pet) { p_mode = PM_FORCE_PET; g_mode = 0; } else { p_mode = PM_NO_PET; g_mode = PM_ALLOW_GROUP; } if (!success || (randint1(50+plev) < plev/10)) u_mode = PM_ALLOW_UNIQUE; /* spell code */ switch (spell) { case MS_SHRIEK: msg_print("You make a high pitched shriek."); aggravate_monsters(0); break; case MS_XXX1: break; case MS_DISPEL: { int m_idx; if (!target_set(TARGET_KILL)) return FALSE; m_idx = cave[target_row][target_col].m_idx; if (!m_idx) break; if (!player_has_los_bold(target_row, target_col)) break; if (!projectable(py, px, target_row, target_col)) break; dispel_monster_status(m_idx); break; } case MS_ROCKET: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You fire a rocket."); damage = hp / 4; fire_rocket(GF_ROCKET, dir, spell_power(damage), 2); break; case MS_SHOOT: { int slot; if (!get_aim_dir(&dir)) return FALSE; msg_print("You fire an arrow."); damage = 1; slot = equip_find_first(object_is_melee_weapon); if (slot) { object_type *o_ptr = equip_obj(slot); damage = damroll(o_ptr->dd, o_ptr->ds)+ o_ptr->to_d; if (damage < 1) damage = 1; } fire_bolt(GF_ARROW, dir, spell_power(damage)); break; } case MS_XXX2: break; case MS_XXX3: break; case MS_BR_STORM: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe storm."); damage = MIN(hp / 3, 300); fire_ball(GF_STORM, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_ACID: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe acid."); damage = hp / 3; fire_ball(GF_ACID, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_ELEC: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe lightning."); damage = hp / 3; fire_ball(GF_ELEC, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_FIRE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe fire."); damage = hp / 3; fire_ball(GF_FIRE, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_COLD: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe frost."); damage = hp / 3; fire_ball(GF_COLD, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_POIS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe gas."); damage = hp / 3; fire_ball(GF_POIS, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_NETHER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe nether."); damage = hp / 6; fire_ball(GF_NETHER, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_LITE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe light."); damage = hp / 6; fire_ball(GF_LITE, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_DARK: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe darkness."); damage = hp / 6; fire_ball(GF_DARK, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_CONF: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe confusion."); damage = hp / 6; fire_ball(GF_CONFUSION, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_SOUND: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe sound."); damage = hp / 6; fire_ball(GF_SOUND, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_CHAOS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe chaos."); damage = hp / 6; fire_ball(GF_CHAOS, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_DISEN: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe disenchantment."); damage = hp / 6; fire_ball(GF_DISENCHANT, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_NEXUS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe nexus."); damage = MIN(hp / 3, 250); fire_ball(GF_NEXUS, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_TIME: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe time."); damage = MIN(hp / 3, 150); fire_ball(GF_TIME, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_INERTIA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe inertia."); damage = MIN(hp / 6, 200); fire_ball(GF_INERT, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_GRAVITY: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe gravity."); damage = MIN(hp / 3, 200); fire_ball(GF_GRAVITY, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_SHARDS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe shards."); damage = hp / 6; fire_ball(GF_SHARDS, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_PLASMA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe plasma."); damage = MIN(hp / 6, 150); fire_ball(GF_PLASMA, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_FORCE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe force."); damage = MIN(hp / 6, 200); fire_ball(GF_FORCE, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BR_MANA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe mana."); damage = MIN(hp / 3, 250); fire_ball(GF_MANA, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BALL_NUKE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a ball of radiation."); damage = plev * 2 + damroll(10, 6); fire_ball(GF_NUKE, dir, spell_power(damage), 2); break; case MS_BR_NUKE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe toxic waste."); damage = hp / 3; fire_ball(GF_NUKE, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BALL_CHAOS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke a raw Logrus."); damage = plev * 4 + damroll(10, 10); fire_ball(GF_CHAOS, dir, spell_power(damage), 4); break; case MS_BR_DISI: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe disintegration."); damage = MIN(hp / 6, 150); fire_ball(GF_DISINTEGRATE, dir, spell_power(damage), (plev > 40 ? -3 : -2)); break; case MS_BALL_ACID: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast an acid ball."); damage = randint1(plev * 6) + 15; fire_ball(GF_ACID, dir, spell_power(damage), 2); break; case MS_BALL_ELEC: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a lightning ball."); damage = randint1(plev * 3) + 8; fire_ball(GF_ELEC, dir, spell_power(damage), 2); break; case MS_BALL_FIRE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a fire ball."); damage = randint1(plev * 7) + 10; fire_ball(GF_FIRE, dir, spell_power(damage), 2); break; case MS_BALL_COLD: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a frost ball."); damage = randint1(plev * 3) + 10; fire_ball(GF_COLD, dir, spell_power(damage), 2); break; case MS_BALL_POIS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a stinking cloud."); damage = damroll(12,2); fire_ball(GF_POIS, dir, spell_power(damage), 2); break; case MS_BALL_NETHER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a nether ball."); damage = plev * 2 + 50 + damroll(10, 10); fire_ball(GF_NETHER, dir, spell_power(damage), 2); break; case MS_BALL_WATER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You gesture fluidly."); damage = randint1(plev * 4) + 50; fire_ball(GF_WATER, dir, spell_power(damage), 4); break; case MS_BALL_MANA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke a mana storm."); damage = plev * 8 + 50 + damroll(10, 10); fire_ball(GF_MANA, dir, spell_power(damage), 4); break; case MS_BALL_DARK: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke a darkness storm."); damage = plev * 8 + 50 + damroll(10, 10); fire_ball(GF_DARK, dir, spell_power(damage), 4); break; case MS_DRAIN_MANA: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_DRAIN_MANA, dir, spell_power(randint1(plev)+plev), 0); break; case MS_MIND_BLAST: if (!get_aim_dir(&dir)) return FALSE; damage = damroll(7, 7); fire_ball_hide(GF_MIND_BLAST, dir, spell_power(damage), 0); break; case MS_BRAIN_SMASH: if (!get_aim_dir(&dir)) return FALSE; damage = damroll(12, 12); fire_ball_hide(GF_BRAIN_SMASH, dir, spell_power(damage), 0); break; case MS_CAUSE_1: if (!get_aim_dir(&dir)) return FALSE; damage = damroll(3, 8); fire_ball_hide(GF_CAUSE_1, dir, spell_power(damage), 0); break; case MS_CAUSE_2: if (!get_aim_dir(&dir)) return FALSE; damage = damroll(8, 8); fire_ball_hide(GF_CAUSE_2, dir, spell_power(damage), 0); break; case MS_CAUSE_3: if (!get_aim_dir(&dir)) return FALSE; damage = damroll(10, 15); fire_ball_hide(GF_CAUSE_3, dir, spell_power(damage), 0); break; case MS_CAUSE_4: if (!get_aim_dir(&dir)) return FALSE; damage = damroll(15, 15); fire_ball_hide(GF_CAUSE_4, dir, spell_power(damage), 0); break; case MS_BOLT_ACID: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast an acid bolt."); damage = damroll(7, 8) + plev * 2 / 3; fire_bolt(GF_ACID, dir, spell_power(damage)); break; case MS_BOLT_ELEC: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a lightning bolt."); damage = damroll(4, 8) + plev * 2 / 3; fire_bolt(GF_ELEC, dir, spell_power(damage)); break; case MS_BOLT_FIRE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a fire bolt."); damage = damroll(9, 8) + plev * 2 / 3; fire_bolt(GF_FIRE, dir, spell_power(damage)); break; case MS_BOLT_COLD: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a frost bolt."); damage = damroll(6, 8) + plev * 2 / 3; fire_bolt(GF_COLD, dir, spell_power(damage)); break; case MS_STARBURST: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke a starburst."); damage = plev * 8 + 50 + damroll(10, 10); fire_ball(GF_LITE, dir, spell_power(damage), 4); break; case MS_BOLT_NETHER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a nether bolt."); damage = 30 + damroll(5, 5) + plev * 8 / 3; fire_bolt(GF_NETHER, dir, spell_power(damage)); break; case MS_BOLT_WATER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a water bolt."); damage = damroll(10, 10) + plev * 2; fire_bolt(GF_WATER, dir, spell_power(damage)); break; case MS_BOLT_MANA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a mana bolt."); damage = randint1(plev * 7) + 50; fire_bolt(GF_MANA, dir, spell_power(damage)); break; case MS_BOLT_PLASMA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a plasma bolt."); damage = 10 + damroll(8, 7) + plev * 2; fire_bolt(GF_PLASMA, dir, spell_power(damage)); break; case MS_BOLT_ICE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a ice bolt."); damage = damroll(6, 6) + plev * 2; fire_bolt(GF_ICE, dir, spell_power(damage)); break; case MS_MAGIC_MISSILE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a magic missile."); damage = damroll(2, 6) + plev * 2 / 3; fire_bolt(GF_MISSILE, dir, spell_power(damage)); break; case MS_SCARE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a fearful illusion."); fear_monster(dir, spell_power(plev+10)); break; case MS_BLIND: if (!get_aim_dir(&dir)) return FALSE; confuse_monster(dir, spell_power(plev * 2)); break; case MS_CONF: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a mesmerizing illusion."); confuse_monster(dir, spell_power(plev * 2)); break; case MS_SLOW: if (!get_aim_dir(&dir)) return FALSE; slow_monster(dir); break; case MS_SLEEP: if (!get_aim_dir(&dir)) return FALSE; sleep_monster(dir, plev*3); break; case MS_SPEED: (void)set_fast(randint1(20 + plev) + plev, FALSE); break; case MS_HAND_DOOM: { if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke the Hand of Doom!"); fire_ball_hide(GF_HAND_DOOM, dir, spell_power(plev * 3), 0); break; } case MS_HEAL: msg_print("You concentrate on your wounds!"); (void)hp_player(spell_power(plev*4)); (void)set_stun(0, TRUE); (void)set_cut(0, TRUE); break; case MS_INVULNER: msg_print("You cast a Globe of Invulnerability."); (void)set_invuln(spell_power(randint1(4) + 4), FALSE); break; case MS_BLINK: teleport_player(10, 0L); break; case MS_TELEPORT: teleport_player(plev * 5, 0L); break; case MS_WORLD: world_player = TRUE; msg_print("'Time!'"); msg_print(NULL); /* Hack */ p_ptr->energy_need -= 1000 + (100 + randint1(200)+200)*TURNS_PER_TICK/10; /* Redraw map */ p_ptr->redraw |= (PR_MAP | PR_STATUS); /* Update monsters */ p_ptr->update |= (PU_MONSTERS); /* Window stuff */ p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON); handle_stuff(); break; case MS_SPECIAL: break; case MS_TELE_TO: { monster_type *m_ptr; monster_race *r_ptr; char m_name[80]; if (!target_set(TARGET_KILL)) return FALSE; if (!cave[target_row][target_col].m_idx) break; if (!player_has_los_bold(target_row, target_col)) break; if (!projectable(py, px, target_row, target_col)) break; m_ptr = &m_list[cave[target_row][target_col].m_idx]; r_ptr = &r_info[m_ptr->r_idx]; monster_desc(m_name, m_ptr, 0); if (r_ptr->flagsr & RFR_RES_TELE) { if ((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flagsr & RFR_RES_ALL)) { if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE; msg_format("%s is unaffected!", m_name); break; } else if (r_ptr->level > randint1(100)) { if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE; msg_format("%s resists!", m_name); break; } } msg_format("You command %s to return.", m_name); teleport_monster_to(cave[target_row][target_col].m_idx, py, px, 100, TELEPORT_PASSIVE); break; } case MS_TELE_AWAY: if (!get_aim_dir(&dir)) return FALSE; (void)fire_beam(GF_AWAY_ALL, dir, spell_power(100)); break; case MS_TELE_LEVEL: { int target_m_idx; monster_type *m_ptr; monster_race *r_ptr; char m_name[80]; if (!target_set(TARGET_KILL)) return FALSE; target_m_idx = cave[target_row][target_col].m_idx; if (!target_m_idx) break; if (!player_has_los_bold(target_row, target_col)) break; if (!projectable(py, px, target_row, target_col)) break; m_ptr = &m_list[target_m_idx]; r_ptr = &r_info[m_ptr->r_idx]; monster_desc(m_name, m_ptr, 0); msg_format("You gesture at %^s's feet.", m_name); if ((r_ptr->flagsr & (RFR_EFF_RES_NEXU_MASK | RFR_RES_TELE)) || (r_ptr->flags1 & RF1_QUESTOR) || (r_ptr->level + randint1(50) > plev + randint1(60))) { msg_format("%^s is unaffected!", m_name); } else teleport_level(target_m_idx); break; } case MS_PSY_SPEAR: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You throw a psycho-spear."); damage = randint1(plev * 3) + 100; (void)fire_beam(GF_PSY_SPEAR, dir, spell_power(damage)); break; case MS_DARKNESS: msg_print("You gesture in shadow."); (void)unlite_area(10, 3); break; case MS_MAKE_TRAP: if (!target_set(TARGET_KILL)) return FALSE; msg_print("You cast a spell and cackle evilly."); trap_creation(target_row, target_col); break; case MS_FORGET: msg_print("Nothing happen."); break; case MS_RAISE_DEAD: msg_print("You cast a animate dead."); (void)animate_dead(0, py, px); break; case MS_S_KIN: { int k; msg_print("You summon minions."); for (k = 0;k < 1; k++) { if (summon_kin_player(summon_lev, py, px, (pet ? PM_FORCE_PET : 0L))) { if (!pet) msg_print("Summoned fellows are angry!"); } else { no_trump = TRUE; } } break; } case MS_S_CYBER: { int k; msg_print("You summon a Cyberdemon!"); for (k = 0 ;k < 1 ; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_CYBER, p_mode)) { if (!pet) msg_print("The summoned Cyberdemon are angry!"); } else { no_trump = TRUE; } break; } case MS_S_MONSTER: { int k; msg_print("You summon help."); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, 0, p_mode)) { if (!pet) msg_print("The summoned monster is angry!"); } else { no_trump = TRUE; } break; } case MS_S_MONSTERS: { int k; msg_print("You summon monsters!"); for (k = 0;k < plev / 15 + 2; k++) if(summon_specific((pet ? -1 : 0), py, px, summon_lev, 0, (p_mode | u_mode))) { if (!pet) msg_print("Summoned monsters are angry!"); } else { no_trump = TRUE; } break; } case MS_S_ANT: { int k; msg_print("You summon ants."); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_ANT, (PM_ALLOW_GROUP | p_mode))) { if (!pet) msg_print("Summoned ants are angry!"); } else { no_trump = TRUE; } break; } case MS_S_SPIDER: { int k; msg_print("You summon spiders."); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_SPIDER, (PM_ALLOW_GROUP | p_mode))) { if (!pet) msg_print("Summoned spiders are angry!"); } else { no_trump = TRUE; } break; } case MS_S_HOUND: { int k; msg_print("You summon hounds."); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_HOUND, (PM_ALLOW_GROUP | p_mode))) { if (!pet) msg_print("Summoned hounds are angry!"); } else { no_trump = TRUE; } break; } case MS_S_HYDRA: { int k; msg_print("You summon a hydras."); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_HYDRA, (g_mode | p_mode))) { if (!pet) msg_print("Summoned hydras are angry!"); } else { no_trump = TRUE; } break; } case MS_S_ANGEL: { int k; msg_print("You summon an angel!"); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_ANGEL, (g_mode | p_mode))) { if (!pet) msg_print("Summoned angels are angry!"); } else { no_trump = TRUE; } break; } case MS_S_DEMON: { int k; msg_print("You summon a demon from the Courts of Chaos!"); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_DEMON, (g_mode | p_mode))) { if (!pet) msg_print("Summoned demons are angry!"); } else { no_trump = TRUE; } break; } case MS_S_UNDEAD: { int k; msg_print("You summon an undead adversary!"); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_UNDEAD, (g_mode | p_mode))) { if (!pet) msg_print("Summoned undeads are angry!"); } else { no_trump = TRUE; } break; } case MS_S_DRAGON: { int k; msg_print("You summon a dragon!"); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_DRAGON, (g_mode | p_mode))) { if (!pet) msg_print("Summoned dragons are angry!"); } else { no_trump = TRUE; } break; } case MS_S_HI_UNDEAD: { int k; msg_print("You summon a greater undead!"); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_HI_UNDEAD, (g_mode | p_mode | u_mode))) { if (!pet) msg_print("Summoned greater undeads are angry!"); } else { no_trump = TRUE; } break; } case MS_S_HI_DRAGON: { int k; msg_print("You summon an ancient dragon!"); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_HI_DRAGON, (g_mode | p_mode | u_mode))) { if (!pet) msg_print("Summoned ancient dragons are angry!"); } else { no_trump = TRUE; } break; } case MS_S_AMBERITE: { int k; msg_print("You summon a Lord of Amber!"); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_AMBERITE, (g_mode | p_mode | u_mode))) { if (!pet) msg_print("Summoned Lords of Amber are angry!"); } else { no_trump = TRUE; } break; } case MS_S_UNIQUE: { int k, count = 0; msg_print("You summon a special opponent!"); for (k = 0;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_UNIQUE, (g_mode | p_mode | PM_ALLOW_UNIQUE))) { count++; if (!pet) msg_print("Summoned special opponents are angry!"); } for (k = count;k < 1; k++) if (summon_specific((pet ? -1 : 0), py, px, summon_lev, SUMMON_HI_UNDEAD, (g_mode | p_mode | PM_ALLOW_UNIQUE))) { count++; if (!pet) msg_print("Summoned greater undeads are angry!"); } if (!count) { no_trump = TRUE; } break; } default: msg_print("hoge?"); } if (no_trump) { msg_print("No one have appeared."); } return TRUE; }
/* * do_cmd_cast calls this function if the player's class * is 'imitator'. */ static bool use_mane(int spell) { int dir; int plev = p_ptr->lev; u32b mode = (PM_ALLOW_GROUP | PM_FORCE_PET); u32b u_mode = 0L; if (randint1(50+plev) < plev/10) u_mode = PM_ALLOW_UNIQUE; /* spell code */ switch (spell) { case MS_SHRIEK: msg_print("You make a high pitched shriek."); aggravate_monsters(0); break; case MS_XXX1: break; case MS_DISPEL: { int m_idx; if (!target_set(TARGET_KILL)) return FALSE; m_idx = cave[target_row][target_col].m_idx; if (!m_idx) break; if (!player_has_los_bold(target_row, target_col)) break; if (!projectable(py, px, target_row, target_col)) break; dispel_monster_status(m_idx); break; } case MS_ROCKET: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You fire a rocket."); fire_rocket(GF_ROCKET, dir, damage, 2); break; case MS_SHOOT: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You fire an arrow."); fire_bolt(GF_ARROW, dir, damage); break; case MS_XXX2: break; case MS_XXX3: break; case MS_BR_STORM: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe storm."); fire_ball(GF_STORM, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_ACID: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe acid."); fire_ball(GF_ACID, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_ELEC: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe lightning."); fire_ball(GF_ELEC, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_FIRE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe fire."); fire_ball(GF_FIRE, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_COLD: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe frost."); fire_ball(GF_COLD, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_POIS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe gas."); fire_ball(GF_POIS, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_NETHER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe nether."); fire_ball(GF_NETHER, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_LITE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe light."); fire_ball(GF_LITE, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_DARK: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe darkness."); fire_ball(GF_DARK, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_CONF: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe confusion."); fire_ball(GF_CONFUSION, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_SOUND: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe sound."); fire_ball(GF_SOUND, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_CHAOS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe chaos."); fire_ball(GF_CHAOS, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_DISEN: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe disenchantment."); fire_ball(GF_DISENCHANT, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_NEXUS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe nexus."); fire_ball(GF_NEXUS, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_TIME: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe time."); fire_ball(GF_TIME, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_INERTIA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe inertia."); fire_ball(GF_INERT, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_GRAVITY: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe gravity."); fire_ball(GF_GRAVITY, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_SHARDS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe shards."); fire_ball(GF_SHARDS, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_PLASMA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe plasma."); fire_ball(GF_PLASMA, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_FORCE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe force."); fire_ball(GF_FORCE, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_MANA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe mana."); fire_ball(GF_MANA, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BALL_NUKE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a ball of radiation."); fire_ball(GF_NUKE, dir, damage, 2); break; case MS_BR_NUKE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe toxic waste."); fire_ball(GF_NUKE, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BALL_CHAOS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke a raw Logrus."); fire_ball(GF_CHAOS, dir, damage, 4); break; case MS_BR_DISI: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe disintegration."); fire_ball(GF_DISINTEGRATE, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BALL_ACID: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast an acid ball."); fire_ball(GF_ACID, dir, damage, 2); break; case MS_BALL_ELEC: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a lightning ball."); fire_ball(GF_ELEC, dir, damage, 2); break; case MS_BALL_FIRE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a fire ball."); fire_ball(GF_FIRE, dir, damage, 2); break; case MS_BALL_COLD: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a frost ball."); fire_ball(GF_COLD, dir, damage, 2); break; case MS_BALL_POIS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a stinking cloud."); fire_ball(GF_POIS, dir, damage, 2); break; case MS_BALL_NETHER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a nether ball."); fire_ball(GF_NETHER, dir, damage, 2); break; case MS_BALL_WATER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You gesture fluidly."); fire_ball(GF_WATER, dir, damage, 4); break; case MS_BALL_MANA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke a mana storm."); fire_ball(GF_MANA, dir, damage, 4); break; case MS_BALL_DARK: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke a darkness storm."); fire_ball(GF_DARK, dir, damage, 4); break; case MS_DRAIN_MANA: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_DRAIN_MANA, dir, randint1(plev*3)+plev, 0); break; case MS_MIND_BLAST: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_MIND_BLAST, dir, damage, 0); break; case MS_BRAIN_SMASH: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_BRAIN_SMASH, dir, damage, 0); break; case MS_CAUSE_1: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_CAUSE_1, dir, damage, 0); break; case MS_CAUSE_2: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_CAUSE_2, dir, damage, 0); break; case MS_CAUSE_3: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_CAUSE_3, dir, damage, 0); break; case MS_CAUSE_4: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_CAUSE_4, dir, damage, 0); break; case MS_BOLT_ACID: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast an acid bolt."); fire_bolt(GF_ACID, dir, damage); break; case MS_BOLT_ELEC: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a lightning bolt."); fire_bolt(GF_ELEC, dir, damage); break; case MS_BOLT_FIRE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a fire bolt."); fire_bolt(GF_FIRE, dir, damage); break; case MS_BOLT_COLD: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a frost bolt."); fire_bolt(GF_COLD, dir, damage); break; case MS_STARBURST: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke a starburst."); fire_ball(GF_LITE, dir, damage, 4); break; case MS_BOLT_NETHER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a nether bolt."); fire_bolt(GF_NETHER, dir, damage); break; case MS_BOLT_WATER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a water bolt."); fire_bolt(GF_WATER, dir, damage); break; case MS_BOLT_MANA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a mana bolt."); fire_bolt(GF_MANA, dir, damage); break; case MS_BOLT_PLASMA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a plasma bolt."); fire_bolt(GF_PLASMA, dir, damage); break; case MS_BOLT_ICE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a ice bolt."); fire_bolt(GF_ICE, dir, damage); break; case MS_MAGIC_MISSILE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a magic missile."); fire_bolt(GF_MISSILE, dir, damage); break; case MS_SCARE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a fearful illusion."); fear_monster(dir, plev+10); break; case MS_BLIND: if (!get_aim_dir(&dir)) return FALSE; confuse_monster(dir, plev * 2); break; case MS_CONF: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a mesmerizing illusion."); confuse_monster(dir, plev * 2); break; case MS_SLOW: if (!get_aim_dir(&dir)) return FALSE; slow_monster(dir); break; case MS_SLEEP: if (!get_aim_dir(&dir)) return FALSE; sleep_monster(dir, plev*3); break; case MS_SPEED: (void)set_fast(randint1(20 + plev) + plev, FALSE); break; case MS_HAND_DOOM: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke the Hand of Doom!"); fire_ball_hide(GF_HAND_DOOM, dir, 200, 0); break; case MS_HEAL: msg_print("You concentrate on your wounds!"); (void)hp_player(plev*6); (void)set_stun(0, TRUE); (void)set_cut(0, TRUE); break; case MS_INVULNER: msg_print("You cast a Globe of Invulnerability."); (void)set_invuln(randint1(7) + 7, FALSE); break; case MS_BLINK: if (mut_present(MUT_ASTRAL_GUIDE)) energy_use = 30; teleport_player(10, 0L); break; case MS_TELEPORT: if (mut_present(MUT_ASTRAL_GUIDE)) energy_use = 30; teleport_player(plev * 5, 0L); break; case MS_WORLD: world_player = TRUE; if (damage == 1 || damage == 2) msg_print("You yell 'The World! Time has stopped!'"); else if (damage == 3 || damage == 6) msg_print("You yell 'Time!'"); else msg_print("hek!"); msg_print(NULL); p_ptr->energy_need -= 1000 + (100 + randint1(200)+200)*TURNS_PER_TICK/10; p_ptr->redraw |= (PR_MAP); p_ptr->update |= (PU_MONSTERS); p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON); handle_stuff(); break; case MS_SPECIAL: break; case MS_TELE_TO: { monster_type *m_ptr; monster_race *r_ptr; char m_name[80]; if (!target_set(TARGET_KILL)) return FALSE; if (!cave[target_row][target_col].m_idx) break; if (!player_has_los_bold(target_row, target_col)) break; if (!projectable(py, px, target_row, target_col)) break; m_ptr = &m_list[cave[target_row][target_col].m_idx]; r_ptr = &r_info[m_ptr->r_idx]; monster_desc(m_name, m_ptr, 0); if (r_ptr->flagsr & RFR_RES_TELE) { if ((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flagsr & RFR_RES_ALL)) { if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE; msg_format("%s is unaffected!", m_name); break; } else if (r_ptr->level > randint1(100)) { if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE; msg_format("%s resists!", m_name); break; } } msg_format("You command %s to return.", m_name); teleport_monster_to(cave[target_row][target_col].m_idx, py, px, 100, TELEPORT_PASSIVE); break; } case MS_TELE_AWAY: if (!get_aim_dir(&dir)) return FALSE; (void)fire_beam(GF_AWAY_ALL, dir, plev); break; case MS_TELE_LEVEL: { int target_m_idx; monster_type *m_ptr; monster_race *r_ptr; char m_name[80]; if (!target_set(TARGET_KILL)) return FALSE; target_m_idx = cave[target_row][target_col].m_idx; if (!target_m_idx) break; if (!player_has_los_bold(target_row, target_col)) break; if (!projectable(py, px, target_row, target_col)) break; m_ptr = &m_list[target_m_idx]; r_ptr = &r_info[m_ptr->r_idx]; monster_desc(m_name, m_ptr, 0); msg_format("You gesture at %^s's feet.", m_name); if ((r_ptr->flagsr & (RFR_EFF_RES_NEXU_MASK | RFR_RES_TELE)) || (r_ptr->flags1 & RF1_QUESTOR) || (r_ptr->level + randint1(50) > plev + randint1(60))) { msg_format("%^s is unaffected!", m_name); } else teleport_level(target_m_idx); break; } case MS_PSY_SPEAR: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You throw a psycho-spear."); fire_beam(GF_PSY_SPEAR, dir, damage); break; case MS_DARKNESS: msg_print("You gesture in shadow."); unlite_area(10, 3); break; case MS_MAKE_TRAP: if (!target_set(TARGET_KILL)) return FALSE; msg_print("You cast a spell and cackle evilly."); trap_creation(target_row, target_col); break; case MS_FORGET: msg_print("Nothing happens."); /* TODO: forget_spell(m_idx) ... */ break; case MS_RAISE_DEAD: msg_print("You cast a animate dead."); animate_dead(0, py, px); break; case MS_S_KIN: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon minions."); for (k = 0;k < 4; k++) { (void)summon_kin_player(plev, target_row, target_col, (PM_FORCE_PET | PM_ALLOW_GROUP)); } break; } case MS_S_CYBER: { int k; int max_cyber = (dun_level / 50) + randint1(3); if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon Cyberdemons!"); if (max_cyber > 4) max_cyber = 4; for (k = 0;k < max_cyber; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_CYBER, mode); break; } case MS_S_MONSTER: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon help."); for (k = 0;k < 1; k++) summon_specific(-1, target_row, target_col, plev, 0, (mode | u_mode)); break; } case MS_S_MONSTERS: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon monsters!"); for (k = 0;k < 6; k++) summon_specific(-1, target_row, target_col, plev, 0, (mode | u_mode)); break; } case MS_S_ANT: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon ants."); for (k = 0;k < 6; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_ANT, mode); break; } case MS_S_SPIDER: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon spiders."); for (k = 0;k < 6; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_SPIDER, mode); break; } case MS_S_HOUND: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon hounds."); for (k = 0;k < 4; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_HOUND, mode); break; } case MS_S_HYDRA: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon hydras."); for (k = 0;k < 4; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_HYDRA, mode); break; } case MS_S_ANGEL: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon angel!"); for (k = 0;k < 1; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_ANGEL, mode); break; } case MS_S_DEMON: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon a demon from the Courts of Chaos!"); for (k = 0;k < 1; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_DEMON, (mode | u_mode)); break; } case MS_S_UNDEAD: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon an undead adversary!"); for (k = 0;k < 1; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_UNDEAD, (mode | u_mode)); break; } case MS_S_DRAGON: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon dragon!"); for (k = 0;k < 1; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_DRAGON, (mode | u_mode)); break; } case MS_S_HI_UNDEAD: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon greater undead!"); for (k = 0;k < 6; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_HI_UNDEAD, (mode | u_mode)); break; } case MS_S_HI_DRAGON: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon ancient dragons!"); for (k = 0;k < 4; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_HI_DRAGON, (mode | u_mode)); break; } case MS_S_AMBERITE: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon Lords of Amber!"); for (k = 0;k < 4; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_AMBERITE, (mode | PM_ALLOW_UNIQUE)); break; } case MS_S_UNIQUE: { int k, count = 0; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon special opponents!"); for (k = 0;k < 4; k++) if (summon_specific(-1, target_row, target_col, plev, SUMMON_UNIQUE, (mode | PM_ALLOW_UNIQUE))) count++; for (k = count;k < 4; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_HI_UNDEAD, (mode | u_mode)); break; } default: msg_print("hoge?"); } return TRUE; }
static bool zap_rod(object_type *o_ptr, bool *ident) { int chance, dir, lev; bool used_charge = TRUE; object_kind *k_ptr = &k_info[o_ptr->k_idx]; /* Get a direction (unless KNOWN not to need it) */ if ((o_ptr->sval >= SV_ROD_MIN_DIRECTION) || !object_aware_p(o_ptr)) { /* Get a direction, allow cancel */ if (!get_aim_dir(&dir)) return FALSE; } /* Take a turn */ p_ptr->energy_use = 100; /* Not identified yet */ *ident = FALSE; /* Extract the item level */ lev = k_info[o_ptr->k_idx].level; /* Base chance of success */ chance = p_ptr->skill_dev; /* Confusion hurts skill */ if (p_ptr->confused) chance = chance / 2; /* High level objects are harder */ chance = chance - ((lev > 50) ? 50 : lev); /* Give everyone a (slight) chance */ if ((chance < USE_DEVICE) && (rand_int(USE_DEVICE - chance + 1) == 0)) { chance = USE_DEVICE; } /* Roll for usage */ if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE)) { if (flush_failure) flush(); msg_print("Вы не смогли использовать жезл."); return FALSE; } /* Still charging? */ if (o_ptr->timeout > (o_ptr->pval - k_ptr->pval)) { if (flush_failure) flush(); if (o_ptr->number == 1) msg_print("Жезл все еще заряжается."); else msg_print("Все жезлы все еще заряжаются."); return FALSE; } /* Sound */ sound(MSG_ZAP); /* Analyze the rod */ switch (o_ptr->sval) { case SV_ROD_DETECT_TRAP: { if (detect_traps()) *ident = TRUE; break; } case SV_ROD_DETECT_DOOR: { if (detect_doors()) *ident = TRUE; if (detect_stairs()) *ident = TRUE; break; } case SV_ROD_IDENTIFY: { *ident = TRUE; if (ident_spell()) used_charge = FALSE; break; } case SV_ROD_RECALL: { set_recall(); *ident = TRUE; break; } case SV_ROD_ILLUMINATION: { if (lite_area(damroll(2, 8), 2)) *ident = TRUE; break; } case SV_ROD_MAPPING: { map_area(); *ident = TRUE; break; } case SV_ROD_DETECTION: { detect_all(); *ident = TRUE; break; } case SV_ROD_PROBING: { probing(); *ident = TRUE; break; } case SV_ROD_CURING: { if (set_blind(0)) *ident = TRUE; if (set_poisoned(0)) *ident = TRUE; if (set_confused(0)) *ident = TRUE; if (set_stun(0)) *ident = TRUE; if (set_cut(0)) *ident = TRUE; break; } case SV_ROD_HEALING: { if (hp_player(500)) *ident = TRUE; if (set_stun(0)) *ident = TRUE; if (set_cut(0)) *ident = TRUE; break; } case SV_ROD_RESTORATION: { if (restore_level()) *ident = TRUE; if (do_res_stat(A_STR)) *ident = TRUE; if (do_res_stat(A_INT)) *ident = TRUE; if (do_res_stat(A_WIS)) *ident = TRUE; if (do_res_stat(A_DEX)) *ident = TRUE; if (do_res_stat(A_CON)) *ident = TRUE; if (do_res_stat(A_CHR)) *ident = TRUE; break; } case SV_ROD_SPEED: { if (!p_ptr->fast) { if (set_fast(randint(30) + 15)) *ident = TRUE; } else { (void)set_fast(p_ptr->fast + 5); } break; } case SV_ROD_TELEPORT_AWAY: { if (teleport_monster(dir)) *ident = TRUE; break; } case SV_ROD_DISARMING: { if (disarm_trap(dir)) *ident = TRUE; break; } case SV_ROD_LITE: { msg_print("Появляется коридор синего мерцающего света."); lite_line(dir); *ident = TRUE; break; } case SV_ROD_SLEEP_MONSTER: { if (sleep_monster(dir)) *ident = TRUE; break; } case SV_ROD_SLOW_MONSTER: { if (slow_monster(dir)) *ident = TRUE; break; } case SV_ROD_DRAIN_LIFE: { if (drain_life(dir, 150)) *ident = TRUE; break; } case SV_ROD_POLYMORPH: { if (poly_monster(dir)) *ident = TRUE; break; } case SV_ROD_ACID_BOLT: { fire_bolt_or_beam(10, GF_ACID, dir, damroll(12, 8)); *ident = TRUE; break; } case SV_ROD_ELEC_BOLT: { fire_bolt_or_beam(10, GF_ELEC, dir, damroll(6, 6)); *ident = TRUE; break; } case SV_ROD_FIRE_BOLT: { fire_bolt_or_beam(10, GF_FIRE, dir, damroll(16, 8)); *ident = TRUE; break; } case SV_ROD_COLD_BOLT: { fire_bolt_or_beam(10, GF_COLD, dir, damroll(10, 8)); *ident = TRUE; break; } case SV_ROD_ACID_BALL: { fire_ball(GF_ACID, dir, 120, 2); *ident = TRUE; break; } case SV_ROD_ELEC_BALL: { fire_ball(GF_ELEC, dir, 64, 2); *ident = TRUE; break; } case SV_ROD_FIRE_BALL: { fire_ball(GF_FIRE, dir, 144, 2); *ident = TRUE; break; } case SV_ROD_COLD_BALL: { fire_ball(GF_COLD, dir, 96, 2); *ident = TRUE; break; } } /* Drain the charge */ if (used_charge) o_ptr->timeout += k_ptr->pval; return TRUE; }