OSDN Git Service

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