OSDN Git Service

[Refactor] #40571 Moved targeting.c/h from io/ to target/
[hengband/hengband.git] / src / realm / realm-hissatsu.c
1 #include "realm/realm-hissatsu.h"
2 #include "art-definition/art-sword-types.h"
3 #include "cmd-action/cmd-attack.h"
4 #include "cmd-action/cmd-spell.h"
5 #include "cmd-item/cmd-throw.h"
6 #include "combat/combat-options-type.h"
7 #include "core/asking-player.h"
8 #include "core/player-redraw-types.h"
9 #include "core/player-update-types.h"
10 #include "core/stuff-handler.h"
11 #include "dungeon/dungeon-flag-types.h"
12 #include "dungeon/dungeon.h"
13 #include "effect/effect-characteristics.h"
14 #include "effect/spells-effect-util.h"
15 #include "floor/cave.h"
16 #include "floor/floor.h"
17 #include "grid/feature-flag-types.h"
18 #include "grid/grid.h"
19 #include "inventory/inventory-slot-types.h"
20 #include "io/input-key-acceptor.h"
21 #include "io/input-key-requester.h"
22 #include "mind/mind-ninja.h"
23 #include "monster-race/monster-race-hook.h"
24 #include "monster-race/monster-race.h"
25 #include "monster-race/race-flags7.h"
26 #include "monster/monster-describer.h"
27 #include "monster/monster-info.h"
28 #include "monster/monster-update.h"
29 #include "object-enchant/tr-types.h"
30 #include "object/object-flags.h"
31 #include "player/player-damage.h"
32 #include "player/player-move.h"
33 #include "player/player-status.h"
34 #include "spell-kind/earthquake.h"
35 #include "spell-kind/spells-detection.h"
36 #include "spell-kind/spells-launcher.h"
37 #include "spell-kind/spells-perception.h"
38 #include "spell-kind/spells-sight.h"
39 #include "spell-kind/spells-teleport.h"
40 #include "spell/process-effect.h"
41 #include "spell/spell-types.h"
42 #include "spell/technic-info-table.h"
43 #include "status/bad-status-setter.h"
44 #include "system/floor-type-definition.h"
45 #include "target/targeting.h"
46 #include "term/screen-processor.h"
47 #include "util/bit-flags-calculator.h"
48 #include "view/display-messages.h"
49 #include "world/world.h"
50
51 /*!
52  * @brief 剣術の各処理を行う
53  * @param caster_ptr プレーヤーへの参照ポインタ
54  * @param spell 剣術ID
55  * @param mode 処理内容 (SPELL_NAME / SPELL_DESC / SPELL_CAST)
56  * @return SPELL_NAME / SPELL_DESC 時には文字列ポインタを返す。SPELL_CAST時はNULL文字列を返す。
57  */
58 concptr do_hissatsu_spell(player_type *caster_ptr, SPELL_IDX spell, spell_type mode)
59 {
60     bool name = (mode == SPELL_NAME) ? TRUE : FALSE;
61     bool desc = (mode == SPELL_DESC) ? TRUE : FALSE;
62     bool cast = (mode == SPELL_CAST) ? TRUE : FALSE;
63
64     DIRECTION dir;
65     PLAYER_LEVEL plev = caster_ptr->lev;
66
67     switch (spell) {
68     case 0:
69         if (name)
70             return _("飛飯綱", "Tobi-Izuna");
71         if (desc)
72             return _("2マス離れたところにいるモンスターを攻撃する。", "Attacks a monster two squares away.");
73
74         if (cast) {
75             project_length = 2;
76             if (!get_aim_dir(caster_ptr, &dir))
77                 return NULL;
78
79             project_hook(caster_ptr, GF_ATTACK, dir, HISSATSU_2, PROJECT_STOP | PROJECT_KILL);
80         }
81         break;
82
83     case 1:
84         if (name)
85             return _("五月雨斬り", "3-Way Attack");
86         if (desc)
87             return _("3方向に対して攻撃する。", "Attacks in 3 directions at one time.");
88
89         if (cast) {
90             DIRECTION cdir;
91             POSITION y, x;
92
93             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
94                 return NULL;
95             if (dir == 5)
96                 return NULL;
97
98             for (cdir = 0; cdir < 8; cdir++) {
99                 if (cdd[cdir] == dir)
100                     break;
101             }
102
103             if (cdir == 8)
104                 return NULL;
105
106             y = caster_ptr->y + ddy_cdd[cdir];
107             x = caster_ptr->x + ddx_cdd[cdir];
108             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
109                 do_cmd_attack(caster_ptr, y, x, 0);
110             else
111                 msg_print(_("攻撃は空を切った。", "You attack the empty air."));
112
113             y = caster_ptr->y + ddy_cdd[(cdir + 7) % 8];
114             x = caster_ptr->x + ddx_cdd[(cdir + 7) % 8];
115             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
116                 do_cmd_attack(caster_ptr, y, x, 0);
117             else
118                 msg_print(_("攻撃は空を切った。", "You attack the empty air."));
119
120             y = caster_ptr->y + ddy_cdd[(cdir + 1) % 8];
121             x = caster_ptr->x + ddx_cdd[(cdir + 1) % 8];
122             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
123                 do_cmd_attack(caster_ptr, y, x, 0);
124             else
125                 msg_print(_("攻撃は空を切った。", "You attack the empty air."));
126         }
127         break;
128
129     case 2:
130         if (name)
131             return _("ブーメラン", "Boomerang");
132         if (desc)
133             return _(
134                 "武器を手元に戻ってくるように投げる。戻ってこないこともある。", "Throws current weapon. It'll return to your hand unless the action failed.");
135
136         if (cast) {
137             if (!do_cmd_throw(caster_ptr, 1, TRUE, -1))
138                 return NULL;
139         }
140         break;
141
142     case 3:
143         if (name)
144             return _("焔霊", "Burning Strike");
145         if (desc)
146             return _("火炎耐性のないモンスターに大ダメージを与える。", "Attacks a monster with more damage unless it has resistance to fire.");
147
148         if (cast) {
149             POSITION y, x;
150
151             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
152                 return NULL;
153             if (dir == 5)
154                 return NULL;
155
156             y = caster_ptr->y + ddy[dir];
157             x = caster_ptr->x + ddx[dir];
158
159             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
160                 do_cmd_attack(caster_ptr, y, x, HISSATSU_FIRE);
161             else {
162                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
163                 return NULL;
164             }
165         }
166         break;
167
168     case 4:
169         if (name)
170             return _("殺気感知", "Detect Ferocity");
171         if (desc)
172             return _("近くの思考することができるモンスターを感知する。", "Detects all monsters except the mindless in your vicinity.");
173
174         if (cast) {
175             detect_monsters_mind(caster_ptr, DETECT_RAD_DEFAULT);
176         }
177         break;
178
179     case 5:
180         if (name)
181             return _("みね打ち", "Strike to Stun");
182         if (desc)
183             return _("相手にダメージを与えないが、朦朧とさせる。", "Attempts to stun a monster next to you.");
184
185         if (cast) {
186             POSITION y, x;
187
188             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
189                 return NULL;
190             if (dir == 5)
191                 return NULL;
192
193             y = caster_ptr->y + ddy[dir];
194             x = caster_ptr->x + ddx[dir];
195
196             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
197                 do_cmd_attack(caster_ptr, y, x, HISSATSU_MINEUCHI);
198             else {
199                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
200                 return NULL;
201             }
202         }
203         break;
204
205     case 6:
206         if (name)
207             return _("カウンター", "Counter");
208         if (desc)
209             return _("相手に攻撃されたときに反撃する。反撃するたびにMPを消費。",
210                 "Prepares to counterattack. When attacked by a monster, strikes back using SP each time.");
211
212         if (cast) {
213             if (caster_ptr->riding) {
214                 msg_print(_("乗馬中には無理だ。", "You cannot do it when riding."));
215                 return NULL;
216             }
217             msg_print(_("相手の攻撃に対して身構えた。", "You prepare to counterattack."));
218             caster_ptr->counter = TRUE;
219         }
220         break;
221
222     case 7:
223         if (name)
224             return _("払い抜け", "Harainuke");
225         if (desc)
226             return _("攻撃した後、反対側に抜ける。",
227                 "In one action, attacks a monster with your weapons normally and then moves to the space beyond the monster if that space is not blocked.");
228
229         if (cast) {
230             POSITION y, x;
231
232             if (caster_ptr->riding) {
233                 msg_print(_("乗馬中には無理だ。", "You cannot do it when riding."));
234                 return NULL;
235             }
236
237             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
238                 return NULL;
239
240             if (dir == 5)
241                 return NULL;
242             y = caster_ptr->y + ddy[dir];
243             x = caster_ptr->x + ddx[dir];
244
245             if (!caster_ptr->current_floor_ptr->grid_array[y][x].m_idx) {
246                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
247                 return NULL;
248             }
249
250             do_cmd_attack(caster_ptr, y, x, 0);
251
252             if (!player_can_enter(caster_ptr, caster_ptr->current_floor_ptr->grid_array[y][x].feat, 0)
253                 || is_trap(caster_ptr, caster_ptr->current_floor_ptr->grid_array[y][x].feat))
254                 break;
255
256             y += ddy[dir];
257             x += ddx[dir];
258
259             if (player_can_enter(caster_ptr, caster_ptr->current_floor_ptr->grid_array[y][x].feat, 0)
260                 && !is_trap(caster_ptr, caster_ptr->current_floor_ptr->grid_array[y][x].feat) && !caster_ptr->current_floor_ptr->grid_array[y][x].m_idx) {
261                 msg_print(NULL);
262                 (void)move_player_effect(caster_ptr, y, x, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP);
263             }
264         }
265         break;
266
267     case 8:
268         if (name)
269             return _("サーペンツタン", "Serpent's Tongue");
270         if (desc)
271             return _("毒耐性のないモンスターに大ダメージを与える。", "Attacks a monster with more damage unless it has resistance to poison.");
272
273         if (cast) {
274             POSITION y, x;
275
276             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
277                 return NULL;
278             if (dir == 5)
279                 return NULL;
280
281             y = caster_ptr->y + ddy[dir];
282             x = caster_ptr->x + ddx[dir];
283
284             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
285                 do_cmd_attack(caster_ptr, y, x, HISSATSU_POISON);
286             else {
287                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
288                 return NULL;
289             }
290         }
291         break;
292
293     case 9:
294         if (name)
295             return _("斬魔剣弐の太刀", "Zammaken");
296         if (desc)
297             return _("生命のない邪悪なモンスターに大ダメージを与えるが、他のモンスターには全く効果がない。",
298                 "Attacks an evil unliving monster with great damage. Has no effect on other monsters.");
299
300         if (cast) {
301             POSITION y, x;
302
303             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
304                 return NULL;
305             if (dir == 5)
306                 return NULL;
307
308             y = caster_ptr->y + ddy[dir];
309             x = caster_ptr->x + ddx[dir];
310
311             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
312                 do_cmd_attack(caster_ptr, y, x, HISSATSU_ZANMA);
313             else {
314                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
315                 return NULL;
316             }
317         }
318         break;
319
320     case 10:
321         if (name)
322             return _("裂風剣", "Wind Blast");
323         if (desc)
324             return _("攻撃した相手を後方へ吹き飛ばす。", "Attacks an adjacent monster and blows it away.");
325
326         if (cast) {
327             POSITION y, x;
328
329             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
330                 return NULL;
331             if (dir == 5)
332                 return NULL;
333
334             y = caster_ptr->y + ddy[dir];
335             x = caster_ptr->x + ddx[dir];
336
337             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
338                 do_cmd_attack(caster_ptr, y, x, 0);
339             else {
340                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
341                 return NULL;
342             }
343             if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_NO_MELEE) {
344                 return "";
345             }
346             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx) {
347                 int i;
348                 POSITION ty = y, tx = x;
349                 POSITION oy = y, ox = x;
350                 MONSTER_IDX m_idx = caster_ptr->current_floor_ptr->grid_array[y][x].m_idx;
351                 monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[m_idx];
352                 GAME_TEXT m_name[MAX_NLEN];
353
354                 monster_desc(caster_ptr, m_name, m_ptr, 0);
355
356                 for (i = 0; i < 5; i++) {
357                     y += ddy[dir];
358                     x += ddx[dir];
359                     if (is_cave_empty_bold(caster_ptr, y, x)) {
360                         ty = y;
361                         tx = x;
362                     } else
363                         break;
364                 }
365                 if ((ty != oy) || (tx != ox)) {
366                     msg_format(_("%sを吹き飛ばした!", "You blow %s away!"), m_name);
367                     caster_ptr->current_floor_ptr->grid_array[oy][ox].m_idx = 0;
368                     caster_ptr->current_floor_ptr->grid_array[ty][tx].m_idx = m_idx;
369                     m_ptr->fy = ty;
370                     m_ptr->fx = tx;
371
372                     update_monster(caster_ptr, m_idx, TRUE);
373                     lite_spot(caster_ptr, oy, ox);
374                     lite_spot(caster_ptr, ty, tx);
375
376                     if (r_info[m_ptr->r_idx].flags7 & (RF7_LITE_MASK | RF7_DARK_MASK))
377                         caster_ptr->update |= (PU_MON_LITE);
378                 }
379             }
380         }
381         break;
382
383     case 11:
384         if (name)
385             return _("刀匠の目利き", "Judge");
386         if (desc)
387             return _("武器・防具を1つ識別する。レベル45以上で武器・防具の能力を完全に知ることができる。",
388                 "Identifies a weapon or armor. *Identifies* the item at level 45.");
389
390         if (cast) {
391             if (plev > 44) {
392                 if (!identify_fully(caster_ptr, TRUE, 0))
393                     return NULL;
394             } else {
395                 if (!ident_spell(caster_ptr, TRUE, 0))
396                     return NULL;
397             }
398         }
399         break;
400
401     case 12:
402         if (name)
403             return _("破岩斬", "Rock Smash");
404         if (desc)
405             return _("岩を壊し、岩石系のモンスターに大ダメージを与える。", "Breaks rock or greatly damages a monster made of rocks.");
406
407         if (cast) {
408             POSITION y, x;
409
410             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
411                 return NULL;
412             if (dir == 5)
413                 return NULL;
414
415             y = caster_ptr->y + ddy[dir];
416             x = caster_ptr->x + ddx[dir];
417
418             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
419                 do_cmd_attack(caster_ptr, y, x, HISSATSU_HAGAN);
420
421             if (!cave_have_flag_bold(caster_ptr->current_floor_ptr, y, x, FF_HURT_ROCK))
422                 break;
423
424             /* Destroy the feature */
425             cave_alter_feat(caster_ptr, y, x, FF_HURT_ROCK);
426             caster_ptr->update |= (PU_FLOW);
427         }
428         break;
429
430     case 13:
431         if (name)
432             return _("乱れ雪月花", "Midare-Setsugekka");
433         if (desc)
434             return _("攻撃回数が増え、冷気耐性のないモンスターに大ダメージを与える。",
435                 "Attacks a monster with an increased number of attacks and more damage unless it has resistance to cold.");
436
437         if (cast) {
438             POSITION y, x;
439
440             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
441                 return NULL;
442             if (dir == 5)
443                 return NULL;
444
445             y = caster_ptr->y + ddy[dir];
446             x = caster_ptr->x + ddx[dir];
447
448             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
449                 do_cmd_attack(caster_ptr, y, x, HISSATSU_COLD);
450             else {
451                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
452                 return NULL;
453             }
454         }
455         break;
456
457     case 14:
458         if (name)
459             return _("急所突き", "Spot Aiming");
460         if (desc)
461             return _("モンスターを一撃で倒す攻撃を繰り出す。失敗すると1点しかダメージを与えられない。",
462                 "Attempts to kill a monster instantly. If that fails, causes only 1HP of damage.");
463
464         if (cast) {
465             POSITION y, x;
466
467             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
468                 return NULL;
469             if (dir == 5)
470                 return NULL;
471
472             y = caster_ptr->y + ddy[dir];
473             x = caster_ptr->x + ddx[dir];
474
475             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
476                 do_cmd_attack(caster_ptr, y, x, HISSATSU_KYUSHO);
477             else {
478                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
479                 return NULL;
480             }
481         }
482         break;
483
484     case 15:
485         if (name)
486             return _("魔神斬り", "Majingiri");
487         if (desc)
488             return _("会心の一撃で攻撃する。攻撃がかわされやすい。", "Attempts to attack with a critical hit, but this attack is easy to evade for a monster.");
489
490         if (cast) {
491             POSITION y, x;
492
493             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
494                 return NULL;
495             if (dir == 5)
496                 return NULL;
497
498             y = caster_ptr->y + ddy[dir];
499             x = caster_ptr->x + ddx[dir];
500
501             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
502                 do_cmd_attack(caster_ptr, y, x, HISSATSU_MAJIN);
503             else {
504                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
505                 return NULL;
506             }
507         }
508         break;
509
510     case 16:
511         if (name)
512             return _("捨て身", "Desperate Attack");
513         if (desc)
514             return _("強力な攻撃を繰り出す。次のターンまでの間、食らうダメージが増える。",
515                 "Attacks with all of your power, but all damage you take will be doubled for one turn.");
516
517         if (cast) {
518             POSITION y, x;
519
520             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
521                 return NULL;
522             if (dir == 5)
523                 return NULL;
524
525             y = caster_ptr->y + ddy[dir];
526             x = caster_ptr->x + ddx[dir];
527
528             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
529                 do_cmd_attack(caster_ptr, y, x, HISSATSU_SUTEMI);
530             else {
531                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
532                 return NULL;
533             }
534             caster_ptr->sutemi = TRUE;
535         }
536         break;
537
538     case 17:
539         if (name)
540             return _("雷撃鷲爪斬", "Lightning Eagle");
541         if (desc)
542             return _("電撃耐性のないモンスターに非常に大きいダメージを与える。", "Attacks a monster with more damage unless it has resistance to electricity.");
543
544         if (cast) {
545             POSITION y, x;
546
547             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
548                 return NULL;
549             if (dir == 5)
550                 return NULL;
551
552             y = caster_ptr->y + ddy[dir];
553             x = caster_ptr->x + ddx[dir];
554
555             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
556                 do_cmd_attack(caster_ptr, y, x, HISSATSU_ELEC);
557             else {
558                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
559                 return NULL;
560             }
561         }
562         break;
563
564     case 18:
565         if (name)
566             return _("入身", "Rush Attack");
567         if (desc)
568             return _("素早く相手に近寄り攻撃する。", "Steps close to a monster and attacks at the same time.");
569
570         if (cast) {
571             if (!rush_attack(caster_ptr, NULL))
572                 return NULL;
573         }
574         break;
575
576     case 19:
577         if (name)
578             return _("赤流渦", "Bloody Maelstrom");
579         if (desc)
580             return _("自分自身も傷を作りつつ、その傷が深いほど大きい威力で全方向の敵を攻撃できる。生きていないモンスターには効果がない。",
581                 "Attacks all adjacent monsters with power corresponding to your cuts. Then increases your cuts. Has no effect on unliving monsters.");
582
583         if (cast) {
584             POSITION y = 0, x = 0;
585
586             grid_type *g_ptr;
587             monster_type *m_ptr;
588
589             if (caster_ptr->cut < 300)
590                 set_cut(caster_ptr, caster_ptr->cut + 300);
591             else
592                 set_cut(caster_ptr, caster_ptr->cut * 2);
593
594             for (dir = 0; dir < 8; dir++) {
595                 y = caster_ptr->y + ddy_ddd[dir];
596                 x = caster_ptr->x + ddx_ddd[dir];
597                 g_ptr = &caster_ptr->current_floor_ptr->grid_array[y][x];
598                 m_ptr = &caster_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
599
600                 /* Hack -- attack monsters */
601                 if (g_ptr->m_idx && (m_ptr->ml || cave_have_flag_bold(caster_ptr->current_floor_ptr, y, x, FF_PROJECT))) {
602                     if (!monster_living(m_ptr->r_idx)) {
603                         GAME_TEXT m_name[MAX_NLEN];
604
605                         monster_desc(caster_ptr, m_name, m_ptr, 0);
606                         msg_format(_("%sには効果がない!", "%s is unharmed!"), m_name);
607                     } else
608                         do_cmd_attack(caster_ptr, y, x, HISSATSU_SEKIRYUKA);
609                 }
610             }
611         }
612         break;
613
614     case 20:
615         if (name)
616             return _("激震撃", "Earthquake Blow");
617         if (desc)
618             return _("地震を起こす。", "Shakes dungeon structure, and results in random swapping of floors and walls.");
619
620         if (cast) {
621             POSITION y, x;
622
623             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
624                 return NULL;
625             if (dir == 5)
626                 return NULL;
627
628             y = caster_ptr->y + ddy[dir];
629             x = caster_ptr->x + ddx[dir];
630
631             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
632                 do_cmd_attack(caster_ptr, y, x, HISSATSU_QUAKE);
633             else
634                 earthquake(caster_ptr, caster_ptr->y, caster_ptr->x, 10, 0);
635         }
636         break;
637
638     case 21:
639         if (name)
640             return _("地走り", "Crack");
641         if (desc)
642             return _("衝撃波のビームを放つ。", "Fires a shock wave as a beam.");
643
644         if (cast) {
645             int total_damage = 0, basedam, i;
646             BIT_FLAGS flgs[TR_FLAG_SIZE];
647             object_type *o_ptr;
648             if (!get_aim_dir(caster_ptr, &dir))
649                 return NULL;
650             msg_print(_("武器を大きく振り下ろした。", "You swing your weapon downward."));
651             for (i = 0; i < 2; i++) {
652                 int damage;
653
654                 if (!has_melee_weapon(caster_ptr, INVEN_RARM + i))
655                     break;
656                 o_ptr = &caster_ptr->inventory_list[INVEN_RARM + i];
657                 basedam = (o_ptr->dd * (o_ptr->ds + 1)) * 50;
658                 damage = o_ptr->to_d * 100;
659                 object_flags(caster_ptr, o_ptr, flgs);
660                 if ((o_ptr->name1 == ART_VORPAL_BLADE) || (o_ptr->name1 == ART_CHAINSWORD)) {
661                     /* vorpal blade */
662                     basedam *= 5;
663                     basedam /= 3;
664                 } else if (have_flag(flgs, TR_VORPAL)) {
665                     /* vorpal flag only */
666                     basedam *= 11;
667                     basedam /= 9;
668                 }
669                 damage += basedam;
670                 damage *= caster_ptr->num_blow[i];
671                 total_damage += damage / 200;
672                 if (i)
673                     total_damage = total_damage * 7 / 10;
674             }
675             fire_beam(caster_ptr, GF_FORCE, dir, total_damage);
676         }
677         break;
678
679     case 22:
680         if (name)
681             return _("気迫の雄叫び", "War Cry");
682         if (desc)
683             return _("視界内の全モンスターに対して轟音の攻撃を行う。さらに、近くにいるモンスターを怒らせる。",
684                 "Damages all monsters in sight with sound. Aggravates nearby monsters.");
685
686         if (cast) {
687             msg_print(_("雄叫びをあげた!", "You roar!"));
688             project_all_los(caster_ptr, GF_SOUND, randint1(plev * 3));
689             aggravate_monsters(caster_ptr, 0);
690         }
691         break;
692
693     case 23:
694         if (name)
695             return _("無双三段", "Musou-Sandan");
696         if (desc)
697             return _("強力な3段攻撃を繰り出す。", "Attacks with three powerful strikes.");
698
699         if (cast) {
700             int i;
701
702             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
703                 return NULL;
704             if (dir == 5)
705                 return NULL;
706
707             for (i = 0; i < 3; i++) {
708                 POSITION y, x;
709                 POSITION ny, nx;
710                 MONSTER_IDX m_idx;
711                 grid_type *g_ptr;
712                 monster_type *m_ptr;
713
714                 y = caster_ptr->y + ddy[dir];
715                 x = caster_ptr->x + ddx[dir];
716                 g_ptr = &caster_ptr->current_floor_ptr->grid_array[y][x];
717
718                 if (g_ptr->m_idx)
719                     do_cmd_attack(caster_ptr, y, x, HISSATSU_3DAN);
720                 else {
721                     msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
722                     return NULL;
723                 }
724
725                 if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_NO_MELEE) {
726                     return "";
727                 }
728
729                 /* Monster is dead? */
730                 if (!g_ptr->m_idx)
731                     break;
732
733                 ny = y + ddy[dir];
734                 nx = x + ddx[dir];
735                 m_idx = g_ptr->m_idx;
736                 m_ptr = &caster_ptr->current_floor_ptr->m_list[m_idx];
737
738                 /* Monster cannot move back? */
739                 if (!monster_can_enter(caster_ptr, ny, nx, &r_info[m_ptr->r_idx], 0)) {
740                     /* -more- */
741                     if (i < 2)
742                         msg_print(NULL);
743                     continue;
744                 }
745
746                 g_ptr->m_idx = 0;
747                 caster_ptr->current_floor_ptr->grid_array[ny][nx].m_idx = m_idx;
748                 m_ptr->fy = ny;
749                 m_ptr->fx = nx;
750
751                 update_monster(caster_ptr, m_idx, TRUE);
752
753                 /* Redraw the old spot */
754                 lite_spot(caster_ptr, y, x);
755
756                 /* Redraw the new spot */
757                 lite_spot(caster_ptr, ny, nx);
758
759                 /* Player can move forward? */
760                 if (player_can_enter(caster_ptr, g_ptr->feat, 0)) {
761                     if (!move_player_effect(caster_ptr, y, x, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP))
762                         break;
763                 } else {
764                     break;
765                 }
766
767                 /* -more- */
768                 if (i < 2)
769                     msg_print(NULL);
770             }
771         }
772         break;
773
774     case 24:
775         if (name)
776             return _("吸血鬼の牙", "Vampire's Fang");
777         if (desc)
778             return _("攻撃した相手の体力を吸いとり、自分の体力を回復させる。生命を持たないモンスターには通じない。",
779                 "Attacks with vampiric strikes which absorb HP from a monster and heal you. Has no effect on unliving monsters.");
780
781         if (cast) {
782             POSITION y, x;
783
784             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
785                 return NULL;
786             if (dir == 5)
787                 return NULL;
788
789             y = caster_ptr->y + ddy[dir];
790             x = caster_ptr->x + ddx[dir];
791
792             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
793                 do_cmd_attack(caster_ptr, y, x, HISSATSU_DRAIN);
794             else {
795                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
796                 return NULL;
797             }
798         }
799         break;
800
801     case 25:
802         if (name)
803             return _("幻惑", "Moon Dazzling");
804         if (desc)
805             return _("視界内の起きている全モンスターに朦朧、混乱、眠りを与えようとする。", "Attempts to stun, confuse and put to sleep all waking monsters.");
806
807         if (cast) {
808             msg_print(_("武器を不規則に揺らした...", "You irregularly wave your weapon..."));
809             project_all_los(caster_ptr, GF_ENGETSU, plev * 4);
810             project_all_los(caster_ptr, GF_ENGETSU, plev * 4);
811             project_all_los(caster_ptr, GF_ENGETSU, plev * 4);
812         }
813         break;
814
815     case 26:
816         if (name)
817             return _("百人斬り", "Hundred Slaughter");
818         if (desc)
819             return _("連続して入身でモンスターを攻撃する。攻撃するたびにMPを消費。MPがなくなるか、モンスターを倒せなかったら百人斬りは終了する。",
820                 "Performs a series of rush attacks. The series continues as long as the attacked monster dies and you have sufficient SP.");
821
822         if (cast) {
823             const int mana_cost_per_monster = 8;
824             bool is_new = TRUE;
825             bool mdeath;
826
827             do {
828                 if (!rush_attack(caster_ptr, &mdeath))
829                     break;
830                 if (is_new) {
831                     /* Reserve needed mana point */
832                     caster_ptr->csp -= technic_info[REALM_HISSATSU - MIN_TECHNIC][26].smana;
833                     is_new = FALSE;
834                 } else
835                     caster_ptr->csp -= mana_cost_per_monster;
836
837                 if (!mdeath)
838                     break;
839                 command_dir = 0;
840
841                 caster_ptr->redraw |= PR_MANA;
842                 handle_stuff(caster_ptr);
843             } while (caster_ptr->csp > mana_cost_per_monster);
844
845             if (is_new)
846                 return NULL;
847
848             /* Restore reserved mana */
849             caster_ptr->csp += technic_info[REALM_HISSATSU - MIN_TECHNIC][26].smana;
850         }
851         break;
852
853     case 27:
854         if (name)
855             return _("天翔龍閃", "Dragonic Flash");
856         if (desc)
857             return _("視界内の場所を指定して、その場所と自分の間にいる全モンスターを攻撃し、その場所に移動する。",
858                 "Runs toward given location while attacking all monsters on the path.");
859
860         if (cast) {
861             POSITION y, x;
862
863             if (!tgt_pt(caster_ptr, &x, &y))
864                 return NULL;
865
866             if (!cave_player_teleportable_bold(caster_ptr, y, x, TELEPORT_SPONTANEOUS) || (distance(y, x, caster_ptr->y, caster_ptr->x) > MAX_SIGHT / 2)
867                 || !projectable(caster_ptr, caster_ptr->y, caster_ptr->x, y, x)) {
868                 msg_print(_("失敗!", "You cannot move to that place!"));
869                 break;
870             }
871             if (caster_ptr->anti_tele) {
872                 msg_print(_("不思議な力がテレポートを防いだ!", "A mysterious force prevents you from teleporting!"));
873                 break;
874             }
875             project(caster_ptr, 0, 0, y, x, HISSATSU_ISSEN, GF_ATTACK, PROJECT_BEAM | PROJECT_KILL, -1);
876             teleport_player_to(caster_ptr, y, x, TELEPORT_SPONTANEOUS);
877         }
878         break;
879
880     case 28:
881         if (name)
882             return _("二重の剣撃", "Twin Slash");
883         if (desc)
884             return _("1ターンで2度攻撃を行う。", "double attacks at a time.");
885
886         if (cast) {
887             POSITION x, y;
888
889             if (!get_rep_dir(caster_ptr, &dir, FALSE))
890                 return NULL;
891
892             y = caster_ptr->y + ddy[dir];
893             x = caster_ptr->x + ddx[dir];
894
895             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx) {
896                 do_cmd_attack(caster_ptr, y, x, 0);
897                 if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx) {
898                     handle_stuff(caster_ptr);
899                     do_cmd_attack(caster_ptr, y, x, 0);
900                 }
901             } else {
902                 msg_print(_("その方向にはモンスターはいません。", "You don't see any monster in this direction"));
903                 return NULL;
904             }
905         }
906         break;
907
908     case 29:
909         if (name)
910             return _("虎伏絶刀勢", "Kofuku-Zettousei");
911         if (desc)
912             return _("強力な攻撃を行い、近くの場所にも効果が及ぶ。", "Performs a powerful attack which even affects nearby monsters.");
913
914         if (cast) {
915             int total_damage = 0, basedam, i;
916             POSITION y, x;
917             BIT_FLAGS flgs[TR_FLAG_SIZE];
918             object_type *o_ptr;
919
920             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
921                 return NULL;
922             if (dir == 5)
923                 return NULL;
924
925             y = caster_ptr->y + ddy[dir];
926             x = caster_ptr->x + ddx[dir];
927
928             if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_NO_MELEE) {
929                 msg_print(_("なぜか攻撃することができない。", "Something prevents you from attacking."));
930                 return "";
931             }
932             msg_print(_("武器を大きく振り下ろした。", "You swing your weapon downward."));
933             for (i = 0; i < 2; i++) {
934                 int damage;
935                 if (!has_melee_weapon(caster_ptr, INVEN_RARM + i))
936                     break;
937                 o_ptr = &caster_ptr->inventory_list[INVEN_RARM + i];
938                 basedam = (o_ptr->dd * (o_ptr->ds + 1)) * 50;
939                 damage = o_ptr->to_d * 100;
940                 object_flags(caster_ptr, o_ptr, flgs);
941                 if ((o_ptr->name1 == ART_VORPAL_BLADE) || (o_ptr->name1 == ART_CHAINSWORD)) {
942                     /* vorpal blade */
943                     basedam *= 5;
944                     basedam /= 3;
945                 } else if (have_flag(flgs, TR_VORPAL)) {
946                     /* vorpal flag only */
947                     basedam *= 11;
948                     basedam /= 9;
949                 }
950                 damage += basedam;
951                 damage += caster_ptr->to_d[i] * 100;
952                 damage *= caster_ptr->num_blow[i];
953                 total_damage += (damage / 100);
954             }
955             project(caster_ptr, 0, (cave_have_flag_bold(caster_ptr->current_floor_ptr, y, x, FF_PROJECT) ? 5 : 0), y, x, total_damage * 3 / 2, GF_METEOR,
956                 PROJECT_KILL | PROJECT_JUMP | PROJECT_ITEM, -1);
957         }
958         break;
959
960     case 30:
961         if (name)
962             return _("慶雲鬼忍剣", "Keiun-Kininken");
963         if (desc)
964             return _("自分もダメージをくらうが、相手に非常に大きなダメージを与える。アンデッドには特に効果がある。",
965                 "Attacks a monster with extremely powerful damage, but you also take some damage. Hurts an undead monster greatly.");
966
967         if (cast) {
968             POSITION y, x;
969
970             if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
971                 return NULL;
972             if (dir == 5)
973                 return NULL;
974
975             y = caster_ptr->y + ddy[dir];
976             x = caster_ptr->x + ddx[dir];
977
978             if (caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
979                 do_cmd_attack(caster_ptr, y, x, HISSATSU_UNDEAD);
980             else {
981                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
982                 return NULL;
983             }
984             take_hit(caster_ptr, DAMAGE_NOESCAPE, 100 + randint1(100), _("慶雲鬼忍剣を使った衝撃", "exhaustion on using Keiun-Kininken"), -1);
985         }
986         break;
987
988     case 31:
989         if (name)
990             return _("切腹", "Harakiri");
991         if (desc)
992             return _("「武士道とは、死ぬことと見つけたり。」", "'Bushido, the way of warriors, is found in death'");
993
994         if (cast) {
995             int i;
996             if (!get_check(_("本当に自殺しますか?", "Do you really want to commit suicide? ")))
997                 return NULL;
998             /* Special Verification for suicide */
999             prt(_("確認のため '@' を押して下さい。", "Please verify SUICIDE by typing the '@' sign: "), 0, 0);
1000
1001             flush();
1002             i = inkey();
1003             prt("", 0, 0);
1004             if (i != '@')
1005                 return NULL;
1006             if (current_world_ptr->total_winner) {
1007                 take_hit(caster_ptr, DAMAGE_FORCE, 9999, "Seppuku", -1);
1008                 current_world_ptr->total_winner = TRUE;
1009             } else {
1010                 msg_print(_("武士道とは、死ぬことと見つけたり。", "The meaning of bushido is found in death."));
1011                 take_hit(caster_ptr, DAMAGE_FORCE, 9999, "Seppuku", -1);
1012             }
1013         }
1014         break;
1015     }
1016
1017     return "";
1018 }