OSDN Git Service

Merge branch 'Release-3.0.0Alpha' into release/3.0.0Alpha
[hengband/hengband.git] / src / mspell / mspell-summon.c
1 #include "mspell/mspell-summon.h"
2 #include "core/disturbance.h"
3 #include "effect/effect-characteristics.h"
4 #include "effect/effect-processor.h"
5 #include "floor/cave.h"
6 #include "game-option/birth-options.h"
7 #include "monster-floor/monster-summon.h"
8 #include "monster-floor/place-monster-types.h"
9 #include "monster-race/monster-race.h"
10 #include "monster-race/race-flags1.h"
11 #include "monster-race/race-indice-types.h"
12 #include "monster/monster-describer.h"
13 #include "monster/monster-description-types.h"
14 #include "monster/monster-info.h"
15 #include "monster/monster-status.h"
16 #include "mspell/mspell-util.h"
17 #include "mspell/specified-summon.h"
18 #include "spell-kind/spells-launcher.h"
19 #include "spell/spell-types.h"
20 #include "spell/spells-summon.h"
21 #include "spell/summon-types.h"
22 #include "system/floor-type-definition.h"
23 #include "view/display-messages.h"
24
25 /* summoning number */
26 #define S_NUM_6 (easy_band ? 2 : 6)
27 #define S_NUM_4 (easy_band ? 1 : 4)
28
29 /*!
30  * @brief 特定条件のモンスター召喚のみPM_ALLOW_UNIQUEを許可する /
31  * @param floor_ptr 現在フロアへの参照ポインタ
32  * @param m_idx モンスターID
33  * @return 召喚可能であればPM_ALLOW_UNIQUEを返す。
34  */
35 static BIT_FLAGS monster_u_mode(floor_type *floor_ptr, MONSTER_IDX m_idx)
36 {
37     BIT_FLAGS u_mode = 0L;
38     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
39     bool pet = is_pet(m_ptr);
40     if (!pet)
41         u_mode |= PM_ALLOW_UNIQUE;
42     return u_mode;
43 }
44
45 /*!
46  * @brief 救援召喚の通常処理。同シンボルのモンスターを召喚する。 /
47  * @param target_ptr プレーヤーへの参照ポインタ
48  * @param y 対象の地点のy座標
49  * @param x 対象の地点のx座標
50  * @param rlev 呪文を唱えるモンスターのレベル
51  * @param m_idx 呪文を唱えるモンスターID
52  * @return 召喚したモンスターの数を返す。
53  */
54 MONSTER_NUMBER summon_Kin(player_type *target_ptr, POSITION y, POSITION x, int rlev, MONSTER_IDX m_idx)
55 {
56     int count = 0;
57     for (int k = 0; k < 4; k++) {
58         count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_KIN, PM_ALLOW_GROUP);
59     }
60
61     return count;
62 }
63
64 static void decide_summon_kin_caster(
65     player_type *target_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type, concptr m_name, concptr m_poss, const bool known)
66 {
67     floor_type *floor_ptr = target_ptr->current_floor_ptr;
68     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
69     bool see_either = see_monster(target_ptr, m_idx) || see_monster(target_ptr, t_idx);
70     bool mon_to_mon = target_type == MONSTER_TO_MONSTER;
71     bool mon_to_player = target_type == MONSTER_TO_PLAYER;
72     if (m_ptr->r_idx == MON_SERPENT || m_ptr->r_idx == MON_ZOMBI_SERPENT) {
73         monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
74             _("%^sがダンジョンの主を召喚した。", "%^s magically summons guardians of dungeons."),
75             _("%^sがダンジョンの主を召喚した。", "%^s magically summons guardians of dungeons."), target_type);
76         return;
77     }
78
79     if (mon_to_player || (mon_to_mon && known && see_either))
80         disturb(target_ptr, TRUE, TRUE);
81
82     if (target_ptr->blind) {
83         if (mon_to_player)
84             msg_format(_("%^sが何かをつぶやいた。", "%^s mumbles."), m_name);
85     } else if (mon_to_player || (mon_to_mon && known && see_either)) {
86         monster_race *r_ptr = &r_info[m_ptr->r_idx];
87 #ifdef JP
88         (void)m_poss;
89 #endif
90         _(msg_format("%sが魔法で%sを召喚した。", m_name, ((r_ptr->flags1 & RF1_UNIQUE) ? "手下" : "仲間")),
91             msg_format("%^s magically summons %s %s.", m_name, m_poss, ((r_ptr->flags1 & RF1_UNIQUE) ? "minions" : "kin")));
92     }
93
94     if (mon_to_mon && known && !see_either)
95         floor_ptr->monster_noise = TRUE;
96 }
97
98 /*!
99  * @brief RF6_S_KINの処理。救援召喚。使用するモンスターの種類により、実処理に分岐させる。 /
100  * @param target_ptr プレーヤーへの参照ポインタ
101  * @param y 対象の地点のy座標
102  * @param x 対象の地点のx座標
103  * @param m_idx 呪文を唱えるモンスターID
104  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
105  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
106  * @return 召喚したモンスターの数を返す。
107  */
108 void spell_RF6_S_KIN(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
109 {
110     floor_type *floor_ptr = target_ptr->current_floor_ptr;
111     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
112     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
113     GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN], m_poss[80];
114     monster_name(target_ptr, m_idx, m_name);
115     monster_name(target_ptr, t_idx, t_name);
116     monster_desc(target_ptr, m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
117
118     disturb(target_ptr, TRUE, TRUE);
119     bool known = monster_near_player(floor_ptr, m_idx, t_idx);
120     decide_summon_kin_caster(target_ptr, m_idx, t_idx, target_type, m_name, m_poss, known);
121     int count = 0;
122     switch (m_ptr->r_idx) {
123     case MON_MENELDOR:
124     case MON_GWAIHIR:
125     case MON_THORONDOR:
126         count += summon_EAGLE(target_ptr, y, x, rlev, m_idx);
127         break;
128     case MON_BULLGATES:
129         count += summon_IE(target_ptr, y, x, rlev, m_idx);
130         break;
131     case MON_SERPENT:
132     case MON_ZOMBI_SERPENT:
133         count += summon_guardian(target_ptr, y, x, rlev, m_idx, t_idx, target_type);
134         break;
135     case MON_CALDARM:
136         count += summon_LOCKE_CLONE(target_ptr, y, x, m_idx);
137         break;
138     case MON_LOUSY:
139         count += summon_LOUSE(target_ptr, y, x, rlev, m_idx);
140         break;
141     case MON_VAIF:
142         count += summon_MOAI(target_ptr, y, x, rlev, m_idx);
143         break;
144     case MON_DEMON_SLAYER_SENIOR:
145         count += summon_DEMON_SLAYER(target_ptr, y, x, m_idx);
146         break;
147     default:
148         count += summon_Kin(target_ptr, y, x, rlev, m_idx);
149         break;
150     }
151
152     if (target_ptr->blind && count && (target_type == MONSTER_TO_PLAYER))
153         msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
154
155     if (known && !see_monster(target_ptr, t_idx) && count && (target_type == MONSTER_TO_MONSTER))
156         floor_ptr->monster_noise = TRUE;
157 }
158
159 /*!
160  * @brief RF6_S_CYBERの処理。サイバー・デーモン召喚。 /
161  * @param target_ptr プレーヤーへの参照ポインタ
162  * @param y 対象の地点のy座標
163  * @param x 対象の地点のx座標
164  * @param m_idx 呪文を唱えるモンスターID
165  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
166  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
167  * @return 召喚したモンスターの数を返す。
168  */
169 void spell_RF6_S_CYBER(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
170 {
171     int count = 0;
172     floor_type *floor_ptr = target_ptr->current_floor_ptr;
173     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
174     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
175     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
176     bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
177
178     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
179         _("%^sがサイバーデーモンを召喚した!", "%^s magically summons Cyberdemons!"),
180         _("%^sがサイバーデーモンを召喚した!", "%^s magically summons Cyberdemons!"), TARGET_TYPE);
181
182     if (is_friendly(m_ptr) && mon_to_mon) {
183         count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_CYBER, (PM_ALLOW_GROUP));
184     } else {
185         count += summon_cyber(target_ptr, m_idx, y, x);
186     }
187
188     if (target_ptr->blind && count && mon_to_player)
189         msg_print(_("重厚な足音が近くで聞こえる。", "You hear heavy steps nearby."));
190
191     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
192         floor_ptr->monster_noise = TRUE;
193 }
194
195 /*!
196  * @brief RF6_S_MONSTERの処理。モンスター一体召喚。 /
197  * @param target_ptr プレーヤーへの参照ポインタ
198  * @param y 対象の地点のy座標
199  * @param x 対象の地点のx座標
200  * @param m_idx 呪文を唱えるモンスターID
201  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
202  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
203  * @return 召喚したモンスターの数を返す。
204  */
205 void spell_RF6_S_MONSTER(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
206 {
207     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."), _("%^sが魔法で仲間を召喚した!", "%^s magically summons help!"),
208         _("%^sが魔法で仲間を召喚した!", "%^s magically summons help!"), TARGET_TYPE);
209
210     floor_type *floor_ptr = target_ptr->current_floor_ptr;
211     int count = 0;
212     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
213     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
214     bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
215     for (int k = 0; k < 1; k++) {
216         if (mon_to_player)
217             count += summon_specific(target_ptr, m_idx, y, x, rlev, 0, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
218
219         if (mon_to_mon)
220             count += summon_specific(target_ptr, m_idx, y, x, rlev, 0, (monster_u_mode(floor_ptr, m_idx)));
221     }
222
223     if (target_ptr->blind && count && mon_to_player)
224         msg_print(_("何かが間近に現れた音がする。", "You hear something appear nearby."));
225
226     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
227         floor_ptr->monster_noise = TRUE;
228 }
229
230 /*!
231  * @brief RF6_S_MONSTERSの処理。モンスター複数召喚。 /
232  * @param target_ptr プレーヤーへの参照ポインタ
233  * @param y 対象の地点のy座標
234  * @param x 対象の地点のx座標
235  * @param m_idx 呪文を唱えるモンスターID
236  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
237  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
238  * @return 召喚したモンスターの数を返す。
239  */
240 void spell_RF6_S_MONSTERS(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
241 {
242     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
243         _("%^sが魔法でモンスターを召喚した!", "%^s magically summons monsters!"), _("%^sが魔法でモンスターを召喚した!", "%^s magically summons monsters!"),
244         TARGET_TYPE);
245
246     floor_type *floor_ptr = target_ptr->current_floor_ptr;
247     int count = 0;
248     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
249     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
250     bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
251     for (int k = 0; k < S_NUM_6; k++) {
252         if (mon_to_player)
253             count += summon_specific(target_ptr, m_idx, y, x, rlev, 0, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
254
255         if (mon_to_mon)
256             count += summon_specific(target_ptr, m_idx, y, x, rlev, 0, (PM_ALLOW_GROUP | monster_u_mode(floor_ptr, m_idx)));
257     }
258
259     if (target_ptr->blind && count && mon_to_player)
260         msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
261
262     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
263         floor_ptr->monster_noise = TRUE;
264 }
265
266 /*!
267  * @brief RF6_S_ANTの処理。アリ召喚。 /
268  * @param target_ptr プレーヤーへの参照ポインタ
269  * @param y 対象の地点のy座標
270  * @param x 対象の地点のx座標
271  * @param m_idx 呪文を唱えるモンスターID
272  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
273  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
274  * @return 召喚したモンスターの数を返す。
275  */
276 void spell_RF6_S_ANT(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
277 {
278     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."), _("%^sが魔法でアリを召喚した。", "%^s magically summons ants."),
279         _("%^sが魔法でアリを召喚した。", "%^s magically summons ants."), TARGET_TYPE);
280
281     int count = 0;
282     floor_type *floor_ptr = target_ptr->current_floor_ptr;
283     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
284     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
285     bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
286     for (int k = 0; k < S_NUM_6; k++) {
287         count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_ANT, PM_ALLOW_GROUP);
288     }
289
290     if (target_ptr->blind && count && mon_to_player)
291         msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
292
293     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
294         floor_ptr->monster_noise = TRUE;
295 }
296
297 /*!
298  * @brief RF6_S_SPIDERの処理。クモ召喚。 /
299  * @param target_ptr プレーヤーへの参照ポインタ
300  * @param y 対象の地点のy座標
301  * @param x 対象の地点のx座標
302  * @param m_idx 呪文を唱えるモンスターID
303  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
304  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
305  * @return 召喚したモンスターの数を返す。
306  */
307 void spell_RF6_S_SPIDER(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
308 {
309     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."), _("%^sが魔法でクモを召喚した。", "%^s magically summons spiders."),
310         _("%^sが魔法でクモを召喚した。", "%^s magically summons spiders."), TARGET_TYPE);
311
312     int count = 0;
313     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
314     bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
315     floor_type *floor_ptr = target_ptr->current_floor_ptr;
316     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
317     for (int k = 0; k < S_NUM_6; k++) {
318         count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_SPIDER, PM_ALLOW_GROUP);
319     }
320
321     if (target_ptr->blind && count && mon_to_player)
322         msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
323
324     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
325         floor_ptr->monster_noise = TRUE;
326 }
327
328 /*!
329  * @brief RF6_S_HOUNDの処理。ハウンド召喚。 /
330  * @param target_ptr プレーヤーへの参照ポインタ
331  * @param y 対象の地点のy座標
332  * @param x 対象の地点のx座標
333  * @param m_idx 呪文を唱えるモンスターID
334  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
335  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
336  * @return 召喚したモンスターの数を返す。
337  */
338 void spell_RF6_S_HOUND(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
339 {
340     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
341         _("%^sが魔法でハウンドを召喚した。", "%^s magically summons hounds."), _("%^sが魔法でハウンドを召喚した。", "%^s magically summons hounds."),
342         TARGET_TYPE);
343
344     int count = 0;
345     floor_type *floor_ptr = target_ptr->current_floor_ptr;
346     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
347     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
348     bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
349     for (int k = 0; k < S_NUM_4; k++) {
350         count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_HOUND, PM_ALLOW_GROUP);
351     }
352
353     if (target_ptr->blind && count && mon_to_player)
354         msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
355
356     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
357         floor_ptr->monster_noise = TRUE;
358 }
359
360 /*!
361  * @brief RF6_S_HYDRAの処理。ヒドラ召喚。 /
362  * @param target_ptr プレーヤーへの参照ポインタ
363  * @param y 対象の地点のy座標
364  * @param x 対象の地点のx座標
365  * @param m_idx 呪文を唱えるモンスターID
366  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
367  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
368  * @return 召喚したモンスターの数を返す。
369  */
370 void spell_RF6_S_HYDRA(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
371 {
372     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
373         _("%^sが魔法でヒドラを召喚した。", "%^s magically summons hydras."), _("%^sが魔法でヒドラを召喚した。", "%^s magically summons hydras."), TARGET_TYPE);
374
375     int count = 0;
376     floor_type *floor_ptr = target_ptr->current_floor_ptr;
377     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
378     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
379     bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
380     for (int k = 0; k < S_NUM_4; k++) {
381         count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_HYDRA, PM_ALLOW_GROUP);
382     }
383
384     if (target_ptr->blind && count && mon_to_player)
385         msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
386
387     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
388         floor_ptr->monster_noise = TRUE;
389 }
390
391 /*!
392  * @brief RF6_S_ANGELの処理。天使一体召喚。 /
393  * @param target_ptr プレーヤーへの参照ポインタ
394  * @param y 対象の地点のy座標
395  * @param x 対象の地点のx座標
396  * @param m_idx 呪文を唱えるモンスターID
397  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
398  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
399  * @return 召喚したモンスターの数を返す。
400  */
401 void spell_RF6_S_ANGEL(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
402 {
403     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
404         _("%^sが魔法で天使を召喚した!", "%^s magically summons an angel!"), _("%^sが魔法で天使を召喚した!", "%^s magically summons an angel!"), TARGET_TYPE);
405
406     floor_type *floor_ptr = target_ptr->current_floor_ptr;
407     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
408     monster_race *r_ptr = &r_info[m_ptr->r_idx];
409     int num = 1;
410     if ((r_ptr->flags1 & RF1_UNIQUE) && !easy_band) {
411         num += r_ptr->level / 40;
412     }
413
414     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
415     int count = 0;
416     for (int k = 0; k < num; k++) {
417         count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_ANGEL, PM_ALLOW_GROUP);
418     }
419
420     if (count < 2) {
421         if (target_ptr->blind && count)
422             msg_print(_("何かが間近に現れた音がする。", "You hear something appear nearby."));
423     } else {
424         if (target_ptr->blind)
425             msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
426     }
427
428     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
429     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
430         floor_ptr->monster_noise = TRUE;
431 }
432
433 /*!
434  * @brief RF6_S_DEMONの処理。デーモン一体召喚。 /
435  * @param target_ptr プレーヤーへの参照ポインタ
436  * @param y 対象の地点のy座標
437  * @param x 対象の地点のx座標
438  * @param m_idx 呪文を唱えるモンスターID
439  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
440  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
441  * @return 召喚したモンスターの数を返す。
442  */
443 void spell_RF6_S_DEMON(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
444 {
445     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
446         _("%^sは魔法で混沌の宮廷から悪魔を召喚した!", "%^s magically summons a demon from the Courts of Chaos!"),
447         _("%^sは魔法で混沌の宮廷から悪魔を召喚した!", "%^s magically summons a demon from the Courts of Chaos!"), TARGET_TYPE);
448
449     floor_type *floor_ptr = target_ptr->current_floor_ptr;
450     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
451     int count = 0;
452     for (int k = 0; k < 1; k++) {
453         count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_DEMON, PM_ALLOW_GROUP);
454     }
455
456     if (target_ptr->blind && count)
457         msg_print(_("何かが間近に現れた音がする。", "You hear something appear nearby."));
458
459     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
460     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
461         floor_ptr->monster_noise = TRUE;
462 }
463
464 /*!
465  * @brief RF6_S_UNDEADの処理。アンデッド一体召喚。 /
466  * @param target_ptr プレーヤーへの参照ポインタ
467  * @param y 対象の地点のy座標
468  * @param x 対象の地点のx座標
469  * @param m_idx 呪文を唱えるモンスターID
470  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
471  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
472  * @return 召喚したモンスターの数を返す。
473  */
474 void spell_RF6_S_UNDEAD(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
475 {
476     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
477         _("%^sが魔法でアンデッドの強敵を召喚した!", "%^s magically summons an undead adversary!"),
478         _("%sが魔法でアンデッドを召喚した。", "%^s magically summons undead."), TARGET_TYPE);
479
480     floor_type *floor_ptr = target_ptr->current_floor_ptr;
481     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
482     int count = 0;
483     for (int k = 0; k < 1; k++) {
484         count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_UNDEAD, PM_ALLOW_GROUP);
485     }
486
487     if (target_ptr->blind && count)
488         msg_print(_("何かが間近に現れた音がする。", "You hear something appear nearby."));
489
490     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
491     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
492         floor_ptr->monster_noise = TRUE;
493 }
494
495 /*!
496  * @brief RF6_S_DRAGONの処理。ドラゴン一体召喚。 /
497  * @param target_ptr プレーヤーへの参照ポインタ
498  * @param y 対象の地点のy座標
499  * @param x 対象の地点のx座標
500  * @param m_idx 呪文を唱えるモンスターID
501  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
502  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
503  * @return 召喚したモンスターの数を返す。
504  */
505 void spell_RF6_S_DRAGON(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
506 {
507     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
508         _("%^sが魔法でドラゴンを召喚した!", "%^s magically summons a dragon!"), _("%^sが魔法でドラゴンを召喚した!", "%^s magically summons a dragon!"),
509         TARGET_TYPE);
510
511     floor_type *floor_ptr = target_ptr->current_floor_ptr;
512     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
513     int count = 0;
514     for (int k = 0; k < 1; k++) {
515         count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_DRAGON, PM_ALLOW_GROUP);
516     }
517
518     if (target_ptr->blind && count)
519         msg_print(_("何かが間近に現れた音がする。", "You hear something appear nearby."));
520
521     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
522     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
523         floor_ptr->monster_noise = TRUE;
524 }
525
526 /*!
527  * @brief RF6_S_HI_UNDEADの処理。強力なアンデッド召喚。 /
528  * @param target_ptr プレーヤーへの参照ポインタ
529  * @param y 対象の地点のy座標
530  * @param x 対象の地点のx座標
531  * @param m_idx 呪文を唱えるモンスターID
532  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
533  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
534  * @return 召喚したモンスターの数を返す。
535  */
536 void spell_RF6_S_HI_UNDEAD(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
537 {
538     GAME_TEXT m_name[MAX_NLEN];
539     monster_name(target_ptr, m_idx, m_name);
540
541     disturb(target_ptr, TRUE, TRUE);
542
543     floor_type *floor_ptr = target_ptr->current_floor_ptr;
544     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
545     bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
546     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
547     int count = 0;
548     if (((m_ptr->r_idx == MON_MORGOTH) || (m_ptr->r_idx == MON_SAURON) || (m_ptr->r_idx == MON_ANGMAR))
549         && ((r_info[MON_NAZGUL].cur_num + 2) < r_info[MON_NAZGUL].max_num) && mon_to_player) {
550         count += summon_NAZGUL(target_ptr, y, x, m_idx);
551     } else {
552         monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
553             _("%^sが魔法で強力なアンデッドを召喚した!", "%^s magically summons greater undead!"),
554             _("%sが魔法でアンデッドを召喚した。", "%^s magically summons undead."), TARGET_TYPE);
555
556         DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
557         for (int k = 0; k < S_NUM_6; k++) {
558             if (mon_to_player)
559                 count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_HI_UNDEAD, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
560
561             if (mon_to_mon)
562                 count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_HI_UNDEAD, (PM_ALLOW_GROUP | monster_u_mode(floor_ptr, m_idx)));
563         }
564     }
565
566     if (target_ptr->blind && count && mon_to_player) {
567         msg_print(_("間近で何か多くのものが這い回る音が聞こえる。", "You hear many creepy things appear nearby."));
568     }
569
570     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
571         floor_ptr->monster_noise = TRUE;
572 }
573
574 /*!
575  * @brief RF6_S_HI_DRAGONの処理。古代ドラゴン召喚。 /
576  * @param target_ptr プレーヤーへの参照ポインタ
577  * @param y 対象の地点のy座標
578  * @param x 対象の地点のx座標
579  * @param m_idx 呪文を唱えるモンスターID
580  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
581  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
582  * @return 召喚したモンスターの数を返す。
583  */
584 void spell_RF6_S_HI_DRAGON(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
585 {
586     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
587         _("%^sが魔法で古代ドラゴンを召喚した!", "%^s magically summons ancient dragons!"),
588         _("%^sが魔法で古代ドラゴンを召喚した!", "%^s magically summons ancient dragons!"), TARGET_TYPE);
589
590     floor_type *floor_ptr = target_ptr->current_floor_ptr;
591     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
592     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
593     bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
594     int count = 0;
595     for (int k = 0; k < S_NUM_4; k++) {
596         if (mon_to_player)
597             count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_HI_DRAGON, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
598
599         if (mon_to_mon)
600             count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_HI_DRAGON, (PM_ALLOW_GROUP | monster_u_mode(floor_ptr, m_idx)));
601     }
602
603     if (target_ptr->blind && count && mon_to_player) {
604         msg_print(_("多くの力強いものが間近に現れた音が聞こえる。", "You hear many powerful things appear nearby."));
605     }
606
607     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
608         floor_ptr->monster_noise = TRUE;
609 }
610
611 /*!
612  * @brief RF6_S_AMBERITESの処理。アンバーの王族召喚。 /
613  * @param target_ptr プレーヤーへの参照ポインタ
614  * @param y 対象の地点のy座標
615  * @param x 対象の地点のx座標
616  * @param m_idx 呪文を唱えるモンスターID
617  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
618  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
619  * @return 召喚したモンスターの数を返す。
620  */
621 void spell_RF6_S_AMBERITES(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
622 {
623     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
624         _("%^sがアンバーの王族を召喚した!", "%^s magically summons Lords of Amber!"),
625         _("%^sがアンバーの王族を召喚した!", "%^s magically summons Lords of Amber!"), TARGET_TYPE);
626
627     int count = 0;
628     floor_type *floor_ptr = target_ptr->current_floor_ptr;
629     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
630     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
631     bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
632     for (int k = 0; k < S_NUM_4; k++) {
633         count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_AMBERITES, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
634     }
635
636     if (target_ptr->blind && count && mon_to_player) {
637         msg_print(_("不死の者が近くに現れるのが聞こえた。", "You hear immortal beings appear nearby."));
638     }
639
640     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
641         floor_ptr->monster_noise = TRUE;
642 }
643
644 /*!
645  * @brief RF6_S_UNIQUEの処理。ユニーク・モンスター召喚。 /
646  * @param target_ptr プレーヤーへの参照ポインタ
647  * @param y 対象の地点のy座標
648  * @param x 対象の地点のx座標
649  * @param m_idx 呪文を唱えるモンスターID
650  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
651  * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
652  * @return 召喚したモンスターの数を返す。
653  */
654 void spell_RF6_S_UNIQUE(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
655 {
656     monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
657         _("%^sが魔法で特別な強敵を召喚した!", "%^s magically summons special opponents!"),
658         _("%^sが魔法で特別な強敵を召喚した!", "%^s magically summons special opponents!"), TARGET_TYPE);
659
660     floor_type *floor_ptr = target_ptr->current_floor_ptr;
661     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
662     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
663     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
664     bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
665     bool uniques_are_summoned = FALSE;
666     int count = 0;
667     for (int k = 0; k < S_NUM_4; k++) {
668         count += summon_specific(target_ptr, m_idx, y, x, rlev, SUMMON_UNIQUE, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
669     }
670
671     if (count)
672         uniques_are_summoned = TRUE;
673
674     int non_unique_type = SUMMON_HI_UNDEAD;
675     if ((m_ptr->sub_align & (SUB_ALIGN_GOOD | SUB_ALIGN_EVIL)) == (SUB_ALIGN_GOOD | SUB_ALIGN_EVIL))
676         non_unique_type = 0;
677     else if (m_ptr->sub_align & SUB_ALIGN_GOOD)
678         non_unique_type = SUMMON_ANGEL;
679
680     for (int k = count; k < S_NUM_4; k++) {
681         count += summon_specific(target_ptr, m_idx, y, x, rlev, non_unique_type, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
682     }
683
684     if (target_ptr->blind && count && mon_to_player) {
685         msg_format(_("多くの%sが間近に現れた音が聞こえる。", "You hear many %s appear nearby."),
686             uniques_are_summoned ? _("力強いもの", "powerful things") : _("もの", "things"));
687     }
688
689     if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(target_ptr, t_idx) && count && mon_to_mon)
690         floor_ptr->monster_noise = TRUE;
691 }