2 * @brief フロアの一定範囲に効果を及ぼす (悲鳴、テレポート等)スペルの効果
7 #include "mspell/mspell-floor.h"
8 #include "blue-magic/blue-magic-checker.h"
9 #include "core/disturbance.h"
10 #include "core/player-update-types.h"
11 #include "effect/effect-characteristics.h"
12 #include "effect/effect-processor.h"
13 #include "mind/drs-types.h"
14 #include "monster-race/monster-race.h"
15 #include "monster-race/race-flags-resistance.h"
16 #include "monster-race/race-flags1.h"
17 #include "monster-race/race-flags3.h"
18 #include "monster-race/race-flags7.h"
19 #include "monster-race/race-indice-types.h"
20 #include "monster/monster-info.h"
21 #include "monster/monster-status-setter.h"
22 #include "monster/monster-status.h"
23 #include "monster/monster-update.h"
24 #include "mspell/mspell-status.h"
25 #include "mspell/mspell-type.h"
26 #include "mspell/mspell-util.h"
27 #include "player/player-personalities-types.h"
28 #include "spell-kind/spells-lite.h"
29 #include "spell-kind/spells-neighbor.h"
30 #include "spell-kind/spells-sight.h"
31 #include "spell-kind/spells-teleport.h"
32 #include "spell-kind/spells-world.h"
33 #include "spell-realm/spells-hex.h"
34 #include "spell/spell-types.h"
35 #include "system/floor-type-definition.h"
36 #include "view/display-messages.h"
39 * @brief RF4_SHRIEKの処理。叫び。 /
40 * @param m_idx 呪文を唱えるモンスターID
41 * @param target_ptr プレーヤーへの参照ポインタ
42 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
43 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
45 void spell_RF4_SHRIEK(MONSTER_IDX m_idx, player_type *target_ptr, MONSTER_IDX t_idx, int TARGET_TYPE)
47 simple_monspell_message(target_ptr, m_idx, t_idx, _("%^sがかん高い金切り声をあげた。", "%^s makes a high pitched shriek."),
48 _("%^sが%sに向かって叫んだ。", "%^s shrieks at %s."), TARGET_TYPE);
50 if (TARGET_TYPE == MONSTER_TO_PLAYER) {
51 aggravate_monsters(target_ptr, m_idx);
55 if (TARGET_TYPE == MONSTER_TO_MONSTER) {
56 set_monster_csleep(target_ptr, t_idx, 0);
61 * @brief RF6_WORLDの処理。時を止める。 /
62 * @param target_ptr プレーヤーへの参照ポインタ
63 * @param m_idx 呪文を唱えるモンスターID
65 HIT_POINT spell_RF6_WORLD(player_type *target_ptr, MONSTER_IDX m_idx)
67 monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
69 GAME_TEXT m_name[MAX_NLEN];
70 monster_name(target_ptr, m_idx, m_name);
72 disturb(target_ptr, TRUE, TRUE);
73 if (m_ptr->r_idx == MON_DIO)
75 else if (m_ptr->r_idx == MON_WONG)
77 if (!set_monster_timewalk(target_ptr, randint1(2) + 2, who, TRUE))
83 * @brief RF6_BLINKの処理。ショート・テレポート。 /
84 * @param target_ptr プレーヤーへの参照ポインタ
85 * @param m_idx 呪文を唱えるモンスターID
86 * @param is_quantum_effect 量子的効果によるショート・テレポートの場合時TRUE
87 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
89 void spell_RF6_BLINK(player_type *target_ptr, MONSTER_IDX m_idx, int TARGET_TYPE, bool is_quantum_effect)
91 GAME_TEXT m_name[MAX_NLEN];
92 monster_name(target_ptr, m_idx, m_name);
94 if (TARGET_TYPE == MONSTER_TO_PLAYER)
95 disturb(target_ptr, TRUE, TRUE);
97 if (!is_quantum_effect && teleport_barrier(target_ptr, m_idx)) {
98 if (see_monster(target_ptr, m_idx))
99 msg_format(_("魔法のバリアが%^sのテレポートを邪魔した。", "Magic barrier obstructs teleporting of %^s."), m_name);
103 if (see_monster(target_ptr, m_idx))
104 msg_format(_("%^sが瞬時に消えた。", "%^s blinks away."), m_name);
106 teleport_away(target_ptr, m_idx, 10, TELEPORT_SPONTANEOUS);
108 if (TARGET_TYPE == MONSTER_TO_PLAYER)
109 target_ptr->update |= (PU_MONSTERS);
113 * @brief RF6_TPORTの処理。テレポート。 /
114 * @param target_ptr プレーヤーへの参照ポインタ
115 * @param m_idx 呪文を唱えるモンスターID
116 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
118 void spell_RF6_TPORT(player_type *target_ptr, MONSTER_IDX m_idx, int TARGET_TYPE)
120 GAME_TEXT m_name[MAX_NLEN];
121 monster_name(target_ptr, m_idx, m_name);
123 if (TARGET_TYPE == MONSTER_TO_PLAYER)
124 disturb(target_ptr, TRUE, TRUE);
125 if (teleport_barrier(target_ptr, m_idx)) {
126 if (see_monster(target_ptr, m_idx))
127 msg_format(_("魔法のバリアが%^sのテレポートを邪魔した。", "Magic barrier obstructs teleporting of %^s."), m_name);
131 if (see_monster(target_ptr, m_idx))
132 msg_format(_("%^sがテレポートした。", "%^s teleports away."), m_name);
134 teleport_away_followable(target_ptr, m_idx);
138 * @brief RF6_TELE_TOの処理。テレポート・バック。 /
139 * @param target_ptr プレーヤーへの参照ポインタ
140 * @param m_idx 呪文を唱えるモンスターID
141 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
142 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
145 void spell_RF6_TELE_TO(player_type *target_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
147 floor_type *floor_ptr = target_ptr->current_floor_ptr;
148 monster_type *m_ptr = &floor_ptr->m_list[m_idx];
149 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
150 monster_race *tr_ptr = &r_info[t_ptr->r_idx];
152 simple_monspell_message(target_ptr, m_idx, t_idx, _("%^sがあなたを引き戻した。", "%^s commands you to return."),
153 _("%^sが%sを引き戻した。", "%^s commands %s to return."), TARGET_TYPE);
155 if (TARGET_TYPE == MONSTER_TO_PLAYER) {
156 teleport_player_to(target_ptr, m_ptr->fy, m_ptr->fx, TELEPORT_PASSIVE);
157 learn_spell(target_ptr, MS_TELE_TO);
161 if (TARGET_TYPE != MONSTER_TO_MONSTER)
164 bool resists_tele = FALSE;
165 GAME_TEXT t_name[MAX_NLEN];
166 monster_name(target_ptr, t_idx, t_name);
168 if (tr_ptr->flagsr & RFR_RES_TELE) {
169 if ((tr_ptr->flags1 & RF1_UNIQUE) || (tr_ptr->flagsr & RFR_RES_ALL)) {
170 if (is_original_ap_and_seen(target_ptr, t_ptr))
171 tr_ptr->r_flagsr |= RFR_RES_TELE;
172 if (see_monster(target_ptr, t_idx)) {
173 msg_format(_("%^sには効果がなかった。", "%^s is unaffected!"), t_name);
176 } else if (tr_ptr->level > randint1(100)) {
177 if (is_original_ap_and_seen(target_ptr, t_ptr))
178 tr_ptr->r_flagsr |= RFR_RES_TELE;
179 if (see_monster(target_ptr, t_idx)) {
180 msg_format(_("%^sは耐性を持っている!", "%^s resists!"), t_name);
187 set_monster_csleep(target_ptr, t_idx, 0);
191 if (t_idx == target_ptr->riding)
192 teleport_player_to(target_ptr, m_ptr->fy, m_ptr->fx, TELEPORT_PASSIVE);
194 teleport_monster_to(target_ptr, t_idx, m_ptr->fy, m_ptr->fx, 100, TELEPORT_PASSIVE);
195 set_monster_csleep(target_ptr, t_idx, 0);
199 * @brief RF6_TELE_AWAYの処理。テレポート・アウェイ。 /
200 * @param target_ptr プレーヤーへの参照ポインタ
201 * @param m_idx 呪文を唱えるモンスターID
202 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
203 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
206 void spell_RF6_TELE_AWAY(player_type *target_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
208 floor_type *floor_ptr = target_ptr->current_floor_ptr;
209 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
210 monster_race *tr_ptr = &r_info[t_ptr->r_idx];
212 simple_monspell_message(target_ptr, m_idx, t_idx, _("%^sにテレポートさせられた。", "%^s teleports you away."),
213 _("%^sは%sをテレポートさせた。", "%^s teleports %s away."), TARGET_TYPE);
215 if (TARGET_TYPE == MONSTER_TO_PLAYER) {
216 if (is_echizen(target_ptr))
217 msg_print(_("くっそ~", ""));
218 else if ((target_ptr->pseikaku == PERSONALITY_CHARGEMAN)) {
219 if (randint0(2) == 0)
220 msg_print(_("ジュラル星人め!", ""));
222 msg_print(_("弱い者いじめは止めるんだ!", ""));
225 learn_spell(target_ptr, MS_TELE_AWAY);
226 teleport_player_away(m_idx, target_ptr, 100, FALSE);
230 if (TARGET_TYPE != MONSTER_TO_MONSTER)
233 bool resists_tele = FALSE;
234 GAME_TEXT t_name[MAX_NLEN];
235 monster_name(target_ptr, t_idx, t_name);
237 if (tr_ptr->flagsr & RFR_RES_TELE) {
238 if ((tr_ptr->flags1 & RF1_UNIQUE) || (tr_ptr->flagsr & RFR_RES_ALL)) {
239 if (is_original_ap_and_seen(target_ptr, t_ptr))
240 tr_ptr->r_flagsr |= RFR_RES_TELE;
241 if (see_monster(target_ptr, t_idx)) {
242 msg_format(_("%^sには効果がなかった。", "%^s is unaffected!"), t_name);
245 } else if (tr_ptr->level > randint1(100)) {
246 if (is_original_ap_and_seen(target_ptr, t_ptr))
247 tr_ptr->r_flagsr |= RFR_RES_TELE;
248 if (see_monster(target_ptr, t_idx)) {
249 msg_format(_("%^sは耐性を持っている!", "%^s resists!"), t_name);
256 set_monster_csleep(target_ptr, t_idx, 0);
260 if (t_idx == target_ptr->riding)
261 teleport_player_away(m_idx, target_ptr, MAX_SIGHT * 2 + 5, FALSE);
263 teleport_away(target_ptr, t_idx, MAX_SIGHT * 2 + 5, TELEPORT_PASSIVE);
264 set_monster_csleep(target_ptr, t_idx, 0);
268 * @brief RF6_TELE_LEVELの処理。テレポート・レベル。 /
269 * @param target_ptr プレーヤーへの参照ポインタ
270 * @param m_idx 呪文を唱えるモンスターID
271 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
272 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
275 void spell_RF6_TELE_LEVEL(player_type *target_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
277 floor_type *floor_ptr = target_ptr->current_floor_ptr;
278 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
279 monster_race *tr_ptr = &r_info[t_ptr->r_idx];
280 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
281 bool resist, saving_throw;
283 if (TARGET_TYPE == MONSTER_TO_PLAYER) {
284 resist = target_ptr->resist_nexus;
285 saving_throw = (randint0(100 + rlev / 2) < target_ptr->skill_sav);
286 spell_badstatus_message(target_ptr, m_idx, t_idx, _("%^sが何か奇妙な言葉をつぶやいた。", "%^s mumbles strangely."),
287 _("%^sがあなたの足を指さした。", "%^s gestures at your feet."), _("しかし効果がなかった!", "You are unaffected!"),
288 _("しかし効力を跳ね返した!", "You resist the effects!"), resist, saving_throw, TARGET_TYPE);
290 if (!resist && !saving_throw) {
291 teleport_level(target_ptr, 0);
294 learn_spell(target_ptr, MS_TELE_LEVEL);
295 update_smart_learn(target_ptr, m_idx, DRS_NEXUS);
299 if (TARGET_TYPE != MONSTER_TO_MONSTER)
302 resist = tr_ptr->flagsr & (RFR_EFF_RES_NEXU_MASK | RFR_RES_TELE);
303 saving_throw = (tr_ptr->flags1 & RF1_QUESTOR) || (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
305 spell_badstatus_message(target_ptr, m_idx, t_idx, _("%^sが%sの足を指さした。", "%^s gestures at %s's feet."),
306 _("%^sには効果がなかった。", "%^s is unaffected!"), _("%^sは効力を跳ね返した!", "%^s resist the effects!"), "", resist, saving_throw, TARGET_TYPE);
308 if (!resist && !saving_throw) {
309 teleport_level(target_ptr, (t_idx == target_ptr->riding) ? 0 : t_idx);
314 * @brief RF6_DARKNESSの処理。暗闇or閃光。 /
315 * @param target_type プレーヤーへの参照ポインタ
318 * @param m_idx 呪文を唱えるモンスターID
319 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
320 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
322 void spell_RF6_DARKNESS(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
324 floor_type *floor_ptr = target_ptr->current_floor_ptr;
325 monster_type *m_ptr = &floor_ptr->m_list[m_idx];
326 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
327 monster_race *r_ptr = &r_info[m_ptr->r_idx];
328 bool can_use_lite_area = FALSE;
329 bool monster_to_monster = TARGET_TYPE == MONSTER_TO_MONSTER;
330 bool monster_to_player = TARGET_TYPE == MONSTER_TO_PLAYER;
331 GAME_TEXT t_name[MAX_NLEN];
332 monster_name(target_ptr, t_idx, t_name);
334 if ((target_ptr->pclass == CLASS_NINJA) && !(r_ptr->flags3 & (RF3_UNDEAD | RF3_HURT_LITE)) && !(r_ptr->flags7 & RF7_DARK_MASK))
335 can_use_lite_area = TRUE;
337 if (monster_to_monster && !is_hostile(t_ptr))
338 can_use_lite_area = FALSE;
340 if (can_use_lite_area) {
341 monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
342 _("%^sが辺りを明るく照らした。", "%^s cast a spell to light up."), _("%^sが辺りを明るく照らした。", "%^s cast a spell to light up."), TARGET_TYPE);
344 if (see_monster(target_ptr, t_idx) && monster_to_monster) {
345 msg_format(_("%^sは白い光に包まれた。", "%^s is surrounded by a white light."), t_name);
348 monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."), _("%^sが暗闇の中で手を振った。", "%^s gestures in shadow."),
349 _("%^sが暗闇の中で手を振った。", "%^s gestures in shadow."), TARGET_TYPE);
351 if (see_monster(target_ptr, t_idx) && monster_to_monster) {
352 msg_format(_("%^sは暗闇に包まれた。", "%^s is surrounded by darkness."), t_name);
356 if (monster_to_player) {
357 if (can_use_lite_area) {
358 (void)lite_area(target_ptr, 0, 3);
360 learn_spell(target_ptr, MS_DARKNESS);
361 (void)unlite_area(target_ptr, 0, 3);
367 if (!monster_to_monster)
370 int lite_area = can_use_lite_area ? -1 : MS_DARKNESS;
371 (void)project(target_ptr, m_idx, 3, y, x, 0, GF_LITE_WEAK, PROJECT_GRID | PROJECT_KILL, lite_area);
372 lite_room(target_ptr, y, x);
376 * @brief RF6_TRAPSの処理。トラップ。 /
377 * @param target_ptr プレーヤーへの参照ポインタ
380 * @param m_idx 呪文を唱えるモンスターID
383 void spell_RF6_TRAPS(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx)
385 GAME_TEXT m_name[MAX_NLEN];
386 monster_name(target_ptr, m_idx, m_name);
387 disturb(target_ptr, TRUE, TRUE);
389 if (target_ptr->blind)
390 msg_format(_("%^sが何かをつぶやいて邪悪に微笑んだ。", "%^s mumbles, and then cackles evilly."), m_name);
392 msg_format(_("%^sが呪文を唱えて邪悪に微笑んだ。", "%^s casts a spell and cackles evilly."), m_name);
394 learn_spell(target_ptr, MS_MAKE_TRAP);
395 (void)trap_creation(target_ptr, y, x);
399 * @brief RF6_RAISE_DEADの処理。死者復活。 /
400 * @param target_ptr プレーヤーへの参照ポインタ
401 * @param m_idx 呪文を唱えるモンスターID
402 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
403 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
405 void spell_RF6_RAISE_DEAD(player_type *target_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
407 monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
409 monspell_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
410 _("%^sが死者復活の呪文を唱えた。", "%^s casts a spell to revive corpses."), _("%^sが死者復活の呪文を唱えた。", "%^s casts a spell to revive corpses."),
413 animate_dead(target_ptr, m_idx, m_ptr->fy, m_ptr->fx);