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-result.h"
17 #include "mspell/mspell-util.h"
18 #include "mspell/specified-summon.h"
19 #include "spell-kind/spells-launcher.h"
20 #include "effect/attribute-types.h"
21 #include "spell/spells-summon.h"
22 #include "spell/summon-types.h"
23 #include "system/floor-type-definition.h"
24 #include "system/monster-race-definition.h"
25 #include "system/monster-type-definition.h"
26 #include "system/player-type-definition.h"
27 #include "util/bit-flags-calculator.h"
28 #include "view/display-messages.h"
30 /* summoning number */
31 constexpr int S_NUM_6 = 6;
32 constexpr int S_NUM_4 = 4;
35 * @brief モンスターが召喚呪文を使った際にプレイヤーの連続行動を止める処理 /
36 * @param player_ptr プレイヤーへの参照ポインタ
37 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
38 * @param known モンスターが近くにいる場合TRUE
39 * @param see_either モンスターを視認可能な場合TRUE
41 static void summon_disturb(PlayerType *player_ptr, int target_type, bool known, bool see_either)
43 bool mon_to_mon = target_type == MONSTER_TO_MONSTER;
44 bool mon_to_player = target_type == MONSTER_TO_PLAYER;
45 if (mon_to_player || (mon_to_mon && known && see_either)) {
46 disturb(player_ptr, true, true);
52 * @brief 特定条件のモンスター召喚のみPM_ALLOW_UNIQUEを許可する /
53 * @param floor_ptr 現在フロアへの参照ポインタ
54 * @param m_idx モンスターID
55 * @return 召喚可能であればPM_ALLOW_UNIQUEを返す。
57 static BIT_FLAGS monster_u_mode(floor_type *floor_ptr, MONSTER_IDX m_idx)
59 BIT_FLAGS u_mode = 0L;
60 monster_type *m_ptr = &floor_ptr->m_list[m_idx];
61 bool pet = is_pet(m_ptr);
63 u_mode |= PM_ALLOW_UNIQUE;
68 * @brief 救援召喚の通常処理。同シンボルのモンスターを召喚する。 /
69 * @param player_ptr プレイヤーへの参照ポインタ
72 * @param rlev 呪文を唱えるモンスターのレベル
73 * @param m_idx 呪文を唱えるモンスターID
74 * @return 召喚したモンスターの数を返す。
76 static MONSTER_NUMBER summon_Kin(PlayerType *player_ptr, POSITION y, POSITION x, int rlev, MONSTER_IDX m_idx)
79 for (int k = 0; k < 4; k++) {
80 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_KIN, PM_ALLOW_GROUP);
86 static void decide_summon_kin_caster(
87 PlayerType *player_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type, concptr m_name, concptr m_poss, const bool known)
89 floor_type *floor_ptr = player_ptr->current_floor_ptr;
90 monster_type *m_ptr = &floor_ptr->m_list[m_idx];
91 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
92 bool mon_to_mon = target_type == MONSTER_TO_MONSTER;
93 bool mon_to_player = target_type == MONSTER_TO_PLAYER;
95 if (m_ptr->r_idx == MON_SERPENT || m_ptr->r_idx == MON_ZOMBI_SERPENT) {
96 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
97 _("%^sがダンジョンの主を召喚した。", "%^s magically summons guardians of dungeons."),
98 _("%^sがダンジョンの主を召喚した。", "%^s magically summons guardians of dungeons."));
100 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
104 summon_disturb(player_ptr, target_type, known, see_either);
106 if (player_ptr->blind) {
108 msg_format(_("%^sが何かをつぶやいた。", "%^s mumbles."), m_name);
109 } else if (mon_to_player || (mon_to_mon && known && see_either)) {
110 monster_race *r_ptr = &r_info[m_ptr->r_idx];
114 _(msg_format("%sが魔法で%sを召喚した。", m_name, ((r_ptr->flags1 & RF1_UNIQUE) ? "手下" : "仲間")),
115 msg_format("%^s magically summons %s %s.", m_name, m_poss, ((r_ptr->flags1 & RF1_UNIQUE) ? "minions" : "kin")));
118 if (mon_to_mon && known && !see_either)
119 floor_ptr->monster_noise = true;
123 * @brief RF6_S_KINの処理。救援召喚。使用するモンスターの種類により、実処理に分岐させる。 /
124 * @param player_ptr プレイヤーへの参照ポインタ
127 * @param m_idx 呪文を唱えるモンスターID
128 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
129 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
133 MonsterSpellResult spell_RF6_S_KIN(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
135 floor_type *floor_ptr = player_ptr->current_floor_ptr;
136 monster_type *m_ptr = &floor_ptr->m_list[m_idx];
137 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
138 GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN], m_poss[80];
139 monster_name(player_ptr, m_idx, m_name);
140 monster_name(player_ptr, t_idx, t_name);
141 monster_desc(player_ptr, m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
143 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
144 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
146 summon_disturb(player_ptr, target_type, known, see_either);
148 decide_summon_kin_caster(player_ptr, m_idx, t_idx, target_type, m_name, m_poss, known);
150 switch (m_ptr->r_idx) {
154 count += summon_EAGLE(player_ptr, y, x, rlev, m_idx);
157 count += summon_EDGE(player_ptr, y, x, rlev, m_idx);
160 case MON_ZOMBI_SERPENT:
161 count += summon_guardian(player_ptr, y, x, rlev, m_idx, t_idx, target_type);
164 count += summon_HIGHEST_DRAGON(player_ptr, y, x, m_idx);
167 count += summon_LOCKE_CLONE(player_ptr, y, x, m_idx);
170 count += summon_LOUSE(player_ptr, y, x, rlev, m_idx);
173 count += summon_MOAI(player_ptr, y, x, rlev, m_idx);
175 case MON_DEMON_SLAYER_SENIOR:
176 count += summon_DEMON_SLAYER(player_ptr, y, x, m_idx);
179 count += summon_HIGHEST_DRAGON(player_ptr, y, x, m_idx);
182 count += summon_APOCRYPHA(player_ptr, y, x, m_idx);
185 count += summon_PYRAMID(player_ptr, y, x, rlev, m_idx);
188 count += summon_EYE_PHORN(player_ptr, y, x, rlev, m_idx);
190 case MON_QUEEN_VESPOID:
191 count += summon_VESPOID(player_ptr, y, x, rlev, m_idx);
193 case MON_YENDOR_WIZARD_1:
194 count += summon_YENDER_WIZARD(player_ptr, y, x, m_idx);
197 msg_print(_("しかし、誰も来てくれなかった…。", "However, no one answered the call..."));
200 count += summon_THUNDERS(player_ptr, y, x, rlev, m_idx);
203 count += summon_PLASMA(player_ptr, y, x, rlev, m_idx);
206 count += summon_Kin(player_ptr, y, x, rlev, m_idx);
210 if (player_ptr->blind && count && (target_type == MONSTER_TO_PLAYER))
211 msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
213 if (known && !see_monster(player_ptr, t_idx) && count && (target_type == MONSTER_TO_MONSTER))
214 floor_ptr->monster_noise = true;
216 auto res = MonsterSpellResult::make_valid();
217 res.learnable = target_type == MONSTER_TO_PLAYER;
223 * @brief RF6_S_CYBERの処理。サイバー・デーモン召喚。 /
224 * @param player_ptr プレイヤーへの参照ポインタ
227 * @param m_idx 呪文を唱えるモンスターID
228 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
229 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
233 MonsterSpellResult spell_RF6_S_CYBER(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
235 floor_type *floor_ptr = player_ptr->current_floor_ptr;
236 monster_type *m_ptr = &floor_ptr->m_list[m_idx];
237 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
238 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
239 bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
240 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
241 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
242 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
243 _("%^sがサイバーデーモンを召喚した!", "%^s magically summons Cyberdemons!"),
244 _("%^sがサイバーデーモンを召喚した!", "%^s magically summons Cyberdemons!"));
246 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
247 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
250 if (is_friendly(m_ptr) && mon_to_mon) {
251 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_CYBER, (PM_ALLOW_GROUP));
253 count += summon_cyber(player_ptr, m_idx, y, x);
256 if (player_ptr->blind && count && mon_to_player)
257 msg_print(_("重厚な足音が近くで聞こえる。", "You hear heavy steps nearby."));
259 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
260 floor_ptr->monster_noise = true;
262 auto res = MonsterSpellResult::make_valid();
263 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
269 * @brief RF6_S_MONSTERの処理。モンスター一体召喚。 /
270 * @param player_ptr プレイヤーへの参照ポインタ
273 * @param m_idx 呪文を唱えるモンスターID
274 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
275 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
279 MonsterSpellResult spell_RF6_S_MONSTER(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
281 floor_type *floor_ptr = player_ptr->current_floor_ptr;
282 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
283 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
284 bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
285 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
286 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
288 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."), _("%^sが魔法で仲間を召喚した!", "%^s magically summons help!"),
289 _("%^sが魔法で仲間を召喚した!", "%^s magically summons help!"));
291 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
292 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
295 for (int k = 0; k < 1; k++) {
297 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_NONE, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
300 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_NONE, (monster_u_mode(floor_ptr, m_idx)));
303 if (player_ptr->blind && count && mon_to_player)
304 msg_print(_("何かが間近に現れた音がする。", "You hear something appear nearby."));
306 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
307 floor_ptr->monster_noise = true;
309 auto res = MonsterSpellResult::make_valid();
310 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
316 * @brief RF6_S_MONSTERSの処理。モンスター複数召喚。 /
317 * @param player_ptr プレイヤーへの参照ポインタ
320 * @param m_idx 呪文を唱えるモンスターID
321 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
322 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
326 MonsterSpellResult spell_RF6_S_MONSTERS(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
328 floor_type *floor_ptr = player_ptr->current_floor_ptr;
329 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
330 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
331 bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
332 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
333 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
335 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
336 _("%^sが魔法でモンスターを召喚した!", "%^s magically summons monsters!"), _("%^sが魔法でモンスターを召喚した!", "%^s magically summons monsters!"));
338 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
339 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
342 for (auto k = 0; k < S_NUM_6; k++) {
344 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_NONE, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
347 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_NONE, (PM_ALLOW_GROUP | monster_u_mode(floor_ptr, m_idx)));
350 if (player_ptr->blind && count && mon_to_player)
351 msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
353 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
354 floor_ptr->monster_noise = true;
356 auto res = MonsterSpellResult::make_valid();
357 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
363 * @brief RF6_S_ANTの処理。アリ召喚。 /
364 * @param player_ptr プレイヤーへの参照ポインタ
367 * @param m_idx 呪文を唱えるモンスターID
368 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
369 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
373 MonsterSpellResult spell_RF6_S_ANT(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
375 floor_type *floor_ptr = player_ptr->current_floor_ptr;
376 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
377 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
378 bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
379 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
380 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
382 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."), _("%^sが魔法でアリを召喚した。", "%^s magically summons ants."),
383 _("%^sが魔法でアリを召喚した。", "%^s magically summons ants."));
385 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
386 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
389 for (auto k = 0; k < S_NUM_6; k++) {
390 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_ANT, PM_ALLOW_GROUP);
393 if (player_ptr->blind && count && mon_to_player)
394 msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
396 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
397 floor_ptr->monster_noise = true;
399 auto res = MonsterSpellResult::make_valid();
400 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
406 * @brief RF6_S_SPIDERの処理。クモ召喚。 /
407 * @param player_ptr プレイヤーへの参照ポインタ
410 * @param m_idx 呪文を唱えるモンスターID
411 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
412 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
416 MonsterSpellResult spell_RF6_S_SPIDER(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
418 floor_type *floor_ptr = player_ptr->current_floor_ptr;
419 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
420 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
421 bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
422 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
423 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
425 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."), _("%^sが魔法でクモを召喚した。", "%^s magically summons spiders."),
426 _("%^sが魔法でクモを召喚した。", "%^s magically summons spiders."));
428 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
429 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
432 for (auto k = 0; k < S_NUM_6; k++) {
433 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_SPIDER, PM_ALLOW_GROUP);
436 if (player_ptr->blind && count && mon_to_player)
437 msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
439 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
440 floor_ptr->monster_noise = true;
442 auto res = MonsterSpellResult::make_valid();
443 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
449 * @brief RF6_S_HOUNDの処理。ハウンド召喚。 /
450 * @param player_ptr プレイヤーへの参照ポインタ
453 * @param m_idx 呪文を唱えるモンスターID
454 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
455 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
459 MonsterSpellResult spell_RF6_S_HOUND(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
461 floor_type *floor_ptr = player_ptr->current_floor_ptr;
462 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
463 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
464 bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
465 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
466 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
468 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
469 _("%^sが魔法でハウンドを召喚した。", "%^s magically summons hounds."), _("%^sが魔法でハウンドを召喚した。", "%^s magically summons hounds."));
471 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
472 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
475 for (auto k = 0; k < S_NUM_4; k++) {
476 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_HOUND, PM_ALLOW_GROUP);
479 if (player_ptr->blind && count && mon_to_player)
480 msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
482 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
483 floor_ptr->monster_noise = true;
485 auto res = MonsterSpellResult::make_valid();
486 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
492 * @brief RF6_S_HYDRAの処理。ヒドラ召喚。 /
493 * @param player_ptr プレイヤーへの参照ポインタ
496 * @param m_idx 呪文を唱えるモンスターID
497 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
498 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
502 MonsterSpellResult spell_RF6_S_HYDRA(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
504 floor_type *floor_ptr = player_ptr->current_floor_ptr;
505 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
506 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
507 bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
508 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
509 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
511 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
512 _("%^sが魔法でヒドラを召喚した。", "%^s magically summons hydras."), _("%^sが魔法でヒドラを召喚した。", "%^s magically summons hydras."));
514 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
515 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
518 for (auto k = 0; k < S_NUM_4; k++) {
519 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_HYDRA, PM_ALLOW_GROUP);
522 if (player_ptr->blind && count && mon_to_player)
523 msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
525 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
526 floor_ptr->monster_noise = true;
528 auto res = MonsterSpellResult::make_valid();
529 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
535 * @brief RF6_S_ANGELの処理。天使一体召喚。 /
536 * @param player_ptr プレイヤーへの参照ポインタ
539 * @param m_idx 呪文を唱えるモンスターID
540 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
541 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
545 MonsterSpellResult spell_RF6_S_ANGEL(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
547 floor_type *floor_ptr = player_ptr->current_floor_ptr;
548 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
549 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
550 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
551 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
553 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
554 _("%^sが魔法で天使を召喚した!", "%^s magically summons an angel!"), _("%^sが魔法で天使を召喚した!", "%^s magically summons an angel!"));
556 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
557 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
559 monster_type *m_ptr = &floor_ptr->m_list[m_idx];
560 monster_race *r_ptr = &r_info[m_ptr->r_idx];
562 if (any_bits(r_ptr->flags1, RF1_UNIQUE)) {
563 num += r_ptr->level / 40;
567 for (int k = 0; k < num; k++) {
568 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_ANGEL, PM_ALLOW_GROUP);
572 if (player_ptr->blind && count)
573 msg_print(_("何かが間近に現れた音がする。", "You hear something appear nearby."));
575 if (player_ptr->blind)
576 msg_print(_("多くのものが間近に現れた音がする。", "You hear many things appear nearby."));
579 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
580 floor_ptr->monster_noise = true;
582 auto res = MonsterSpellResult::make_valid();
583 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
589 * @brief RF6_S_DEMONの処理。デーモン一体召喚。 /
590 * @param player_ptr プレイヤーへの参照ポインタ
593 * @param m_idx 呪文を唱えるモンスターID
594 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
595 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
599 MonsterSpellResult spell_RF6_S_DEMON(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
601 floor_type *floor_ptr = player_ptr->current_floor_ptr;
602 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
603 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
604 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
605 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
607 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
608 _("%^sは魔法で混沌の宮廷から悪魔を召喚した!", "%^s magically summons a demon from the Courts of Chaos!"),
609 _("%^sは魔法で混沌の宮廷から悪魔を召喚した!", "%^s magically summons a demon from the Courts of Chaos!"));
611 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
612 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
615 for (int k = 0; k < 1; k++) {
616 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_DEMON, PM_ALLOW_GROUP);
619 if (player_ptr->blind && count)
620 msg_print(_("何かが間近に現れた音がする。", "You hear something appear nearby."));
622 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
623 floor_ptr->monster_noise = true;
625 auto res = MonsterSpellResult::make_valid();
626 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
632 * @brief RF6_S_UNDEADの処理。アンデッド一体召喚。 /
633 * @param player_ptr プレイヤーへの参照ポインタ
636 * @param m_idx 呪文を唱えるモンスターID
637 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
638 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
642 MonsterSpellResult spell_RF6_S_UNDEAD(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
644 floor_type *floor_ptr = player_ptr->current_floor_ptr;
645 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
646 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
647 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
648 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
650 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
651 _("%^sが魔法でアンデッドの強敵を召喚した!", "%^s magically summons an undead adversary!"),
652 _("%sが魔法でアンデッドを召喚した。", "%^s magically summons undead."));
654 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
655 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
658 for (int k = 0; k < 1; k++) {
659 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_UNDEAD, PM_ALLOW_GROUP);
662 if (player_ptr->blind && count)
663 msg_print(_("何かが間近に現れた音がする。", "You hear something appear nearby."));
665 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
666 floor_ptr->monster_noise = true;
668 auto res = MonsterSpellResult::make_valid();
669 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
675 * @brief RF6_S_DRAGONの処理。ドラゴン一体召喚。 /
676 * @param player_ptr プレイヤーへの参照ポインタ
679 * @param m_idx 呪文を唱えるモンスターID
680 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
681 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
685 MonsterSpellResult spell_RF6_S_DRAGON(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
687 floor_type *floor_ptr = player_ptr->current_floor_ptr;
688 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
689 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
690 bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
691 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
692 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
694 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
695 _("%^sが魔法でドラゴンを召喚した!", "%^s magically summons a dragon!"), _("%^sが魔法でドラゴンを召喚した!", "%^s magically summons a dragon!"));
697 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
698 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
702 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_DRAGON, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
705 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_DRAGON, (PM_ALLOW_GROUP | monster_u_mode(floor_ptr, m_idx)));
707 if (player_ptr->blind && count)
708 msg_print(_("何かが間近に現れた音がする。", "You hear something appear nearby."));
710 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
711 floor_ptr->monster_noise = true;
713 auto res = MonsterSpellResult::make_valid();
714 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
720 * @brief RF6_S_HI_UNDEADの処理。強力なアンデッド召喚。 /
721 * @param player_ptr プレイヤーへの参照ポインタ
724 * @param m_idx 呪文を唱えるモンスターID
725 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
726 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
730 MonsterSpellResult spell_RF6_S_HI_UNDEAD(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
732 floor_type *floor_ptr = player_ptr->current_floor_ptr;
733 monster_type *m_ptr = &floor_ptr->m_list[m_idx];
734 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
735 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
736 bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
737 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
738 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
740 GAME_TEXT m_name[MAX_NLEN];
741 monster_name(player_ptr, m_idx, m_name);
742 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
745 if (((m_ptr->r_idx == MON_MORGOTH) || (m_ptr->r_idx == MON_SAURON) || (m_ptr->r_idx == MON_ANGMAR)) && ((r_info[MON_NAZGUL].cur_num + 2) < r_info[MON_NAZGUL].max_num) && mon_to_player) {
746 count += summon_NAZGUL(player_ptr, y, x, m_idx);
748 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
749 _("%^sが魔法で強力なアンデッドを召喚した!", "%^s magically summons greater undead!"),
750 _("%sが魔法でアンデッドを召喚した。", "%^s magically summons undead."));
752 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
754 for (auto k = 0; k < S_NUM_6; k++) {
756 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_HI_UNDEAD, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
759 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_HI_UNDEAD, (PM_ALLOW_GROUP | monster_u_mode(floor_ptr, m_idx)));
763 if (player_ptr->blind && count && mon_to_player) {
764 msg_print(_("間近で何か多くのものが這い回る音が聞こえる。", "You hear many creepy things appear nearby."));
767 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
768 floor_ptr->monster_noise = true;
770 auto res = MonsterSpellResult::make_valid();
771 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
777 * @brief RF6_S_HI_DRAGONの処理。古代ドラゴン召喚。 /
778 * @param player_ptr プレイヤーへの参照ポインタ
781 * @param m_idx 呪文を唱えるモンスターID
782 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
783 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
787 MonsterSpellResult spell_RF6_S_HI_DRAGON(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
789 floor_type *floor_ptr = player_ptr->current_floor_ptr;
790 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
791 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
792 bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
793 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
794 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
796 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
797 _("%^sが魔法で古代ドラゴンを召喚した!", "%^s magically summons ancient dragons!"),
798 _("%^sが魔法で古代ドラゴンを召喚した!", "%^s magically summons ancient dragons!"));
800 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
801 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
804 for (auto k = 0; k < S_NUM_4; k++) {
806 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_HI_DRAGON, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
809 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_HI_DRAGON, (PM_ALLOW_GROUP | monster_u_mode(floor_ptr, m_idx)));
812 if (player_ptr->blind && count && mon_to_player) {
813 msg_print(_("多くの力強いものが間近に現れた音が聞こえる。", "You hear many powerful things appear nearby."));
816 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
817 floor_ptr->monster_noise = true;
819 auto res = MonsterSpellResult::make_valid();
820 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
826 * @brief RF6_S_AMBERITESの処理。アンバーの王族召喚。 /
827 * @param player_ptr プレイヤーへの参照ポインタ
830 * @param m_idx 呪文を唱えるモンスターID
831 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
832 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
836 MonsterSpellResult spell_RF6_S_AMBERITES(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
838 floor_type *floor_ptr = player_ptr->current_floor_ptr;
839 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
840 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
841 bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
842 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
843 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
845 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
846 _("%^sがアンバーの王族を召喚した!", "%^s magically summons Lords of Amber!"),
847 _("%^sがアンバーの王族を召喚した!", "%^s magically summons Lords of Amber!"));
849 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
850 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
853 for (auto k = 0; k < S_NUM_4; k++) {
854 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_AMBERITES, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
857 if (player_ptr->blind && count && mon_to_player) {
858 msg_print(_("不死の者が近くに現れるのが聞こえた。", "You hear immortal beings appear nearby."));
861 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
862 floor_ptr->monster_noise = true;
864 auto res = MonsterSpellResult::make_valid();
865 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
871 * @brief RF6_S_UNIQUEの処理。ユニーク・モンスター召喚。 /
872 * @param player_ptr プレイヤーへの参照ポインタ
875 * @param m_idx 呪文を唱えるモンスターID
876 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
877 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
881 MonsterSpellResult spell_RF6_S_UNIQUE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
883 floor_type *floor_ptr = player_ptr->current_floor_ptr;
884 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
885 bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
886 bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
887 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
888 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
890 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
891 _("%^sが魔法で特別な強敵を召喚した!", "%^s magically summons special opponents!"),
892 _("%^sが魔法で特別な強敵を召喚した!", "%^s magically summons special opponents!"));
894 monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
895 summon_disturb(player_ptr, TARGET_TYPE, known, see_either);
897 monster_type *m_ptr = &floor_ptr->m_list[m_idx];
898 bool uniques_are_summoned = false;
900 for (auto k = 0; k < S_NUM_4; k++) {
901 count += summon_specific(player_ptr, m_idx, y, x, rlev, SUMMON_UNIQUE, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
905 uniques_are_summoned = true;
907 summon_type non_unique_type = SUMMON_HI_UNDEAD;
908 if ((m_ptr->sub_align & (SUB_ALIGN_GOOD | SUB_ALIGN_EVIL)) == (SUB_ALIGN_GOOD | SUB_ALIGN_EVIL))
909 non_unique_type = SUMMON_NONE;
910 else if (m_ptr->sub_align & SUB_ALIGN_GOOD)
911 non_unique_type = SUMMON_ANGEL;
913 for (auto k = count; k < S_NUM_4; k++) {
914 count += summon_specific(player_ptr, m_idx, y, x, rlev, non_unique_type, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE));
917 if (player_ptr->blind && count && mon_to_player) {
918 msg_format(_("多くの%sが間近に現れた音が聞こえる。", "You hear many %s appear nearby."),
919 uniques_are_summoned ? _("力強いもの", "powerful things") : _("もの", "things"));
922 if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
923 floor_ptr->monster_noise = true;
925 auto res = MonsterSpellResult::make_valid();
926 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;