#include "view/display-messages.h"
#include "world/world.h"
-#define DO_SPELL_NONE 0
+#define DO_SPELL_NONE 0
#define DO_SPELL_BR_LITE 1
#define DO_SPELL_BR_DISI 2
#define DO_SPELL_BA_LITE 3
- /*!
- * @brief モンスターがプレイヤーの弱点をついた選択を取るかどうかの判定 /
- * Internal probability routine
- * @param r_ptr モンスター種族の構造体参照ポインタ
- * @param prob 基本確率(%)
- * @return 適した選択を取るならばTRUEを返す。
- */
+/*!
+ * @brief モンスターがプレイヤーの弱点をついた選択を取るかどうかの判定 /
+ * Internal probability routine
+ * @param r_ptr モンスター種族の構造体参照ポインタ
+ * @param prob 基本確率(%)
+ * @return 適した選択を取るならばTRUEを返す。
+ */
static bool int_outof(monster_race *r_ptr, PERCENTAGE prob)
{
- if (!(r_ptr->flags2 & RF2_SMART)) prob = prob / 2;
+ if (!(r_ptr->flags2 & RF2_SMART))
+ prob = prob / 2;
- return (randint0(100) < prob);
+ return (randint0(100) < prob);
}
-
/*!
* @brief モンスターの魔法一覧から戦術的に適さない魔法を除外する /
* Remove the "bad" spells from a spell list
*/
static void remove_bad_spells(MONSTER_IDX m_idx, player_type *target_ptr, u32b *f4p, u32b *f5p, u32b *f6p)
{
- monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- u32b f4 = (*f4p);
- u32b f5 = (*f5p);
- u32b f6 = (*f6p);
- u32b smart = 0L;
- if (r_ptr->flags2 & RF2_STUPID) return;
-
- if (!smart_cheat && !smart_learn) return;
-
- if (smart_learn)
- {
- if (m_ptr->smart && (randint0(100) < 1)) m_ptr->smart &= (SM_FRIENDLY | SM_PET | SM_CLONED);
-
- smart = m_ptr->smart;
- }
-
- if (smart_cheat)
- {
- if (target_ptr->resist_acid) smart |= (SM_RES_ACID);
- if (is_oppose_acid(target_ptr)) smart |= (SM_OPP_ACID);
- if (target_ptr->immune_acid) smart |= (SM_IMM_ACID);
- if (target_ptr->resist_elec) smart |= (SM_RES_ELEC);
- if (is_oppose_elec(target_ptr)) smart |= (SM_OPP_ELEC);
- if (target_ptr->immune_elec) smart |= (SM_IMM_ELEC);
- if (target_ptr->resist_fire) smart |= (SM_RES_FIRE);
- if (is_oppose_fire(target_ptr)) smart |= (SM_OPP_FIRE);
- if (target_ptr->immune_fire) smart |= (SM_IMM_FIRE);
- if (target_ptr->resist_cold) smart |= (SM_RES_COLD);
- if (is_oppose_cold(target_ptr)) smart |= (SM_OPP_COLD);
- if (target_ptr->immune_cold) smart |= (SM_IMM_COLD);
- if (target_ptr->resist_pois) smart |= (SM_RES_POIS);
- if (is_oppose_pois(target_ptr)) smart |= (SM_OPP_POIS);
-
- if (target_ptr->resist_neth) smart |= (SM_RES_NETH);
- if (target_ptr->resist_lite) smart |= (SM_RES_LITE);
- if (target_ptr->resist_dark) smart |= (SM_RES_DARK);
- if (target_ptr->resist_fear) smart |= (SM_RES_FEAR);
- if (target_ptr->resist_conf) smart |= (SM_RES_CONF);
- if (target_ptr->resist_chaos) smart |= (SM_RES_CHAOS);
- if (target_ptr->resist_disen) smart |= (SM_RES_DISEN);
- if (target_ptr->resist_blind) smart |= (SM_RES_BLIND);
- if (target_ptr->resist_nexus) smart |= (SM_RES_NEXUS);
- if (target_ptr->resist_sound) smart |= (SM_RES_SOUND);
- if (target_ptr->resist_shard) smart |= (SM_RES_SHARD);
- if (target_ptr->reflect) smart |= (SM_IMM_REFLECT);
-
- if (target_ptr->free_act) smart |= (SM_IMM_FREE);
- if (!target_ptr->msp) smart |= (SM_IMM_MANA);
- }
-
- if (!smart) return;
-
- if (smart & SM_IMM_ACID)
- {
- f4 &= ~(RF4_BR_ACID);
- f5 &= ~(RF5_BA_ACID);
- f5 &= ~(RF5_BO_ACID);
- }
- else if ((smart & (SM_OPP_ACID)) && (smart & (SM_RES_ACID)))
- {
- if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_ACID);
- if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_ACID);
- if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_ACID);
- }
- else if ((smart & (SM_OPP_ACID)) || (smart & (SM_RES_ACID)))
- {
- if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_ACID);
- if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_ACID);
- if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BO_ACID);
- }
-
- if (smart & (SM_IMM_ELEC))
- {
- f4 &= ~(RF4_BR_ELEC);
- f5 &= ~(RF5_BA_ELEC);
- f5 &= ~(RF5_BO_ELEC);
- }
- else if ((smart & (SM_OPP_ELEC)) && (smart & (SM_RES_ELEC)))
- {
- if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_ELEC);
- if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_ELEC);
- if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_ELEC);
- }
- else if ((smart & (SM_OPP_ELEC)) || (smart & (SM_RES_ELEC)))
- {
- if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_ELEC);
- if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_ELEC);
- if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BO_ELEC);
- }
-
- if (smart & (SM_IMM_FIRE))
- {
- f4 &= ~(RF4_BR_FIRE);
- f5 &= ~(RF5_BA_FIRE);
- f5 &= ~(RF5_BO_FIRE);
- }
- else if ((smart & (SM_OPP_FIRE)) && (smart & (SM_RES_FIRE)))
- {
- if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_FIRE);
- if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_FIRE);
- if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_FIRE);
- }
- else if ((smart & (SM_OPP_FIRE)) || (smart & (SM_RES_FIRE)))
- {
- if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_FIRE);
- if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_FIRE);
- if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BO_FIRE);
- }
-
- if (smart & (SM_IMM_COLD))
- {
- f4 &= ~(RF4_BR_COLD);
- f5 &= ~(RF5_BA_COLD);
- f5 &= ~(RF5_BO_COLD);
- f5 &= ~(RF5_BO_ICEE);
- }
- else if ((smart & (SM_OPP_COLD)) && (smart & (SM_RES_COLD)))
- {
- if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_COLD);
- if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_COLD);
- if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_COLD);
- if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_ICEE);
- }
- else if ((smart & (SM_OPP_COLD)) || (smart & (SM_RES_COLD)))
- {
- if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_COLD);
- if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_COLD);
- if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BO_COLD);
- if (int_outof(r_ptr, 20)) f5 &= ~(RF5_BO_ICEE);
- }
-
- if ((smart & (SM_OPP_POIS)) && (smart & (SM_RES_POIS)))
- {
- if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_POIS);
- if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_POIS);
- if (int_outof(r_ptr, 60)) f4 &= ~(RF4_BA_NUKE);
- if (int_outof(r_ptr, 60)) f4 &= ~(RF4_BR_NUKE);
- }
- else if ((smart & (SM_OPP_POIS)) || (smart & (SM_RES_POIS)))
- {
- if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_POIS);
- if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_POIS);
- }
-
- if (smart & (SM_RES_NETH))
- {
- if (is_specific_player_race(target_ptr, RACE_SPECTRE))
- {
- f4 &= ~(RF4_BR_NETH);
- f5 &= ~(RF5_BA_NETH);
- f5 &= ~(RF5_BO_NETH);
- }
- else
- {
- if (int_outof(r_ptr, 20)) f4 &= ~(RF4_BR_NETH);
- if (int_outof(r_ptr, 50)) f5 &= ~(RF5_BA_NETH);
- if (int_outof(r_ptr, 50)) f5 &= ~(RF5_BO_NETH);
- }
- }
-
- if (smart & (SM_RES_LITE))
- {
- if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_LITE);
- if (int_outof(r_ptr, 50)) f5 &= ~(RF5_BA_LITE);
- }
-
- if (smart & (SM_RES_DARK))
- {
- if (is_specific_player_race(target_ptr, RACE_VAMPIRE))
- {
- f4 &= ~(RF4_BR_DARK);
- f5 &= ~(RF5_BA_DARK);
- }
- else
- {
- if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_DARK);
- if (int_outof(r_ptr, 50)) f5 &= ~(RF5_BA_DARK);
- }
- }
-
- if (smart & (SM_RES_FEAR))
- {
- f5 &= ~(RF5_SCARE);
- }
-
- if (smart & (SM_RES_CONF))
- {
- f5 &= ~(RF5_CONF);
- if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_CONF);
- }
-
- if (smart & (SM_RES_CHAOS))
- {
- if (int_outof(r_ptr, 20)) f4 &= ~(RF4_BR_CHAO);
- if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BA_CHAO);
- }
-
- if (smart & (SM_RES_DISEN))
- {
- if (int_outof(r_ptr, 40)) f4 &= ~(RF4_BR_DISE);
- }
-
- if (smart & (SM_RES_BLIND))
- {
- f5 &= ~(RF5_BLIND);
- }
-
- if (smart & (SM_RES_NEXUS))
- {
- if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_NEXU);
- f6 &= ~(RF6_TELE_LEVEL);
- }
-
- if (smart & (SM_RES_SOUND))
- {
- if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_SOUN);
- }
-
- if (smart & (SM_RES_SHARD))
- {
- if (int_outof(r_ptr, 40)) f4 &= ~(RF4_BR_SHAR);
- }
-
- if (smart & (SM_IMM_REFLECT))
- {
- if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_COLD);
- if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_FIRE);
- if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_ACID);
- if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_ELEC);
- if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_NETH);
- if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_WATE);
- if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_MANA);
- if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_PLAS);
- if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_ICEE);
- if (int_outof(r_ptr, 150)) f5 &= ~(RF5_MISSILE);
- }
-
- if (smart & (SM_IMM_FREE))
- {
- f5 &= ~(RF5_HOLD);
- f5 &= ~(RF5_SLOW);
- }
-
- if (smart & (SM_IMM_MANA))
- {
- f5 &= ~(RF5_DRAIN_MANA);
- }
-
- (*f4p) = f4;
- (*f5p) = f5;
- (*f6p) = f6;
-}
+ monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ u32b f4 = (*f4p);
+ u32b f5 = (*f5p);
+ u32b f6 = (*f6p);
+ u32b smart = 0L;
+ if (r_ptr->flags2 & RF2_STUPID)
+ return;
+
+ if (!smart_cheat && !smart_learn)
+ return;
+
+ if (smart_learn) {
+ if (m_ptr->smart && (randint0(100) < 1))
+ m_ptr->smart &= (SM_FRIENDLY | SM_PET | SM_CLONED);
+
+ smart = m_ptr->smart;
+ }
+
+ if (smart_cheat) {
+ if (target_ptr->resist_acid)
+ smart |= (SM_RES_ACID);
+ if (is_oppose_acid(target_ptr))
+ smart |= (SM_OPP_ACID);
+ if (target_ptr->immune_acid)
+ smart |= (SM_IMM_ACID);
+ if (target_ptr->resist_elec)
+ smart |= (SM_RES_ELEC);
+ if (is_oppose_elec(target_ptr))
+ smart |= (SM_OPP_ELEC);
+ if (target_ptr->immune_elec)
+ smart |= (SM_IMM_ELEC);
+ if (target_ptr->resist_fire)
+ smart |= (SM_RES_FIRE);
+ if (is_oppose_fire(target_ptr))
+ smart |= (SM_OPP_FIRE);
+ if (target_ptr->immune_fire)
+ smart |= (SM_IMM_FIRE);
+ if (target_ptr->resist_cold)
+ smart |= (SM_RES_COLD);
+ if (is_oppose_cold(target_ptr))
+ smart |= (SM_OPP_COLD);
+ if (target_ptr->immune_cold)
+ smart |= (SM_IMM_COLD);
+ if (target_ptr->resist_pois)
+ smart |= (SM_RES_POIS);
+ if (is_oppose_pois(target_ptr))
+ smart |= (SM_OPP_POIS);
+
+ if (target_ptr->resist_neth)
+ smart |= (SM_RES_NETH);
+ if (target_ptr->resist_lite)
+ smart |= (SM_RES_LITE);
+ if (target_ptr->resist_dark)
+ smart |= (SM_RES_DARK);
+ if (target_ptr->resist_fear)
+ smart |= (SM_RES_FEAR);
+ if (target_ptr->resist_conf)
+ smart |= (SM_RES_CONF);
+ if (target_ptr->resist_chaos)
+ smart |= (SM_RES_CHAOS);
+ if (target_ptr->resist_disen)
+ smart |= (SM_RES_DISEN);
+ if (target_ptr->resist_blind)
+ smart |= (SM_RES_BLIND);
+ if (target_ptr->resist_nexus)
+ smart |= (SM_RES_NEXUS);
+ if (target_ptr->resist_sound)
+ smart |= (SM_RES_SOUND);
+ if (target_ptr->resist_shard)
+ smart |= (SM_RES_SHARD);
+ if (target_ptr->reflect)
+ smart |= (SM_IMM_REFLECT);
+
+ if (target_ptr->free_act)
+ smart |= (SM_IMM_FREE);
+ if (!target_ptr->msp)
+ smart |= (SM_IMM_MANA);
+ }
+
+ if (!smart)
+ return;
+
+ if (smart & SM_IMM_ACID) {
+ f4 &= ~(RF4_BR_ACID);
+ f5 &= ~(RF5_BA_ACID);
+ f5 &= ~(RF5_BO_ACID);
+ } else if ((smart & (SM_OPP_ACID)) && (smart & (SM_RES_ACID))) {
+ if (int_outof(r_ptr, 80))
+ f4 &= ~(RF4_BR_ACID);
+ if (int_outof(r_ptr, 80))
+ f5 &= ~(RF5_BA_ACID);
+ if (int_outof(r_ptr, 80))
+ f5 &= ~(RF5_BO_ACID);
+ } else if ((smart & (SM_OPP_ACID)) || (smart & (SM_RES_ACID))) {
+ if (int_outof(r_ptr, 30))
+ f4 &= ~(RF4_BR_ACID);
+ if (int_outof(r_ptr, 30))
+ f5 &= ~(RF5_BA_ACID);
+ if (int_outof(r_ptr, 30))
+ f5 &= ~(RF5_BO_ACID);
+ }
+
+ if (smart & (SM_IMM_ELEC)) {
+ f4 &= ~(RF4_BR_ELEC);
+ f5 &= ~(RF5_BA_ELEC);
+ f5 &= ~(RF5_BO_ELEC);
+ } else if ((smart & (SM_OPP_ELEC)) && (smart & (SM_RES_ELEC))) {
+ if (int_outof(r_ptr, 80))
+ f4 &= ~(RF4_BR_ELEC);
+ if (int_outof(r_ptr, 80))
+ f5 &= ~(RF5_BA_ELEC);
+ if (int_outof(r_ptr, 80))
+ f5 &= ~(RF5_BO_ELEC);
+ } else if ((smart & (SM_OPP_ELEC)) || (smart & (SM_RES_ELEC))) {
+ if (int_outof(r_ptr, 30))
+ f4 &= ~(RF4_BR_ELEC);
+ if (int_outof(r_ptr, 30))
+ f5 &= ~(RF5_BA_ELEC);
+ if (int_outof(r_ptr, 30))
+ f5 &= ~(RF5_BO_ELEC);
+ }
+
+ if (smart & (SM_IMM_FIRE)) {
+ f4 &= ~(RF4_BR_FIRE);
+ f5 &= ~(RF5_BA_FIRE);
+ f5 &= ~(RF5_BO_FIRE);
+ } else if ((smart & (SM_OPP_FIRE)) && (smart & (SM_RES_FIRE))) {
+ if (int_outof(r_ptr, 80))
+ f4 &= ~(RF4_BR_FIRE);
+ if (int_outof(r_ptr, 80))
+ f5 &= ~(RF5_BA_FIRE);
+ if (int_outof(r_ptr, 80))
+ f5 &= ~(RF5_BO_FIRE);
+ } else if ((smart & (SM_OPP_FIRE)) || (smart & (SM_RES_FIRE))) {
+ if (int_outof(r_ptr, 30))
+ f4 &= ~(RF4_BR_FIRE);
+ if (int_outof(r_ptr, 30))
+ f5 &= ~(RF5_BA_FIRE);
+ if (int_outof(r_ptr, 30))
+ f5 &= ~(RF5_BO_FIRE);
+ }
+ if (smart & (SM_IMM_COLD)) {
+ f4 &= ~(RF4_BR_COLD);
+ f5 &= ~(RF5_BA_COLD);
+ f5 &= ~(RF5_BO_COLD);
+ f5 &= ~(RF5_BO_ICEE);
+ } else if ((smart & (SM_OPP_COLD)) && (smart & (SM_RES_COLD))) {
+ if (int_outof(r_ptr, 80))
+ f4 &= ~(RF4_BR_COLD);
+ if (int_outof(r_ptr, 80))
+ f5 &= ~(RF5_BA_COLD);
+ if (int_outof(r_ptr, 80))
+ f5 &= ~(RF5_BO_COLD);
+ if (int_outof(r_ptr, 80))
+ f5 &= ~(RF5_BO_ICEE);
+ } else if ((smart & (SM_OPP_COLD)) || (smart & (SM_RES_COLD))) {
+ if (int_outof(r_ptr, 30))
+ f4 &= ~(RF4_BR_COLD);
+ if (int_outof(r_ptr, 30))
+ f5 &= ~(RF5_BA_COLD);
+ if (int_outof(r_ptr, 30))
+ f5 &= ~(RF5_BO_COLD);
+ if (int_outof(r_ptr, 20))
+ f5 &= ~(RF5_BO_ICEE);
+ }
+
+ if ((smart & (SM_OPP_POIS)) && (smart & (SM_RES_POIS))) {
+ if (int_outof(r_ptr, 80))
+ f4 &= ~(RF4_BR_POIS);
+ if (int_outof(r_ptr, 80))
+ f5 &= ~(RF5_BA_POIS);
+ if (int_outof(r_ptr, 60))
+ f4 &= ~(RF4_BA_NUKE);
+ if (int_outof(r_ptr, 60))
+ f4 &= ~(RF4_BR_NUKE);
+ } else if ((smart & (SM_OPP_POIS)) || (smart & (SM_RES_POIS))) {
+ if (int_outof(r_ptr, 30))
+ f4 &= ~(RF4_BR_POIS);
+ if (int_outof(r_ptr, 30))
+ f5 &= ~(RF5_BA_POIS);
+ }
+
+ if (smart & (SM_RES_NETH)) {
+ if (is_specific_player_race(target_ptr, RACE_SPECTRE)) {
+ f4 &= ~(RF4_BR_NETH);
+ f5 &= ~(RF5_BA_NETH);
+ f5 &= ~(RF5_BO_NETH);
+ } else {
+ if (int_outof(r_ptr, 20))
+ f4 &= ~(RF4_BR_NETH);
+ if (int_outof(r_ptr, 50))
+ f5 &= ~(RF5_BA_NETH);
+ if (int_outof(r_ptr, 50))
+ f5 &= ~(RF5_BO_NETH);
+ }
+ }
+
+ if (smart & (SM_RES_LITE)) {
+ if (int_outof(r_ptr, 50))
+ f4 &= ~(RF4_BR_LITE);
+ if (int_outof(r_ptr, 50))
+ f5 &= ~(RF5_BA_LITE);
+ }
+
+ if (smart & (SM_RES_DARK)) {
+ if (is_specific_player_race(target_ptr, RACE_VAMPIRE)) {
+ f4 &= ~(RF4_BR_DARK);
+ f5 &= ~(RF5_BA_DARK);
+ } else {
+ if (int_outof(r_ptr, 50))
+ f4 &= ~(RF4_BR_DARK);
+ if (int_outof(r_ptr, 50))
+ f5 &= ~(RF5_BA_DARK);
+ }
+ }
+
+ if (smart & (SM_RES_FEAR)) {
+ f5 &= ~(RF5_SCARE);
+ }
+
+ if (smart & (SM_RES_CONF)) {
+ f5 &= ~(RF5_CONF);
+ if (int_outof(r_ptr, 50))
+ f4 &= ~(RF4_BR_CONF);
+ }
+
+ if (smart & (SM_RES_CHAOS)) {
+ if (int_outof(r_ptr, 20))
+ f4 &= ~(RF4_BR_CHAO);
+ if (int_outof(r_ptr, 50))
+ f4 &= ~(RF4_BA_CHAO);
+ }
+
+ if (smart & (SM_RES_DISEN)) {
+ if (int_outof(r_ptr, 40))
+ f4 &= ~(RF4_BR_DISE);
+ }
+
+ if (smart & (SM_RES_BLIND)) {
+ f5 &= ~(RF5_BLIND);
+ }
+
+ if (smart & (SM_RES_NEXUS)) {
+ if (int_outof(r_ptr, 50))
+ f4 &= ~(RF4_BR_NEXU);
+ f6 &= ~(RF6_TELE_LEVEL);
+ }
+
+ if (smart & (SM_RES_SOUND)) {
+ if (int_outof(r_ptr, 50))
+ f4 &= ~(RF4_BR_SOUN);
+ }
+
+ if (smart & (SM_RES_SHARD)) {
+ if (int_outof(r_ptr, 40))
+ f4 &= ~(RF4_BR_SHAR);
+ }
+
+ if (smart & (SM_IMM_REFLECT)) {
+ if (int_outof(r_ptr, 150))
+ f5 &= ~(RF5_BO_COLD);
+ if (int_outof(r_ptr, 150))
+ f5 &= ~(RF5_BO_FIRE);
+ if (int_outof(r_ptr, 150))
+ f5 &= ~(RF5_BO_ACID);
+ if (int_outof(r_ptr, 150))
+ f5 &= ~(RF5_BO_ELEC);
+ if (int_outof(r_ptr, 150))
+ f5 &= ~(RF5_BO_NETH);
+ if (int_outof(r_ptr, 150))
+ f5 &= ~(RF5_BO_WATE);
+ if (int_outof(r_ptr, 150))
+ f5 &= ~(RF5_BO_MANA);
+ if (int_outof(r_ptr, 150))
+ f5 &= ~(RF5_BO_PLAS);
+ if (int_outof(r_ptr, 150))
+ f5 &= ~(RF5_BO_ICEE);
+ if (int_outof(r_ptr, 150))
+ f5 &= ~(RF5_MISSILE);
+ }
+
+ if (smart & (SM_IMM_FREE)) {
+ f5 &= ~(RF5_HOLD);
+ f5 &= ~(RF5_SLOW);
+ }
+
+ if (smart & (SM_IMM_MANA)) {
+ f5 &= ~(RF5_DRAIN_MANA);
+ }
+
+ (*f4p) = f4;
+ (*f5p) = f5;
+ (*f6p) = f6;
+}
/*!
* @brief モンスターにとって所定の地点が召還に相応しい地点かどうかを返す。 /
*/
bool summon_possible(player_type *target_ptr, POSITION y1, POSITION x1)
{
- POSITION y, x;
- floor_type *floor_ptr = target_ptr->current_floor_ptr;
- for (y = y1 - 2; y <= y1 + 2; y++)
- {
- for (x = x1 - 2; x <= x1 + 2; x++)
- {
- if (!in_bounds(floor_ptr, y, x)) continue;
-
- if (distance(y1, x1, y, x) > 2) continue;
-
- if (pattern_tile(floor_ptr, y, x)) continue;
-
- if (is_cave_empty_bold(target_ptr, y, x) && projectable(target_ptr, y1, x1, y, x) && projectable(target_ptr, y, x, y1, x1)) return TRUE;
- }
- }
+ POSITION y, x;
+ floor_type *floor_ptr = target_ptr->current_floor_ptr;
+ for (y = y1 - 2; y <= y1 + 2; y++) {
+ for (x = x1 - 2; x <= x1 + 2; x++) {
+ if (!in_bounds(floor_ptr, y, x))
+ continue;
+
+ if (distance(y1, x1, y, x) > 2)
+ continue;
+
+ if (pattern_tile(floor_ptr, y, x))
+ continue;
+
+ if (is_cave_empty_bold(target_ptr, y, x) && projectable(target_ptr, y1, x1, y, x) && projectable(target_ptr, y, x, y1, x1))
+ return TRUE;
+ }
+ }
- return FALSE;
+ return FALSE;
}
-
/*!
* @brief モンスターにとって死者復活を行うべき状態かどうかを返す /
* Determine if there is a space near the player in which a summoned creature can appear
*/
bool raise_possible(player_type *target_ptr, monster_type *m_ptr)
{
- POSITION y = m_ptr->fy;
- POSITION x = m_ptr->fx;
- floor_type *floor_ptr = target_ptr->current_floor_ptr;
- for (POSITION xx = x - 5; xx <= x + 5; xx++)
- {
- grid_type *g_ptr;
- for (POSITION yy = y - 5; yy <= y + 5; yy++)
- {
- if (distance(y, x, yy, xx) > 5) continue;
- if (!los(target_ptr, y, x, yy, xx)) continue;
- if (!projectable(target_ptr, y, x, yy, xx)) continue;
-
- g_ptr = &floor_ptr->grid_array[yy][xx];
- OBJECT_IDX this_o_idx, next_o_idx = 0;
- for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
- {
- object_type *o_ptr = &floor_ptr->o_list[this_o_idx];
- next_o_idx = o_ptr->next_o_idx;
- if (o_ptr->tval == TV_CORPSE)
- {
- if (!monster_has_hostile_align(target_ptr, m_ptr, 0, 0, &r_info[o_ptr->pval])) return TRUE;
- }
- }
- }
- }
-
- return FALSE;
-}
+ POSITION y = m_ptr->fy;
+ POSITION x = m_ptr->fx;
+ floor_type *floor_ptr = target_ptr->current_floor_ptr;
+ for (POSITION xx = x - 5; xx <= x + 5; xx++) {
+ grid_type *g_ptr;
+ for (POSITION yy = y - 5; yy <= y + 5; yy++) {
+ if (distance(y, x, yy, xx) > 5)
+ continue;
+ if (!los(target_ptr, y, x, yy, xx))
+ continue;
+ if (!projectable(target_ptr, y, x, yy, xx))
+ continue;
+
+ g_ptr = &floor_ptr->grid_array[yy][xx];
+ OBJECT_IDX this_o_idx, next_o_idx = 0;
+ for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) {
+ object_type *o_ptr = &floor_ptr->o_list[this_o_idx];
+ next_o_idx = o_ptr->next_o_idx;
+ if (o_ptr->tval == TV_CORPSE) {
+ if (!monster_has_hostile_align(target_ptr, m_ptr, 0, 0, &r_info[o_ptr->pval]))
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
/*!
* @brief モンスターにとってボルト型魔法が有効な状態かを返す /
*/
bool clean_shot(player_type *target_ptr, POSITION y1, POSITION x1, POSITION y2, POSITION x2, bool is_friend)
{
- floor_type *floor_ptr = target_ptr->current_floor_ptr;
- u16b grid_g[512];
- int grid_n = project_path(target_ptr, grid_g, MAX_RANGE, y1, x1, y2, x2, 0);
- if (!grid_n) return FALSE;
-
- POSITION y = GRID_Y(grid_g[grid_n - 1]);
- POSITION x = GRID_X(grid_g[grid_n - 1]);
- if ((y != y2) || (x != x2)) return FALSE;
-
- for (int i = 0; i < grid_n; i++)
- {
- y = GRID_Y(grid_g[i]);
- x = GRID_X(grid_g[i]);
-
- if ((floor_ptr->grid_array[y][x].m_idx > 0) && !((y == y2) && (x == x2)))
- {
- monster_type *m_ptr = &floor_ptr->m_list[floor_ptr->grid_array[y][x].m_idx];
- if (is_friend == is_pet(m_ptr))
- {
- return FALSE;
- }
- }
-
- if (player_bold(target_ptr, y, x) && is_friend) return FALSE;
- }
-
- return TRUE;
-}
+ floor_type *floor_ptr = target_ptr->current_floor_ptr;
+ u16b grid_g[512];
+ int grid_n = project_path(target_ptr, grid_g, MAX_RANGE, y1, x1, y2, x2, 0);
+ if (!grid_n)
+ return FALSE;
+
+ POSITION y = GRID_Y(grid_g[grid_n - 1]);
+ POSITION x = GRID_X(grid_g[grid_n - 1]);
+ if ((y != y2) || (x != x2))
+ return FALSE;
+
+ for (int i = 0; i < grid_n; i++) {
+ y = GRID_Y(grid_g[i]);
+ x = GRID_X(grid_g[i]);
+
+ if ((floor_ptr->grid_array[y][x].m_idx > 0) && !((y == y2) && (x == x2))) {
+ monster_type *m_ptr = &floor_ptr->m_list[floor_ptr->grid_array[y][x].m_idx];
+ if (is_friend == is_pet(m_ptr)) {
+ return FALSE;
+ }
+ }
+
+ if (player_bold(target_ptr, y, x) && is_friend)
+ return FALSE;
+ }
+ return TRUE;
+}
/*!
* @brief モンスターのボルト型魔法処理 /
*/
void bolt(player_type *target_ptr, MONSTER_IDX m_idx, POSITION y, POSITION x, EFFECT_ID typ, int dam_hp, int monspell, int target_type)
{
- BIT_FLAGS flg = 0;
- switch (target_type)
- {
- case MONSTER_TO_MONSTER:
- flg = PROJECT_STOP | PROJECT_KILL;
- break;
- case MONSTER_TO_PLAYER:
- flg = PROJECT_STOP | PROJECT_KILL | PROJECT_PLAYER;
- break;
- }
-
- if (typ != GF_ARROW) flg |= PROJECT_REFLECTABLE;
- bool learnable = spell_learnable(target_ptr, m_idx);
- (void)project(target_ptr, m_idx, 0, y, x, dam_hp, typ, flg, (learnable ? monspell : -1));
-}
+ BIT_FLAGS flg = 0;
+ switch (target_type) {
+ case MONSTER_TO_MONSTER:
+ flg = PROJECT_STOP | PROJECT_KILL;
+ break;
+ case MONSTER_TO_PLAYER:
+ flg = PROJECT_STOP | PROJECT_KILL | PROJECT_PLAYER;
+ break;
+ }
+ if (typ != GF_ARROW)
+ flg |= PROJECT_REFLECTABLE;
+ bool learnable = spell_learnable(target_ptr, m_idx);
+ (void)project(target_ptr, m_idx, 0, y, x, dam_hp, typ, flg, (learnable ? monspell : -1));
+}
/*!
* @brief モンスターのビーム型魔法処理 /
*/
void beam(player_type *target_ptr, MONSTER_IDX m_idx, POSITION y, POSITION x, EFFECT_ID typ, int dam_hp, int monspell, int target_type)
{
- BIT_FLAGS flg = 0;
- switch (target_type)
- {
- case MONSTER_TO_MONSTER:
- flg = PROJECT_BEAM | PROJECT_KILL | PROJECT_THRU;
- break;
- case MONSTER_TO_PLAYER:
- flg = PROJECT_BEAM | PROJECT_KILL | PROJECT_THRU | PROJECT_PLAYER;
- break;
- }
-
- bool learnable = spell_learnable(target_ptr, m_idx);
- (void)project(target_ptr, m_idx, 0, y, x, dam_hp, typ, flg, (learnable ? monspell : -1));
-}
+ BIT_FLAGS flg = 0;
+ switch (target_type) {
+ case MONSTER_TO_MONSTER:
+ flg = PROJECT_BEAM | PROJECT_KILL | PROJECT_THRU;
+ break;
+ case MONSTER_TO_PLAYER:
+ flg = PROJECT_BEAM | PROJECT_KILL | PROJECT_THRU | PROJECT_PLAYER;
+ break;
+ }
+ bool learnable = spell_learnable(target_ptr, m_idx);
+ (void)project(target_ptr, m_idx, 0, y, x, dam_hp, typ, flg, (learnable ? monspell : -1));
+}
/*!
* @brief モンスターのボール型&ブレス型魔法処理 /
* @param target_type モンスターからモンスターへ撃つならMONSTER_TO_MONSTER、モンスターからプレイヤーならMONSTER_TO_PLAYER
* @return なし
*/
-void breath(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, EFFECT_ID typ, int dam_hp, POSITION rad, bool breath, int monspell, int target_type)
+void breath(
+ player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, EFFECT_ID typ, int dam_hp, POSITION rad, bool breath, int monspell, int target_type)
{
- monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- BIT_FLAGS flg = 0x00;
- switch (target_type)
- {
- case MONSTER_TO_MONSTER:
- flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
- break;
- case MONSTER_TO_PLAYER:
- flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_PLAYER;
- break;
- }
-
- if ((rad < 1) && breath) rad = (r_ptr->flags2 & (RF2_POWERFUL)) ? 3 : 2;
-
- if (breath) rad = 0 - rad;
-
- switch (typ)
- {
- case GF_ROCKET:
- flg |= PROJECT_STOP;
- break;
- case GF_DRAIN_MANA:
- case GF_MIND_BLAST:
- case GF_BRAIN_SMASH:
- case GF_CAUSE_1:
- case GF_CAUSE_2:
- case GF_CAUSE_3:
- case GF_CAUSE_4:
- case GF_HAND_DOOM:
- flg |= (PROJECT_HIDE | PROJECT_AIMED);
- break;
- }
-
- bool learnable = spell_learnable(target_ptr, m_idx);
- (void)project(target_ptr, m_idx, rad, y, x, dam_hp, typ, flg, (learnable ? monspell : -1));
-}
+ monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ BIT_FLAGS flg = 0x00;
+ switch (target_type) {
+ case MONSTER_TO_MONSTER:
+ flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
+ break;
+ case MONSTER_TO_PLAYER:
+ flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_PLAYER;
+ break;
+ }
+
+ if ((rad < 1) && breath)
+ rad = (r_ptr->flags2 & (RF2_POWERFUL)) ? 3 : 2;
+
+ if (breath)
+ rad = 0 - rad;
+
+ switch (typ) {
+ case GF_ROCKET:
+ flg |= PROJECT_STOP;
+ break;
+ case GF_DRAIN_MANA:
+ case GF_MIND_BLAST:
+ case GF_BRAIN_SMASH:
+ case GF_CAUSE_1:
+ case GF_CAUSE_2:
+ case GF_CAUSE_3:
+ case GF_CAUSE_4:
+ case GF_HAND_DOOM:
+ flg |= (PROJECT_HIDE | PROJECT_AIMED);
+ break;
+ }
+ bool learnable = spell_learnable(target_ptr, m_idx);
+ (void)project(target_ptr, m_idx, rad, y, x, dam_hp, typ, flg, (learnable ? monspell : -1));
+}
/*!
* @brief ID値が正しいモンスター魔法IDかどうかを返す /
*/
static bool spell_attack(byte spell)
{
- /* All RF4 spells hurt (except for shriek and dispel) */
- if (spell < 128 && spell > 98) return TRUE;
+ /* All RF4 spells hurt (except for shriek and dispel) */
+ if (spell < 128 && spell > 98)
+ return TRUE;
- /* Various "ball" spells */
- if (spell >= 128 && spell <= 128 + 8) return TRUE;
+ /* Various "ball" spells */
+ if (spell >= 128 && spell <= 128 + 8)
+ return TRUE;
- /* "Cause wounds" and "bolt" spells */
- if (spell >= 128 + 12 && spell < 128 + 27) return TRUE;
+ /* "Cause wounds" and "bolt" spells */
+ if (spell >= 128 + 12 && spell < 128 + 27)
+ return TRUE;
- /* Hand of Doom */
- if (spell == 160 + 1) return TRUE;
+ /* Hand of Doom */
+ if (spell == 160 + 1)
+ return TRUE;
- /* Psycho-Spear */
- if (spell == 160 + 11) return TRUE;
+ /* Psycho-Spear */
+ if (spell == 160 + 11)
+ return TRUE;
- /* Doesn't hurt */
- return FALSE;
+ /* Doesn't hurt */
+ return FALSE;
}
-
/*!
* @brief ID値が退避目的に適したモンスター魔法IDかどうかを返す /
* Return TRUE if a spell is good for escaping.
*/
static bool spell_escape(byte spell)
{
- /* Blink or Teleport */
- if (spell == 160 + 4 || spell == 160 + 5) return TRUE;
+ /* Blink or Teleport */
+ if (spell == 160 + 4 || spell == 160 + 5)
+ return TRUE;
- /* Teleport the player away */
- if (spell == 160 + 9 || spell == 160 + 10) return TRUE;
+ /* Teleport the player away */
+ if (spell == 160 + 9 || spell == 160 + 10)
+ return TRUE;
- /* Isn't good for escaping */
- return FALSE;
+ /* Isn't good for escaping */
+ return FALSE;
}
-
/*!
* @brief ID値が妨害目的に適したモンスター魔法IDかどうかを返す /
* Return TRUE if a spell is good for annoying the player.
*/
static bool spell_annoy(byte spell)
{
- /* Shriek */
- if (spell == 96 + 0) return TRUE;
+ /* Shriek */
+ if (spell == 96 + 0)
+ return TRUE;
- /* Brain smash, et al (added curses) */
- if (spell >= 128 + 9 && spell <= 128 + 14) return TRUE;
+ /* Brain smash, et al (added curses) */
+ if (spell >= 128 + 9 && spell <= 128 + 14)
+ return TRUE;
- /* Scare, confuse, blind, slow, paralyze */
- if (spell >= 128 + 27 && spell <= 128 + 31) return TRUE;
+ /* Scare, confuse, blind, slow, paralyze */
+ if (spell >= 128 + 27 && spell <= 128 + 31)
+ return TRUE;
- /* Teleport to */
- if (spell == 160 + 8) return TRUE;
+ /* Teleport to */
+ if (spell == 160 + 8)
+ return TRUE;
- /* Teleport level */
- if (spell == 160 + 10) return TRUE;
+ /* Teleport level */
+ if (spell == 160 + 10)
+ return TRUE;
- /* Darkness, make traps, cause amnesia */
- if (spell >= 160 + 12 && spell <= 160 + 14) return TRUE;
+ /* Darkness, make traps, cause amnesia */
+ if (spell >= 160 + 12 && spell <= 160 + 14)
+ return TRUE;
- /* Doesn't annoy */
- return FALSE;
+ /* Doesn't annoy */
+ return FALSE;
}
-
/*!
* @brief ID値が召喚型のモンスター魔法IDかどうかを返す /
* Return TRUE if a spell is good for annoying the player.
*/
static bool spell_summon(byte spell)
{
- /* All summon spells */
- if (spell >= 160 + 16) return TRUE;
+ /* All summon spells */
+ if (spell >= 160 + 16)
+ return TRUE;
- /* Doesn't summon */
- return FALSE;
+ /* Doesn't summon */
+ return FALSE;
}
-
/*!
* @brief ID値が死者復活処理かどうかを返す /
* Return TRUE if a spell is good for annoying the player.
*/
static bool spell_raise(byte spell)
{
- /* All raise-dead spells */
- if (spell == 160 + 15) return TRUE;
+ /* All raise-dead spells */
+ if (spell == 160 + 15)
+ return TRUE;
- /* Doesn't summon */
- return FALSE;
+ /* Doesn't summon */
+ return FALSE;
}
-
/*!
* @brief ID値が戦術的なモンスター魔法IDかどうかを返す /
* Return TRUE if a spell is good in a tactical situation.
*/
static bool spell_tactic(byte spell)
{
- /* Blink */
- if (spell == 160 + 4) return TRUE;
+ /* Blink */
+ if (spell == 160 + 4)
+ return TRUE;
- /* Not good */
- return FALSE;
+ /* Not good */
+ return FALSE;
}
-
/*!
* @brief ID値が無敵化するモンスター魔法IDかどうかを返す /
* Return TRUE if a spell makes invulnerable.
*/
static bool spell_invulner(byte spell)
{
- /* Invulnerability */
- if (spell == 160 + 3) return TRUE;
+ /* Invulnerability */
+ if (spell == 160 + 3)
+ return TRUE;
- /* No invulnerability */
- return FALSE;
+ /* No invulnerability */
+ return FALSE;
}
-
/*!
* @brief ID値が加速するモンスター魔法IDかどうかを返す /
* Return TRUE if a spell hastes.
*/
static bool spell_haste(byte spell)
{
- /* Haste self */
- if (spell == 160 + 0) return TRUE;
+ /* Haste self */
+ if (spell == 160 + 0)
+ return TRUE;
- /* Not a haste spell */
- return FALSE;
+ /* Not a haste spell */
+ return FALSE;
}
-
/*!
* @brief ID値が時間停止を行うモンスター魔法IDかどうかを返す /
* Return TRUE if a spell world.
*/
static bool spell_world(byte spell)
{
- if (spell == 160 + 6) return TRUE;
- return FALSE;
+ if (spell == 160 + 6)
+ return TRUE;
+ return FALSE;
}
-
/*!
* @brief ID値が特別効果のモンスター魔法IDかどうかを返す /
* Return TRUE if a spell special.
*/
static bool spell_special(player_type *target_ptr, byte spell)
{
- if (target_ptr->phase_out) return FALSE;
- if (spell == 160 + 7) return TRUE;
- return FALSE;
+ if (target_ptr->phase_out)
+ return FALSE;
+ if (spell == 160 + 7)
+ return TRUE;
+ return FALSE;
}
-
/*!
* @brief ID値が光の剣のモンスター魔法IDかどうかを返す /
* Return TRUE if a spell psycho-spear.
*/
static bool spell_psy_spe(byte spell)
{
- /* world */
- if (spell == 160 + 11) return TRUE;
+ /* world */
+ if (spell == 160 + 11)
+ return TRUE;
- /* Not a haste spell */
- return FALSE;
+ /* Not a haste spell */
+ return FALSE;
}
-
/*!
* @brief ID値が治癒魔法かどうかを返す /
* Return TRUE if a spell is good for healing.
*/
static bool spell_heal(byte spell)
{
- /* Heal */
- if (spell == 160 + 2) return TRUE;
+ /* Heal */
+ if (spell == 160 + 2)
+ return TRUE;
- /* No healing */
- return FALSE;
+ /* No healing */
+ return FALSE;
}
-
/*!
* @brief ID値が魔力消去かどうかを返す /
* Return TRUE if a spell is good for dispel.
*/
static bool spell_dispel(byte spell)
{
- /* Dispel */
- if (spell == 96 + 2) return TRUE;
+ /* Dispel */
+ if (spell == 96 + 2)
+ return TRUE;
- /* No dispel */
- return FALSE;
+ /* No dispel */
+ return FALSE;
}
-
/*!
* @brief モンスターがプレイヤーに魔力消去を与えるべきかを判定するルーチン
* Check should monster cast dispel spell.
*/
bool dispel_check(player_type *creature_ptr, MONSTER_IDX m_idx)
{
- if (IS_INVULN(creature_ptr)) return TRUE;
-
- if (creature_ptr->wraith_form) return TRUE;
-
- if (creature_ptr->shield) return TRUE;
+ if (IS_INVULN(creature_ptr))
+ return TRUE;
- if (creature_ptr->magicdef) return TRUE;
+ if (creature_ptr->wraith_form)
+ return TRUE;
- if (creature_ptr->multishadow) return TRUE;
+ if (creature_ptr->shield)
+ return TRUE;
- if (creature_ptr->dustrobe) return TRUE;
+ if (creature_ptr->magicdef)
+ return TRUE;
- if (creature_ptr->shero && (creature_ptr->pclass != CLASS_BERSERKER)) return TRUE;
+ if (creature_ptr->multishadow)
+ return TRUE;
- if (creature_ptr->mimic_form == MIMIC_DEMON_LORD) return TRUE;
+ if (creature_ptr->dustrobe)
+ return TRUE;
- monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[m_idx];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (r_ptr->flags4 & RF4_BR_ACID)
- {
- if (!creature_ptr->immune_acid && (creature_ptr->oppose_acid || music_singing(creature_ptr, MUSIC_RESIST))) return TRUE;
- if (creature_ptr->special_defense & DEFENSE_ACID) return TRUE;
- }
+ if (creature_ptr->shero && (creature_ptr->pclass != CLASS_BERSERKER))
+ return TRUE;
- if (r_ptr->flags4 & RF4_BR_FIRE)
- {
- if (!((creature_ptr->prace == RACE_BALROG) && creature_ptr->lev > 44))
- {
- if (!creature_ptr->immune_fire && (creature_ptr->oppose_fire || music_singing(creature_ptr, MUSIC_RESIST))) return TRUE;
- if (creature_ptr->special_defense & DEFENSE_FIRE) return TRUE;
- }
- }
+ if (creature_ptr->mimic_form == MIMIC_DEMON_LORD)
+ return TRUE;
- if (r_ptr->flags4 & RF4_BR_ELEC)
- {
- if (!creature_ptr->immune_elec && (creature_ptr->oppose_elec || music_singing(creature_ptr, MUSIC_RESIST))) return TRUE;
- if (creature_ptr->special_defense & DEFENSE_ELEC) return TRUE;
- }
-
- if (r_ptr->flags4 & RF4_BR_COLD)
- {
- if (!creature_ptr->immune_cold && (creature_ptr->oppose_cold || music_singing(creature_ptr, MUSIC_RESIST))) return TRUE;
- if (creature_ptr->special_defense & DEFENSE_COLD) return TRUE;
- }
+ monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[m_idx];
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ if (r_ptr->flags4 & RF4_BR_ACID) {
+ if (!creature_ptr->immune_acid && (creature_ptr->oppose_acid || music_singing(creature_ptr, MUSIC_RESIST)))
+ return TRUE;
+ if (creature_ptr->special_defense & DEFENSE_ACID)
+ return TRUE;
+ }
- if (r_ptr->flags4 & (RF4_BR_POIS | RF4_BR_NUKE))
- {
- if (!((creature_ptr->pclass == CLASS_NINJA) && creature_ptr->lev > 44))
- {
- if (creature_ptr->oppose_pois || music_singing(creature_ptr, MUSIC_RESIST)) return TRUE;
- if (creature_ptr->special_defense & DEFENSE_POIS) return TRUE;
- }
- }
+ if (r_ptr->flags4 & RF4_BR_FIRE) {
+ if (!((creature_ptr->prace == RACE_BALROG) && creature_ptr->lev > 44)) {
+ if (!creature_ptr->immune_fire && (creature_ptr->oppose_fire || music_singing(creature_ptr, MUSIC_RESIST)))
+ return TRUE;
+ if (creature_ptr->special_defense & DEFENSE_FIRE)
+ return TRUE;
+ }
+ }
- if (creature_ptr->ult_res) return TRUE;
+ if (r_ptr->flags4 & RF4_BR_ELEC) {
+ if (!creature_ptr->immune_elec && (creature_ptr->oppose_elec || music_singing(creature_ptr, MUSIC_RESIST)))
+ return TRUE;
+ if (creature_ptr->special_defense & DEFENSE_ELEC)
+ return TRUE;
+ }
- if (creature_ptr->tsuyoshi) return TRUE;
+ if (r_ptr->flags4 & RF4_BR_COLD) {
+ if (!creature_ptr->immune_cold && (creature_ptr->oppose_cold || music_singing(creature_ptr, MUSIC_RESIST)))
+ return TRUE;
+ if (creature_ptr->special_defense & DEFENSE_COLD)
+ return TRUE;
+ }
- if ((creature_ptr->special_attack & ATTACK_ACID) && !(r_ptr->flagsr & RFR_EFF_IM_ACID_MASK)) return TRUE;
- if ((creature_ptr->special_attack & ATTACK_FIRE) && !(r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK)) return TRUE;
- if ((creature_ptr->special_attack & ATTACK_ELEC) && !(r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK)) return TRUE;
- if ((creature_ptr->special_attack & ATTACK_COLD) && !(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK)) return TRUE;
- if ((creature_ptr->special_attack & ATTACK_POIS) && !(r_ptr->flagsr & RFR_EFF_IM_POIS_MASK)) return TRUE;
+ if (r_ptr->flags4 & (RF4_BR_POIS | RF4_BR_NUKE)) {
+ if (!((creature_ptr->pclass == CLASS_NINJA) && creature_ptr->lev > 44)) {
+ if (creature_ptr->oppose_pois || music_singing(creature_ptr, MUSIC_RESIST))
+ return TRUE;
+ if (creature_ptr->special_defense & DEFENSE_POIS)
+ return TRUE;
+ }
+ }
- if (creature_ptr->pspeed < 145)
- {
- if (IS_FAST(creature_ptr)) return TRUE;
- }
+ if (creature_ptr->ult_res)
+ return TRUE;
+
+ if (creature_ptr->tsuyoshi)
+ return TRUE;
+
+ if ((creature_ptr->special_attack & ATTACK_ACID) && !(r_ptr->flagsr & RFR_EFF_IM_ACID_MASK))
+ return TRUE;
+ if ((creature_ptr->special_attack & ATTACK_FIRE) && !(r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK))
+ return TRUE;
+ if ((creature_ptr->special_attack & ATTACK_ELEC) && !(r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK))
+ return TRUE;
+ if ((creature_ptr->special_attack & ATTACK_COLD) && !(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK))
+ return TRUE;
+ if ((creature_ptr->special_attack & ATTACK_POIS) && !(r_ptr->flagsr & RFR_EFF_IM_POIS_MASK))
+ return TRUE;
+
+ if (creature_ptr->pspeed < 145) {
+ if (IS_FAST(creature_ptr))
+ return TRUE;
+ }
- if (creature_ptr->lightspeed && (m_ptr->mspeed < 136)) return TRUE;
+ if (creature_ptr->lightspeed && (m_ptr->mspeed < 136))
+ return TRUE;
- if (creature_ptr->riding && (creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].mspeed < 135))
- {
- if (monster_fast_remaining(&creature_ptr->current_floor_ptr->m_list[creature_ptr->riding])) return TRUE;
- }
+ if (creature_ptr->riding && (creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].mspeed < 135)) {
+ if (monster_fast_remaining(&creature_ptr->current_floor_ptr->m_list[creature_ptr->riding]))
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
-
/*!
* todo 長過ぎる。切り分けが必要
* @brief モンスターの魔法選択ルーチン
*/
static int choose_attack_spell(player_type *target_ptr, MONSTER_IDX m_idx, byte spells[], byte num)
{
- byte escape[96], escape_num = 0;
- byte attack[96], attack_num = 0;
- byte summon[96], summon_num = 0;
- byte tactic[96], tactic_num = 0;
- byte annoy[96], annoy_num = 0;
- byte invul[96], invul_num = 0;
- byte haste[96], haste_num = 0;
- byte world[96], world_num = 0;
- byte special[96], special_num = 0;
- byte psy_spe[96], psy_spe_num = 0;
- byte raise[96], raise_num = 0;
- byte heal[96], heal_num = 0;
- byte dispel[96], dispel_num = 0;
-
- monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (r_ptr->flags2 & (RF2_STUPID)) return (spells[randint0(num)]);
-
- for (int i = 0; i < num; i++)
- {
- if (spell_escape(spells[i])) escape[escape_num++] = spells[i];
-
- if (spell_attack(spells[i])) attack[attack_num++] = spells[i];
-
- if (spell_summon(spells[i])) summon[summon_num++] = spells[i];
-
- if (spell_tactic(spells[i])) tactic[tactic_num++] = spells[i];
-
- if (spell_annoy(spells[i])) annoy[annoy_num++] = spells[i];
-
- if (spell_invulner(spells[i])) invul[invul_num++] = spells[i];
-
- if (spell_haste(spells[i])) haste[haste_num++] = spells[i];
-
- if (spell_world(spells[i])) world[world_num++] = spells[i];
-
- if (spell_special(target_ptr, spells[i])) special[special_num++] = spells[i];
-
- if (spell_psy_spe(spells[i])) psy_spe[psy_spe_num++] = spells[i];
-
- if (spell_raise(spells[i])) raise[raise_num++] = spells[i];
-
- if (spell_heal(spells[i])) heal[heal_num++] = spells[i];
-
- if (spell_dispel(spells[i])) dispel[dispel_num++] = spells[i];
- }
-
- if (world_num && (randint0(100) < 15) && !current_world_ptr->timewalk_m_idx)
- {
- return (world[randint0(world_num)]);
- }
-
- if (special_num)
- {
- bool success = FALSE;
- switch (m_ptr->r_idx)
- {
- case MON_BANOR:
- case MON_LUPART:
- if ((m_ptr->hp < m_ptr->maxhp / 2) && r_info[MON_BANOR].max_num && r_info[MON_LUPART].max_num) success = TRUE;
- break;
- default: break;
- }
-
- if (success) return (special[randint0(special_num)]);
- }
-
- if (m_ptr->hp < m_ptr->maxhp / 3 && one_in_(2))
- {
- if (heal_num) return (heal[randint0(heal_num)]);
- }
-
- if (((m_ptr->hp < m_ptr->maxhp / 3) || monster_fear_remaining(m_ptr)) && one_in_(2))
- {
- if (escape_num) return (escape[randint0(escape_num)]);
- }
-
- if (special_num)
- {
- bool success = FALSE;
- switch (m_ptr->r_idx)
- {
- case MON_OHMU:
- case MON_BANOR:
- case MON_LUPART:
- break;
- case MON_BANORLUPART:
- if (randint0(100) < 70) success = TRUE;
- break;
- case MON_ROLENTO:
- if (randint0(100) < 40) success = TRUE;
- break;
- default:
- if (randint0(100) < 50) success = TRUE;
- break;
- }
- if (success) return (special[randint0(special_num)]);
- }
-
- if ((distance(target_ptr->y, target_ptr->x, m_ptr->fy, m_ptr->fx) < 4) && (attack_num || (r_ptr->a_ability_flags2 & RF6_TRAPS)) && (randint0(100) < 75) && !current_world_ptr->timewalk_m_idx)
- {
- if (tactic_num) return (tactic[randint0(tactic_num)]);
- }
-
- if (summon_num && (randint0(100) < 40))
- {
- return (summon[randint0(summon_num)]);
- }
-
- if (dispel_num && one_in_(2))
- {
- if (dispel_check(target_ptr, m_idx))
- {
- return (dispel[randint0(dispel_num)]);
- }
- }
-
- if (raise_num && (randint0(100) < 40))
- {
- return (raise[randint0(raise_num)]);
- }
-
- if (IS_INVULN(target_ptr))
- {
- if (psy_spe_num && (randint0(100) < 50))
- {
- return (psy_spe[randint0(psy_spe_num)]);
- }
- else if (attack_num && (randint0(100) < 40))
- {
- return (attack[randint0(attack_num)]);
- }
- }
- else if (attack_num && (randint0(100) < 85))
- {
- return (attack[randint0(attack_num)]);
- }
-
- if (tactic_num && (randint0(100) < 50) && !current_world_ptr->timewalk_m_idx)
- {
- return (tactic[randint0(tactic_num)]);
- }
-
- if (invul_num && !m_ptr->mtimed[MTIMED_INVULNER] && (randint0(100) < 50))
- {
- return (invul[randint0(invul_num)]);
- }
-
- if ((m_ptr->hp < m_ptr->maxhp * 3 / 4) && (randint0(100) < 25))
- {
- if (heal_num) return (heal[randint0(heal_num)]);
- }
-
- if (haste_num && (randint0(100) < 20) && !monster_fast_remaining(m_ptr))
- {
- return (haste[randint0(haste_num)]);
- }
-
- if (annoy_num && (randint0(100) < 80))
- {
- return (annoy[randint0(annoy_num)]);
- }
-
- return 0;
-}
+ byte escape[96], escape_num = 0;
+ byte attack[96], attack_num = 0;
+ byte summon[96], summon_num = 0;
+ byte tactic[96], tactic_num = 0;
+ byte annoy[96], annoy_num = 0;
+ byte invul[96], invul_num = 0;
+ byte haste[96], haste_num = 0;
+ byte world[96], world_num = 0;
+ byte special[96], special_num = 0;
+ byte psy_spe[96], psy_spe_num = 0;
+ byte raise[96], raise_num = 0;
+ byte heal[96], heal_num = 0;
+ byte dispel[96], dispel_num = 0;
+
+ monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ if (r_ptr->flags2 & (RF2_STUPID))
+ return (spells[randint0(num)]);
+
+ for (int i = 0; i < num; i++) {
+ if (spell_escape(spells[i]))
+ escape[escape_num++] = spells[i];
+
+ if (spell_attack(spells[i]))
+ attack[attack_num++] = spells[i];
+
+ if (spell_summon(spells[i]))
+ summon[summon_num++] = spells[i];
+
+ if (spell_tactic(spells[i]))
+ tactic[tactic_num++] = spells[i];
+
+ if (spell_annoy(spells[i]))
+ annoy[annoy_num++] = spells[i];
+
+ if (spell_invulner(spells[i]))
+ invul[invul_num++] = spells[i];
+
+ if (spell_haste(spells[i]))
+ haste[haste_num++] = spells[i];
+ if (spell_world(spells[i]))
+ world[world_num++] = spells[i];
+
+ if (spell_special(target_ptr, spells[i]))
+ special[special_num++] = spells[i];
+
+ if (spell_psy_spe(spells[i]))
+ psy_spe[psy_spe_num++] = spells[i];
+
+ if (spell_raise(spells[i]))
+ raise[raise_num++] = spells[i];
+
+ if (spell_heal(spells[i]))
+ heal[heal_num++] = spells[i];
+
+ if (spell_dispel(spells[i]))
+ dispel[dispel_num++] = spells[i];
+ }
+
+ if (world_num && (randint0(100) < 15) && !current_world_ptr->timewalk_m_idx) {
+ return (world[randint0(world_num)]);
+ }
+
+ if (special_num) {
+ bool success = FALSE;
+ switch (m_ptr->r_idx) {
+ case MON_BANOR:
+ case MON_LUPART:
+ if ((m_ptr->hp < m_ptr->maxhp / 2) && r_info[MON_BANOR].max_num && r_info[MON_LUPART].max_num)
+ success = TRUE;
+ break;
+ default:
+ break;
+ }
+
+ if (success)
+ return (special[randint0(special_num)]);
+ }
+
+ if (m_ptr->hp < m_ptr->maxhp / 3 && one_in_(2)) {
+ if (heal_num)
+ return (heal[randint0(heal_num)]);
+ }
+
+ if (((m_ptr->hp < m_ptr->maxhp / 3) || monster_fear_remaining(m_ptr)) && one_in_(2)) {
+ if (escape_num)
+ return (escape[randint0(escape_num)]);
+ }
+
+ if (special_num) {
+ bool success = FALSE;
+ switch (m_ptr->r_idx) {
+ case MON_OHMU:
+ case MON_BANOR:
+ case MON_LUPART:
+ break;
+ case MON_BANORLUPART:
+ if (randint0(100) < 70)
+ success = TRUE;
+ break;
+ case MON_ROLENTO:
+ if (randint0(100) < 40)
+ success = TRUE;
+ break;
+ default:
+ if (randint0(100) < 50)
+ success = TRUE;
+ break;
+ }
+ if (success)
+ return (special[randint0(special_num)]);
+ }
+
+ if ((distance(target_ptr->y, target_ptr->x, m_ptr->fy, m_ptr->fx) < 4) && (attack_num || (r_ptr->a_ability_flags2 & RF6_TRAPS)) && (randint0(100) < 75)
+ && !current_world_ptr->timewalk_m_idx) {
+ if (tactic_num)
+ return (tactic[randint0(tactic_num)]);
+ }
+
+ if (summon_num && (randint0(100) < 40)) {
+ return (summon[randint0(summon_num)]);
+ }
+
+ if (dispel_num && one_in_(2)) {
+ if (dispel_check(target_ptr, m_idx)) {
+ return (dispel[randint0(dispel_num)]);
+ }
+ }
+
+ if (raise_num && (randint0(100) < 40)) {
+ return (raise[randint0(raise_num)]);
+ }
+
+ if (IS_INVULN(target_ptr)) {
+ if (psy_spe_num && (randint0(100) < 50)) {
+ return (psy_spe[randint0(psy_spe_num)]);
+ } else if (attack_num && (randint0(100) < 40)) {
+ return (attack[randint0(attack_num)]);
+ }
+ } else if (attack_num && (randint0(100) < 85)) {
+ return (attack[randint0(attack_num)]);
+ }
+
+ if (tactic_num && (randint0(100) < 50) && !current_world_ptr->timewalk_m_idx) {
+ return (tactic[randint0(tactic_num)]);
+ }
+
+ if (invul_num && !m_ptr->mtimed[MTIMED_INVULNER] && (randint0(100) < 50)) {
+ return (invul[randint0(invul_num)]);
+ }
+
+ if ((m_ptr->hp < m_ptr->maxhp * 3 / 4) && (randint0(100) < 25)) {
+ if (heal_num)
+ return (heal[randint0(heal_num)]);
+ }
+
+ if (haste_num && (randint0(100) < 20) && !monster_fast_remaining(m_ptr)) {
+ return (haste[randint0(haste_num)]);
+ }
+
+ if (annoy_num && (randint0(100) < 80)) {
+ return (annoy[randint0(annoy_num)]);
+ }
+
+ return 0;
+}
/*!
* @brief ID値が非魔術的な特殊技能かどうかを返す /
*/
bool spell_is_inate(SPELL_IDX spell)
{
- if (spell < 32 * 4) /* Set RF4 */
- {
- if ((1L << (spell - 32 * 3)) & RF4_NOMAGIC_MASK) return TRUE;
- }
-
- if (spell < 32 * 5) /* Set RF5 */
- {
- if ((1L << (spell - 32 * 4)) & RF5_NOMAGIC_MASK) return TRUE;
- }
-
- if (spell < 32 * 6) /* Set RF6 */
- {
- if ((1L << (spell - 32 * 5)) & RF6_NOMAGIC_MASK) return TRUE;
- }
-
- /* This spell is not "inate" */
- return FALSE;
-}
+ if (spell < 32 * 4) /* Set RF4 */
+ {
+ if ((1L << (spell - 32 * 3)) & RF4_NOMAGIC_MASK)
+ return TRUE;
+ }
+
+ if (spell < 32 * 5) /* Set RF5 */
+ {
+ if ((1L << (spell - 32 * 4)) & RF5_NOMAGIC_MASK)
+ return TRUE;
+ }
+
+ if (spell < 32 * 6) /* Set RF6 */
+ {
+ if ((1L << (spell - 32 * 5)) & RF6_NOMAGIC_MASK)
+ return TRUE;
+ }
+ /* This spell is not "inate" */
+ return FALSE;
+}
/*!
* @brief モンスターがプレイヤーにダメージを与えるための最適な座標を算出する /
* @param path_check 射線を判定するための関数ポインタ
* @return 有効な座標があった場合TRUEを返す
*/
-static bool adjacent_grid_check(player_type *target_ptr, monster_type *m_ptr, POSITION *yp, POSITION *xp,
- int f_flag, bool(*path_check)(player_type *, POSITION, POSITION, POSITION, POSITION))
+static bool adjacent_grid_check(player_type *target_ptr, monster_type *m_ptr, POSITION *yp, POSITION *xp, int f_flag,
+ bool (*path_check)(player_type *, POSITION, POSITION, POSITION, POSITION))
{
- static int tonari_y[4][8] = { {-1, -1, -1, 0, 0, 1, 1, 1},
- {-1, -1, -1, 0, 0, 1, 1, 1},
- { 1, 1, 1, 0, 0, -1, -1, -1},
- { 1, 1, 1, 0, 0, -1, -1, -1} };
- static int tonari_x[4][8] = { {-1, 0, 1, -1, 1, -1, 0, 1},
- { 1, 0, -1, 1, -1, 1, 0, -1},
- {-1, 0, 1, -1, 1, -1, 0, 1},
- { 1, 0, -1, 1, -1, 1, 0, -1} };
-
- int next;
- if (m_ptr->fy < target_ptr->y && m_ptr->fx < target_ptr->x) next = 0;
- else if (m_ptr->fy < target_ptr->y) next = 1;
- else if (m_ptr->fx < target_ptr->x) next = 2;
- else next = 3;
-
- floor_type *floor_ptr = target_ptr->current_floor_ptr;
- for (int i = 0; i < 8; i++)
- {
- int next_x = *xp + tonari_x[next][i];
- int next_y = *yp + tonari_y[next][i];
- grid_type *g_ptr;
- g_ptr = &floor_ptr->grid_array[next_y][next_x];
- if (!cave_have_flag_grid(g_ptr, f_flag)) continue;
-
- if (path_check(target_ptr, m_ptr->fy, m_ptr->fx, next_y, next_x))
- {
- *yp = next_y;
- *xp = next_x;
- return TRUE;
- }
- }
-
- return FALSE;
-}
+ static int tonari_y[4][8] = { { -1, -1, -1, 0, 0, 1, 1, 1 }, { -1, -1, -1, 0, 0, 1, 1, 1 }, { 1, 1, 1, 0, 0, -1, -1, -1 }, { 1, 1, 1, 0, 0, -1, -1, -1 } };
+ static int tonari_x[4][8] = { { -1, 0, 1, -1, 1, -1, 0, 1 }, { 1, 0, -1, 1, -1, 1, 0, -1 }, { -1, 0, 1, -1, 1, -1, 0, 1 }, { 1, 0, -1, 1, -1, 1, 0, -1 } };
+
+ int next;
+ if (m_ptr->fy < target_ptr->y && m_ptr->fx < target_ptr->x)
+ next = 0;
+ else if (m_ptr->fy < target_ptr->y)
+ next = 1;
+ else if (m_ptr->fx < target_ptr->x)
+ next = 2;
+ else
+ next = 3;
+
+ floor_type *floor_ptr = target_ptr->current_floor_ptr;
+ for (int i = 0; i < 8; i++) {
+ int next_x = *xp + tonari_x[next][i];
+ int next_y = *yp + tonari_y[next][i];
+ grid_type *g_ptr;
+ g_ptr = &floor_ptr->grid_array[next_y][next_x];
+ if (!cave_have_flag_grid(g_ptr, f_flag))
+ continue;
+
+ if (path_check(target_ptr, m_ptr->fy, m_ptr->fx, next_y, next_x)) {
+ *yp = next_y;
+ *xp = next_x;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
/*!
* todo メインルーチンの割に長過ぎる。要分割
{
#ifdef JP
#else
- char m_poss[80];
+ char m_poss[80];
#endif
- floor_type *floor_ptr = target_ptr->current_floor_ptr;
- monster_type *m_ptr = &floor_ptr->m_list[m_idx];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
-
- if (monster_confused_remaining(m_ptr))
- {
- reset_target(m_ptr);
- return FALSE;
- }
-
- if (m_ptr->mflag & MFLAG_NICE) return FALSE;
- if (!is_hostile(m_ptr)) return FALSE;
-
- bool no_inate = FALSE;
- if (randint0(100) >= (r_ptr->freq_spell * 2)) no_inate = TRUE;
-
- BIT_FLAGS f4 = r_ptr->flags4;
- BIT_FLAGS f5 = r_ptr->a_ability_flags1;
- BIT_FLAGS f6 = r_ptr->a_ability_flags2;
-
- if ((m_ptr->cdis > MAX_RANGE) && !m_ptr->target_y) return FALSE;
-
- POSITION x = target_ptr->x;
- POSITION y = target_ptr->y;
- POSITION x_br_lite = 0;
- POSITION y_br_lite = 0;
- if (f4 & RF4_BR_LITE)
- {
- y_br_lite = y;
- x_br_lite = x;
-
- if (los(target_ptr, m_ptr->fy, m_ptr->fx, y_br_lite, x_br_lite))
- {
- feature_type *f_ptr = &f_info[floor_ptr->grid_array[y_br_lite][x_br_lite].feat];
-
- if (!have_flag(f_ptr->flags, FF_LOS))
- {
- if (have_flag(f_ptr->flags, FF_PROJECT) && one_in_(2)) f4 &= ~(RF4_BR_LITE);
- }
- }
- else if (!adjacent_grid_check(target_ptr, m_ptr, &y_br_lite, &x_br_lite, FF_LOS, los)) f4 &= ~(RF4_BR_LITE);
-
- if (!(f4 & RF4_BR_LITE))
- {
- y_br_lite = 0;
- x_br_lite = 0;
- }
- }
-
- bool do_spell = DO_SPELL_NONE;
- if (projectable(target_ptr, m_ptr->fy, m_ptr->fx, y, x))
- {
- feature_type *f_ptr = &f_info[floor_ptr->grid_array[y][x].feat];
- if (!have_flag(f_ptr->flags, FF_PROJECT))
- {
- if ((f4 & RF4_BR_DISI) && have_flag(f_ptr->flags, FF_HURT_DISI) && one_in_(2)) do_spell = DO_SPELL_BR_DISI;
- else if ((f4 & RF4_BR_LITE) && have_flag(f_ptr->flags, FF_LOS) && one_in_(2)) do_spell = DO_SPELL_BR_LITE;
- }
- }
- else
- {
- bool success = FALSE;
- if ((f4 & RF4_BR_DISI) && (m_ptr->cdis < MAX_RANGE / 2) &&
- in_disintegration_range(floor_ptr, m_ptr->fy, m_ptr->fx, y, x) &&
- (one_in_(10) || (projectable(target_ptr, y, x, m_ptr->fy, m_ptr->fx) && one_in_(2))))
- {
- do_spell = DO_SPELL_BR_DISI;
- success = TRUE;
- }
- else if ((f4 & RF4_BR_LITE) && (m_ptr->cdis < MAX_RANGE / 2) &&
- los(target_ptr, m_ptr->fy, m_ptr->fx, y, x) && one_in_(5))
- {
- do_spell = DO_SPELL_BR_LITE;
- success = TRUE;
- }
- else if ((f5 & RF5_BA_LITE) && (m_ptr->cdis <= MAX_RANGE))
- {
- POSITION by = y, bx = x;
- get_project_point(target_ptr, m_ptr->fy, m_ptr->fx, &by, &bx, 0L);
- if ((distance(by, bx, y, x) <= 3) && los(target_ptr, by, bx, y, x) && one_in_(5))
- {
- do_spell = DO_SPELL_BA_LITE;
- success = TRUE;
- }
- }
-
- if (!success) success = adjacent_grid_check(target_ptr, m_ptr, &y, &x, FF_PROJECT, projectable);
-
- if (!success)
- {
- if (m_ptr->target_y && m_ptr->target_x)
- {
- y = m_ptr->target_y;
- x = m_ptr->target_x;
- f4 &= (RF4_INDIRECT_MASK);
- f5 &= (RF5_INDIRECT_MASK);
- f6 &= (RF6_INDIRECT_MASK);
- success = TRUE;
- }
-
- if (y_br_lite && x_br_lite && (m_ptr->cdis < MAX_RANGE / 2) && one_in_(5))
- {
- if (!success)
- {
- y = y_br_lite;
- x = x_br_lite;
- do_spell = DO_SPELL_BR_LITE;
- success = TRUE;
- }
- else f4 |= (RF4_BR_LITE);
- }
- }
-
- if (!success) return FALSE;
- }
-
- reset_target(m_ptr);
- DEPTH rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
- if (no_inate)
- {
- f4 &= ~(RF4_NOMAGIC_MASK);
- f5 &= ~(RF5_NOMAGIC_MASK);
- f6 &= ~(RF6_NOMAGIC_MASK);
- }
-
- bool can_use_lite_area = FALSE;
- if (f6 & RF6_DARKNESS)
- {
- if ((target_ptr->pclass == CLASS_NINJA) &&
- !(r_ptr->flags3 & (RF3_UNDEAD | RF3_HURT_LITE)) &&
- !(r_ptr->flags7 & RF7_DARK_MASK))
- can_use_lite_area = TRUE;
-
- if (!(r_ptr->flags2 & RF2_STUPID))
- {
- if (d_info[target_ptr->dungeon_idx].flags1 & DF1_DARKNESS) f6 &= ~(RF6_DARKNESS);
- else if ((target_ptr->pclass == CLASS_NINJA) && !can_use_lite_area) f6 &= ~(RF6_DARKNESS);
- }
- }
-
- bool in_no_magic_dungeon = (d_info[target_ptr->dungeon_idx].flags1 & DF1_NO_MAGIC) && floor_ptr->dun_level
- && (!floor_ptr->inside_quest || is_fixed_quest_idx(floor_ptr->inside_quest));
- if (in_no_magic_dungeon && !(r_ptr->flags2 & RF2_STUPID))
- {
- f4 &= (RF4_NOMAGIC_MASK);
- f5 &= (RF5_NOMAGIC_MASK);
- f6 &= (RF6_NOMAGIC_MASK);
- }
-
- if (r_ptr->flags2 & RF2_SMART)
- {
- if ((m_ptr->hp < m_ptr->maxhp / 10) &&
- (randint0(100) < 50))
- {
- f4 &= (RF4_INT_MASK);
- f5 &= (RF5_INT_MASK);
- f6 &= (RF6_INT_MASK);
- }
-
- if ((f6 & RF6_TELE_LEVEL) && is_teleport_level_ineffective(target_ptr, 0))
- {
- f6 &= ~(RF6_TELE_LEVEL);
- }
- }
-
- if (!f4 && !f5 && !f6) return FALSE;
-
- remove_bad_spells(m_idx, target_ptr, &f4, &f5, &f6);
- if (floor_ptr->inside_arena || target_ptr->phase_out)
- {
- f4 &= ~(RF4_SUMMON_MASK);
- f5 &= ~(RF5_SUMMON_MASK);
- f6 &= ~(RF6_SUMMON_MASK | RF6_TELE_LEVEL);
-
- if (m_ptr->r_idx == MON_ROLENTO) f6 &= ~(RF6_SPECIAL);
- }
-
- if (!f4 && !f5 && !f6) return FALSE;
-
- if (!(r_ptr->flags2 & RF2_STUPID))
- {
- if (!target_ptr->csp) f5 &= ~(RF5_DRAIN_MANA);
-
- if (((f4 & RF4_BOLT_MASK) ||
- (f5 & RF5_BOLT_MASK) ||
- (f6 & RF6_BOLT_MASK)) &&
- !clean_shot(target_ptr, m_ptr->fy, m_ptr->fx, target_ptr->y, target_ptr->x, FALSE))
- {
- f4 &= ~(RF4_BOLT_MASK);
- f5 &= ~(RF5_BOLT_MASK);
- f6 &= ~(RF6_BOLT_MASK);
- }
-
- if (((f4 & RF4_SUMMON_MASK) ||
- (f5 & RF5_SUMMON_MASK) ||
- (f6 & RF6_SUMMON_MASK)) &&
- !(summon_possible(target_ptr, y, x)))
- {
- f4 &= ~(RF4_SUMMON_MASK);
- f5 &= ~(RF5_SUMMON_MASK);
- f6 &= ~(RF6_SUMMON_MASK);
- }
-
- if ((f6 & RF6_RAISE_DEAD) && !raise_possible(target_ptr, m_ptr))
- {
- f6 &= ~(RF6_RAISE_DEAD);
- }
-
- if (f6 & RF6_SPECIAL)
- {
- if ((m_ptr->r_idx == MON_ROLENTO) && !summon_possible(target_ptr, y, x))
- {
- f6 &= ~(RF6_SPECIAL);
- }
- }
-
- if (!f4 && !f5 && !f6) return FALSE;
- }
-
- byte spell[96], num = 0;
- for (int k = 0; k < 32; k++)
- {
- if (f4 & (1L << k)) spell[num++] = k + RF4_SPELL_START;
- }
-
- for (int k = 0; k < 32; k++)
- {
- if (f5 & (1L << k)) spell[num++] = k + RF5_SPELL_START;
- }
-
- for (int k = 0; k < 32; k++)
- {
- if (f6 & (1L << k)) spell[num++] = k + RF6_SPELL_START;
- }
-
- if (!num) return FALSE;
-
- if (!target_ptr->playing || target_ptr->is_dead) return FALSE;
-
- if (target_ptr->leaving) return FALSE;
-
- GAME_TEXT m_name[MAX_NLEN];
- monster_desc(target_ptr, m_name, m_ptr, 0x00);
+ floor_type *floor_ptr = target_ptr->current_floor_ptr;
+ monster_type *m_ptr = &floor_ptr->m_list[m_idx];
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+
+ if (monster_confused_remaining(m_ptr)) {
+ reset_target(m_ptr);
+ return FALSE;
+ }
+
+ if (m_ptr->mflag & MFLAG_NICE)
+ return FALSE;
+ if (!is_hostile(m_ptr))
+ return FALSE;
+
+ bool no_inate = FALSE;
+ if (randint0(100) >= (r_ptr->freq_spell * 2))
+ no_inate = TRUE;
+
+ BIT_FLAGS f4 = r_ptr->flags4;
+ BIT_FLAGS f5 = r_ptr->a_ability_flags1;
+ BIT_FLAGS f6 = r_ptr->a_ability_flags2;
+
+ if ((m_ptr->cdis > MAX_RANGE) && !m_ptr->target_y)
+ return FALSE;
+
+ POSITION x = target_ptr->x;
+ POSITION y = target_ptr->y;
+ POSITION x_br_lite = 0;
+ POSITION y_br_lite = 0;
+ if (f4 & RF4_BR_LITE) {
+ y_br_lite = y;
+ x_br_lite = x;
+
+ if (los(target_ptr, m_ptr->fy, m_ptr->fx, y_br_lite, x_br_lite)) {
+ feature_type *f_ptr = &f_info[floor_ptr->grid_array[y_br_lite][x_br_lite].feat];
+
+ if (!have_flag(f_ptr->flags, FF_LOS)) {
+ if (have_flag(f_ptr->flags, FF_PROJECT) && one_in_(2))
+ f4 &= ~(RF4_BR_LITE);
+ }
+ } else if (!adjacent_grid_check(target_ptr, m_ptr, &y_br_lite, &x_br_lite, FF_LOS, los))
+ f4 &= ~(RF4_BR_LITE);
+
+ if (!(f4 & RF4_BR_LITE)) {
+ y_br_lite = 0;
+ x_br_lite = 0;
+ }
+ }
+
+ bool do_spell = DO_SPELL_NONE;
+ if (projectable(target_ptr, m_ptr->fy, m_ptr->fx, y, x)) {
+ feature_type *f_ptr = &f_info[floor_ptr->grid_array[y][x].feat];
+ if (!have_flag(f_ptr->flags, FF_PROJECT)) {
+ if ((f4 & RF4_BR_DISI) && have_flag(f_ptr->flags, FF_HURT_DISI) && one_in_(2))
+ do_spell = DO_SPELL_BR_DISI;
+ else if ((f4 & RF4_BR_LITE) && have_flag(f_ptr->flags, FF_LOS) && one_in_(2))
+ do_spell = DO_SPELL_BR_LITE;
+ }
+ } else {
+ bool success = FALSE;
+ if ((f4 & RF4_BR_DISI) && (m_ptr->cdis < MAX_RANGE / 2) && in_disintegration_range(floor_ptr, m_ptr->fy, m_ptr->fx, y, x)
+ && (one_in_(10) || (projectable(target_ptr, y, x, m_ptr->fy, m_ptr->fx) && one_in_(2)))) {
+ do_spell = DO_SPELL_BR_DISI;
+ success = TRUE;
+ } else if ((f4 & RF4_BR_LITE) && (m_ptr->cdis < MAX_RANGE / 2) && los(target_ptr, m_ptr->fy, m_ptr->fx, y, x) && one_in_(5)) {
+ do_spell = DO_SPELL_BR_LITE;
+ success = TRUE;
+ } else if ((f5 & RF5_BA_LITE) && (m_ptr->cdis <= MAX_RANGE)) {
+ POSITION by = y, bx = x;
+ get_project_point(target_ptr, m_ptr->fy, m_ptr->fx, &by, &bx, 0L);
+ if ((distance(by, bx, y, x) <= 3) && los(target_ptr, by, bx, y, x) && one_in_(5)) {
+ do_spell = DO_SPELL_BA_LITE;
+ success = TRUE;
+ }
+ }
+
+ if (!success)
+ success = adjacent_grid_check(target_ptr, m_ptr, &y, &x, FF_PROJECT, projectable);
+
+ if (!success) {
+ if (m_ptr->target_y && m_ptr->target_x) {
+ y = m_ptr->target_y;
+ x = m_ptr->target_x;
+ f4 &= (RF4_INDIRECT_MASK);
+ f5 &= (RF5_INDIRECT_MASK);
+ f6 &= (RF6_INDIRECT_MASK);
+ success = TRUE;
+ }
+
+ if (y_br_lite && x_br_lite && (m_ptr->cdis < MAX_RANGE / 2) && one_in_(5)) {
+ if (!success) {
+ y = y_br_lite;
+ x = x_br_lite;
+ do_spell = DO_SPELL_BR_LITE;
+ success = TRUE;
+ } else
+ f4 |= (RF4_BR_LITE);
+ }
+ }
+
+ if (!success)
+ return FALSE;
+ }
+
+ reset_target(m_ptr);
+ DEPTH rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
+ if (no_inate) {
+ f4 &= ~(RF4_NOMAGIC_MASK);
+ f5 &= ~(RF5_NOMAGIC_MASK);
+ f6 &= ~(RF6_NOMAGIC_MASK);
+ }
+
+ bool can_use_lite_area = FALSE;
+ if (f6 & RF6_DARKNESS) {
+ if ((target_ptr->pclass == CLASS_NINJA) && !(r_ptr->flags3 & (RF3_UNDEAD | RF3_HURT_LITE)) && !(r_ptr->flags7 & RF7_DARK_MASK))
+ can_use_lite_area = TRUE;
+
+ if (!(r_ptr->flags2 & RF2_STUPID)) {
+ if (d_info[target_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
+ f6 &= ~(RF6_DARKNESS);
+ else if ((target_ptr->pclass == CLASS_NINJA) && !can_use_lite_area)
+ f6 &= ~(RF6_DARKNESS);
+ }
+ }
+
+ bool in_no_magic_dungeon = (d_info[target_ptr->dungeon_idx].flags1 & DF1_NO_MAGIC) && floor_ptr->dun_level
+ && (!floor_ptr->inside_quest || is_fixed_quest_idx(floor_ptr->inside_quest));
+ if (in_no_magic_dungeon && !(r_ptr->flags2 & RF2_STUPID)) {
+ f4 &= (RF4_NOMAGIC_MASK);
+ f5 &= (RF5_NOMAGIC_MASK);
+ f6 &= (RF6_NOMAGIC_MASK);
+ }
+
+ if (r_ptr->flags2 & RF2_SMART) {
+ if ((m_ptr->hp < m_ptr->maxhp / 10) && (randint0(100) < 50)) {
+ f4 &= (RF4_INT_MASK);
+ f5 &= (RF5_INT_MASK);
+ f6 &= (RF6_INT_MASK);
+ }
+
+ if ((f6 & RF6_TELE_LEVEL) && is_teleport_level_ineffective(target_ptr, 0)) {
+ f6 &= ~(RF6_TELE_LEVEL);
+ }
+ }
+
+ if (!f4 && !f5 && !f6)
+ return FALSE;
+
+ remove_bad_spells(m_idx, target_ptr, &f4, &f5, &f6);
+ if (floor_ptr->inside_arena || target_ptr->phase_out) {
+ f4 &= ~(RF4_SUMMON_MASK);
+ f5 &= ~(RF5_SUMMON_MASK);
+ f6 &= ~(RF6_SUMMON_MASK | RF6_TELE_LEVEL);
+
+ if (m_ptr->r_idx == MON_ROLENTO)
+ f6 &= ~(RF6_SPECIAL);
+ }
+
+ if (!f4 && !f5 && !f6)
+ return FALSE;
+
+ if (!(r_ptr->flags2 & RF2_STUPID)) {
+ if (!target_ptr->csp)
+ f5 &= ~(RF5_DRAIN_MANA);
+
+ if (((f4 & RF4_BOLT_MASK) || (f5 & RF5_BOLT_MASK) || (f6 & RF6_BOLT_MASK))
+ && !clean_shot(target_ptr, m_ptr->fy, m_ptr->fx, target_ptr->y, target_ptr->x, FALSE)) {
+ f4 &= ~(RF4_BOLT_MASK);
+ f5 &= ~(RF5_BOLT_MASK);
+ f6 &= ~(RF6_BOLT_MASK);
+ }
+
+ if (((f4 & RF4_SUMMON_MASK) || (f5 & RF5_SUMMON_MASK) || (f6 & RF6_SUMMON_MASK)) && !(summon_possible(target_ptr, y, x))) {
+ f4 &= ~(RF4_SUMMON_MASK);
+ f5 &= ~(RF5_SUMMON_MASK);
+ f6 &= ~(RF6_SUMMON_MASK);
+ }
+
+ if ((f6 & RF6_RAISE_DEAD) && !raise_possible(target_ptr, m_ptr)) {
+ f6 &= ~(RF6_RAISE_DEAD);
+ }
+
+ if (f6 & RF6_SPECIAL) {
+ if ((m_ptr->r_idx == MON_ROLENTO) && !summon_possible(target_ptr, y, x)) {
+ f6 &= ~(RF6_SPECIAL);
+ }
+ }
+
+ if (!f4 && !f5 && !f6)
+ return FALSE;
+ }
+
+ byte spell[96], num = 0;
+ for (int k = 0; k < 32; k++) {
+ if (f4 & (1L << k))
+ spell[num++] = k + RF4_SPELL_START;
+ }
+
+ for (int k = 0; k < 32; k++) {
+ if (f5 & (1L << k))
+ spell[num++] = k + RF5_SPELL_START;
+ }
+
+ for (int k = 0; k < 32; k++) {
+ if (f6 & (1L << k))
+ spell[num++] = k + RF6_SPELL_START;
+ }
+
+ if (!num)
+ return FALSE;
+
+ if (!target_ptr->playing || target_ptr->is_dead)
+ return FALSE;
+
+ if (target_ptr->leaving)
+ return FALSE;
+
+ GAME_TEXT m_name[MAX_NLEN];
+ monster_desc(target_ptr, m_name, m_ptr, 0x00);
#ifdef JP
#else
- /* Get the monster possessive ("his"/"her"/"its") */
- monster_desc(target_ptr, m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
+ /* Get the monster possessive ("his"/"her"/"its") */
+ monster_desc(target_ptr, m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
#endif
- SPELL_IDX thrown_spell = 0;
- switch (do_spell)
- {
- case DO_SPELL_NONE:
- {
- int attempt = 10;
- while (attempt--)
- {
- thrown_spell = choose_attack_spell(target_ptr, m_idx, spell, num);
- if (thrown_spell) break;
- }
+ SPELL_IDX thrown_spell = 0;
+ switch (do_spell) {
+ case DO_SPELL_NONE: {
+ int attempt = 10;
+ while (attempt--) {
+ thrown_spell = choose_attack_spell(target_ptr, m_idx, spell, num);
+ if (thrown_spell)
break;
+ }
+ break;
+ }
+ case DO_SPELL_BR_LITE:
+ thrown_spell = 96 + 14; /* RF4_BR_LITE */
+ break;
+ case DO_SPELL_BR_DISI:
+ thrown_spell = 96 + 31; /* RF4_BR_DISI */
+ break;
+ case DO_SPELL_BA_LITE:
+ thrown_spell = 128 + 20; /* RF5_BA_LITE */
+ break;
+ default:
+ return FALSE;
+ }
+
+ if (!thrown_spell)
+ return FALSE;
+
+ PERCENTAGE failrate = 25 - (rlev + 3) / 4;
+
+ if (r_ptr->flags2 & RF2_STUPID)
+ failrate = 0;
+
+ if (!spell_is_inate(thrown_spell) && (in_no_magic_dungeon || (monster_stunned_remaining(m_ptr) && one_in_(2)) || (randint0(100) < failrate))) {
+ disturb(target_ptr, TRUE, TRUE);
+ msg_format(_("%^sは呪文を唱えようとしたが失敗した。", "%^s tries to cast a spell, but fails."), m_name);
+
+ return TRUE;
+ }
+
+ if (!spell_is_inate(thrown_spell) && magic_barrier(target_ptr, m_idx)) {
+ msg_format(_("反魔法バリアが%^sの呪文をかき消した。", "Anti magic barrier cancels the spell which %^s casts."), m_name);
+ return TRUE;
}
- case DO_SPELL_BR_LITE:
- thrown_spell = 96 + 14; /* RF4_BR_LITE */
- break;
- case DO_SPELL_BR_DISI:
- thrown_spell = 96 + 31; /* RF4_BR_DISI */
- break;
- case DO_SPELL_BA_LITE:
- thrown_spell = 128 + 20; /* RF5_BA_LITE */
- break;
- default:
- return FALSE;
- }
-
- if (!thrown_spell) return FALSE;
-
- PERCENTAGE failrate = 25 - (rlev + 3) / 4;
-
- if (r_ptr->flags2 & RF2_STUPID) failrate = 0;
-
- if (!spell_is_inate(thrown_spell)
- && (in_no_magic_dungeon || (monster_stunned_remaining(m_ptr) && one_in_(2)) || (randint0(100) < failrate)))
- {
- disturb(target_ptr, TRUE, TRUE);
- msg_format(_("%^sは呪文を唱えようとしたが失敗した。", "%^s tries to cast a spell, but fails."), m_name);
-
- return TRUE;
- }
-
- if (!spell_is_inate(thrown_spell) && magic_barrier(target_ptr, m_idx))
- {
- msg_format(_("反魔法バリアが%^sの呪文をかき消した。", "Anti magic barrier cancels the spell which %^s casts."), m_name);
- return TRUE;
- }
-
- bool direct = player_bold(target_ptr, y, x);
- bool can_remember = is_original_ap_and_seen(target_ptr, m_ptr);
- if (!direct)
- {
- switch (thrown_spell)
- {
- case 96 + 2: /* RF4_DISPEL */
- case 96 + 4: /* RF4_SHOOT */
- case 128 + 9: /* RF5_DRAIN_MANA */
- case 128 + 10: /* RF5_MIND_BLAST */
- case 128 + 11: /* RF5_BRAIN_SMASH */
- case 128 + 12: /* RF5_CAUSE_1 */
- case 128 + 13: /* RF5_CAUSE_2 */
- case 128 + 14: /* RF5_CAUSE_3 */
- case 128 + 15: /* RF5_CAUSE_4 */
- case 128 + 16: /* RF5_BO_ACID */
- case 128 + 17: /* RF5_BO_ELEC */
- case 128 + 18: /* RF5_BO_FIRE */
- case 128 + 19: /* RF5_BO_COLD */
- case 128 + 21: /* RF5_BO_NETH */
- case 128 + 22: /* RF5_BO_WATE */
- case 128 + 23: /* RF5_BO_MANA */
- case 128 + 24: /* RF5_BO_PLAS */
- case 128 + 25: /* RF5_BO_ICEE */
- case 128 + 26: /* RF5_MISSILE */
- case 128 + 27: /* RF5_SCARE */
- case 128 + 28: /* RF5_BLIND */
- case 128 + 29: /* RF5_CONF */
- case 128 + 30: /* RF5_SLOW */
- case 128 + 31: /* RF5_HOLD */
- case 160 + 1: /* RF6_HAND_DOOM */
- case 160 + 8: /* RF6_TELE_TO */
- case 160 + 9: /* RF6_TELE_AWAY */
- case 160 + 10: /* RF6_TELE_LEVEL */
- case 160 + 11: /* RF6_PSY_SPEAR */
- case 160 + 12: /* RF6_DARKNESS */
- case 160 + 14: /* RF6_FORGET */
- return FALSE;
- }
- }
-
- int dam = monspell_to_player(target_ptr, thrown_spell, y, x, m_idx);
- if (dam < 0) return FALSE;
-
- if ((target_ptr->action == ACTION_LEARN) && thrown_spell > 175)
- {
- learn_spell(target_ptr, thrown_spell - 96);
- }
-
- bool seen = (!target_ptr->blind && m_ptr->ml);
- bool maneable = player_has_los_bold(target_ptr, m_ptr->fy, m_ptr->fx);
- if (seen && maneable && !current_world_ptr->timewalk_m_idx && (target_ptr->pclass == CLASS_IMITATOR))
- {
- if (thrown_spell != 167) /* Not RF6_SPECIAL */
- {
- if (target_ptr->mane_num == MAX_MANE)
- {
- int i;
- target_ptr->mane_num--;
- for (i = 0; i < target_ptr->mane_num; i++)
- {
- target_ptr->mane_spell[i] = target_ptr->mane_spell[i + 1];
- target_ptr->mane_dam[i] = target_ptr->mane_dam[i + 1];
- }
- }
- target_ptr->mane_spell[target_ptr->mane_num] = thrown_spell - 96;
- target_ptr->mane_dam[target_ptr->mane_num] = dam;
- target_ptr->mane_num++;
- target_ptr->new_mane = TRUE;
-
- target_ptr->redraw |= (PR_IMITATION);
- }
- }
-
- if (can_remember)
- {
- if (thrown_spell < 32 * 4)
- {
- r_ptr->r_flags4 |= (1L << (thrown_spell - 32 * 3));
- if (r_ptr->r_cast_spell < MAX_UCHAR) r_ptr->r_cast_spell++;
- }
- else if (thrown_spell < 32 * 5)
- {
- r_ptr->r_flags5 |= (1L << (thrown_spell - 32 * 4));
- if (r_ptr->r_cast_spell < MAX_UCHAR) r_ptr->r_cast_spell++;
- }
- else if (thrown_spell < 32 * 6)
- {
- r_ptr->r_flags6 |= (1L << (thrown_spell - 32 * 5));
- if (r_ptr->r_cast_spell < MAX_UCHAR) r_ptr->r_cast_spell++;
- }
- }
-
- if (target_ptr->is_dead && (r_ptr->r_deaths < MAX_SHORT) && !floor_ptr->inside_arena)
- {
- r_ptr->r_deaths++;
- }
-
- return TRUE;
+
+ bool direct = player_bold(target_ptr, y, x);
+ bool can_remember = is_original_ap_and_seen(target_ptr, m_ptr);
+ if (!direct) {
+ switch (thrown_spell) {
+ case 96 + 2: /* RF4_DISPEL */
+ case 96 + 4: /* RF4_SHOOT */
+ case 128 + 9: /* RF5_DRAIN_MANA */
+ case 128 + 10: /* RF5_MIND_BLAST */
+ case 128 + 11: /* RF5_BRAIN_SMASH */
+ case 128 + 12: /* RF5_CAUSE_1 */
+ case 128 + 13: /* RF5_CAUSE_2 */
+ case 128 + 14: /* RF5_CAUSE_3 */
+ case 128 + 15: /* RF5_CAUSE_4 */
+ case 128 + 16: /* RF5_BO_ACID */
+ case 128 + 17: /* RF5_BO_ELEC */
+ case 128 + 18: /* RF5_BO_FIRE */
+ case 128 + 19: /* RF5_BO_COLD */
+ case 128 + 21: /* RF5_BO_NETH */
+ case 128 + 22: /* RF5_BO_WATE */
+ case 128 + 23: /* RF5_BO_MANA */
+ case 128 + 24: /* RF5_BO_PLAS */
+ case 128 + 25: /* RF5_BO_ICEE */
+ case 128 + 26: /* RF5_MISSILE */
+ case 128 + 27: /* RF5_SCARE */
+ case 128 + 28: /* RF5_BLIND */
+ case 128 + 29: /* RF5_CONF */
+ case 128 + 30: /* RF5_SLOW */
+ case 128 + 31: /* RF5_HOLD */
+ case 160 + 1: /* RF6_HAND_DOOM */
+ case 160 + 8: /* RF6_TELE_TO */
+ case 160 + 9: /* RF6_TELE_AWAY */
+ case 160 + 10: /* RF6_TELE_LEVEL */
+ case 160 + 11: /* RF6_PSY_SPEAR */
+ case 160 + 12: /* RF6_DARKNESS */
+ case 160 + 14: /* RF6_FORGET */
+ return FALSE;
+ }
+ }
+
+ int dam = monspell_to_player(target_ptr, thrown_spell, y, x, m_idx);
+ if (dam < 0)
+ return FALSE;
+
+ if ((target_ptr->action == ACTION_LEARN) && thrown_spell > 175) {
+ learn_spell(target_ptr, thrown_spell - 96);
+ }
+
+ bool seen = (!target_ptr->blind && m_ptr->ml);
+ bool maneable = player_has_los_bold(target_ptr, m_ptr->fy, m_ptr->fx);
+ if (seen && maneable && !current_world_ptr->timewalk_m_idx && (target_ptr->pclass == CLASS_IMITATOR)) {
+ if (thrown_spell != 167) /* Not RF6_SPECIAL */
+ {
+ if (target_ptr->mane_num == MAX_MANE) {
+ int i;
+ target_ptr->mane_num--;
+ for (i = 0; i < target_ptr->mane_num; i++) {
+ target_ptr->mane_spell[i] = target_ptr->mane_spell[i + 1];
+ target_ptr->mane_dam[i] = target_ptr->mane_dam[i + 1];
+ }
+ }
+ target_ptr->mane_spell[target_ptr->mane_num] = thrown_spell - 96;
+ target_ptr->mane_dam[target_ptr->mane_num] = dam;
+ target_ptr->mane_num++;
+ target_ptr->new_mane = TRUE;
+
+ target_ptr->redraw |= (PR_IMITATION);
+ }
+ }
+
+ if (can_remember) {
+ if (thrown_spell < 32 * 4) {
+ r_ptr->r_flags4 |= (1L << (thrown_spell - 32 * 3));
+ if (r_ptr->r_cast_spell < MAX_UCHAR)
+ r_ptr->r_cast_spell++;
+ } else if (thrown_spell < 32 * 5) {
+ r_ptr->r_flags5 |= (1L << (thrown_spell - 32 * 4));
+ if (r_ptr->r_cast_spell < MAX_UCHAR)
+ r_ptr->r_cast_spell++;
+ } else if (thrown_spell < 32 * 6) {
+ r_ptr->r_flags6 |= (1L << (thrown_spell - 32 * 5));
+ if (r_ptr->r_cast_spell < MAX_UCHAR)
+ r_ptr->r_cast_spell++;
+ }
+ }
+
+ if (target_ptr->is_dead && (r_ptr->r_deaths < MAX_SHORT) && !floor_ptr->inside_arena) {
+ r_ptr->r_deaths++;
+ }
+
+ return TRUE;
}
*/
static bool direct_beam(player_type *target_ptr, POSITION y1, POSITION x1, POSITION y2, POSITION x2, monster_type *m_ptr)
{
- floor_type *floor_ptr = target_ptr->current_floor_ptr;
- u16b grid_g[512];
- int grid_n = project_path(target_ptr, grid_g, MAX_RANGE, y1, x1, y2, x2, PROJECT_THRU);
- if (!grid_n) return FALSE;
-
- bool hit2 = FALSE;
- POSITION y, x;
- bool is_friend = is_pet(m_ptr);
- for (int i = 0; i < grid_n; i++)
- {
- y = GRID_Y(grid_g[i]);
- x = GRID_X(grid_g[i]);
-
- if (y == y2 && x == x2)
- hit2 = TRUE;
- else if (is_friend && floor_ptr->grid_array[y][x].m_idx > 0 &&
- !are_enemies(target_ptr, m_ptr, &floor_ptr->m_list[floor_ptr->grid_array[y][x].m_idx]))
- {
- return FALSE;
- }
-
- if (is_friend && player_bold(target_ptr, y, x))
- return FALSE;
- }
-
- if (!hit2) return FALSE;
- return TRUE;
+ floor_type *floor_ptr = target_ptr->current_floor_ptr;
+ u16b grid_g[512];
+ int grid_n = project_path(target_ptr, grid_g, MAX_RANGE, y1, x1, y2, x2, PROJECT_THRU);
+ if (!grid_n)
+ return FALSE;
+
+ bool hit2 = FALSE;
+ POSITION y, x;
+ bool is_friend = is_pet(m_ptr);
+ for (int i = 0; i < grid_n; i++) {
+ y = GRID_Y(grid_g[i]);
+ x = GRID_X(grid_g[i]);
+
+ if (y == y2 && x == x2)
+ hit2 = TRUE;
+ else if (is_friend && floor_ptr->grid_array[y][x].m_idx > 0 && !are_enemies(target_ptr, m_ptr, &floor_ptr->m_list[floor_ptr->grid_array[y][x].m_idx])) {
+ return FALSE;
+ }
+
+ if (is_friend && player_bold(target_ptr, y, x))
+ return FALSE;
+ }
+
+ if (!hit2)
+ return FALSE;
+ return TRUE;
}
-
/*!
* @brief モンスターが敵対モンスターに直接ブレスを当てることが可能かを判定する /
* Determine if a breath will hit the target.
*/
static bool breath_direct(player_type *master_ptr, POSITION y1, POSITION x1, POSITION y2, POSITION x2, POSITION rad, EFFECT_ID typ, bool is_friend)
{
- BIT_FLAGS flg;
- switch (typ)
- {
- case GF_LITE:
- case GF_LITE_WEAK:
- flg = PROJECT_LOS;
- break;
- case GF_DISINTEGRATE:
- flg = PROJECT_DISI;
- break;
- default:
- flg = 0;
- break;
- }
-
- u16b grid_g[512];
- int grid_n = project_path(master_ptr, grid_g, MAX_RANGE, y1, x1, y2, x2, flg);
- int i;
- POSITION y = y1;
- POSITION x = x1;
- for (i = 0; i < grid_n; ++i)
- {
- int ny = GRID_Y(grid_g[i]);
- int nx = GRID_X(grid_g[i]);
-
- if (flg & PROJECT_DISI)
- {
- if (cave_stop_disintegration(master_ptr->current_floor_ptr, ny, nx)) break;
- }
- else if (flg & PROJECT_LOS)
- {
- if (!cave_los_bold(master_ptr->current_floor_ptr, ny, nx)) break;
- }
- else
- {
- if (!cave_have_flag_bold(master_ptr->current_floor_ptr, ny, nx, FF_PROJECT)) break;
- }
-
- y = ny;
- x = nx;
- }
-
- grid_n = i;
- bool hit2 = FALSE;
- bool hityou = FALSE;
- if (!grid_n)
- {
- if (flg & PROJECT_DISI)
- {
- if (in_disintegration_range(master_ptr->current_floor_ptr, y1, x1, y2, x2) && (distance(y1, x1, y2, x2) <= rad)) hit2 = TRUE;
- if (in_disintegration_range(master_ptr->current_floor_ptr, y1, x1, master_ptr->y, master_ptr->x) && (distance(y1, x1, master_ptr->y, master_ptr->x) <= rad)) hityou = TRUE;
- }
- else if (flg & PROJECT_LOS)
- {
- if (los(master_ptr, y1, x1, y2, x2) && (distance(y1, x1, y2, x2) <= rad)) hit2 = TRUE;
- if (los(master_ptr, y1, x1, master_ptr->y, master_ptr->x) && (distance(y1, x1, master_ptr->y, master_ptr->x) <= rad)) hityou = TRUE;
- }
- else
- {
- if (projectable(master_ptr, y1, x1, y2, x2) && (distance(y1, x1, y2, x2) <= rad)) hit2 = TRUE;
- if (projectable(master_ptr, y1, x1, master_ptr->y, master_ptr->x) && (distance(y1, x1, master_ptr->y, master_ptr->x) <= rad)) hityou = TRUE;
- }
- }
- else
- {
- int grids = 0;
- POSITION gx[1024], gy[1024];
- POSITION gm[32];
- POSITION gm_rad = rad;
- breath_shape(master_ptr, grid_g, grid_n, &grids, gx, gy, gm, &gm_rad, rad, y1, x1, y, x, typ);
- for (i = 0; i < grids; i++)
- {
- y = gy[i];
- x = gx[i];
- if ((y == y2) && (x == x2)) hit2 = TRUE;
- if (player_bold(master_ptr, y, x)) hityou = TRUE;
- }
- }
-
- if (!hit2) return FALSE;
- if (is_friend && hityou) return FALSE;
-
- return TRUE;
+ BIT_FLAGS flg;
+ switch (typ) {
+ case GF_LITE:
+ case GF_LITE_WEAK:
+ flg = PROJECT_LOS;
+ break;
+ case GF_DISINTEGRATE:
+ flg = PROJECT_DISI;
+ break;
+ default:
+ flg = 0;
+ break;
+ }
+
+ u16b grid_g[512];
+ int grid_n = project_path(master_ptr, grid_g, MAX_RANGE, y1, x1, y2, x2, flg);
+ int i;
+ POSITION y = y1;
+ POSITION x = x1;
+ for (i = 0; i < grid_n; ++i) {
+ int ny = GRID_Y(grid_g[i]);
+ int nx = GRID_X(grid_g[i]);
+
+ if (flg & PROJECT_DISI) {
+ if (cave_stop_disintegration(master_ptr->current_floor_ptr, ny, nx))
+ break;
+ } else if (flg & PROJECT_LOS) {
+ if (!cave_los_bold(master_ptr->current_floor_ptr, ny, nx))
+ break;
+ } else {
+ if (!cave_have_flag_bold(master_ptr->current_floor_ptr, ny, nx, FF_PROJECT))
+ break;
+ }
+
+ y = ny;
+ x = nx;
+ }
+
+ grid_n = i;
+ bool hit2 = FALSE;
+ bool hityou = FALSE;
+ if (!grid_n) {
+ if (flg & PROJECT_DISI) {
+ if (in_disintegration_range(master_ptr->current_floor_ptr, y1, x1, y2, x2) && (distance(y1, x1, y2, x2) <= rad))
+ hit2 = TRUE;
+ if (in_disintegration_range(master_ptr->current_floor_ptr, y1, x1, master_ptr->y, master_ptr->x)
+ && (distance(y1, x1, master_ptr->y, master_ptr->x) <= rad))
+ hityou = TRUE;
+ } else if (flg & PROJECT_LOS) {
+ if (los(master_ptr, y1, x1, y2, x2) && (distance(y1, x1, y2, x2) <= rad))
+ hit2 = TRUE;
+ if (los(master_ptr, y1, x1, master_ptr->y, master_ptr->x) && (distance(y1, x1, master_ptr->y, master_ptr->x) <= rad))
+ hityou = TRUE;
+ } else {
+ if (projectable(master_ptr, y1, x1, y2, x2) && (distance(y1, x1, y2, x2) <= rad))
+ hit2 = TRUE;
+ if (projectable(master_ptr, y1, x1, master_ptr->y, master_ptr->x) && (distance(y1, x1, master_ptr->y, master_ptr->x) <= rad))
+ hityou = TRUE;
+ }
+ } else {
+ int grids = 0;
+ POSITION gx[1024], gy[1024];
+ POSITION gm[32];
+ POSITION gm_rad = rad;
+ breath_shape(master_ptr, grid_g, grid_n, &grids, gx, gy, gm, &gm_rad, rad, y1, x1, y, x, typ);
+ for (i = 0; i < grids; i++) {
+ y = gy[i];
+ x = gx[i];
+ if ((y == y2) && (x == x2))
+ hit2 = TRUE;
+ if (player_bold(master_ptr, y, x))
+ hityou = TRUE;
+ }
+ }
+
+ if (!hit2)
+ return FALSE;
+ if (is_friend && hityou)
+ return FALSE;
+
+ return TRUE;
}
-
/*!
* @brief モンスターが特殊能力の目標地点を決める処理 /
* Get the actual center point of ball spells (rad > 1) (originally from TOband)
*/
void get_project_point(player_type *target_ptr, POSITION sy, POSITION sx, POSITION *ty, POSITION *tx, BIT_FLAGS flg)
{
- u16b path_g[128];
- int path_n = project_path(target_ptr, path_g, MAX_RANGE, sy, sx, *ty, *tx, flg);
- *ty = sy;
- *tx = sx;
- for (int i = 0; i < path_n; i++)
- {
- sy = GRID_Y(path_g[i]);
- sx = GRID_X(path_g[i]);
- if (!cave_have_flag_bold(target_ptr->current_floor_ptr, sy, sx, FF_PROJECT)) break;
-
- *ty = sy;
- *tx = sx;
- }
+ u16b path_g[128];
+ int path_n = project_path(target_ptr, path_g, MAX_RANGE, sy, sx, *ty, *tx, flg);
+ *ty = sy;
+ *tx = sx;
+ for (int i = 0; i < path_n; i++) {
+ sy = GRID_Y(path_g[i]);
+ sx = GRID_X(path_g[i]);
+ if (!cave_have_flag_bold(target_ptr->current_floor_ptr, sy, sx, FF_PROJECT))
+ break;
+
+ *ty = sy;
+ *tx = sx;
+ }
}
-
/*!
* @brief モンスターが敵モンスターに魔力消去を使うかどうかを返す /
* Check should monster cast dispel spell at other monster.
*/
static bool dispel_check_monster(player_type *target_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx)
{
- monster_type *t_ptr = &target_ptr->current_floor_ptr->m_list[t_idx];
- if (monster_invulner_remaining(t_ptr)) return TRUE;
+ monster_type *t_ptr = &target_ptr->current_floor_ptr->m_list[t_idx];
+ if (monster_invulner_remaining(t_ptr))
+ return TRUE;
- if ((t_ptr->mspeed < 135) && monster_fast_remaining(t_ptr)) return TRUE;
+ if ((t_ptr->mspeed < 135) && monster_fast_remaining(t_ptr))
+ return TRUE;
- if ((t_idx == target_ptr->riding) && dispel_check(target_ptr, m_idx)) return TRUE;
+ if ((t_idx == target_ptr->riding) && dispel_check(target_ptr, m_idx))
+ return TRUE;
- return FALSE;
+ return FALSE;
}
-
/*!
* todo モンスターからモンスターへの呪文なのにplayer_typeが引数になり得るのは間違っている……
* @brief モンスターが敵モンスターに特殊能力を使う処理のメインルーチン /
*/
bool monst_spell_monst(player_type *target_ptr, MONSTER_IDX m_idx)
{
- POSITION y = 0, x = 0;
- int k;
- MONSTER_IDX target_idx = 0;
- int thrown_spell;
- HIT_POINT dam = 0;
- int start;
- int plus = 1;
+ POSITION y = 0, x = 0;
+ int k;
+ MONSTER_IDX target_idx = 0;
+ int thrown_spell;
+ HIT_POINT dam = 0;
+ int start;
+ int plus = 1;
- byte spell[96], num = 0;
+ byte spell[96], num = 0;
- GAME_TEXT m_name[160];
- GAME_TEXT t_name[160];
+ GAME_TEXT m_name[160];
+ GAME_TEXT t_name[160];
#ifdef JP
#else
- char m_poss[160];
+ char m_poss[160];
#endif
- floor_type *floor_ptr = target_ptr->current_floor_ptr;
- monster_type *m_ptr = &floor_ptr->m_list[m_idx];
- monster_type *t_ptr = NULL;
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- bool see_m = is_seen(target_ptr, m_ptr);
- bool maneable = player_has_los_bold(target_ptr, m_ptr->fy, m_ptr->fx);
- bool pet = is_pet(m_ptr);
- bool in_no_magic_dungeon = (d_info[target_ptr->dungeon_idx].flags1 & DF1_NO_MAGIC) && floor_ptr->dun_level
- && (!floor_ptr->inside_quest || is_fixed_quest_idx(floor_ptr->inside_quest));
- bool can_use_lite_area = FALSE;
- bool can_remember;
-
- if (monster_confused_remaining(m_ptr)) return FALSE;
-
- BIT_FLAGS f4 = r_ptr->flags4;
- BIT_FLAGS f5 = r_ptr->a_ability_flags1;
- BIT_FLAGS f6 = r_ptr->a_ability_flags2;
- if (target_ptr->pet_t_m_idx && pet)
- {
- target_idx = target_ptr->pet_t_m_idx;
- t_ptr = &floor_ptr->m_list[target_idx];
- if ((m_idx == target_idx) || !projectable(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx))
- {
- target_idx = 0;
- }
- }
-
- if (!target_idx && m_ptr->target_y)
- {
- target_idx = floor_ptr->grid_array[m_ptr->target_y][m_ptr->target_x].m_idx;
- if (target_idx)
- {
- t_ptr = &floor_ptr->m_list[target_idx];
- if ((m_idx == target_idx) ||
- ((target_idx != target_ptr->pet_t_m_idx) && !are_enemies(target_ptr, m_ptr, t_ptr)))
- {
- target_idx = 0;
- }
- else if (!projectable(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx))
- {
- f4 &= (RF4_INDIRECT_MASK);
- f5 &= (RF5_INDIRECT_MASK);
- f6 &= (RF6_INDIRECT_MASK);
- }
- }
- }
-
- if (!target_idx)
- {
- bool success = FALSE;
- if (target_ptr->phase_out)
- {
- start = randint1(floor_ptr->m_max - 1) + floor_ptr->m_max;
- if (randint0(2)) plus = -1;
- }
- else start = floor_ptr->m_max + 1;
-
- for (int i = start; ((i < start + floor_ptr->m_max) && (i > start - floor_ptr->m_max)); i += plus)
- {
- MONSTER_IDX dummy = (i % floor_ptr->m_max);
- if (!dummy) continue;
-
- target_idx = dummy;
- t_ptr = &floor_ptr->m_list[target_idx];
- if (!monster_is_valid(t_ptr)) continue;
-
- if ((m_idx == target_idx) || !are_enemies(target_ptr, m_ptr, t_ptr)) continue;
-
- if (!projectable(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx)) continue;
-
- success = TRUE;
- break;
- }
-
- if (!success) return FALSE;
- }
-
- y = t_ptr->fy;
- x = t_ptr->fx;
- reset_target(m_ptr);
- f6 &= ~(RF6_WORLD | RF6_TRAPS | RF6_FORGET);
- if (f4 & RF4_BR_LITE)
- {
- if (!los(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx))
- f4 &= ~(RF4_BR_LITE);
- }
-
- if (f6 & RF6_SPECIAL)
- {
- if ((m_ptr->r_idx != MON_ROLENTO) && (r_ptr->d_char != 'B'))
- f6 &= ~(RF6_SPECIAL);
- }
-
- if (f6 & RF6_DARKNESS)
- {
- bool vs_ninja = (target_ptr->pclass == CLASS_NINJA) && !is_hostile(t_ptr);
- if (vs_ninja &&
- !(r_ptr->flags3 & (RF3_UNDEAD | RF3_HURT_LITE)) &&
- !(r_ptr->flags7 & RF7_DARK_MASK))
- can_use_lite_area = TRUE;
-
- if (!(r_ptr->flags2 & RF2_STUPID))
- {
- if (d_info[target_ptr->dungeon_idx].flags1 & DF1_DARKNESS) f6 &= ~(RF6_DARKNESS);
- else if (vs_ninja && !can_use_lite_area) f6 &= ~(RF6_DARKNESS);
- }
- }
-
- if (in_no_magic_dungeon && !(r_ptr->flags2 & RF2_STUPID))
- {
- f4 &= (RF4_NOMAGIC_MASK);
- f5 &= (RF5_NOMAGIC_MASK);
- f6 &= (RF6_NOMAGIC_MASK);
- }
-
- if (floor_ptr->inside_arena || target_ptr->phase_out)
- {
- f4 &= ~(RF4_SUMMON_MASK);
- f5 &= ~(RF5_SUMMON_MASK);
- f6 &= ~(RF6_SUMMON_MASK | RF6_TELE_LEVEL);
-
- if (m_ptr->r_idx == MON_ROLENTO) f6 &= ~(RF6_SPECIAL);
- }
-
- if (target_ptr->phase_out && !one_in_(3))
- {
- f6 &= ~(RF6_HEAL);
- }
-
- if (m_idx == target_ptr->riding)
- {
- f4 &= ~(RF4_RIDING_MASK);
- f5 &= ~(RF5_RIDING_MASK);
- f6 &= ~(RF6_RIDING_MASK);
- }
-
- if (pet)
- {
- f4 &= ~(RF4_SHRIEK);
- f6 &= ~(RF6_DARKNESS | RF6_TRAPS);
-
- if (!(target_ptr->pet_extra_flags & PF_TELEPORT))
- {
- f6 &= ~(RF6_BLINK | RF6_TPORT | RF6_TELE_TO | RF6_TELE_AWAY | RF6_TELE_LEVEL);
- }
-
- if (!(target_ptr->pet_extra_flags & PF_ATTACK_SPELL))
- {
- f4 &= ~(RF4_ATTACK_MASK);
- f5 &= ~(RF5_ATTACK_MASK);
- f6 &= ~(RF6_ATTACK_MASK);
- }
-
- if (!(target_ptr->pet_extra_flags & PF_SUMMON_SPELL))
- {
- f4 &= ~(RF4_SUMMON_MASK);
- f5 &= ~(RF5_SUMMON_MASK);
- f6 &= ~(RF6_SUMMON_MASK);
- }
-
- if (!(target_ptr->pet_extra_flags & PF_BALL_SPELL) && (m_idx != target_ptr->riding))
- {
- if ((f4 & (RF4_BALL_MASK & ~(RF4_ROCKET))) ||
- (f5 & RF5_BALL_MASK) ||
- (f6 & RF6_BALL_MASK))
- {
- POSITION real_y = y;
- POSITION real_x = x;
-
- get_project_point(target_ptr, m_ptr->fy, m_ptr->fx, &real_y, &real_x, 0L);
-
- if (projectable(target_ptr, real_y, real_x, target_ptr->y, target_ptr->x))
- {
- int dist = distance(real_y, real_x, target_ptr->y, target_ptr->x);
-
- if (dist <= 2)
- {
- f4 &= ~(RF4_BALL_MASK & ~(RF4_ROCKET));
- f5 &= ~(RF5_BALL_MASK);
- f6 &= ~(RF6_BALL_MASK);
- }
- else if (dist <= 4)
- {
- f4 &= ~(RF4_BIG_BALL_MASK);
- f5 &= ~(RF5_BIG_BALL_MASK);
- f6 &= ~(RF6_BIG_BALL_MASK);
- }
- }
- else if (f5 & RF5_BA_LITE)
- {
- if ((distance(real_y, real_x, target_ptr->y, target_ptr->x) <= 4) && los(target_ptr, real_y, real_x, target_ptr->y, target_ptr->x))
- f5 &= ~(RF5_BA_LITE);
- }
- }
-
- if (f4 & RF4_ROCKET)
- {
- POSITION real_y = y;
- POSITION real_x = x;
- get_project_point(target_ptr, m_ptr->fy, m_ptr->fx, &real_y, &real_x, PROJECT_STOP);
- if (projectable(target_ptr, real_y, real_x, target_ptr->y, target_ptr->x) && (distance(real_y, real_x, target_ptr->y, target_ptr->x) <= 2))
- f4 &= ~(RF4_ROCKET);
- }
-
- if (((f4 & RF4_BEAM_MASK) || (f5 & RF5_BEAM_MASK) || (f6 & RF6_BEAM_MASK)) &&
- !direct_beam(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, m_ptr))
- {
- f4 &= ~(RF4_BEAM_MASK);
- f5 &= ~(RF5_BEAM_MASK);
- f6 &= ~(RF6_BEAM_MASK);
- }
-
- if ((f4 & RF4_BREATH_MASK) || (f5 & RF5_BREATH_MASK) || (f6 & RF6_BREATH_MASK))
- {
- POSITION rad = (r_ptr->flags2 & RF2_POWERFUL) ? 3 : 2;
- if (!breath_direct(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, rad, 0, TRUE))
- {
- f4 &= ~(RF4_BREATH_MASK);
- f5 &= ~(RF5_BREATH_MASK);
- f6 &= ~(RF6_BREATH_MASK);
- }
- else if ((f4 & RF4_BR_LITE) &&
- !breath_direct(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, rad, GF_LITE, TRUE))
- {
- f4 &= ~(RF4_BR_LITE);
- }
- else if ((f4 & RF4_BR_DISI) &&
- !breath_direct(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, rad, GF_DISINTEGRATE, TRUE))
- {
- f4 &= ~(RF4_BR_DISI);
- }
- }
- }
-
- if (f6 & RF6_SPECIAL)
- {
- if (m_ptr->r_idx == MON_ROLENTO)
- {
- if ((target_ptr->pet_extra_flags & (PF_ATTACK_SPELL | PF_SUMMON_SPELL)) != (PF_ATTACK_SPELL | PF_SUMMON_SPELL))
- f6 &= ~(RF6_SPECIAL);
- }
- else if (r_ptr->d_char == 'B')
- {
- if ((target_ptr->pet_extra_flags & (PF_ATTACK_SPELL | PF_TELEPORT)) != (PF_ATTACK_SPELL | PF_TELEPORT))
- f6 &= ~(RF6_SPECIAL);
- }
- else f6 &= ~(RF6_SPECIAL);
- }
- }
-
- if (!(r_ptr->flags2 & RF2_STUPID))
- {
- if (((f4 & RF4_BOLT_MASK) ||
- (f5 & RF5_BOLT_MASK) ||
- (f6 & RF6_BOLT_MASK)) &&
- !clean_shot(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, pet))
- {
- f4 &= ~(RF4_BOLT_MASK);
- f5 &= ~(RF5_BOLT_MASK);
- f6 &= ~(RF6_BOLT_MASK);
- }
-
- if (((f4 & RF4_SUMMON_MASK) ||
- (f5 & RF5_SUMMON_MASK) ||
- (f6 & RF6_SUMMON_MASK)) &&
- !(summon_possible(target_ptr, t_ptr->fy, t_ptr->fx)))
- {
- f4 &= ~(RF4_SUMMON_MASK);
- f5 &= ~(RF5_SUMMON_MASK);
- f6 &= ~(RF6_SUMMON_MASK);
- }
-
- if ((f4 & RF4_DISPEL) && !dispel_check_monster(target_ptr, m_idx, target_idx))
- {
- f4 &= ~(RF4_DISPEL);
- }
-
- if ((f6 & RF6_RAISE_DEAD) && !raise_possible(target_ptr, m_ptr))
- {
- f6 &= ~(RF6_RAISE_DEAD);
- }
-
- if (f6 & RF6_SPECIAL)
- {
- if ((m_ptr->r_idx == MON_ROLENTO) && !summon_possible(target_ptr, t_ptr->fy, t_ptr->fx))
- {
- f6 &= ~(RF6_SPECIAL);
- }
- }
- }
-
- if (r_ptr->flags2 & RF2_SMART)
- {
- if ((m_ptr->hp < m_ptr->maxhp / 10) &&
- (randint0(100) < 50))
- {
- f4 &= (RF4_INT_MASK);
- f5 &= (RF5_INT_MASK);
- f6 &= (RF6_INT_MASK);
- }
-
- if ((f6 & RF6_TELE_LEVEL) && is_teleport_level_ineffective(target_ptr, (target_idx == target_ptr->riding) ? 0 : target_idx))
- {
- f6 &= ~(RF6_TELE_LEVEL);
- }
- }
-
- if (!f4 && !f5 && !f6) return FALSE;
-
- for (k = 0; k < 32; k++)
- {
- if (f4 & (1L << k)) spell[num++] = k + RF4_SPELL_START;
- }
-
- for (k = 0; k < 32; k++)
- {
- if (f5 & (1L << k)) spell[num++] = k + RF5_SPELL_START;
- }
-
- for (k = 0; k < 32; k++)
- {
- if (f6 & (1L << k)) spell[num++] = k + RF6_SPELL_START;
- }
-
- if (!num) return FALSE;
-
- if (!target_ptr->playing || target_ptr->is_dead) return FALSE;
-
- if (target_ptr->leaving) return FALSE;
-
- /* Get the monster name (or "it") */
- monster_desc(target_ptr, m_name, m_ptr, 0x00);
+ floor_type *floor_ptr = target_ptr->current_floor_ptr;
+ monster_type *m_ptr = &floor_ptr->m_list[m_idx];
+ monster_type *t_ptr = NULL;
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ bool see_m = is_seen(target_ptr, m_ptr);
+ bool maneable = player_has_los_bold(target_ptr, m_ptr->fy, m_ptr->fx);
+ bool pet = is_pet(m_ptr);
+ bool in_no_magic_dungeon = (d_info[target_ptr->dungeon_idx].flags1 & DF1_NO_MAGIC) && floor_ptr->dun_level
+ && (!floor_ptr->inside_quest || is_fixed_quest_idx(floor_ptr->inside_quest));
+ bool can_use_lite_area = FALSE;
+ bool can_remember;
+
+ if (monster_confused_remaining(m_ptr))
+ return FALSE;
+
+ BIT_FLAGS f4 = r_ptr->flags4;
+ BIT_FLAGS f5 = r_ptr->a_ability_flags1;
+ BIT_FLAGS f6 = r_ptr->a_ability_flags2;
+ if (target_ptr->pet_t_m_idx && pet) {
+ target_idx = target_ptr->pet_t_m_idx;
+ t_ptr = &floor_ptr->m_list[target_idx];
+ if ((m_idx == target_idx) || !projectable(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx)) {
+ target_idx = 0;
+ }
+ }
+
+ if (!target_idx && m_ptr->target_y) {
+ target_idx = floor_ptr->grid_array[m_ptr->target_y][m_ptr->target_x].m_idx;
+ if (target_idx) {
+ t_ptr = &floor_ptr->m_list[target_idx];
+ if ((m_idx == target_idx) || ((target_idx != target_ptr->pet_t_m_idx) && !are_enemies(target_ptr, m_ptr, t_ptr))) {
+ target_idx = 0;
+ } else if (!projectable(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx)) {
+ f4 &= (RF4_INDIRECT_MASK);
+ f5 &= (RF5_INDIRECT_MASK);
+ f6 &= (RF6_INDIRECT_MASK);
+ }
+ }
+ }
+
+ if (!target_idx) {
+ bool success = FALSE;
+ if (target_ptr->phase_out) {
+ start = randint1(floor_ptr->m_max - 1) + floor_ptr->m_max;
+ if (randint0(2))
+ plus = -1;
+ } else
+ start = floor_ptr->m_max + 1;
+
+ for (int i = start; ((i < start + floor_ptr->m_max) && (i > start - floor_ptr->m_max)); i += plus) {
+ MONSTER_IDX dummy = (i % floor_ptr->m_max);
+ if (!dummy)
+ continue;
+
+ target_idx = dummy;
+ t_ptr = &floor_ptr->m_list[target_idx];
+ if (!monster_is_valid(t_ptr))
+ continue;
+
+ if ((m_idx == target_idx) || !are_enemies(target_ptr, m_ptr, t_ptr))
+ continue;
+
+ if (!projectable(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx))
+ continue;
+
+ success = TRUE;
+ break;
+ }
+
+ if (!success)
+ return FALSE;
+ }
+
+ y = t_ptr->fy;
+ x = t_ptr->fx;
+ reset_target(m_ptr);
+ f6 &= ~(RF6_WORLD | RF6_TRAPS | RF6_FORGET);
+ if (f4 & RF4_BR_LITE) {
+ if (!los(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx))
+ f4 &= ~(RF4_BR_LITE);
+ }
+
+ if (f6 & RF6_SPECIAL) {
+ if ((m_ptr->r_idx != MON_ROLENTO) && (r_ptr->d_char != 'B'))
+ f6 &= ~(RF6_SPECIAL);
+ }
+
+ if (f6 & RF6_DARKNESS) {
+ bool vs_ninja = (target_ptr->pclass == CLASS_NINJA) && !is_hostile(t_ptr);
+ if (vs_ninja && !(r_ptr->flags3 & (RF3_UNDEAD | RF3_HURT_LITE)) && !(r_ptr->flags7 & RF7_DARK_MASK))
+ can_use_lite_area = TRUE;
+
+ if (!(r_ptr->flags2 & RF2_STUPID)) {
+ if (d_info[target_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
+ f6 &= ~(RF6_DARKNESS);
+ else if (vs_ninja && !can_use_lite_area)
+ f6 &= ~(RF6_DARKNESS);
+ }
+ }
+
+ if (in_no_magic_dungeon && !(r_ptr->flags2 & RF2_STUPID)) {
+ f4 &= (RF4_NOMAGIC_MASK);
+ f5 &= (RF5_NOMAGIC_MASK);
+ f6 &= (RF6_NOMAGIC_MASK);
+ }
+
+ if (floor_ptr->inside_arena || target_ptr->phase_out) {
+ f4 &= ~(RF4_SUMMON_MASK);
+ f5 &= ~(RF5_SUMMON_MASK);
+ f6 &= ~(RF6_SUMMON_MASK | RF6_TELE_LEVEL);
+
+ if (m_ptr->r_idx == MON_ROLENTO)
+ f6 &= ~(RF6_SPECIAL);
+ }
+
+ if (target_ptr->phase_out && !one_in_(3)) {
+ f6 &= ~(RF6_HEAL);
+ }
+
+ if (m_idx == target_ptr->riding) {
+ f4 &= ~(RF4_RIDING_MASK);
+ f5 &= ~(RF5_RIDING_MASK);
+ f6 &= ~(RF6_RIDING_MASK);
+ }
+
+ if (pet) {
+ f4 &= ~(RF4_SHRIEK);
+ f6 &= ~(RF6_DARKNESS | RF6_TRAPS);
+
+ if (!(target_ptr->pet_extra_flags & PF_TELEPORT)) {
+ f6 &= ~(RF6_BLINK | RF6_TPORT | RF6_TELE_TO | RF6_TELE_AWAY | RF6_TELE_LEVEL);
+ }
+
+ if (!(target_ptr->pet_extra_flags & PF_ATTACK_SPELL)) {
+ f4 &= ~(RF4_ATTACK_MASK);
+ f5 &= ~(RF5_ATTACK_MASK);
+ f6 &= ~(RF6_ATTACK_MASK);
+ }
+
+ if (!(target_ptr->pet_extra_flags & PF_SUMMON_SPELL)) {
+ f4 &= ~(RF4_SUMMON_MASK);
+ f5 &= ~(RF5_SUMMON_MASK);
+ f6 &= ~(RF6_SUMMON_MASK);
+ }
+
+ if (!(target_ptr->pet_extra_flags & PF_BALL_SPELL) && (m_idx != target_ptr->riding)) {
+ if ((f4 & (RF4_BALL_MASK & ~(RF4_ROCKET))) || (f5 & RF5_BALL_MASK) || (f6 & RF6_BALL_MASK)) {
+ POSITION real_y = y;
+ POSITION real_x = x;
+
+ get_project_point(target_ptr, m_ptr->fy, m_ptr->fx, &real_y, &real_x, 0L);
+
+ if (projectable(target_ptr, real_y, real_x, target_ptr->y, target_ptr->x)) {
+ int dist = distance(real_y, real_x, target_ptr->y, target_ptr->x);
+
+ if (dist <= 2) {
+ f4 &= ~(RF4_BALL_MASK & ~(RF4_ROCKET));
+ f5 &= ~(RF5_BALL_MASK);
+ f6 &= ~(RF6_BALL_MASK);
+ } else if (dist <= 4) {
+ f4 &= ~(RF4_BIG_BALL_MASK);
+ f5 &= ~(RF5_BIG_BALL_MASK);
+ f6 &= ~(RF6_BIG_BALL_MASK);
+ }
+ } else if (f5 & RF5_BA_LITE) {
+ if ((distance(real_y, real_x, target_ptr->y, target_ptr->x) <= 4) && los(target_ptr, real_y, real_x, target_ptr->y, target_ptr->x))
+ f5 &= ~(RF5_BA_LITE);
+ }
+ }
+
+ if (f4 & RF4_ROCKET) {
+ POSITION real_y = y;
+ POSITION real_x = x;
+ get_project_point(target_ptr, m_ptr->fy, m_ptr->fx, &real_y, &real_x, PROJECT_STOP);
+ if (projectable(target_ptr, real_y, real_x, target_ptr->y, target_ptr->x) && (distance(real_y, real_x, target_ptr->y, target_ptr->x) <= 2))
+ f4 &= ~(RF4_ROCKET);
+ }
+
+ if (((f4 & RF4_BEAM_MASK) || (f5 & RF5_BEAM_MASK) || (f6 & RF6_BEAM_MASK))
+ && !direct_beam(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, m_ptr)) {
+ f4 &= ~(RF4_BEAM_MASK);
+ f5 &= ~(RF5_BEAM_MASK);
+ f6 &= ~(RF6_BEAM_MASK);
+ }
+
+ if ((f4 & RF4_BREATH_MASK) || (f5 & RF5_BREATH_MASK) || (f6 & RF6_BREATH_MASK)) {
+ POSITION rad = (r_ptr->flags2 & RF2_POWERFUL) ? 3 : 2;
+ if (!breath_direct(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, rad, 0, TRUE)) {
+ f4 &= ~(RF4_BREATH_MASK);
+ f5 &= ~(RF5_BREATH_MASK);
+ f6 &= ~(RF6_BREATH_MASK);
+ } else if ((f4 & RF4_BR_LITE) && !breath_direct(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, rad, GF_LITE, TRUE)) {
+ f4 &= ~(RF4_BR_LITE);
+ } else if ((f4 & RF4_BR_DISI) && !breath_direct(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, rad, GF_DISINTEGRATE, TRUE)) {
+ f4 &= ~(RF4_BR_DISI);
+ }
+ }
+ }
+
+ if (f6 & RF6_SPECIAL) {
+ if (m_ptr->r_idx == MON_ROLENTO) {
+ if ((target_ptr->pet_extra_flags & (PF_ATTACK_SPELL | PF_SUMMON_SPELL)) != (PF_ATTACK_SPELL | PF_SUMMON_SPELL))
+ f6 &= ~(RF6_SPECIAL);
+ } else if (r_ptr->d_char == 'B') {
+ if ((target_ptr->pet_extra_flags & (PF_ATTACK_SPELL | PF_TELEPORT)) != (PF_ATTACK_SPELL | PF_TELEPORT))
+ f6 &= ~(RF6_SPECIAL);
+ } else
+ f6 &= ~(RF6_SPECIAL);
+ }
+ }
+
+ if (!(r_ptr->flags2 & RF2_STUPID)) {
+ if (((f4 & RF4_BOLT_MASK) || (f5 & RF5_BOLT_MASK) || (f6 & RF6_BOLT_MASK))
+ && !clean_shot(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, pet)) {
+ f4 &= ~(RF4_BOLT_MASK);
+ f5 &= ~(RF5_BOLT_MASK);
+ f6 &= ~(RF6_BOLT_MASK);
+ }
+
+ if (((f4 & RF4_SUMMON_MASK) || (f5 & RF5_SUMMON_MASK) || (f6 & RF6_SUMMON_MASK)) && !(summon_possible(target_ptr, t_ptr->fy, t_ptr->fx))) {
+ f4 &= ~(RF4_SUMMON_MASK);
+ f5 &= ~(RF5_SUMMON_MASK);
+ f6 &= ~(RF6_SUMMON_MASK);
+ }
+
+ if ((f4 & RF4_DISPEL) && !dispel_check_monster(target_ptr, m_idx, target_idx)) {
+ f4 &= ~(RF4_DISPEL);
+ }
+
+ if ((f6 & RF6_RAISE_DEAD) && !raise_possible(target_ptr, m_ptr)) {
+ f6 &= ~(RF6_RAISE_DEAD);
+ }
+
+ if (f6 & RF6_SPECIAL) {
+ if ((m_ptr->r_idx == MON_ROLENTO) && !summon_possible(target_ptr, t_ptr->fy, t_ptr->fx)) {
+ f6 &= ~(RF6_SPECIAL);
+ }
+ }
+ }
+
+ if (r_ptr->flags2 & RF2_SMART) {
+ if ((m_ptr->hp < m_ptr->maxhp / 10) && (randint0(100) < 50)) {
+ f4 &= (RF4_INT_MASK);
+ f5 &= (RF5_INT_MASK);
+ f6 &= (RF6_INT_MASK);
+ }
+
+ if ((f6 & RF6_TELE_LEVEL) && is_teleport_level_ineffective(target_ptr, (target_idx == target_ptr->riding) ? 0 : target_idx)) {
+ f6 &= ~(RF6_TELE_LEVEL);
+ }
+ }
+
+ if (!f4 && !f5 && !f6)
+ return FALSE;
+
+ for (k = 0; k < 32; k++) {
+ if (f4 & (1L << k))
+ spell[num++] = k + RF4_SPELL_START;
+ }
+
+ for (k = 0; k < 32; k++) {
+ if (f5 & (1L << k))
+ spell[num++] = k + RF5_SPELL_START;
+ }
+
+ for (k = 0; k < 32; k++) {
+ if (f6 & (1L << k))
+ spell[num++] = k + RF6_SPELL_START;
+ }
+
+ if (!num)
+ return FALSE;
+
+ if (!target_ptr->playing || target_ptr->is_dead)
+ return FALSE;
+
+ if (target_ptr->leaving)
+ return FALSE;
+
+ /* Get the monster name (or "it") */
+ monster_desc(target_ptr, m_name, m_ptr, 0x00);
#ifdef JP
#else
- /* Get the monster possessive ("his"/"her"/"its") */
- monster_desc(target_ptr, m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
+ /* Get the monster possessive ("his"/"her"/"its") */
+ monster_desc(target_ptr, m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
#endif
- /* Get the target's name (or "it") */
- monster_desc(target_ptr, t_name, t_ptr, 0x00);
-
- thrown_spell = spell[randint0(num)];
-
- if (target_ptr->riding && (m_idx == target_ptr->riding)) disturb(target_ptr, TRUE, TRUE);
-
- if (!spell_is_inate(thrown_spell) && (in_no_magic_dungeon || (monster_stunned_remaining(m_ptr) && one_in_(2))))
- {
- disturb(target_ptr, TRUE, TRUE);
- if (see_m) msg_format(_("%^sは呪文を唱えようとしたが失敗した。",
- "%^s tries to cast a spell, but fails."), m_name);
-
- return TRUE;
- }
-
- if (!spell_is_inate(thrown_spell) && magic_barrier(target_ptr, m_idx))
- {
- if (see_m) msg_format(_("反魔法バリアが%^sの呪文をかき消した。",
- "Anti magic barrier cancels the spell which %^s casts."), m_name);
- return TRUE;
- }
-
- can_remember = is_original_ap_and_seen(target_ptr, m_ptr);
- dam = monspell_to_monster(target_ptr, thrown_spell, y, x, m_idx, target_idx, FALSE);
- if (dam < 0) return FALSE;
-
- bool is_special_magic = m_ptr->ml;
- is_special_magic &= maneable;
- is_special_magic &= current_world_ptr->timewalk_m_idx == 0;
- is_special_magic &= !target_ptr->blind;
- is_special_magic &= target_ptr->pclass == CLASS_IMITATOR;
- is_special_magic &= thrown_spell != 167; /* Not RF6_SPECIAL */
- if (is_special_magic)
- {
- if (target_ptr->mane_num == MAX_MANE)
- {
- target_ptr->mane_num--;
- for (int i = 0; i < target_ptr->mane_num - 1; i++)
- {
- target_ptr->mane_spell[i] = target_ptr->mane_spell[i + 1];
- target_ptr->mane_dam[i] = target_ptr->mane_dam[i + 1];
- }
- }
-
- target_ptr->mane_spell[target_ptr->mane_num] = thrown_spell - RF4_SPELL_START;
- target_ptr->mane_dam[target_ptr->mane_num] = dam;
- target_ptr->mane_num++;
- target_ptr->new_mane = TRUE;
-
- target_ptr->redraw |= PR_IMITATION;
- }
-
- if (can_remember)
- {
- if (thrown_spell < RF4_SPELL_START + RF4_SPELL_SIZE)
- {
- r_ptr->r_flags4 |= (1L << (thrown_spell - RF4_SPELL_START));
- if (r_ptr->r_cast_spell < MAX_UCHAR) r_ptr->r_cast_spell++;
- }
- else if (thrown_spell < RF5_SPELL_START + RF5_SPELL_SIZE)
- {
- r_ptr->r_flags5 |= (1L << (thrown_spell - RF5_SPELL_START));
- if (r_ptr->r_cast_spell < MAX_UCHAR) r_ptr->r_cast_spell++;
- }
- else if (thrown_spell < RF6_SPELL_START + RF6_SPELL_SIZE)
- {
- r_ptr->r_flags6 |= (1L << (thrown_spell - RF6_SPELL_START));
- if (r_ptr->r_cast_spell < MAX_UCHAR) r_ptr->r_cast_spell++;
- }
- }
-
- if (target_ptr->is_dead && (r_ptr->r_deaths < MAX_SHORT) && !floor_ptr->inside_arena)
- {
- r_ptr->r_deaths++;
- }
-
- return TRUE;
+ /* Get the target's name (or "it") */
+ monster_desc(target_ptr, t_name, t_ptr, 0x00);
+
+ thrown_spell = spell[randint0(num)];
+
+ if (target_ptr->riding && (m_idx == target_ptr->riding))
+ disturb(target_ptr, TRUE, TRUE);
+
+ if (!spell_is_inate(thrown_spell) && (in_no_magic_dungeon || (monster_stunned_remaining(m_ptr) && one_in_(2)))) {
+ disturb(target_ptr, TRUE, TRUE);
+ if (see_m)
+ msg_format(_("%^sは呪文を唱えようとしたが失敗した。", "%^s tries to cast a spell, but fails."), m_name);
+
+ return TRUE;
+ }
+
+ if (!spell_is_inate(thrown_spell) && magic_barrier(target_ptr, m_idx)) {
+ if (see_m)
+ msg_format(_("反魔法バリアが%^sの呪文をかき消した。", "Anti magic barrier cancels the spell which %^s casts."), m_name);
+ return TRUE;
+ }
+
+ can_remember = is_original_ap_and_seen(target_ptr, m_ptr);
+ dam = monspell_to_monster(target_ptr, thrown_spell, y, x, m_idx, target_idx, FALSE);
+ if (dam < 0)
+ return FALSE;
+
+ bool is_special_magic = m_ptr->ml;
+ is_special_magic &= maneable;
+ is_special_magic &= current_world_ptr->timewalk_m_idx == 0;
+ is_special_magic &= !target_ptr->blind;
+ is_special_magic &= target_ptr->pclass == CLASS_IMITATOR;
+ is_special_magic &= thrown_spell != 167; /* Not RF6_SPECIAL */
+ if (is_special_magic) {
+ if (target_ptr->mane_num == MAX_MANE) {
+ target_ptr->mane_num--;
+ for (int i = 0; i < target_ptr->mane_num - 1; i++) {
+ target_ptr->mane_spell[i] = target_ptr->mane_spell[i + 1];
+ target_ptr->mane_dam[i] = target_ptr->mane_dam[i + 1];
+ }
+ }
+
+ target_ptr->mane_spell[target_ptr->mane_num] = thrown_spell - RF4_SPELL_START;
+ target_ptr->mane_dam[target_ptr->mane_num] = dam;
+ target_ptr->mane_num++;
+ target_ptr->new_mane = TRUE;
+
+ target_ptr->redraw |= PR_IMITATION;
+ }
+
+ if (can_remember) {
+ if (thrown_spell < RF4_SPELL_START + RF4_SPELL_SIZE) {
+ r_ptr->r_flags4 |= (1L << (thrown_spell - RF4_SPELL_START));
+ if (r_ptr->r_cast_spell < MAX_UCHAR)
+ r_ptr->r_cast_spell++;
+ } else if (thrown_spell < RF5_SPELL_START + RF5_SPELL_SIZE) {
+ r_ptr->r_flags5 |= (1L << (thrown_spell - RF5_SPELL_START));
+ if (r_ptr->r_cast_spell < MAX_UCHAR)
+ r_ptr->r_cast_spell++;
+ } else if (thrown_spell < RF6_SPELL_START + RF6_SPELL_SIZE) {
+ r_ptr->r_flags6 |= (1L << (thrown_spell - RF6_SPELL_START));
+ if (r_ptr->r_cast_spell < MAX_UCHAR)
+ r_ptr->r_cast_spell++;
+ }
+ }
+
+ if (target_ptr->is_dead && (r_ptr->r_deaths < MAX_SHORT) && !floor_ptr->inside_arena) {
+ r_ptr->r_deaths++;
+ }
+
+ return TRUE;
}
#include "view/display-main-window.h"
#include "view/display-messages.h"
- /*!
- * @brief モンスター魔法をプレイヤーが使用する場合の換算レベル
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param 換算レベル
- */
+/*!
+ * @brief モンスター魔法をプレイヤーが使用する場合の換算レベル
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param 換算レベル
+ */
PLAYER_LEVEL get_pseudo_monstetr_level(player_type *caster_ptr)
{
- PLAYER_LEVEL monster_level = caster_ptr->lev + 40;
- return (monster_level * monster_level - 1550) / 130;
+ PLAYER_LEVEL monster_level = caster_ptr->lev + 40;
+ return (monster_level * monster_level - 1550) / 130;
}
-
/*!
-* @brief 文字列に青魔導師の呪文の攻撃力を加える
-* @param SPELL_NUM 呪文番号
-* @param plev プレイヤーレベル
-* @param msg 表示する文字列
-* @param tmp 返すメッセージを格納する配列
-* @return なし
-*/
-void set_bluemage_damage(player_type *learner_type, monster_spell_type ms_type, PLAYER_LEVEL plev, concptr msg, char* tmp)
+ * @brief 文字列に青魔導師の呪文の攻撃力を加える
+ * @param SPELL_NUM 呪文番号
+ * @param plev プレイヤーレベル
+ * @param msg 表示する文字列
+ * @param tmp 返すメッセージを格納する配列
+ * @return なし
+ */
+void set_bluemage_damage(player_type *learner_type, monster_spell_type ms_type, PLAYER_LEVEL plev, concptr msg, char *tmp)
{
int base_damage = monspell_bluemage_damage(learner_type, ms_type, plev, BASE_DAM);
int dice_num = monspell_bluemage_damage(learner_type, ms_type, plev, DICE_NUM);
sprintf(tmp, " %s %s", msg, dmg_str);
}
-
/*!
* @brief 受け取ったモンスター魔法のIDに応じて青魔法の効果情報をまとめたフォーマットを返す
* @param learner_ptr プレーヤーへの参照ポインタ
*/
static void learned_info(player_type *learner_ptr, char *p, int power)
{
- PLAYER_LEVEL plev = get_pseudo_monstetr_level(learner_ptr);
-
- strcpy(p, "");
-
- switch (power)
- {
- case MS_SHRIEK:
- case MS_XXX1:
- case MS_XXX2:
- case MS_XXX3:
- case MS_XXX4:
- case MS_SCARE:
- case MS_BLIND:
- case MS_CONF:
- case MS_SLOW:
- case MS_SLEEP:
- case MS_HAND_DOOM:
- case MS_WORLD:
- case MS_SPECIAL:
- case MS_TELE_TO:
- case MS_TELE_AWAY:
- case MS_TELE_LEVEL:
- case MS_DARKNESS:
- case MS_MAKE_TRAP:
- case MS_FORGET:
- case MS_S_KIN:
- case MS_S_CYBER:
- case MS_S_MONSTER:
- case MS_S_MONSTERS:
- case MS_S_ANT:
- case MS_S_SPIDER:
- case MS_S_HOUND:
- case MS_S_HYDRA:
- case MS_S_ANGEL:
- case MS_S_DEMON:
- case MS_S_UNDEAD:
- case MS_S_DRAGON:
- case MS_S_HI_UNDEAD:
- case MS_S_HI_DRAGON:
- case MS_S_AMBERITE:
- case MS_S_UNIQUE:
- break;
- case MS_BALL_MANA:
- case MS_BALL_DARK:
- case MS_STARBURST:
- set_bluemage_damage(learner_ptr, power, plev, KWD_DAM, p); break;
- case MS_DISPEL:
- break;
- case MS_ROCKET:
- case MS_SHOOT:
- case MS_BR_ACID:
- case MS_BR_ELEC:
- case MS_BR_FIRE:
- case MS_BR_COLD:
- case MS_BR_POIS:
- case MS_BR_NUKE:
- case MS_BR_NEXUS:
- case MS_BR_TIME:
- case MS_BR_GRAVITY:
- case MS_BR_MANA:
- case MS_BR_NETHER:
- case MS_BR_LITE:
- case MS_BR_DARK:
- case MS_BR_CONF:
- case MS_BR_SOUND:
- case MS_BR_CHAOS:
- case MS_BR_DISEN:
- case MS_BR_SHARDS:
- case MS_BR_PLASMA:
- case MS_BR_INERTIA:
- case MS_BR_FORCE:
- case MS_BR_DISI:
- case MS_BALL_NUKE:
- case MS_BALL_CHAOS:
- case MS_BALL_ACID:
- case MS_BALL_ELEC:
- case MS_BALL_FIRE:
- case MS_BALL_COLD:
- case MS_BALL_POIS:
- case MS_BALL_NETHER:
- case MS_BALL_WATER:
- set_bluemage_damage(learner_ptr, power, plev, KWD_DAM, p); break;
- case MS_DRAIN_MANA:
- set_bluemage_damage(learner_ptr, power, plev, KWD_HEAL, p); break;
- case MS_MIND_BLAST:
- case MS_BRAIN_SMASH:
- case MS_CAUSE_1:
- case MS_CAUSE_2:
- case MS_CAUSE_3:
- case MS_CAUSE_4:
- case MS_BOLT_ACID:
- case MS_BOLT_ELEC:
- case MS_BOLT_FIRE:
- case MS_BOLT_COLD:
- case MS_BOLT_NETHER:
- case MS_BOLT_WATER:
- case MS_BOLT_MANA:
- case MS_BOLT_PLASMA:
- case MS_BOLT_ICE:
- case MS_MAGIC_MISSILE:
- set_bluemage_damage(learner_ptr, power, plev, KWD_DAM, p); break;
- case MS_SPEED:
- sprintf(p, " %sd%d+%d", KWD_DURATION, 20+plev, plev);
- break;
- case MS_HEAL:
- set_bluemage_damage(learner_ptr, power, plev, KWD_HEAL, p); break;
- case MS_INVULNER:
- sprintf(p, " %sd7+7", KWD_DURATION);
- break;
- case MS_BLINK:
- sprintf(p, " %s10", KWD_SPHERE);
- break;
- case MS_TELEPORT:
- sprintf(p, " %s%d", KWD_SPHERE, plev * 5);
- break;
- case MS_PSY_SPEAR:
- set_bluemage_damage(learner_ptr, power, plev, KWD_DAM, p); break;
- break;
- case MS_RAISE_DEAD:
- sprintf(p, " %s5", KWD_SPHERE);
- break;
- default:
- break;
- }
+ PLAYER_LEVEL plev = get_pseudo_monstetr_level(learner_ptr);
+
+ strcpy(p, "");
+
+ switch (power) {
+ case MS_SHRIEK:
+ case MS_XXX1:
+ case MS_XXX2:
+ case MS_XXX3:
+ case MS_XXX4:
+ case MS_SCARE:
+ case MS_BLIND:
+ case MS_CONF:
+ case MS_SLOW:
+ case MS_SLEEP:
+ case MS_HAND_DOOM:
+ case MS_WORLD:
+ case MS_SPECIAL:
+ case MS_TELE_TO:
+ case MS_TELE_AWAY:
+ case MS_TELE_LEVEL:
+ case MS_DARKNESS:
+ case MS_MAKE_TRAP:
+ case MS_FORGET:
+ case MS_S_KIN:
+ case MS_S_CYBER:
+ case MS_S_MONSTER:
+ case MS_S_MONSTERS:
+ case MS_S_ANT:
+ case MS_S_SPIDER:
+ case MS_S_HOUND:
+ case MS_S_HYDRA:
+ case MS_S_ANGEL:
+ case MS_S_DEMON:
+ case MS_S_UNDEAD:
+ case MS_S_DRAGON:
+ case MS_S_HI_UNDEAD:
+ case MS_S_HI_DRAGON:
+ case MS_S_AMBERITE:
+ case MS_S_UNIQUE:
+ break;
+ case MS_BALL_MANA:
+ case MS_BALL_DARK:
+ case MS_STARBURST:
+ set_bluemage_damage(learner_ptr, power, plev, KWD_DAM, p);
+ break;
+ case MS_DISPEL:
+ break;
+ case MS_ROCKET:
+ case MS_SHOOT:
+ case MS_BR_ACID:
+ case MS_BR_ELEC:
+ case MS_BR_FIRE:
+ case MS_BR_COLD:
+ case MS_BR_POIS:
+ case MS_BR_NUKE:
+ case MS_BR_NEXUS:
+ case MS_BR_TIME:
+ case MS_BR_GRAVITY:
+ case MS_BR_MANA:
+ case MS_BR_NETHER:
+ case MS_BR_LITE:
+ case MS_BR_DARK:
+ case MS_BR_CONF:
+ case MS_BR_SOUND:
+ case MS_BR_CHAOS:
+ case MS_BR_DISEN:
+ case MS_BR_SHARDS:
+ case MS_BR_PLASMA:
+ case MS_BR_INERTIA:
+ case MS_BR_FORCE:
+ case MS_BR_DISI:
+ case MS_BALL_NUKE:
+ case MS_BALL_CHAOS:
+ case MS_BALL_ACID:
+ case MS_BALL_ELEC:
+ case MS_BALL_FIRE:
+ case MS_BALL_COLD:
+ case MS_BALL_POIS:
+ case MS_BALL_NETHER:
+ case MS_BALL_WATER:
+ set_bluemage_damage(learner_ptr, power, plev, KWD_DAM, p);
+ break;
+ case MS_DRAIN_MANA:
+ set_bluemage_damage(learner_ptr, power, plev, KWD_HEAL, p);
+ break;
+ case MS_MIND_BLAST:
+ case MS_BRAIN_SMASH:
+ case MS_CAUSE_1:
+ case MS_CAUSE_2:
+ case MS_CAUSE_3:
+ case MS_CAUSE_4:
+ case MS_BOLT_ACID:
+ case MS_BOLT_ELEC:
+ case MS_BOLT_FIRE:
+ case MS_BOLT_COLD:
+ case MS_BOLT_NETHER:
+ case MS_BOLT_WATER:
+ case MS_BOLT_MANA:
+ case MS_BOLT_PLASMA:
+ case MS_BOLT_ICE:
+ case MS_MAGIC_MISSILE:
+ set_bluemage_damage(learner_ptr, power, plev, KWD_DAM, p);
+ break;
+ case MS_SPEED:
+ sprintf(p, " %sd%d+%d", KWD_DURATION, 20 + plev, plev);
+ break;
+ case MS_HEAL:
+ set_bluemage_damage(learner_ptr, power, plev, KWD_HEAL, p);
+ break;
+ case MS_INVULNER:
+ sprintf(p, " %sd7+7", KWD_DURATION);
+ break;
+ case MS_BLINK:
+ sprintf(p, " %s10", KWD_SPHERE);
+ break;
+ case MS_TELEPORT:
+ sprintf(p, " %s%d", KWD_SPHERE, plev * 5);
+ break;
+ case MS_PSY_SPEAR:
+ set_bluemage_damage(learner_ptr, power, plev, KWD_DAM, p);
+ break;
+ break;
+ case MS_RAISE_DEAD:
+ sprintf(p, " %s5", KWD_SPHERE);
+ break;
+ default:
+ break;
+ }
}
-
/*!
* @brief 使用可能な青魔法を選択する /
* Allow user to choose a imitation.
*/
static bool get_learned_power(player_type *caster_ptr, SPELL_IDX *sn)
{
- int i = 0;
- int num = 0;
- TERM_LEN y = 1;
- TERM_LEN x = 18;
- PERCENTAGE minfail = 0;
- PLAYER_LEVEL plev = caster_ptr->lev;
- PERCENTAGE chance = 0;
- int ask = TRUE, mode = 0;
- int spellnum[MAX_MONSPELLS];
- char ch;
- char choice;
- char out_val[160];
- char comment[80];
- BIT_FLAGS f4 = 0L, f5 = 0L, f6 = 0L;
- concptr p = _("魔法", "magic");
- COMMAND_CODE code;
- monster_power spell;
- bool flag, redraw;
- int menu_line = (use_menu ? 1 : 0);
-
- *sn = (-1);
-
- flag = FALSE;
- redraw = FALSE;
-
- if (repeat_pull(&code))
- {
- *sn = (SPELL_IDX)code;
- return TRUE;
- }
-
- if (use_menu)
- {
- screen_save();
- while(!mode)
- {
- prt(format(_(" %s ボルト", " %s bolt"), (menu_line == 1) ? _("》", "> ") : " "), 2, 14);
- prt(format(_(" %s ボール", " %s ball"), (menu_line == 2) ? _("》", "> ") : " "), 3, 14);
- prt(format(_(" %s ブレス", " %s breath"), (menu_line == 3) ? _("》", "> ") : " "), 4, 14);
- prt(format(_(" %s 召喚", " %s sommoning"), (menu_line == 4) ? _("》", "> ") : " "), 5, 14);
- prt(format(_(" %s その他", " %s others"), (menu_line == 5) ? _("》", "> ") : " "), 6, 14);
- prt(_("どの種類の魔法を使いますか?", "use which type of magic? "), 0, 0);
-
- choice = inkey();
- switch(choice)
- {
- case ESCAPE:
- case 'z':
- case 'Z':
- screen_load();
- return FALSE;
- case '2':
- case 'j':
- case 'J':
- menu_line++;
- break;
- case '8':
- case 'k':
- case 'K':
- menu_line+= 4;
- break;
- case '\r':
- case 'x':
- case 'X':
- mode = menu_line;
- break;
- }
- if (menu_line > 5) menu_line -= 5;
- }
- screen_load();
- }
- else
- {
- sprintf(comment, _("[A]ボルト, [B]ボール, [C]ブレス, [D]召喚, [E]その他:", "[A] bolt, [B] ball, [C] breath, [D] summoning, [E] others:"));
- while (TRUE)
- {
- if (!get_com(comment, &ch, TRUE))
- {
- return FALSE;
- }
- if (ch == 'A' || ch == 'a')
- {
- mode = 1;
- break;
- }
- if (ch == 'B' || ch == 'b')
- {
- mode = 2;
- break;
- }
- if (ch == 'C' || ch == 'c')
- {
- mode = 3;
- break;
- }
- if (ch == 'D' || ch == 'd')
- {
- mode = 4;
- break;
- }
- if (ch == 'E' || ch == 'e')
- {
- mode = 5;
- break;
- }
- }
- }
-
- set_rf_masks(&f4, &f5, &f6, mode);
-
- for (i = 0, num = 0; i < 32; i++)
- {
- if ((0x00000001 << i) & f4) spellnum[num++] = i;
- }
- for (; i < 64; i++)
- {
- if ((0x00000001 << (i - 32)) & f5) spellnum[num++] = i;
- }
- for (; i < 96; i++)
- {
- if ((0x00000001 << (i - 64)) & f6) spellnum[num++] = i;
- }
- for (i = 0; i < num; i++)
- {
- if (caster_ptr->magic_num2[spellnum[i]])
- {
- if (use_menu) menu_line = i+1;
- break;
- }
- }
- if (i == num)
- {
- msg_print(_("その種類の魔法は覚えていない!", "You don't know any spell of this type."));
- return FALSE;
- }
-
- (void)strnfmt(out_val, 78, _("(%c-%c, '*'で一覧, ESC) どの%sを唱えますか?", "(%c-%c, *=List, ESC=exit) Use which %s? "),
- I2A(0), I2A(num - 1), p);
-
- if (use_menu) screen_save();
-
- choice= (always_show_list || use_menu) ? ESCAPE:1 ;
- while (!flag)
- {
- if(choice==ESCAPE) choice = ' ';
- else if( !get_com(out_val, &choice, TRUE) )break;
-
- if (use_menu && choice != ' ')
- {
- switch(choice)
- {
- case '0':
- {
- screen_load();
- return FALSE;
- }
-
- case '8':
- case 'k':
- case 'K':
- {
- do
- {
- menu_line += (num-1);
- if (menu_line > num) menu_line -= num;
- } while(!caster_ptr->magic_num2[spellnum[menu_line-1]]);
- break;
- }
-
- case '2':
- case 'j':
- case 'J':
- {
- do
- {
- menu_line++;
- if (menu_line > num) menu_line -= num;
- } while(!caster_ptr->magic_num2[spellnum[menu_line-1]]);
- break;
- }
-
- case '6':
- case 'l':
- case 'L':
- {
- menu_line=num;
- while(!caster_ptr->magic_num2[spellnum[menu_line-1]]) menu_line--;
- break;
- }
-
- case '4':
- case 'h':
- case 'H':
- {
- menu_line=1;
- while(!caster_ptr->magic_num2[spellnum[menu_line-1]]) menu_line++;
- break;
- }
-
- case 'x':
- case 'X':
- case '\r':
- {
- i = menu_line - 1;
- ask = FALSE;
- break;
- }
- }
- }
-
- if ((choice == ' ') || (choice == '*') || (choice == '?') || (use_menu && ask))
- {
- if (!redraw || use_menu)
- {
- char psi_desc[80];
- redraw = TRUE;
- if (!use_menu) screen_save();
-
- prt("", y, x);
- put_str(_("名前", "Name"), y, x + 5);
- put_str(_("MP 失率 効果", "SP Fail Info"), y, x + 33);
-
- for (i = 0; i < num; i++)
- {
- int need_mana;
- prt("", y + i + 1, x);
- if (!caster_ptr->magic_num2[spellnum[i]]) continue;
-
- spell = monster_powers[spellnum[i]];
- chance = spell.fail;
- if (plev > spell.level) chance -= 3 * (plev - spell.level);
- else chance += (spell.level - plev);
-
- chance -= 3 * (adj_mag_stat[caster_ptr->stat_ind[A_INT]] - 1);
- chance = mod_spell_chance_1(caster_ptr, chance);
- need_mana = mod_need_mana(caster_ptr, monster_powers[spellnum[i]].smana, 0, REALM_NONE);
- if (need_mana > caster_ptr->csp)
- {
- chance += 5 * (need_mana - caster_ptr->csp);
- }
-
- minfail = adj_mag_fail[caster_ptr->stat_ind[A_INT]];
- if (chance < minfail) chance = minfail;
-
- if (caster_ptr->stun > 50) chance += 25;
- else if (caster_ptr->stun) chance += 15;
-
- if (chance > 95) chance = 95;
-
- chance = mod_spell_chance_2(caster_ptr, chance);
- learned_info(caster_ptr, comment, spellnum[i]);
- if (use_menu)
- {
- if (i == (menu_line-1)) strcpy(psi_desc, _(" 》", " > "));
- else strcpy(psi_desc, " ");
- }
- else sprintf(psi_desc, " %c)", I2A(i));
-
- strcat(psi_desc, format(" %-26s %3d %3d%%%s",
- spell.name, need_mana,
- chance, comment));
- prt(psi_desc, y + i + 1, x);
- }
-
- if (y < 22) prt("", y + i + 1, x);
- }
- else
- {
- redraw = FALSE;
- screen_load();
- }
-
- continue;
- }
-
- if (!use_menu)
- {
- ask = isupper(choice);
- if (ask) choice = (char)tolower(choice);
-
- i = (islower(choice) ? A2I(choice) : -1);
- }
-
- if ((i < 0) || (i >= num) || !caster_ptr->magic_num2[spellnum[i]])
- {
- bell();
- continue;
- }
-
- spell = monster_powers[spellnum[i]];
- if (ask)
- {
- char tmp_val[160];
- (void) strnfmt(tmp_val, 78, _("%sの魔法を唱えますか?", "Use %s? "), monster_powers[spellnum[i]].name);
- if (!get_check(tmp_val)) continue;
- }
-
- flag = TRUE;
- }
-
- if (redraw) screen_load();
-
- caster_ptr->window |= (PW_SPELL);
- handle_stuff(caster_ptr);
-
- if (!flag) return FALSE;
-
- (*sn) = spellnum[i];
- return TRUE;
+ int i = 0;
+ int num = 0;
+ TERM_LEN y = 1;
+ TERM_LEN x = 18;
+ PERCENTAGE minfail = 0;
+ PLAYER_LEVEL plev = caster_ptr->lev;
+ PERCENTAGE chance = 0;
+ int ask = TRUE, mode = 0;
+ int spellnum[MAX_MONSPELLS];
+ char ch;
+ char choice;
+ char out_val[160];
+ char comment[80];
+ BIT_FLAGS f4 = 0L, f5 = 0L, f6 = 0L;
+ concptr p = _("魔法", "magic");
+ COMMAND_CODE code;
+ monster_power spell;
+ bool flag, redraw;
+ int menu_line = (use_menu ? 1 : 0);
+
+ *sn = (-1);
+
+ flag = FALSE;
+ redraw = FALSE;
+
+ if (repeat_pull(&code)) {
+ *sn = (SPELL_IDX)code;
+ return TRUE;
+ }
+
+ if (use_menu) {
+ screen_save();
+ while (!mode) {
+ prt(format(_(" %s ボルト", " %s bolt"), (menu_line == 1) ? _("》", "> ") : " "), 2, 14);
+ prt(format(_(" %s ボール", " %s ball"), (menu_line == 2) ? _("》", "> ") : " "), 3, 14);
+ prt(format(_(" %s ブレス", " %s breath"), (menu_line == 3) ? _("》", "> ") : " "), 4, 14);
+ prt(format(_(" %s 召喚", " %s sommoning"), (menu_line == 4) ? _("》", "> ") : " "), 5, 14);
+ prt(format(_(" %s その他", " %s others"), (menu_line == 5) ? _("》", "> ") : " "), 6, 14);
+ prt(_("どの種類の魔法を使いますか?", "use which type of magic? "), 0, 0);
+
+ choice = inkey();
+ switch (choice) {
+ case ESCAPE:
+ case 'z':
+ case 'Z':
+ screen_load();
+ return FALSE;
+ case '2':
+ case 'j':
+ case 'J':
+ menu_line++;
+ break;
+ case '8':
+ case 'k':
+ case 'K':
+ menu_line += 4;
+ break;
+ case '\r':
+ case 'x':
+ case 'X':
+ mode = menu_line;
+ break;
+ }
+ if (menu_line > 5)
+ menu_line -= 5;
+ }
+ screen_load();
+ } else {
+ sprintf(comment, _("[A]ボルト, [B]ボール, [C]ブレス, [D]召喚, [E]その他:", "[A] bolt, [B] ball, [C] breath, [D] summoning, [E] others:"));
+ while (TRUE) {
+ if (!get_com(comment, &ch, TRUE)) {
+ return FALSE;
+ }
+ if (ch == 'A' || ch == 'a') {
+ mode = 1;
+ break;
+ }
+ if (ch == 'B' || ch == 'b') {
+ mode = 2;
+ break;
+ }
+ if (ch == 'C' || ch == 'c') {
+ mode = 3;
+ break;
+ }
+ if (ch == 'D' || ch == 'd') {
+ mode = 4;
+ break;
+ }
+ if (ch == 'E' || ch == 'e') {
+ mode = 5;
+ break;
+ }
+ }
+ }
+
+ set_rf_masks(&f4, &f5, &f6, mode);
+
+ for (i = 0, num = 0; i < 32; i++) {
+ if ((0x00000001 << i) & f4)
+ spellnum[num++] = i;
+ }
+ for (; i < 64; i++) {
+ if ((0x00000001 << (i - 32)) & f5)
+ spellnum[num++] = i;
+ }
+ for (; i < 96; i++) {
+ if ((0x00000001 << (i - 64)) & f6)
+ spellnum[num++] = i;
+ }
+ for (i = 0; i < num; i++) {
+ if (caster_ptr->magic_num2[spellnum[i]]) {
+ if (use_menu)
+ menu_line = i + 1;
+ break;
+ }
+ }
+ if (i == num) {
+ msg_print(_("その種類の魔法は覚えていない!", "You don't know any spell of this type."));
+ return FALSE;
+ }
+
+ (void)strnfmt(out_val, 78, _("(%c-%c, '*'で一覧, ESC) どの%sを唱えますか?", "(%c-%c, *=List, ESC=exit) Use which %s? "), I2A(0), I2A(num - 1), p);
+
+ if (use_menu)
+ screen_save();
+
+ choice = (always_show_list || use_menu) ? ESCAPE : 1;
+ while (!flag) {
+ if (choice == ESCAPE)
+ choice = ' ';
+ else if (!get_com(out_val, &choice, TRUE))
+ break;
+
+ if (use_menu && choice != ' ') {
+ switch (choice) {
+ case '0': {
+ screen_load();
+ return FALSE;
+ }
+
+ case '8':
+ case 'k':
+ case 'K': {
+ do {
+ menu_line += (num - 1);
+ if (menu_line > num)
+ menu_line -= num;
+ } while (!caster_ptr->magic_num2[spellnum[menu_line - 1]]);
+ break;
+ }
+
+ case '2':
+ case 'j':
+ case 'J': {
+ do {
+ menu_line++;
+ if (menu_line > num)
+ menu_line -= num;
+ } while (!caster_ptr->magic_num2[spellnum[menu_line - 1]]);
+ break;
+ }
+
+ case '6':
+ case 'l':
+ case 'L': {
+ menu_line = num;
+ while (!caster_ptr->magic_num2[spellnum[menu_line - 1]])
+ menu_line--;
+ break;
+ }
+
+ case '4':
+ case 'h':
+ case 'H': {
+ menu_line = 1;
+ while (!caster_ptr->magic_num2[spellnum[menu_line - 1]])
+ menu_line++;
+ break;
+ }
+
+ case 'x':
+ case 'X':
+ case '\r': {
+ i = menu_line - 1;
+ ask = FALSE;
+ break;
+ }
+ }
+ }
+
+ if ((choice == ' ') || (choice == '*') || (choice == '?') || (use_menu && ask)) {
+ if (!redraw || use_menu) {
+ char psi_desc[80];
+ redraw = TRUE;
+ if (!use_menu)
+ screen_save();
+
+ prt("", y, x);
+ put_str(_("名前", "Name"), y, x + 5);
+ put_str(_("MP 失率 効果", "SP Fail Info"), y, x + 33);
+
+ for (i = 0; i < num; i++) {
+ int need_mana;
+ prt("", y + i + 1, x);
+ if (!caster_ptr->magic_num2[spellnum[i]])
+ continue;
+
+ spell = monster_powers[spellnum[i]];
+ chance = spell.fail;
+ if (plev > spell.level)
+ chance -= 3 * (plev - spell.level);
+ else
+ chance += (spell.level - plev);
+
+ chance -= 3 * (adj_mag_stat[caster_ptr->stat_ind[A_INT]] - 1);
+ chance = mod_spell_chance_1(caster_ptr, chance);
+ need_mana = mod_need_mana(caster_ptr, monster_powers[spellnum[i]].smana, 0, REALM_NONE);
+ if (need_mana > caster_ptr->csp) {
+ chance += 5 * (need_mana - caster_ptr->csp);
+ }
+
+ minfail = adj_mag_fail[caster_ptr->stat_ind[A_INT]];
+ if (chance < minfail)
+ chance = minfail;
+
+ if (caster_ptr->stun > 50)
+ chance += 25;
+ else if (caster_ptr->stun)
+ chance += 15;
+
+ if (chance > 95)
+ chance = 95;
+
+ chance = mod_spell_chance_2(caster_ptr, chance);
+ learned_info(caster_ptr, comment, spellnum[i]);
+ if (use_menu) {
+ if (i == (menu_line - 1))
+ strcpy(psi_desc, _(" 》", " > "));
+ else
+ strcpy(psi_desc, " ");
+ } else
+ sprintf(psi_desc, " %c)", I2A(i));
+
+ strcat(psi_desc, format(" %-26s %3d %3d%%%s", spell.name, need_mana, chance, comment));
+ prt(psi_desc, y + i + 1, x);
+ }
+
+ if (y < 22)
+ prt("", y + i + 1, x);
+ } else {
+ redraw = FALSE;
+ screen_load();
+ }
+
+ continue;
+ }
+
+ if (!use_menu) {
+ ask = isupper(choice);
+ if (ask)
+ choice = (char)tolower(choice);
+
+ i = (islower(choice) ? A2I(choice) : -1);
+ }
+
+ if ((i < 0) || (i >= num) || !caster_ptr->magic_num2[spellnum[i]]) {
+ bell();
+ continue;
+ }
+
+ spell = monster_powers[spellnum[i]];
+ if (ask) {
+ char tmp_val[160];
+ (void)strnfmt(tmp_val, 78, _("%sの魔法を唱えますか?", "Use %s? "), monster_powers[spellnum[i]].name);
+ if (!get_check(tmp_val))
+ continue;
+ }
+
+ flag = TRUE;
+ }
+
+ if (redraw)
+ screen_load();
+
+ caster_ptr->window |= (PW_SPELL);
+ handle_stuff(caster_ptr);
+
+ if (!flag)
+ return FALSE;
+
+ (*sn) = spellnum[i];
+ return TRUE;
}
-
/*!
* @brief 青魔法の発動 /
* do_cmd_cast calls this function if the player's class is 'blue-mage'.
*/
static bool cast_learned_spell(player_type *caster_ptr, int spell, bool success)
{
- DIRECTION dir;
- PLAYER_LEVEL plev = get_pseudo_monstetr_level(caster_ptr);
- PLAYER_LEVEL summon_lev = caster_ptr->lev * 2 / 3 + randint1(caster_ptr->lev/2);
- HIT_POINT damage = 0;
- bool pet = success;
- bool no_trump = FALSE;
- BIT_FLAGS 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;
-
- floor_type *floor_ptr = caster_ptr->current_floor_ptr;
- switch (spell)
- {
- case MS_SHRIEK:
+ DIRECTION dir;
+ PLAYER_LEVEL plev = get_pseudo_monstetr_level(caster_ptr);
+ PLAYER_LEVEL summon_lev = caster_ptr->lev * 2 / 3 + randint1(caster_ptr->lev / 2);
+ HIT_POINT damage = 0;
+ bool pet = success;
+ bool no_trump = FALSE;
+ BIT_FLAGS 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;
+
+ floor_type *floor_ptr = caster_ptr->current_floor_ptr;
+ switch (spell) {
+ case MS_SHRIEK:
msg_print(_("かん高い金切り声をあげた。", "You make a high pitched shriek."));
- aggravate_monsters(caster_ptr, 0);
- break;
- case MS_XXX1:
- break;
- case MS_DISPEL:
- {
- MONSTER_IDX m_idx;
-
- if (!target_set(caster_ptr, TARGET_KILL)) return FALSE;
- m_idx = floor_ptr->grid_array[target_row][target_col].m_idx;
- if (!m_idx) break;
- if (!player_has_los_bold(caster_ptr, target_row, target_col)) break;
- if (!projectable(caster_ptr, caster_ptr->y, caster_ptr->x, target_row, target_col)) break;
- dispel_monster_status(caster_ptr, m_idx);
- break;
- }
- case MS_ROCKET:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
-
+ aggravate_monsters(caster_ptr, 0);
+ break;
+ case MS_XXX1:
+ break;
+ case MS_DISPEL: {
+ MONSTER_IDX m_idx;
+
+ if (!target_set(caster_ptr, TARGET_KILL))
+ return FALSE;
+ m_idx = floor_ptr->grid_array[target_row][target_col].m_idx;
+ if (!m_idx)
+ break;
+ if (!player_has_los_bold(caster_ptr, target_row, target_col))
+ break;
+ if (!projectable(caster_ptr, caster_ptr->y, caster_ptr->x, target_row, target_col))
+ break;
+ dispel_monster_status(caster_ptr, m_idx);
+ break;
+ }
+ case MS_ROCKET:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
+
msg_print(_("ロケットを発射した。", "You fire a rocket."));
damage = monspell_bluemage_damage(caster_ptr, (MS_ROCKET), plev, DAM_ROLL);
- fire_rocket(caster_ptr, GF_ROCKET, dir, damage, 2);
- break;
- case MS_SHOOT:
- {
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
-
+ fire_rocket(caster_ptr, GF_ROCKET, dir, damage, 2);
+ break;
+ case MS_SHOOT: {
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
+
msg_print(_("矢を放った。", "You fire an arrow."));
damage = monspell_bluemage_damage(caster_ptr, (MS_SHOOT), plev, DAM_ROLL);
- fire_bolt(caster_ptr, 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(caster_ptr, &dir)) return FALSE;
+ fire_bolt(caster_ptr, 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(caster_ptr, &dir))
+ return FALSE;
msg_print(_("酸のブレスを吐いた。", "You breathe acid."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_ACID), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_ACID, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_ELEC:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_ACID, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_ELEC:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("稲妻のブレスを吐いた。", "You breathe lightning."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_ELEC), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_ELEC, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_FIRE:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_ELEC, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_FIRE:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("火炎のブレスを吐いた。", "You breathe fire."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_FIRE), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_FIRE, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_COLD:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_FIRE, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_COLD:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("冷気のブレスを吐いた。", "You breathe frost."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_COLD), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_COLD, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_POIS:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_COLD, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_POIS:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("ガスのブレスを吐いた。", "You breathe gas."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_POIS), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_POIS, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_NETHER:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_POIS, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_NETHER:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("地獄のブレスを吐いた。", "You breathe nether."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_NETHER), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_NETHER, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_LITE:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_NETHER, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_LITE:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("閃光のブレスを吐いた。", "You breathe light."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_LITE), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_LITE, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_DARK:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_LITE, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_DARK:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("暗黒のブレスを吐いた。", "You breathe darkness."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_DARK), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_DARK, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_CONF:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_DARK, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_CONF:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("混乱のブレスを吐いた。", "You breathe confusion."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_CONF), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_CONFUSION, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_SOUND:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_CONFUSION, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_SOUND:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("轟音のブレスを吐いた。", "You breathe sound."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_SOUND), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_SOUND, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_CHAOS:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_SOUND, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_CHAOS:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("カオスのブレスを吐いた。", "You breathe chaos."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_CHAOS), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_CHAOS, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_DISEN:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_CHAOS, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_DISEN:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("劣化のブレスを吐いた。", "You breathe disenchantment."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_DISEN), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_DISENCHANT, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_NEXUS:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_DISENCHANT, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_NEXUS:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("因果混乱のブレスを吐いた。", "You breathe nexus."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_NEXUS), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_NEXUS, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_TIME:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_NEXUS, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_TIME:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("時間逆転のブレスを吐いた。", "You breathe time."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_TIME), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_TIME, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_INERTIA:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_TIME, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_INERTIA:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("遅鈍のブレスを吐いた。", "You breathe inertia."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_INERTIA), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_INERTIAL, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_GRAVITY:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_INERTIAL, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_GRAVITY:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("重力のブレスを吐いた。", "You breathe gravity."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_GRAVITY), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_GRAVITY, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_SHARDS:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_GRAVITY, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_SHARDS:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("破片のブレスを吐いた。", "You breathe shards."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_SHARDS), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_SHARDS, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_PLASMA:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_SHARDS, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_PLASMA:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("プラズマのブレスを吐いた。", "You breathe plasma."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_PLASMA), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_PLASMA, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_FORCE:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_PLASMA, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_FORCE:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("フォースのブレスを吐いた。", "You breathe force."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_FORCE), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_FORCE, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BR_MANA:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_FORCE, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BR_MANA:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("魔力のブレスを吐いた。", "You breathe mana."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_MANA), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_MANA, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BALL_NUKE:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_MANA, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BALL_NUKE:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("放射能球を放った。", "You cast a ball of radiation."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BALL_NUKE), plev, DAM_ROLL);
- fire_ball(caster_ptr, GF_NUKE, dir, damage, 2);
- break;
- case MS_BR_NUKE:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball(caster_ptr, GF_NUKE, dir, damage, 2);
+ break;
+ case MS_BR_NUKE:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("放射性廃棄物のブレスを吐いた。", "You breathe toxic waste."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_NUKE), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_NUKE, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BALL_CHAOS:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_NUKE, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BALL_CHAOS:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("純ログルスを放った。", "You invoke a raw Logrus."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BALL_CHAOS), plev, DAM_ROLL);
- fire_ball(caster_ptr, GF_CHAOS, dir, damage, 4);
- break;
- case MS_BR_DISI:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball(caster_ptr, GF_CHAOS, dir, damage, 4);
+ break;
+ case MS_BR_DISI:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("分解のブレスを吐いた。", "You breathe disintegration."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BR_DISI), plev, DAM_ROLL);
- fire_breath(caster_ptr, GF_DISINTEGRATE, dir, damage, (plev > 40 ? 3 : 2));
- break;
- case MS_BALL_ACID:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_breath(caster_ptr, GF_DISINTEGRATE, dir, damage, (plev > 40 ? 3 : 2));
+ break;
+ case MS_BALL_ACID:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("アシッド・ボールの呪文を唱えた。", "You cast an acid ball."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BALL_ACID), plev, DAM_ROLL);
- fire_ball(caster_ptr, GF_ACID, dir, damage, 2);
- break;
- case MS_BALL_ELEC:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball(caster_ptr, GF_ACID, dir, damage, 2);
+ break;
+ case MS_BALL_ELEC:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("サンダー・ボールの呪文を唱えた。", "You cast a lightning ball."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BALL_ELEC), plev, DAM_ROLL);
- fire_ball(caster_ptr, GF_ELEC, dir, damage, 2);
- break;
- case MS_BALL_FIRE:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball(caster_ptr, GF_ELEC, dir, damage, 2);
+ break;
+ case MS_BALL_FIRE:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("ファイア・ボールの呪文を唱えた。", "You cast a fire ball."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BALL_FIRE), plev, DAM_ROLL);
- fire_ball(caster_ptr, GF_FIRE, dir, damage, 2);
- break;
- case MS_BALL_COLD:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball(caster_ptr, GF_FIRE, dir, damage, 2);
+ break;
+ case MS_BALL_COLD:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("アイス・ボールの呪文を唱えた。", "You cast a frost ball."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BALL_COLD), plev, DAM_ROLL);
- fire_ball(caster_ptr, GF_COLD, dir, damage, 2);
- break;
- case MS_BALL_POIS:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball(caster_ptr, GF_COLD, dir, damage, 2);
+ break;
+ case MS_BALL_POIS:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("悪臭雲の呪文を唱えた。", "You cast a stinking cloud."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BALL_POIS), plev, DAM_ROLL);
- fire_ball(caster_ptr, GF_POIS, dir, damage, 2);
- break;
- case MS_BALL_NETHER:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball(caster_ptr, GF_POIS, dir, damage, 2);
+ break;
+ case MS_BALL_NETHER:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("地獄球の呪文を唱えた。", "You cast a nether ball."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BALL_NETHER), plev, DAM_ROLL);
- fire_ball(caster_ptr, GF_NETHER, dir, damage, 2);
- break;
- case MS_BALL_WATER:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball(caster_ptr, GF_NETHER, dir, damage, 2);
+ break;
+ case MS_BALL_WATER:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("流れるような身振りをした。", "You gesture fluidly."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BALL_WATER), plev, DAM_ROLL);
- fire_ball(caster_ptr, GF_WATER, dir, damage, 4);
- break;
- case MS_BALL_MANA:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball(caster_ptr, GF_WATER, dir, damage, 4);
+ break;
+ case MS_BALL_MANA:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("魔力の嵐の呪文を念じた。", "You invoke a mana storm."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BALL_MANA), plev, DAM_ROLL);
- fire_ball(caster_ptr, GF_MANA, dir, damage, 4);
- break;
- case MS_BALL_DARK:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball(caster_ptr, GF_MANA, dir, damage, 4);
+ break;
+ case MS_BALL_DARK:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("暗黒の嵐の呪文を念じた。", "You invoke a darkness storm."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BALL_DARK), plev, DAM_ROLL);
- fire_ball(caster_ptr, GF_DARK, dir, damage, 4);
- break;
- case MS_DRAIN_MANA:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball(caster_ptr, GF_DARK, dir, damage, 4);
+ break;
+ case MS_DRAIN_MANA:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
damage = monspell_bluemage_damage(caster_ptr, (MS_DRAIN_MANA), plev, DAM_ROLL);
fire_ball_hide(caster_ptr, GF_DRAIN_MANA, dir, damage, 0);
- break;
- case MS_MIND_BLAST:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ break;
+ case MS_MIND_BLAST:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
damage = monspell_bluemage_damage(caster_ptr, (MS_MIND_BLAST), plev, DAM_ROLL);
- fire_ball_hide(caster_ptr, GF_MIND_BLAST, dir, damage, 0);
- break;
- case MS_BRAIN_SMASH:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball_hide(caster_ptr, GF_MIND_BLAST, dir, damage, 0);
+ break;
+ case MS_BRAIN_SMASH:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
damage = monspell_bluemage_damage(caster_ptr, (MS_BRAIN_SMASH), plev, DAM_ROLL);
- fire_ball_hide(caster_ptr, GF_BRAIN_SMASH, dir, damage, 0);
- break;
- case MS_CAUSE_1:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball_hide(caster_ptr, GF_BRAIN_SMASH, dir, damage, 0);
+ break;
+ case MS_CAUSE_1:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
damage = monspell_bluemage_damage(caster_ptr, (MS_CAUSE_1), plev, DAM_ROLL);
- fire_ball_hide(caster_ptr, GF_CAUSE_1, dir, damage, 0);
- break;
- case MS_CAUSE_2:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball_hide(caster_ptr, GF_CAUSE_1, dir, damage, 0);
+ break;
+ case MS_CAUSE_2:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
damage = monspell_bluemage_damage(caster_ptr, (MS_CAUSE_2), plev, DAM_ROLL);
- fire_ball_hide(caster_ptr, GF_CAUSE_2, dir, damage, 0);
- break;
- case MS_CAUSE_3:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball_hide(caster_ptr, GF_CAUSE_2, dir, damage, 0);
+ break;
+ case MS_CAUSE_3:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
damage = monspell_bluemage_damage(caster_ptr, (MS_CAUSE_3), plev, DAM_ROLL);
- fire_ball_hide(caster_ptr, GF_CAUSE_3, dir, damage, 0);
- break;
- case MS_CAUSE_4:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball_hide(caster_ptr, GF_CAUSE_3, dir, damage, 0);
+ break;
+ case MS_CAUSE_4:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
damage = monspell_bluemage_damage(caster_ptr, (MS_CAUSE_4), plev, DAM_ROLL);
- fire_ball_hide(caster_ptr, GF_CAUSE_4, dir, damage, 0);
- break;
- case MS_BOLT_ACID:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball_hide(caster_ptr, GF_CAUSE_4, dir, damage, 0);
+ break;
+ case MS_BOLT_ACID:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("アシッド・ボルトの呪文を唱えた。", "You cast an acid bolt."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BOLT_ACID), plev, DAM_ROLL);
fire_bolt(caster_ptr, GF_ACID, dir, damage);
- break;
- case MS_BOLT_ELEC:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ break;
+ case MS_BOLT_ELEC:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("サンダー・ボルトの呪文を唱えた。", "You cast a lightning bolt."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BOLT_ELEC), plev, DAM_ROLL);
- fire_bolt(caster_ptr, GF_ELEC, dir, damage);
- break;
- case MS_BOLT_FIRE:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_bolt(caster_ptr, GF_ELEC, dir, damage);
+ break;
+ case MS_BOLT_FIRE:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("ファイア・ボルトの呪文を唱えた。", "You cast a fire bolt."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BOLT_FIRE), plev, DAM_ROLL);
- fire_bolt(caster_ptr, GF_FIRE, dir, damage);
- break;
- case MS_BOLT_COLD:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_bolt(caster_ptr, GF_FIRE, dir, damage);
+ break;
+ case MS_BOLT_COLD:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("アイス・ボルトの呪文を唱えた。", "You cast a frost bolt."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BOLT_COLD), plev, DAM_ROLL);
- fire_bolt(caster_ptr, GF_COLD, dir, damage);
- break;
- case MS_STARBURST:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_bolt(caster_ptr, GF_COLD, dir, damage);
+ break;
+ case MS_STARBURST:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("スターバーストの呪文を念じた。", "You invoke a starburst."));
damage = monspell_bluemage_damage(caster_ptr, (MS_STARBURST), plev, DAM_ROLL);
- fire_ball(caster_ptr, GF_LITE, dir, damage, 4);
- break;
- case MS_BOLT_NETHER:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_ball(caster_ptr, GF_LITE, dir, damage, 4);
+ break;
+ case MS_BOLT_NETHER:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("地獄の矢の呪文を唱えた。", "You cast a nether bolt."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BOLT_NETHER), plev, DAM_ROLL);
- fire_bolt(caster_ptr, GF_NETHER, dir, damage);
- break;
- case MS_BOLT_WATER:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_bolt(caster_ptr, GF_NETHER, dir, damage);
+ break;
+ case MS_BOLT_WATER:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("ウォーター・ボルトの呪文を唱えた。", "You cast a water bolt."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BOLT_WATER), plev, DAM_ROLL);
- fire_bolt(caster_ptr, GF_WATER, dir, damage);
- break;
- case MS_BOLT_MANA:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_bolt(caster_ptr, GF_WATER, dir, damage);
+ break;
+ case MS_BOLT_MANA:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("魔力の矢の呪文を唱えた。", "You cast a mana bolt."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BOLT_MANA), plev, DAM_ROLL);
- fire_bolt(caster_ptr, GF_MANA, dir, damage);
- break;
- case MS_BOLT_PLASMA:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_bolt(caster_ptr, GF_MANA, dir, damage);
+ break;
+ case MS_BOLT_PLASMA:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("プラズマ・ボルトの呪文を唱えた。", "You cast a plasma bolt."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BOLT_PLASMA), plev, DAM_ROLL);
- fire_bolt(caster_ptr, GF_PLASMA, dir, damage);
- break;
- case MS_BOLT_ICE:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_bolt(caster_ptr, GF_PLASMA, dir, damage);
+ break;
+ case MS_BOLT_ICE:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("極寒の矢の呪文を唱えた。", "You cast a ice bolt."));
damage = monspell_bluemage_damage(caster_ptr, (MS_BOLT_ICE), plev, DAM_ROLL);
- fire_bolt(caster_ptr, GF_ICE, dir, damage);
- break;
- case MS_MAGIC_MISSILE:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_bolt(caster_ptr, GF_ICE, dir, damage);
+ break;
+ case MS_MAGIC_MISSILE:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("マジック・ミサイルの呪文を唱えた。", "You cast a magic missile."));
damage = monspell_bluemage_damage(caster_ptr, (MS_MAGIC_MISSILE), plev, DAM_ROLL);
- fire_bolt(caster_ptr, GF_MISSILE, dir, damage);
- break;
- case MS_SCARE:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fire_bolt(caster_ptr, GF_MISSILE, dir, damage);
+ break;
+ case MS_SCARE:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("恐ろしげな幻覚を作り出した。", "You cast a fearful illusion."));
- fear_monster(caster_ptr, dir, plev+10);
- break;
- case MS_BLIND:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
- confuse_monster(caster_ptr, dir, plev * 2);
- break;
- case MS_CONF:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ fear_monster(caster_ptr, dir, plev + 10);
+ break;
+ case MS_BLIND:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
+ confuse_monster(caster_ptr, dir, plev * 2);
+ break;
+ case MS_CONF:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("誘惑的な幻覚をつくり出した。", "You cast a mesmerizing illusion."));
- confuse_monster(caster_ptr, dir, plev * 2);
- break;
- case MS_SLOW:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
- slow_monster(caster_ptr, dir, plev);
- break;
- case MS_SLEEP:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
- sleep_monster(caster_ptr, dir, plev);
- break;
- case MS_SPEED:
- (void)set_fast(caster_ptr, randint1(20 + plev) + plev, FALSE);
- break;
- case MS_HAND_DOOM:
- {
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ confuse_monster(caster_ptr, dir, plev * 2);
+ break;
+ case MS_SLOW:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
+ slow_monster(caster_ptr, dir, plev);
+ break;
+ case MS_SLEEP:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
+ sleep_monster(caster_ptr, dir, plev);
+ break;
+ case MS_SPEED:
+ (void)set_fast(caster_ptr, randint1(20 + plev) + plev, FALSE);
+ break;
+ case MS_HAND_DOOM: {
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("<破滅の手>を放った!", "You invoke the Hand of Doom!"));
- fire_ball_hide(caster_ptr, GF_HAND_DOOM, dir, plev * 3, 0);
- break;
- }
- case MS_HEAL:
+ fire_ball_hide(caster_ptr, GF_HAND_DOOM, dir, plev * 3, 0);
+ break;
+ }
+ case MS_HEAL:
msg_print(_("自分の傷に念を集中した。", "You concentrate on your wounds!"));
- (void)hp_player(caster_ptr, plev*4);
- (void)set_stun(caster_ptr, 0);
- (void)set_cut(caster_ptr,0);
- break;
- case MS_INVULNER:
+ (void)hp_player(caster_ptr, plev * 4);
+ (void)set_stun(caster_ptr, 0);
+ (void)set_cut(caster_ptr, 0);
+ break;
+ case MS_INVULNER:
msg_print(_("無傷の球の呪文を唱えた。", "You cast a Globe of Invulnerability."));
- (void)set_invuln(caster_ptr, randint1(4) + 4, FALSE);
- break;
- case MS_BLINK:
- teleport_player(caster_ptr, 10, TELEPORT_SPONTANEOUS);
- break;
- case MS_TELEPORT:
- teleport_player(caster_ptr, plev * 5, TELEPORT_SPONTANEOUS);
- break;
- case MS_WORLD:
- (void)time_walk(caster_ptr);
- break;
- case MS_SPECIAL:
- break;
- case MS_TELE_TO:
- {
- monster_type *m_ptr;
- monster_race *r_ptr;
- GAME_TEXT m_name[MAX_NLEN];
-
- if (!target_set(caster_ptr, TARGET_KILL)) return FALSE;
- if (!floor_ptr->grid_array[target_row][target_col].m_idx) break;
- if (!player_has_los_bold(caster_ptr, target_row, target_col)) break;
- if (!projectable(caster_ptr, caster_ptr->y, caster_ptr->x, target_row, target_col)) break;
- m_ptr = &floor_ptr->m_list[floor_ptr->grid_array[target_row][target_col].m_idx];
- r_ptr = &r_info[m_ptr->r_idx];
- monster_desc(caster_ptr, 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(caster_ptr, m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
+ (void)set_invuln(caster_ptr, randint1(4) + 4, FALSE);
+ break;
+ case MS_BLINK:
+ teleport_player(caster_ptr, 10, TELEPORT_SPONTANEOUS);
+ break;
+ case MS_TELEPORT:
+ teleport_player(caster_ptr, plev * 5, TELEPORT_SPONTANEOUS);
+ break;
+ case MS_WORLD:
+ (void)time_walk(caster_ptr);
+ break;
+ case MS_SPECIAL:
+ break;
+ case MS_TELE_TO: {
+ monster_type *m_ptr;
+ monster_race *r_ptr;
+ GAME_TEXT m_name[MAX_NLEN];
+
+ if (!target_set(caster_ptr, TARGET_KILL))
+ return FALSE;
+ if (!floor_ptr->grid_array[target_row][target_col].m_idx)
+ break;
+ if (!player_has_los_bold(caster_ptr, target_row, target_col))
+ break;
+ if (!projectable(caster_ptr, caster_ptr->y, caster_ptr->x, target_row, target_col))
+ break;
+ m_ptr = &floor_ptr->m_list[floor_ptr->grid_array[target_row][target_col].m_idx];
+ r_ptr = &r_info[m_ptr->r_idx];
+ monster_desc(caster_ptr, 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(caster_ptr, 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(caster_ptr, m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
+ break;
+ } else if (r_ptr->level > randint1(100)) {
+ if (is_original_ap_and_seen(caster_ptr, m_ptr))
+ r_ptr->r_flagsr |= RFR_RES_TELE;
msg_format(_("%sには耐性がある!", "%s resists!"), m_name);
- break;
- }
- }
+ break;
+ }
+ }
msg_format(_("%sを引き戻した。", "You command %s to return."), m_name);
- teleport_monster_to(caster_ptr, floor_ptr->grid_array[target_row][target_col].m_idx, caster_ptr->y, caster_ptr->x, 100, TELEPORT_PASSIVE);
- break;
- }
- case MS_TELE_AWAY:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ teleport_monster_to(caster_ptr, floor_ptr->grid_array[target_row][target_col].m_idx, caster_ptr->y, caster_ptr->x, 100, TELEPORT_PASSIVE);
+ break;
+ }
+ case MS_TELE_AWAY:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
- (void)fire_beam(caster_ptr, GF_AWAY_ALL, dir, 100);
- break;
+ (void)fire_beam(caster_ptr, GF_AWAY_ALL, dir, 100);
+ break;
- case MS_TELE_LEVEL:
- return teleport_level_other(caster_ptr);
- break;
+ case MS_TELE_LEVEL:
+ return teleport_level_other(caster_ptr);
+ break;
- case MS_PSY_SPEAR:
- if (!get_aim_dir(caster_ptr, &dir)) return FALSE;
+ case MS_PSY_SPEAR:
+ if (!get_aim_dir(caster_ptr, &dir))
+ return FALSE;
msg_print(_("光の剣を放った。", "You throw a psycho-spear."));
damage = monspell_bluemage_damage(caster_ptr, (MS_PSY_SPEAR), plev, DAM_ROLL);
- (void)fire_beam(caster_ptr, GF_PSY_SPEAR, dir, damage);
- break;
- case MS_DARKNESS:
+ (void)fire_beam(caster_ptr, GF_PSY_SPEAR, dir, damage);
+ break;
+ case MS_DARKNESS:
msg_print(_("暗闇の中で手を振った。", "You gesture in shadow."));
- (void)unlite_area(caster_ptr, 10, 3);
- break;
- case MS_MAKE_TRAP:
- if (!target_set(caster_ptr, TARGET_KILL)) return FALSE;
+ (void)unlite_area(caster_ptr, 10, 3);
+ break;
+ case MS_MAKE_TRAP:
+ if (!target_set(caster_ptr, TARGET_KILL))
+ return FALSE;
msg_print(_("呪文を唱えて邪悪に微笑んだ。", "You cast a spell and cackle evilly."));
- trap_creation(caster_ptr, target_row, target_col);
- break;
- case MS_FORGET:
+ trap_creation(caster_ptr, target_row, target_col);
+ break;
+ case MS_FORGET:
msg_print(_("しかし何も起きなかった。", "Nothing happen."));
- break;
+ break;
case MS_RAISE_DEAD:
msg_print(_("死者復活の呪文を唱えた。", "You animate the dead."));
- (void)animate_dead(caster_ptr, 0, caster_ptr->y, caster_ptr->x);
- break;
- case MS_S_KIN:
- {
+ (void)animate_dead(caster_ptr, 0, caster_ptr->y, caster_ptr->x);
+ break;
+ case MS_S_KIN: {
msg_print(_("援軍を召喚した。", "You summon one of your kin."));
- for (int k = 0;k < 1; k++)
- {
- if (summon_kin_player(caster_ptr, summon_lev, caster_ptr->y, caster_ptr->x, (pet ? PM_FORCE_PET : 0L)))
- {
- if (!pet) msg_print(_("召喚された仲間は怒っている!", "The summoned companion is angry!"));
- }
- else
- {
- no_trump = TRUE;
- }
- }
-
- break;
- }
- case MS_S_CYBER:
- {
+ for (int k = 0; k < 1; k++) {
+ if (summon_kin_player(caster_ptr, summon_lev, caster_ptr->y, caster_ptr->x, (pet ? PM_FORCE_PET : 0L))) {
+ if (!pet)
+ msg_print(_("召喚された仲間は怒っている!", "The summoned companion is angry!"));
+ } else {
+ no_trump = TRUE;
+ }
+ }
+
+ break;
+ }
+ case MS_S_CYBER: {
msg_print(_("サイバーデーモンを召喚した!", "You summon a Cyberdemon!"));
- for (int k = 0; k < 1; k++)
- {
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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:
- {
+ for (int k = 0; k < 1; k++) {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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: {
msg_print(_("仲間を召喚した。", "You summon help."));
- for (int k = 0; k < 1; k++)
- {
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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:
- {
+ for (int k = 0; k < 1; k++) {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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: {
msg_print(_("モンスターを召喚した!", "You summon monsters!"));
- for (int k = 0; k < plev / 15 + 2; k++)
- {
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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:
- {
+ for (int k = 0; k < plev / 15 + 2; k++) {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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: {
msg_print(_("アリを召喚した。", "You summon ants."));
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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:
- {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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: {
msg_print(_("蜘蛛を召喚した。", "You summon spiders."));
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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:
- {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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: {
msg_print(_("ハウンドを召喚した。", "You summon hounds."));
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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:
- {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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: {
msg_print(_("ヒドラを召喚した。", "You summon a hydras."));
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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:
- {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_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: {
msg_print(_("天使を召喚した!", "You summon an angel!"));
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_ANGEL, (g_mode | p_mode)))
- {
- if (!pet)
- msg_print(_("召喚された天使は怒っている!", "The summoned angel is angry!"));
- }
- else
- {
- no_trump = TRUE;
- }
- break;
- }
- case MS_S_DEMON:
- {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_ANGEL, (g_mode | p_mode))) {
+ if (!pet)
+ msg_print(_("召喚された天使は怒っている!", "The summoned angel is angry!"));
+ } else {
+ no_trump = TRUE;
+ }
+ break;
+ }
+ case MS_S_DEMON: {
msg_print(_("混沌の宮廷から悪魔を召喚した!", "You summon a demon from the Courts of Chaos!"));
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_DEMON, (g_mode | p_mode)))
- {
- if (!pet)
- msg_print(_("召喚されたデーモンは怒っている!", "The summoned demon is angry!"));
- }
- else
- {
- no_trump = TRUE;
- }
- break;
- }
- case MS_S_UNDEAD:
- {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_DEMON, (g_mode | p_mode))) {
+ if (!pet)
+ msg_print(_("召喚されたデーモンは怒っている!", "The summoned demon is angry!"));
+ } else {
+ no_trump = TRUE;
+ }
+ break;
+ }
+ case MS_S_UNDEAD: {
msg_print(_("アンデッドの強敵を召喚した!", "You summon an undead adversary!"));
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_UNDEAD, (g_mode | p_mode)))
- {
- if (!pet)
- msg_print(_("召喚されたアンデッドは怒っている!", "The summoned undead is angry!"));
- }
- else
- {
- no_trump = TRUE;
- }
- break;
- }
- case MS_S_DRAGON:
- {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_UNDEAD, (g_mode | p_mode))) {
+ if (!pet)
+ msg_print(_("召喚されたアンデッドは怒っている!", "The summoned undead is angry!"));
+ } else {
+ no_trump = TRUE;
+ }
+ break;
+ }
+ case MS_S_DRAGON: {
msg_print(_("ドラゴンを召喚した!", "You summon a dragon!"));
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_DRAGON, (g_mode | p_mode)))
- {
- if (!pet)
- msg_print(_("召喚されたドラゴンは怒っている!", "The summoned dragon is angry!"));
- }
- else
- {
- no_trump = TRUE;
- }
- break;
- }
- case MS_S_HI_UNDEAD:
- {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_DRAGON, (g_mode | p_mode))) {
+ if (!pet)
+ msg_print(_("召喚されたドラゴンは怒っている!", "The summoned dragon is angry!"));
+ } else {
+ no_trump = TRUE;
+ }
+ break;
+ }
+ case MS_S_HI_UNDEAD: {
msg_print(_("強力なアンデッドを召喚した!", "You summon a greater undead!"));
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_HI_UNDEAD, (g_mode | p_mode | u_mode)))
- {
- if (!pet)
- msg_print(_("召喚された上級アンデッドは怒っている!", "The summoned greater undead is angry!"));
- }
- else
- {
- no_trump = TRUE;
- }
- break;
- }
- case MS_S_HI_DRAGON:
- {
- msg_print(_("古代ドラゴンを召喚した!", "You summon an ancient dragon!"));
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_HI_DRAGON, (g_mode | p_mode | u_mode)))
- {
- if (!pet)
- msg_print(_("召喚された古代ドラゴンは怒っている!", "The summoned ancient dragon is angry!"));
- }
- else
- {
- no_trump = TRUE;
- }
- break;
- }
- case MS_S_AMBERITE:
- {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_HI_UNDEAD, (g_mode | p_mode | u_mode))) {
+ if (!pet)
+ msg_print(_("召喚された上級アンデッドは怒っている!", "The summoned greater undead is angry!"));
+ } else {
+ no_trump = TRUE;
+ }
+ break;
+ }
+ case MS_S_HI_DRAGON: {
+ msg_print(_("古代ドラゴンを召喚した!", "You summon an ancient dragon!"));
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_HI_DRAGON, (g_mode | p_mode | u_mode))) {
+ if (!pet)
+ msg_print(_("召喚された古代ドラゴンは怒っている!", "The summoned ancient dragon is angry!"));
+ } else {
+ no_trump = TRUE;
+ }
+ break;
+ }
+ case MS_S_AMBERITE: {
msg_print(_("アンバーの王族を召喚した!", "You summon a Lord of Amber!"));
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_AMBERITES, (g_mode | p_mode | u_mode)))
- {
- if (!pet)
- msg_print(_("召喚されたアンバーの王族は怒っている!", "The summoned Lord of Amber is 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(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_UNIQUE, (g_mode | p_mode | PM_ALLOW_UNIQUE)))
- {
- count++;
- if (!pet)
- msg_print(_("召喚されたユニーク・モンスターは怒っている!", "The summoned special opponent is angry!"));
- }
- }
-
- for (k = count; k < 1; k++)
- {
- if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_HI_UNDEAD, (g_mode | p_mode | PM_ALLOW_UNIQUE)))
- {
- count++;
- if (!pet)
- msg_print(_("召喚された上級アンデッドは怒っている!", "The summoned greater undead is angry!"));
- }
- }
-
- if (!count)
- {
- no_trump = TRUE;
- }
-
- break;
- }
- default:
- msg_print("hoge?");
- }
-
- if (no_trump)
- {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_AMBERITES, (g_mode | p_mode | u_mode))) {
+ if (!pet)
+ msg_print(_("召喚されたアンバーの王族は怒っている!", "The summoned Lord of Amber is 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(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_UNIQUE, (g_mode | p_mode | PM_ALLOW_UNIQUE))) {
+ count++;
+ if (!pet)
+ msg_print(_("召喚されたユニーク・モンスターは怒っている!", "The summoned special opponent is angry!"));
+ }
+ }
+
+ for (k = count; k < 1; k++) {
+ if (summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x, summon_lev, SUMMON_HI_UNDEAD, (g_mode | p_mode | PM_ALLOW_UNIQUE))) {
+ count++;
+ if (!pet)
+ msg_print(_("召喚された上級アンデッドは怒っている!", "The summoned greater undead is angry!"));
+ }
+ }
+
+ if (!count) {
+ no_trump = TRUE;
+ }
+
+ break;
+ }
+ default:
+ msg_print("hoge?");
+ }
+
+ if (no_trump) {
msg_print(_("何も現れなかった。", "No one appeared."));
- }
+ }
- return TRUE;
+ return TRUE;
}
-
/*!
* @brief 青魔法コマンドのメインルーチン /
* do_cmd_cast calls this function if the player's class is 'Blue-Mage'.
*/
bool do_cmd_cast_learned(player_type *caster_ptr)
{
- SPELL_IDX n = 0;
- PERCENTAGE chance;
- PERCENTAGE minfail = 0;
- PLAYER_LEVEL plev = caster_ptr->lev;
- monster_power spell;
- bool cast;
- MANA_POINT need_mana;
-
- if (cmd_limit_confused(caster_ptr)) return FALSE;
-
- if (!get_learned_power(caster_ptr, &n)) return FALSE;
-
- spell = monster_powers[n];
- need_mana = mod_need_mana(caster_ptr, spell.smana, 0, REALM_NONE);
- if (need_mana > caster_ptr->csp)
- {
- msg_print(_("MPが足りません。", "You do not have enough mana to use this power."));
- if (!over_exert) return FALSE;
-
- if (!get_check(_("それでも挑戦しますか? ", "Attempt it anyway? "))) return FALSE;
- }
-
- chance = spell.fail;
- if (plev > spell.level) chance -= 3 * (plev - spell.level);
- else chance += (spell.level - plev);
-
- chance -= 3 * (adj_mag_stat[caster_ptr->stat_ind[A_INT]] - 1);
- chance = mod_spell_chance_1(caster_ptr, chance);
- if (need_mana > caster_ptr->csp)
- {
- chance += 5 * (need_mana - caster_ptr->csp);
- }
-
- minfail = adj_mag_fail[caster_ptr->stat_ind[A_INT]];
- if (chance < minfail) chance = minfail;
-
- if (caster_ptr->stun > 50) chance += 25;
- else if (caster_ptr->stun) chance += 15;
-
- if (chance > 95) chance = 95;
-
- chance = mod_spell_chance_2(caster_ptr, chance);
- if (randint0(100) < chance)
- {
- if (flush_failure) flush();
- msg_print(_("魔法をうまく唱えられなかった。", "You failed to concentrate hard enough!"));
- sound(SOUND_FAIL);
- if (n >= MS_S_KIN)
- cast = cast_learned_spell(caster_ptr, n, FALSE);
- }
- else
- {
- sound(SOUND_ZAP);
- cast = cast_learned_spell(caster_ptr, n, TRUE);
- if (!cast) return FALSE;
- }
-
- if (need_mana <= caster_ptr->csp)
- {
- caster_ptr->csp -= need_mana;
- }
- else
- {
- int oops = need_mana;
- caster_ptr->csp = 0;
- caster_ptr->csp_frac = 0;
- msg_print(_("精神を集中しすぎて気を失ってしまった!", "You faint from the effort!"));
- (void)set_paralyzed(caster_ptr, caster_ptr->paralyzed + randint1(5 * oops + 1));
- chg_virtue(caster_ptr, V_KNOWLEDGE, -10);
- if (randint0(100) < 50)
- {
- bool perm = (randint0(100) < 25);
- msg_print(_("体を悪くしてしまった!", "You have damaged your health!"));
- (void)dec_stat(caster_ptr, A_CON, 15 + randint1(10), perm);
- }
- }
-
- take_turn(caster_ptr, 100);
- caster_ptr->redraw |= (PR_MANA);
- caster_ptr->window |= (PW_PLAYER | PW_SPELL);
- return TRUE;
+ SPELL_IDX n = 0;
+ PERCENTAGE chance;
+ PERCENTAGE minfail = 0;
+ PLAYER_LEVEL plev = caster_ptr->lev;
+ monster_power spell;
+ bool cast;
+ MANA_POINT need_mana;
+
+ if (cmd_limit_confused(caster_ptr))
+ return FALSE;
+
+ if (!get_learned_power(caster_ptr, &n))
+ return FALSE;
+
+ spell = monster_powers[n];
+ need_mana = mod_need_mana(caster_ptr, spell.smana, 0, REALM_NONE);
+ if (need_mana > caster_ptr->csp) {
+ msg_print(_("MPが足りません。", "You do not have enough mana to use this power."));
+ if (!over_exert)
+ return FALSE;
+
+ if (!get_check(_("それでも挑戦しますか? ", "Attempt it anyway? ")))
+ return FALSE;
+ }
+
+ chance = spell.fail;
+ if (plev > spell.level)
+ chance -= 3 * (plev - spell.level);
+ else
+ chance += (spell.level - plev);
+
+ chance -= 3 * (adj_mag_stat[caster_ptr->stat_ind[A_INT]] - 1);
+ chance = mod_spell_chance_1(caster_ptr, chance);
+ if (need_mana > caster_ptr->csp) {
+ chance += 5 * (need_mana - caster_ptr->csp);
+ }
+
+ minfail = adj_mag_fail[caster_ptr->stat_ind[A_INT]];
+ if (chance < minfail)
+ chance = minfail;
+
+ if (caster_ptr->stun > 50)
+ chance += 25;
+ else if (caster_ptr->stun)
+ chance += 15;
+
+ if (chance > 95)
+ chance = 95;
+
+ chance = mod_spell_chance_2(caster_ptr, chance);
+ if (randint0(100) < chance) {
+ if (flush_failure)
+ flush();
+ msg_print(_("魔法をうまく唱えられなかった。", "You failed to concentrate hard enough!"));
+ sound(SOUND_FAIL);
+ if (n >= MS_S_KIN)
+ cast = cast_learned_spell(caster_ptr, n, FALSE);
+ } else {
+ sound(SOUND_ZAP);
+ cast = cast_learned_spell(caster_ptr, n, TRUE);
+ if (!cast)
+ return FALSE;
+ }
+
+ if (need_mana <= caster_ptr->csp) {
+ caster_ptr->csp -= need_mana;
+ } else {
+ int oops = need_mana;
+ caster_ptr->csp = 0;
+ caster_ptr->csp_frac = 0;
+ msg_print(_("精神を集中しすぎて気を失ってしまった!", "You faint from the effort!"));
+ (void)set_paralyzed(caster_ptr, caster_ptr->paralyzed + randint1(5 * oops + 1));
+ chg_virtue(caster_ptr, V_KNOWLEDGE, -10);
+ if (randint0(100) < 50) {
+ bool perm = (randint0(100) < 25);
+ msg_print(_("体を悪くしてしまった!", "You have damaged your health!"));
+ (void)dec_stat(caster_ptr, A_CON, 15 + randint1(10), perm);
+ }
+ }
+
+ take_turn(caster_ptr, 100);
+ caster_ptr->redraw |= (PR_MANA);
+ caster_ptr->window |= (PW_PLAYER | PW_SPELL);
+ return TRUE;
}
-
/*!
* @brief 青魔法のラーニング判定と成功した場合のラーニング処理
* @param monspell ラーニングを試みるモンスター攻撃のID
*/
void learn_spell(player_type *learner_ptr, int monspell)
{
- if (learner_ptr->action != ACTION_LEARN) return;
- if (monspell < 0) return;
- if (learner_ptr->magic_num2[monspell]) return;
- if (learner_ptr->confused || learner_ptr->blind || learner_ptr->image || learner_ptr->stun || learner_ptr->paralyzed) return;
- if (randint1(learner_ptr->lev + 70) > monster_powers[monspell].level + 40)
- {
- learner_ptr->magic_num2[monspell] = 1;
- msg_format(_("%sを学習した!", "You have learned %s!"), monster_powers[monspell].name);
- gain_exp(learner_ptr, monster_powers[monspell].level * monster_powers[monspell].smana);
-
- sound(SOUND_STUDY);
-
- learner_ptr->new_mane = TRUE;
- learner_ptr->redraw |= (PR_STATE);
- }
+ if (learner_ptr->action != ACTION_LEARN)
+ return;
+ if (monspell < 0)
+ return;
+ if (learner_ptr->magic_num2[monspell])
+ return;
+ if (learner_ptr->confused || learner_ptr->blind || learner_ptr->image || learner_ptr->stun || learner_ptr->paralyzed)
+ return;
+ if (randint1(learner_ptr->lev + 70) > monster_powers[monspell].level + 40) {
+ learner_ptr->magic_num2[monspell] = 1;
+ msg_format(_("%sを学習した!", "You have learned %s!"), monster_powers[monspell].name);
+ gain_exp(learner_ptr, monster_powers[monspell].level * monster_powers[monspell].smana);
+
+ sound(SOUND_STUDY);
+
+ learner_ptr->new_mane = TRUE;
+ learner_ptr->redraw |= (PR_STATE);
+ }
}
-
/*!
* todo f4, f5, f6を構造体にまとめ直す
* @brief モンスター特殊能力のフラグ配列から特定条件の魔法だけを抜き出す処理
*/
void set_rf_masks(BIT_FLAGS *f4, BIT_FLAGS *f5, BIT_FLAGS *f6, BIT_FLAGS mode)
{
- switch (mode)
- {
- case MONSPELL_TYPE_BOLT:
- *f4 = ((RF4_BOLT_MASK | RF4_BEAM_MASK) & ~(RF4_ROCKET));
- *f5 = RF5_BOLT_MASK | RF5_BEAM_MASK;
- *f6 = RF6_BOLT_MASK | RF6_BEAM_MASK;
- break;
-
- case MONSPELL_TYPE_BALL:
- *f4 = (RF4_BALL_MASK & ~(RF4_BREATH_MASK));
- *f5 = (RF5_BALL_MASK & ~(RF5_BREATH_MASK));
- *f6 = (RF6_BALL_MASK & ~(RF6_BREATH_MASK));
- break;
-
- case MONSPELL_TYPE_BREATH:
- *f4 = (BIT_FLAGS)RF4_BREATH_MASK;
- *f5 = RF5_BREATH_MASK;
- *f6 = RF6_BREATH_MASK;
- break;
-
- case MONSPELL_TYPE_SUMMON:
- *f4 = RF4_SUMMON_MASK;
- *f5 = RF5_SUMMON_MASK;
- *f6 = (BIT_FLAGS)RF6_SUMMON_MASK;
- break;
-
- case MONSPELL_TYPE_OTHER:
- *f4 = RF4_ATTACK_MASK & ~(RF4_BOLT_MASK | RF4_BEAM_MASK | RF4_BALL_MASK | RF4_INDIRECT_MASK);
- *f5 = RF5_ATTACK_MASK & ~(RF5_BOLT_MASK | RF5_BEAM_MASK | RF5_BALL_MASK | RF5_INDIRECT_MASK);
- *f6 = RF6_ATTACK_MASK & ~(RF6_BOLT_MASK | RF6_BEAM_MASK | RF6_BALL_MASK | RF6_INDIRECT_MASK);
- break;
- }
+ switch (mode) {
+ case MONSPELL_TYPE_BOLT:
+ *f4 = ((RF4_BOLT_MASK | RF4_BEAM_MASK) & ~(RF4_ROCKET));
+ *f5 = RF5_BOLT_MASK | RF5_BEAM_MASK;
+ *f6 = RF6_BOLT_MASK | RF6_BEAM_MASK;
+ break;
+
+ case MONSPELL_TYPE_BALL:
+ *f4 = (RF4_BALL_MASK & ~(RF4_BREATH_MASK));
+ *f5 = (RF5_BALL_MASK & ~(RF5_BREATH_MASK));
+ *f6 = (RF6_BALL_MASK & ~(RF6_BREATH_MASK));
+ break;
+
+ case MONSPELL_TYPE_BREATH:
+ *f4 = (BIT_FLAGS)RF4_BREATH_MASK;
+ *f5 = RF5_BREATH_MASK;
+ *f6 = RF6_BREATH_MASK;
+ break;
+
+ case MONSPELL_TYPE_SUMMON:
+ *f4 = RF4_SUMMON_MASK;
+ *f5 = RF5_SUMMON_MASK;
+ *f6 = (BIT_FLAGS)RF6_SUMMON_MASK;
+ break;
+
+ case MONSPELL_TYPE_OTHER:
+ *f4 = RF4_ATTACK_MASK & ~(RF4_BOLT_MASK | RF4_BEAM_MASK | RF4_BALL_MASK | RF4_INDIRECT_MASK);
+ *f5 = RF5_ATTACK_MASK & ~(RF5_BOLT_MASK | RF5_BEAM_MASK | RF5_BALL_MASK | RF5_INDIRECT_MASK);
+ *f6 = RF6_ATTACK_MASK & ~(RF6_BOLT_MASK | RF6_BEAM_MASK | RF6_BALL_MASK | RF6_INDIRECT_MASK);
+ break;
+ }
}