OSDN Git Service

Merge pull request #3569 from sikabane-works/release/3.0.0.88-alpha
[hengbandforosx/hengbandosx.git] / src / mspell / assign-monster-spell.cpp
1 /*!
2  * @brief モンスターのスペル振り分け処理 / Spell launch by a monster
3  * @date 2014/07/14
4  * @author Habu
5  */
6
7 #include "mspell/assign-monster-spell.h"
8 #include "blue-magic/blue-magic-checker.h"
9 #include "monster-race/race-ability-flags.h"
10 #include "monster/monster-status.h"
11 #include "mspell/mspell-attack/mspell-ball.h"
12 #include "mspell/mspell-attack/mspell-bolt.h"
13 #include "mspell/mspell-attack/mspell-breath.h"
14 #include "mspell/mspell-attack/mspell-curse.h"
15 #include "mspell/mspell-attack/mspell-particularity.h"
16 #include "mspell/mspell-dispel.h"
17 #include "mspell/mspell-floor.h"
18 #include "mspell/mspell-learn-checker.h"
19 #include "mspell/mspell-result.h"
20 #include "mspell/mspell-special.h"
21 #include "mspell/mspell-status.h"
22 #include "mspell/mspell-summon.h"
23 #include "mspell/mspell-util.h"
24 #include "system/player-type-definition.h"
25 #include "util/enum-converter.h"
26
27 static MonsterSpellResult monspell_to_player_impl(PlayerType *player_ptr, MonsterAbilityType ms_type, POSITION y, POSITION x, MONSTER_IDX m_idx)
28 {
29     // clang-format off
30     switch (ms_type) {
31     case MonsterAbilityType::SHRIEK: return spell_RF4_SHRIEK(m_idx, player_ptr, 0, MONSTER_TO_PLAYER); /* RF4_SHRIEK */
32     case MonsterAbilityType::XXX1: break;   /* RF4_XXX1 */
33     case MonsterAbilityType::DISPEL: return spell_RF4_DISPEL(m_idx, player_ptr, 0, MONSTER_TO_PLAYER); /* RF4_DISPEL */
34     case MonsterAbilityType::ROCKET: return spell_RF4_ROCKET(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER);  /* RF4_ROCKET */
35     case MonsterAbilityType::XXX2: break;   /* RF4_XXX2 */
36     case MonsterAbilityType::XXX3: break;   /* RF4_XXX3 */
37     case MonsterAbilityType::XXX4: break;   /* RF4_XXX4 */
38
39     case MonsterAbilityType::BR_ACID:
40     case MonsterAbilityType::BR_ELEC:
41     case MonsterAbilityType::BR_FIRE:
42     case MonsterAbilityType::BR_COLD:
43     case MonsterAbilityType::BR_POIS:
44     case MonsterAbilityType::BR_NETH:
45     case MonsterAbilityType::BR_LITE:
46     case MonsterAbilityType::BR_DARK:
47     case MonsterAbilityType::BR_CONF:
48     case MonsterAbilityType::BR_SOUN:
49     case MonsterAbilityType::BR_CHAO:
50     case MonsterAbilityType::BR_DISE:
51     case MonsterAbilityType::BR_NEXU:
52     case MonsterAbilityType::BR_TIME:
53     case MonsterAbilityType::BR_INER:
54     case MonsterAbilityType::BR_GRAV:
55     case MonsterAbilityType::BR_SHAR:
56     case MonsterAbilityType::BR_PLAS:
57     case MonsterAbilityType::BR_FORC:
58     case MonsterAbilityType::BR_MANA:
59     case MonsterAbilityType::BR_NUKE:
60     case MonsterAbilityType::BR_DISI:
61     case MonsterAbilityType::BR_VOID:
62     case MonsterAbilityType::BR_ABYSS:
63      return spell_RF4_BREATH(player_ptr, ms_type, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_ABYSS */
64     
65     case MonsterAbilityType::BA_ACID:
66     case MonsterAbilityType::BA_ELEC:
67     case MonsterAbilityType::BA_FIRE:
68     case MonsterAbilityType::BA_COLD:
69          {
70          auto rad = monster_is_powerful(player_ptr->current_floor_ptr, m_idx) ? 4 : 2;
71          return MSpellBall(player_ptr, m_idx, ms_type, rad, MONSTER_TO_PLAYER).shoot(y, x);
72          }
73
74     case MonsterAbilityType::BA_POIS:
75     case MonsterAbilityType::BA_NETH:
76     case MonsterAbilityType::BA_NUKE:
77          return MSpellBall(player_ptr, m_idx, ms_type, 2, MONSTER_TO_PLAYER).shoot(y, x);
78
79     case MonsterAbilityType::BA_CHAO:
80     case MonsterAbilityType::BA_WATE:
81     case MonsterAbilityType::BA_MANA:
82     case MonsterAbilityType::BA_LITE:
83     case MonsterAbilityType::BA_DARK:
84     case MonsterAbilityType::BA_VOID:
85     case MonsterAbilityType::BA_ABYSS:
86          return MSpellBall(player_ptr, m_idx, ms_type, 4, MONSTER_TO_PLAYER).shoot(y, x);
87
88     case MonsterAbilityType::DRAIN_MANA: return spell_RF5_DRAIN_MANA(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER);  /* RF5_DRAIN_MANA */
89     case MonsterAbilityType::MIND_BLAST: return spell_RF5_MIND_BLAST(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER);  /* RF5_MIND_BLAST */
90     case MonsterAbilityType::BRAIN_SMASH: return spell_RF5_BRAIN_SMASH(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_MIND_BLAST */
91
92     case MonsterAbilityType::CAUSE_1:
93     case MonsterAbilityType::CAUSE_2:
94     case MonsterAbilityType::CAUSE_3:
95     case MonsterAbilityType::CAUSE_4: 
96         return spell_RF5_CAUSE(player_ptr, ms_type, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_CAUSE_* */
97
98     case MonsterAbilityType::SHOOT:
99     case MonsterAbilityType::BO_ACID:
100     case MonsterAbilityType::BO_ELEC:
101     case MonsterAbilityType::BO_FIRE:
102     case MonsterAbilityType::BO_COLD:
103     case MonsterAbilityType::BO_NETH:
104     case MonsterAbilityType::BO_WATE:
105     case MonsterAbilityType::BO_MANA:
106     case MonsterAbilityType::BO_PLAS:
107     case MonsterAbilityType::BO_ICEE:
108     case MonsterAbilityType::BO_VOID:
109     case MonsterAbilityType::BO_ABYSS:
110     case MonsterAbilityType::MISSILE: 
111         return MSpellBolt(player_ptr, m_idx, ms_type, MONSTER_TO_PLAYER).shoot(y,x);
112
113     case MonsterAbilityType::SCARE: return spell_RF5_SCARE(m_idx, player_ptr, 0, MONSTER_TO_PLAYER); /* RF5_SCARE */
114     case MonsterAbilityType::BLIND: return spell_RF5_BLIND(m_idx, player_ptr, 0, MONSTER_TO_PLAYER); /* RF5_BLIND */
115     case MonsterAbilityType::CONF: return spell_RF5_CONF(m_idx, player_ptr, 0, MONSTER_TO_PLAYER); /* RF5_CONF */
116     case MonsterAbilityType::SLOW: return spell_RF5_SLOW(m_idx, player_ptr, 0, MONSTER_TO_PLAYER); /* RF5_SLOW */
117     case MonsterAbilityType::HOLD: return spell_RF5_HOLD(m_idx, player_ptr, 0, MONSTER_TO_PLAYER); /* RF5_HOLD */
118     case MonsterAbilityType::HASTE: return spell_RF6_HASTE(player_ptr, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_HASTE */
119     case MonsterAbilityType::HAND_DOOM: return spell_RF6_HAND_DOOM(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_HAND_DOOM */
120     case MonsterAbilityType::HEAL: return spell_RF6_HEAL(player_ptr, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_HEAL */
121     case MonsterAbilityType::INVULNER: return spell_RF6_INVULNER(player_ptr, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_INVULNER */
122     case MonsterAbilityType::BLINK: return spell_RF6_BLINK(player_ptr, m_idx, MONSTER_TO_PLAYER, false); /* RF6_BLINK */
123     case MonsterAbilityType::TPORT: return spell_RF6_TPORT(player_ptr, m_idx, MONSTER_TO_PLAYER); /* RF6_TPORT */
124     case MonsterAbilityType::WORLD: return spell_RF6_WORLD(player_ptr, m_idx); /* RF6_WORLD */
125     case MonsterAbilityType::SPECIAL: return spell_RF6_SPECIAL(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER);   /* RF6_SPECIAL */
126     case MonsterAbilityType::TELE_TO: return spell_RF6_TELE_TO(player_ptr, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_TELE_TO */
127     case MonsterAbilityType::TELE_AWAY: return spell_RF6_TELE_AWAY(player_ptr, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_TELE_AWAY */
128     case MonsterAbilityType::TELE_LEVEL: return spell_RF6_TELE_LEVEL(player_ptr, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_TELE_LEVEL */
129     case MonsterAbilityType::PSY_SPEAR: return spell_RF6_PSY_SPEAR(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_PSY_SPEAR */
130     case MonsterAbilityType::DARKNESS: return spell_RF6_DARKNESS(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_DARKNESS */
131     case MonsterAbilityType::TRAPS: return spell_RF6_TRAPS(player_ptr, y, x, m_idx); /* RF6_TRAPS */
132     case MonsterAbilityType::FORGET: return spell_RF6_FORGET(player_ptr, m_idx); /* RF6_FORGET */
133     case MonsterAbilityType::RAISE_DEAD: return spell_RF6_RAISE_DEAD(player_ptr, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_RAISE_DEAD */
134     case MonsterAbilityType::S_KIN: return spell_RF6_S_KIN(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_KIN */
135     case MonsterAbilityType::S_CYBER: return spell_RF6_S_CYBER(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_CYBER */
136     case MonsterAbilityType::S_MONSTER: return spell_RF6_S_MONSTER(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_MONSTER */
137     case MonsterAbilityType::S_MONSTERS: return spell_RF6_S_MONSTERS(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_MONSTER */
138     case MonsterAbilityType::S_ANT: return spell_RF6_S_ANT(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_ANT */
139     case MonsterAbilityType::S_SPIDER: return spell_RF6_S_SPIDER(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_SPIDER */
140     case MonsterAbilityType::S_HOUND: return spell_RF6_S_HOUND(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_HOUND */
141     case MonsterAbilityType::S_HYDRA: return spell_RF6_S_HYDRA(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_HYDRA */
142     case MonsterAbilityType::S_ANGEL: return spell_RF6_S_ANGEL(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_ANGEL */
143     case MonsterAbilityType::S_DEMON: return spell_RF6_S_DEMON(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_DEMON */
144     case MonsterAbilityType::S_UNDEAD: return spell_RF6_S_UNDEAD(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_UNDEAD */
145     case MonsterAbilityType::S_DRAGON: return spell_RF6_S_DRAGON(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_DRAGON */
146     case MonsterAbilityType::S_HI_UNDEAD: return spell_RF6_S_HI_UNDEAD(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_HI_UNDEAD */
147     case MonsterAbilityType::S_HI_DRAGON: return spell_RF6_S_HI_DRAGON(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_HI_DRAGON */
148     case MonsterAbilityType::S_AMBERITES: return spell_RF6_S_AMBERITES(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_AMBERITES */
149     case MonsterAbilityType::S_UNIQUE: return spell_RF6_S_UNIQUE(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_UNIQUE */
150     case MonsterAbilityType::S_DEAD_UNIQUE: return spell_RF6_S_DEAD_UNIQUE(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF6_S_DEAD_UNIQUE */
151     default: break;
152     }
153     // clang-format on
154
155     return MonsterSpellResult::make_invalid();
156 }
157
158 static MonsterSpellResult monspell_to_monster_impl(
159     PlayerType *player_ptr, MonsterAbilityType ms_type, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, bool is_special_spell)
160 {
161     // clang-format off
162     switch (ms_type) {
163     case MonsterAbilityType::SHRIEK: return spell_RF4_SHRIEK(m_idx, player_ptr, t_idx, MONSTER_TO_MONSTER); /* RF4_SHRIEK */
164     case MonsterAbilityType::XXX1: break;   /* RF4_XXX1 */
165     case MonsterAbilityType::DISPEL: return spell_RF4_DISPEL(m_idx, player_ptr, t_idx, MONSTER_TO_MONSTER); /* RF4_DISPEL */
166     case MonsterAbilityType::ROCKET: return spell_RF4_ROCKET(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_ROCKET */
167     case MonsterAbilityType::XXX2: break;   /* RF4_XXX2 */
168     case MonsterAbilityType::XXX3: break;   /* RF4_XXX3 */
169     case MonsterAbilityType::XXX4: break;   /* RF4_XXX4 */
170
171     case MonsterAbilityType::BR_ACID:
172     case MonsterAbilityType::BR_ELEC:
173     case MonsterAbilityType::BR_FIRE:
174     case MonsterAbilityType::BR_COLD:
175     case MonsterAbilityType::BR_POIS:
176     case MonsterAbilityType::BR_NETH:
177     case MonsterAbilityType::BR_LITE:
178     case MonsterAbilityType::BR_DARK:
179     case MonsterAbilityType::BR_CONF:
180     case MonsterAbilityType::BR_SOUN:
181     case MonsterAbilityType::BR_CHAO:
182     case MonsterAbilityType::BR_DISE:
183     case MonsterAbilityType::BR_NEXU:
184     case MonsterAbilityType::BR_TIME:
185     case MonsterAbilityType::BR_INER:
186     case MonsterAbilityType::BR_GRAV:
187     case MonsterAbilityType::BR_SHAR:
188     case MonsterAbilityType::BR_PLAS:
189     case MonsterAbilityType::BR_FORC:
190     case MonsterAbilityType::BR_MANA:
191     case MonsterAbilityType::BR_NUKE:
192     case MonsterAbilityType::BR_DISI:
193     case MonsterAbilityType::BR_VOID:
194     case MonsterAbilityType::BR_ABYSS:
195     return spell_RF4_BREATH(player_ptr, ms_type, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_ABYSS */
196     
197     case MonsterAbilityType::BA_ACID:
198     case MonsterAbilityType::BA_ELEC:
199     case MonsterAbilityType::BA_FIRE:
200     case MonsterAbilityType::BA_COLD:
201          {
202          auto rad = monster_is_powerful(player_ptr->current_floor_ptr, m_idx) ? 4 : 2;
203          return MSpellBall(player_ptr, m_idx, t_idx, ms_type, rad, MONSTER_TO_MONSTER).shoot(y, x);
204          }
205          
206     case MonsterAbilityType::BA_POIS:
207     case MonsterAbilityType::BA_NETH:
208     case MonsterAbilityType::BA_NUKE:
209          return MSpellBall(player_ptr, m_idx, t_idx, ms_type, 2, MONSTER_TO_MONSTER).shoot(y, x);
210
211     case MonsterAbilityType::BA_CHAO:
212     case MonsterAbilityType::BA_WATE:
213     case MonsterAbilityType::BA_MANA:
214     case MonsterAbilityType::BA_LITE:
215     case MonsterAbilityType::BA_DARK:
216     case MonsterAbilityType::BA_VOID:
217     case MonsterAbilityType::BA_ABYSS:
218          return MSpellBall(player_ptr, m_idx, t_idx, ms_type, 4, MONSTER_TO_MONSTER).shoot(y, x);
219
220     case MonsterAbilityType::DRAIN_MANA: return spell_RF5_DRAIN_MANA(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_DRAIN_MANA */
221     case MonsterAbilityType::MIND_BLAST: return spell_RF5_MIND_BLAST(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_MIND_BLAST */
222     case MonsterAbilityType::BRAIN_SMASH: return spell_RF5_BRAIN_SMASH(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BRAIN_SMASH */
223
224     case MonsterAbilityType::CAUSE_1:
225     case MonsterAbilityType::CAUSE_2:
226     case MonsterAbilityType::CAUSE_3:
227     case MonsterAbilityType::CAUSE_4:
228         return spell_RF5_CAUSE(player_ptr, ms_type, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_CAUSE_* */
229
230     case MonsterAbilityType::SHOOT:
231     case MonsterAbilityType::BO_ACID:
232     case MonsterAbilityType::BO_ELEC:
233     case MonsterAbilityType::BO_FIRE:
234     case MonsterAbilityType::BO_COLD:
235     case MonsterAbilityType::BO_NETH:
236     case MonsterAbilityType::BO_WATE:
237     case MonsterAbilityType::BO_MANA:
238     case MonsterAbilityType::BO_PLAS:
239     case MonsterAbilityType::BO_ICEE:
240     case MonsterAbilityType::BO_VOID:
241     case MonsterAbilityType::BO_ABYSS:
242     case MonsterAbilityType::MISSILE: 
243          return MSpellBolt(player_ptr, m_idx, t_idx, ms_type, MONSTER_TO_MONSTER).shoot(y, x);
244
245     case MonsterAbilityType::SCARE: return spell_RF5_SCARE(m_idx, player_ptr, t_idx, MONSTER_TO_MONSTER); /* RF5_SCARE */
246     case MonsterAbilityType::BLIND: return spell_RF5_BLIND(m_idx, player_ptr, t_idx, MONSTER_TO_MONSTER); /* RF5_BLIND */
247     case MonsterAbilityType::CONF: return spell_RF5_CONF(m_idx, player_ptr, t_idx, MONSTER_TO_MONSTER); /* RF5_CONF */
248     case MonsterAbilityType::SLOW: return spell_RF5_SLOW(m_idx, player_ptr, t_idx, MONSTER_TO_MONSTER); /* RF5_SLOW */
249     case MonsterAbilityType::HOLD: return spell_RF5_HOLD(m_idx, player_ptr, t_idx, MONSTER_TO_MONSTER); /* RF5_HOLD */
250     case MonsterAbilityType::HASTE: return spell_RF6_HASTE(player_ptr, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_HASTE */
251     case MonsterAbilityType::HAND_DOOM: return spell_RF6_HAND_DOOM(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_HAND_DOOM */
252     case MonsterAbilityType::HEAL: return spell_RF6_HEAL(player_ptr, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_HEAL */
253     case MonsterAbilityType::INVULNER: return spell_RF6_INVULNER(player_ptr, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_INVULNER */
254     case MonsterAbilityType::BLINK: return spell_RF6_BLINK(player_ptr, m_idx, MONSTER_TO_MONSTER, is_special_spell); /* RF6_BLINK */
255     case MonsterAbilityType::TPORT: return spell_RF6_TPORT(player_ptr, m_idx, MONSTER_TO_MONSTER); /* RF6_TPORT */
256     case MonsterAbilityType::WORLD: break; /* RF6_WORLD */
257     case MonsterAbilityType::SPECIAL: return spell_RF6_SPECIAL(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER);   /* RF6_SPECIAL */
258     case MonsterAbilityType::TELE_TO: return spell_RF6_TELE_TO(player_ptr, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_TELE_TO */
259     case MonsterAbilityType::TELE_AWAY: return spell_RF6_TELE_AWAY(player_ptr, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_TELE_AWAY */
260     case MonsterAbilityType::TELE_LEVEL: return spell_RF6_TELE_LEVEL(player_ptr, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_TELE_LEVEL */
261     case MonsterAbilityType::PSY_SPEAR: return spell_RF6_PSY_SPEAR(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_PSY_SPEAR */
262     case MonsterAbilityType::DARKNESS: return spell_RF6_DARKNESS(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_DARKNESS */
263     case MonsterAbilityType::TRAPS: break; /* RF6_TRAPS */
264     case MonsterAbilityType::FORGET: break; /* RF6_FORGET */
265     case MonsterAbilityType::RAISE_DEAD: return spell_RF6_RAISE_DEAD(player_ptr, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_RAISE_DEAD */
266     case MonsterAbilityType::S_KIN: return spell_RF6_S_KIN(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_KIN */
267     case MonsterAbilityType::S_CYBER: return spell_RF6_S_CYBER(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_CYBER */
268     case MonsterAbilityType::S_MONSTER: return spell_RF6_S_MONSTER(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_MONSTER */
269     case MonsterAbilityType::S_MONSTERS: return spell_RF6_S_MONSTERS(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_MONSTER */
270     case MonsterAbilityType::S_ANT: return spell_RF6_S_ANT(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_ANT */
271     case MonsterAbilityType::S_SPIDER: return spell_RF6_S_SPIDER(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_SPIDER */
272     case MonsterAbilityType::S_HOUND: return spell_RF6_S_HOUND(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_HOUND */
273     case MonsterAbilityType::S_HYDRA: return spell_RF6_S_HYDRA(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_HYDRA */
274     case MonsterAbilityType::S_ANGEL: return spell_RF6_S_ANGEL(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_ANGEL */
275     case MonsterAbilityType::S_DEMON: return spell_RF6_S_DEMON(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_DEMON */
276     case MonsterAbilityType::S_UNDEAD: return spell_RF6_S_UNDEAD(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_UNDEAD */
277     case MonsterAbilityType::S_DRAGON: return spell_RF6_S_DRAGON(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_DRAGON */
278     case MonsterAbilityType::S_HI_UNDEAD: return spell_RF6_S_HI_UNDEAD(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_HI_UNDEAD */
279     case MonsterAbilityType::S_HI_DRAGON: return spell_RF6_S_HI_DRAGON(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_HI_DRAGON */
280     case MonsterAbilityType::S_AMBERITES: return spell_RF6_S_AMBERITES(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_AMBERITES */
281     case MonsterAbilityType::S_UNIQUE: return spell_RF6_S_UNIQUE(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_UNIQUE */
282     case MonsterAbilityType::S_DEAD_UNIQUE: return spell_RF6_S_DEAD_UNIQUE(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF6_S_DEAD_UNIQUE */
283     default: break;
284     }
285     // clang-format on
286
287     return MonsterSpellResult::make_invalid();
288 }
289
290 /*!
291  * @brief モンスターからプレイヤーへの魔法使用。ラーニング処理も行う。
292  * @param ms_type モンスター魔法ID (monster_spell_typeのenum値とは異なる)
293  * @param y 対象の地点のy座標
294  * @param x 対象の地点のx座標
295  * @param m_idx 呪文を唱えるモンスターID
296  */
297 MonsterSpellResult monspell_to_player(PlayerType *player_ptr, MonsterAbilityType ms_type, POSITION y, POSITION x, MONSTER_IDX m_idx)
298 {
299     // 特技使用前の時点でプレイヤーがモンスターを視認できているかチェック(ラーニングの必要条件)。
300     const bool player_could_see_monster = spell_learnable(player_ptr, m_idx);
301
302     auto res = monspell_to_player_impl(player_ptr, ms_type, y, x, m_idx);
303     if (!player_could_see_monster) {
304         res.learnable = false;
305     }
306
307     // 条件を満たしていればラーニングを試みる。
308     if (res.valid && res.learnable) {
309         learn_spell(player_ptr, ms_type);
310     }
311
312     return res;
313 }
314
315 /*!
316  * @brief モンスターからモンスターへの魔法使用。ラーニング処理も行う。
317  * @param player_ptr プレイヤーへの参照ポインタ (monster_spell_typeのenum値とは異なる)
318  * @param ms_type モンスター魔法ID
319  * @param y 対象の地点のy座標
320  * @param x 対象の地点のx座標
321  * @param m_idx 呪文を唱えるモンスターID
322  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
323  * @param is_special_spell 特殊な行動である時TRUE
324  * @todo モンスターからモンスターへの呪文なのにPlayerTypeが引数になり得るのは間違っている……
325  */
326 MonsterSpellResult monspell_to_monster(
327     PlayerType *player_ptr, MonsterAbilityType ms_type, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, bool is_special_spell)
328 {
329     // 特技使用前の時点でプレイヤーがモンスターを視認できているかチェック(ラーニングの必要条件)。
330     const bool player_could_see_monster = spell_learnable(player_ptr, m_idx);
331
332     auto res = monspell_to_monster_impl(player_ptr, ms_type, y, x, m_idx, t_idx, is_special_spell);
333     if (!player_could_see_monster) {
334         res.learnable = false;
335     }
336
337     // 条件を満たしていればラーニングを試みる。
338     if (res.valid && res.learnable) {
339         learn_spell(player_ptr, ms_type);
340     }
341
342     return res;
343 }