OSDN Git Service

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