OSDN Git Service

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