OSDN Git Service

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