OSDN Git Service

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