OSDN Git Service

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