static void _excavation_spell(int cmd, variant *res) { switch (cmd) { case SPELL_NAME: var_set_string(res, "Excavation"); break; case SPELL_DESC: var_set_string(res, "You break walls on your quest for treasure! This takes a bit more time, though."); break; case SPELL_ENERGY: { int n = 200; if (equip_find_object(TV_DIGGING, SV_ANY)) n -= 120 * p_ptr->lev / 50; else n -= 80 * p_ptr->lev / 50; var_set_int(res, n); } break; case SPELL_CAST: { int dir = 5; bool b = FALSE; if ( get_rep_dir2(&dir) && dir != 5 ) { int x, y; y = py + ddy[dir]; x = px + ddx[dir]; if (!in_bounds(y, x)) { msg_print("You may excavate no further."); } else if ( cave_have_flag_bold(y, x, FF_WALL) || cave_have_flag_bold(y, x, FF_TREE) || cave_have_flag_bold(y, x, FF_CAN_DIG) ) { msg_print("You dig your way to treasure!"); cave_alter_feat(y, x, FF_TUNNEL); teleport_player_to(y, x, TELEPORT_NONMAGICAL); /*??*/ b = TRUE; } else { msg_print("There is nothing to excavate."); } } var_set_bool(res, b); } break; default: default_spell(cmd, res); break; } }
/** * Hack -- Teleport to the target. Oangband asks for a target after * the command. */ static void do_cmd_wiz_bamf(void) { feature_type *f_ptr; /* target starts at player. */ s16b ny = 0; s16b nx = 0; /* Use the targeting function. */ if (!target_set_interactive(TARGET_LOOK, -1, -1)) return; /* grab the target coords. */ target_get(&nx, &ny); /* Test for passable terrain. */ f_ptr = &f_info[cave_feat[ny][nx]]; if (!tf_has(f_ptr->flags, TF_PASSABLE)) { msg("The square you are aiming for is impassable."); } /* The simple act of controlled teleport. */ else teleport_player_to(ny, nx, TRUE); }
/* * Hack -- Teleport to the target */ static void do_cmd_wiz_bamf(void) { /* Must have a target */ if (!p_ptr->target_who) return; /* Teleport to the target */ teleport_player_to(p_ptr->target_row, p_ptr->target_col); }
/*! * @brief ウィザードモード用処理としてターゲット中の相手をテレポートバックする / Hack -- Teleport to the target * @return なし */ static void do_cmd_wiz_bamf(void) { /* Must have a target */ if (!target_who) return; /* Teleport to the target */ teleport_player_to(target_row, target_col, TELEPORT_NONMAGICAL); }
/* * Hack -- Teleport to the target */ static void do_cmd_wiz_bamf(void) { /* Must have a target */ if (target_okay()) { /* Teleport to the target */ teleport_player_to(p_ptr->target_row, p_ptr->target_col); } }
/*! * @brief 必ず成功するウィザードモード用次元の扉処理 / Wizard Dimension Door * @return 実際にテレポートを行ったらTRUEを返す */ static bool wiz_dimension_door(void) { int x = 0, y = 0; if (!tgt_pt(&x, &y)) return FALSE; teleport_player_to(y, x, TELEPORT_NONMAGICAL); return (TRUE); }
/* * Hack -- Teleport to the target */ static void do_cmd_wiz_bamf(void) { s16b x, y; /* Must have a target */ if (!target_okay()) return; /* Teleport to the target */ target_get(&x, &y); teleport_player_to(y, x); }
void WizardModeDialog::wiz_teleport_to_target(void) { /* Must have a target */ if (target_okay()) { /* Teleport to the target */ teleport_player_to(p_ptr->target_row, p_ptr->target_col); this->accept(); } else this->reject(); }
static void _jump_spell(int cmd, variant *res) { switch (cmd) { case SPELL_NAME: var_set_string(res, "Jump"); break; case SPELL_DESC: var_set_string(res, "Leap a short distance, clearing any intervening monsters or obstacles."); break; case SPELL_CAST: { int x, y; int len = 2 + p_ptr->lev/35; var_set_bool(res, FALSE); if (!tgt_pt(&x, &y, len)) return; if (distance(y, x, py, px) > len) { msg_print("You can't jump that far."); return; } if (!los(py, px, y, x)) { msg_print("You can't see that location."); return; } if (!cave_player_teleportable_bold(y, x, 0L)) { msg_print("You can't leap there!"); return; } teleport_player_to(y, x, 0L); var_set_bool(res, TRUE); break; } default: default_spell(cmd, res); break; } }
/** * Hack -- Teleport to the target. Oangband asks for a target after * the command. */ static void do_cmd_wiz_bamf(void) { /* target starts at player. */ s16b ny = 0; s16b nx = 0; /* Use the targeting function. */ if (!target_set_interactive(TARGET_LOOK, -1, -1)) return; /* grab the target coords. */ target_get(&nx, &ny); /* Test for passable terrain. */ if (!cave_passable_bold(ny, nx)) { msg_print("The square you are aiming for is impassable."); } /* The simple act of controlled teleport. */ else teleport_player_to(ny, nx, TRUE); }
static bool _elemental_travel(int flag) { int rng = p_ptr->lev / 2 + 10; int x, y; if (!tgt_pt(&x, &y, rng)) return FALSE; if (!in_bounds(y, x)) return FALSE; if (!cave_have_flag_bold(y, x, flag)) { msg_print("Failed! You are out of your element!"); teleport_player((p_ptr->lev + 2) * 2, TELEPORT_PASSIVE); } else if (one_in_(7)) { msg_print("You failed to travel correctly!"); teleport_player((p_ptr->lev + 2) * 2, TELEPORT_PASSIVE); } else teleport_player_to(y, x, 0); return TRUE; }
/** * Apply side effects from a spell attack to the player * * \param spell is the attack type * \param dam is the amount of damage caused by the attack * \param m_idx is the attacking monster * \param rlev is its level * \param seen is whether @ can see it */ static void do_side_effects(int spell, int dam, int m_idx, bool seen) { monster_type *m_ptr = cave_monster(cave, m_idx); monster_race *r_ptr = &r_info[m_ptr->r_idx]; const struct spell_effect *re_ptr; const struct mon_spell *rs_ptr = &mon_spell_table[spell]; int i, choice[99], dur = 0, j = 0, count = 0; s32b d = 0; bool sustain = FALSE, perma = FALSE, chosen[RSE_MAX] = { 0 }; /* Extract the monster level */ int rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1); /* First we note all the effects we'll be doing. */ for (re_ptr = spell_effect_table; re_ptr->index < RSE_MAX; re_ptr++) { if ((re_ptr->method && (re_ptr->method == rs_ptr->index)) || (re_ptr->gf && (re_ptr->gf == rs_ptr->gf))) { /* If we have a choice of effects, we create a cum freq table */ if (re_ptr->chance) { for (i = j; i < (j + re_ptr->chance); i++) choice[i] = re_ptr->index; j = i; } else chosen[re_ptr->index] = TRUE; } } /* If we have built a cum freq table, choose an effect from it */ if (j) chosen[choice[randint0(j)]] = TRUE; /* Now we cycle through again to activate the chosen effects */ for (re_ptr = spell_effect_table; re_ptr->index < RSE_MAX; re_ptr++) { if (chosen[re_ptr->index]) { /* * Check for resistance - there are three possibilities: * 1. Immunity to the attack type if side_immune is TRUE * 2. Resistance to the attack type if it affords no immunity * 3. Resistance to the specific side-effect * * TODO - add interesting messages to the RSE_ and GF_ tables * to replace the generic ones below. (See #1376) */ if (re_ptr->res_flag) update_smart_learn(m_ptr, p_ptr, re_ptr->res_flag); if ((rs_ptr->gf && check_side_immune(rs_ptr->gf)) || check_state(p_ptr, re_ptr->res_flag, p_ptr->state.flags)) { msg("You resist the effect!"); continue; } /* Allow saving throw if available */ if (re_ptr->save && randint0(100) < p_ptr->state.skills[SKILL_SAVE]) { msg("You avoid the effect!"); continue; } /* Implement the effect */ if (re_ptr->timed) { /* Calculate base duration (m_bonus is not used) */ dur = randcalc(re_ptr->base, 0, RANDOMISE); /* Calculate the damage-dependent duration (m_bonus is * used as a cap) */ dur += damcalc(re_ptr->dam.dice, re_ptr->dam.sides * dam / 100, RANDOMISE); if (re_ptr->dam.m_bonus && (dur > re_ptr->dam.m_bonus)) dur = re_ptr->dam.m_bonus; /* Apply the effect - we have already checked for resistance */ (void)player_inc_timed(p_ptr, re_ptr->flag, dur, TRUE, FALSE); } else { switch (re_ptr->flag) { case S_INV_DAM: if (dam > 0) inven_damage(p_ptr, re_ptr->gf, MIN(dam * randcalc(re_ptr->dam, 0, RANDOMISE), 300)); break; case S_TELEPORT: /* m_bonus is used as a clev filter */ if (!re_ptr->dam.m_bonus || randint1(re_ptr->dam.m_bonus) > p_ptr->lev) teleport_player(randcalc(re_ptr->base, 0, RANDOMISE)); break; case S_TELE_TO: teleport_player_to(m_ptr->fy, m_ptr->fx); break; case S_TELE_LEV: teleport_player_level(); break; case S_TELE_SELF: teleport_away(m_ptr, randcalc(re_ptr->base, 0, RANDOMISE)); break; case S_DRAIN_LIFE: d = re_ptr->base.base + (p_ptr->exp * re_ptr->base.sides / 100) * MON_DRAIN_LIFE; msg("You feel your life force draining away!"); player_exp_lose(p_ptr, d, FALSE); break; case S_DRAIN_STAT: /* m_bonus is used as a flag */ if (re_ptr->dam.m_bonus > 0) sustain = TRUE; if (abs(re_ptr->dam.m_bonus) > 1) perma = TRUE; drain_stats(randcalc(re_ptr->base, 0, RANDOMISE), sustain, perma); break; case S_SWAP_STAT: swap_stats(); break; case S_DRAIN_ALL: msg("You're not as powerful as you used to be..."); for (i = 0; i < A_MAX; i++) player_stat_dec(p_ptr, i, FALSE); break; case S_DISEN: (void)apply_disenchant(0); break; case S_DRAIN_MANA: drain_mana(m_idx, rlev, seen); break; case S_HEAL: heal_self(m_idx, rlev, seen); break; case S_DARKEN: (void)unlight_area(0, 3); break; case S_TRAPS: (void)trap_creation(); break; case S_AGGRAVATE: aggravate_monsters(m_idx); break; case S_KIN: summon_kin_type = r_ptr->d_char; case S_MONSTER: case S_MONSTERS: case S_SPIDER: case S_HOUND: case S_HYDRA: case S_AINU: case S_ANIMAL: case S_DEMON: case S_HI_DEMON: case S_UNDEAD: case S_HI_UNDEAD: case S_WRAITH: case S_DRAGON: case S_HI_DRAGON: case S_UNIQUE: count = summon_monster_aux(re_ptr->flag, m_idx, rlev, re_ptr->base.base); /* In the special case that uniques or wraiths were summoned but all were dead S_HI_UNDEAD is used instead */ if ((!count) && ((re_ptr->flag == S_WRAITH) || (re_ptr->flag == S_UNIQUE))) count = summon_monster_aux(S_HI_UNDEAD, m_idx, rlev, re_ptr->base.base); if (count && p_ptr->timed[TMD_BLIND]) msgt(rs_ptr->msgt, "You hear %s appear nearby.", (count > 1 ? "many things" : "something")); default: break; } } } } return; }
/** * Apply side effects from a spell attack to the player * * \param spell is the attack type * \param dam is the amount of damage caused by the attack * \param m_idx is the attacking monster */ static void do_side_effects(int spell, int dam, int m_idx) { const struct spell_effect *re_ptr; const struct mon_spell *rs_ptr = &mon_spell_table[spell]; monster_type *m_ptr = &mon_list[m_idx]; int i, choice[99], dur = 0, j = 0; bool sustain = FALSE, perma = FALSE, chosen[RSE_MAX] = { 0 }; s32b d = 0; /* First we note all the effects we'll be doing. */ for (re_ptr = spell_effect_table; re_ptr->index < RSE_MAX; re_ptr++) { if ((re_ptr->method && (re_ptr->method == rs_ptr->index)) || (re_ptr->gf && (re_ptr->gf == rs_ptr->gf))) { /* If we have a choice of effects, we create a cum freq table */ if (re_ptr->chance) { for (i = j; i < (j + re_ptr->chance); i++) choice[i] = re_ptr->index; j = i; } else chosen[re_ptr->index] = TRUE; } } /* If we have built a cum freq table, choose an effect from it */ if (j) chosen[choice[randint0(j)]] = TRUE; /* Now we cycle through again to activate the chosen effects */ for (re_ptr = spell_effect_table; re_ptr->index < RSE_MAX; re_ptr++) { if (chosen[re_ptr->index]) { /* * Check for resistance - there are three possibilities: * 1. Immunity to the attack type if side_immune is TRUE * 2. Resistance to the attack type if it affords no immunity * 3. Resistance to the specific side-effect * * TODO - add interesting messages to the RSE_ and GF_ tables * to replace the generic ones below. */ if ((rs_ptr->gf && check_side_immune(rs_ptr->gf)) || p_ptr->state.flags[re_ptr->res_flag]) { msg("You resist the effect!"); if (re_ptr->res_flag) wieldeds_notice_flag(re_ptr->res_flag); continue; } /* Allow saving throw if available */ if (re_ptr->save && randint0(100) < p_ptr->state.skills[SKILL_SAVE]) { msg("You avoid the effect!"); continue; } /* Implement the effect */ if (re_ptr->timed) { /* Calculate base duration (m_bonus is not used) */ dur = randcalc(re_ptr->base, 0, RANDOMISE); /* Calculate the damage-dependent duration (m_bonus is * used as a cap) */ dur += damcalc(re_ptr->dam.dice, re_ptr->dam.sides * dam / 100, RANDOMISE); if (re_ptr->dam.m_bonus && (dur > re_ptr->dam.m_bonus)) dur = re_ptr->dam.m_bonus; /* Apply the effect */ (void)inc_timed(re_ptr->flag, dur, TRUE); } else { switch (re_ptr->flag) { case S_INV_DAM: if (dam > 0) inven_damage(re_ptr->gf, MIN(dam * randcalc(re_ptr->dam, 0, RANDOMISE), 300)); break; case S_TELEPORT: /* m_bonus is used as a clev filter */ if (!re_ptr->dam.m_bonus || randint1(re_ptr->dam.m_bonus) > p_ptr->lev) teleport_player(randcalc(re_ptr->base, 0, RANDOMISE)); break; case S_TELE_TO: teleport_player_to(m_ptr->fy, m_ptr->fx); break; case S_TELE_LEV: teleport_player_level(); break; case S_DRAIN_LIFE: d = re_ptr->base.base + (p_ptr->exp * re_ptr->base.sides / 100) * MON_DRAIN_LIFE; msg("You feel your life force draining away!"); lose_exp(d); break; case S_DRAIN_STAT: /* m_bonus is used as a flag */ if (re_ptr->dam.m_bonus > 0) sustain = TRUE; if (abs(re_ptr->dam.m_bonus) > 1) perma = TRUE; drain_stats(randcalc(re_ptr->base, 0, RANDOMISE), sustain, perma); break; case S_SWAP_STAT: swap_stats(); break; case S_DRAIN_ALL: msg("You're not as powerful as you used to be..."); for (i = 0; i < A_MAX; i++) player_stat_dec(p_ptr, i, FALSE); break; case S_DISEN: (void)apply_disenchant(0); break; case S_DRAIN_MANA: case S_HEAL: case S_BLINK: case S_DARKEN: case S_TRAPS: case S_AGGRAVATE: case S_KIN: case S_MONSTER: case S_MONSTERS: /* XXX Fixme */ default: break; } } } } return; }