OSDN Git Service

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