OSDN Git Service

[Refactor] #37353 Separated hook-enchant.c/h from object-hook.c/h
[hengband/hengband.git] / src / spell / spells3.c
1 /*!
2  * @brief 魔法効果の実装/ Spell code (part 3)
3  * @date 2014/07/26
4  * @author
5  * <pre>
6  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
7  * This software may be copied and distributed for educational, research,
8  * and not for profit purposes provided that this copyright and statement
9  * are included in all such copies.  Other copyrights may also apply.
10  * </pre>
11  */
12
13 #include "spell/spells3.h"
14 #include "autopick/autopick.h"
15 #include "cmd-action/cmd-attack.h"
16 #include "cmd-action/cmd-spell.h"
17 #include "cmd-building/cmd-building.h"
18 #include "cmd-io/cmd-dump.h"
19 #include "core/asking-player.h"
20 #include "core/speed-table.h"
21 #include "core/stuff-handler.h"
22 #include "dungeon/dungeon.h"
23 #include "dungeon/quest.h"
24 #include "effect/effect-characteristics.h"
25 #include "effect/spells-effect-util.h"
26 #include "floor/floor-object.h"
27 #include "floor/floor-save.h"
28 #include "floor/floor-town.h"
29 #include "floor/wild.h"
30 #include "game-option/auto-destruction-options.h"
31 #include "game-option/birth-options.h"
32 #include "game-option/disturbance-options.h"
33 #include "game-option/input-options.h"
34 #include "game-option/play-record-options.h"
35 #include "grid/grid.h"
36 #include "inventory/inventory-object.h"
37 #include "inventory/player-inventory.h"
38 #include "io/input-key-acceptor.h"
39 #include "io/input-key-requester.h"
40 #include "io/targeting.h"
41 #include "io/write-diary.h"
42 #include "lore/lore-calculator.h"
43 #include "market/building-util.h"
44 #include "mind/mind-force-trainer.h"
45 #include "mind/mind-sniper.h"
46 #include "mind/mind.h"
47 #include "monster-floor/monster-generator.h"
48 #include "monster-floor/monster-remover.h"
49 #include "monster-floor/monster-summon.h"
50 #include "monster-floor/place-monster-types.h"
51 #include "monster-race/monster-race.h"
52 #include "monster-race/race-flags1.h"
53 #include "monster-race/race-flags7.h"
54 #include "monster/monster-describer.h"
55 #include "monster/monster-flag-types.h"
56 #include "monster/monster-info.h"
57 #include "monster/monster-list.h"
58 #include "monster/monster-processor.h"
59 #include "monster/monster-status.h"
60 #include "monster/monster-update.h"
61 #include "monster/monster-util.h"
62 #include "object-enchant/artifact.h"
63 #include "object-enchant/item-feeling.h"
64 #include "object-enchant/object-boost.h"
65 #include "object-enchant/object-ego.h"
66 #include "object-enchant/special-object-flags.h"
67 #include "object-enchant/tr-types.h"
68 #include "object-enchant/trc-types.h"
69 #include "object-hook/hook-enchant.h"
70 #include "object-hook/hook-expendable.h"
71 #include "object-hook/hook-perception.h"
72 #include "object-hook/hook-magic.h"
73 #include "object-hook/hook-weapon.h"
74 #include "object/item-use-flags.h"
75 #include "object/object-flavor.h"
76 #include "object/object-generator.h"
77 #include "object/object-hook.h"
78 #include "object/object-info.h"
79 #include "object/object-kind.h"
80 #include "object/object-mark-types.h"
81 #include "object/object-value.h"
82 #include "perception/identification.h"
83 #include "perception/object-perception.h"
84 #include "player/avatar.h"
85 #include "player/bad-status-setter.h"
86 #include "player/player-class.h"
87 #include "player/player-damage.h"
88 #include "player/player-effects.h"
89 #include "player/player-move.h"
90 #include "player/player-personalities-types.h"
91 #include "player/player-skill.h"
92 #include "player/player-status.h"
93 #include "realm/realm-names-table.h"
94 #include "spell-kind/earthquake.h"
95 #include "spell-kind/spells-floor.h"
96 #include "spell-kind/spells-launcher.h"
97 #include "spell-kind/spells-sight.h"
98 #include "spell-kind/spells-teleport.h"
99 #include "spell/process-effect.h"
100 #include "spell/spell-types.h"
101 #include "spell/spells-execution.h"
102 #include "spell/spells-summon.h"
103 #include "spell/technic-info-table.h"
104 #include "term/screen-processor.h"
105 #include "term/term-color-types.h"
106 #include "util/bit-flags-calculator.h"
107 #include "util/int-char-converter.h"
108 #include "view/display-messages.h"
109 #include "world/world.h"
110
111 /*!
112  * @brief プレイヤーの装備劣化処理 /
113  * Apply disenchantment to the player's stuff
114  * @param target_ptr プレーヤーへの参照ポインタ
115  * @param mode 最下位ビットが1ならば劣化処理が若干低減される
116  * @return 劣化処理に関するメッセージが発せられた場合はTRUEを返す /
117  * Return "TRUE" if the player notices anything
118  */
119 bool apply_disenchant(player_type *target_ptr, BIT_FLAGS mode)
120 {
121     int t = 0;
122     switch (randint1(8)) {
123     case 1:
124         t = INVEN_RARM;
125         break;
126     case 2:
127         t = INVEN_LARM;
128         break;
129     case 3:
130         t = INVEN_BOW;
131         break;
132     case 4:
133         t = INVEN_BODY;
134         break;
135     case 5:
136         t = INVEN_OUTER;
137         break;
138     case 6:
139         t = INVEN_HEAD;
140         break;
141     case 7:
142         t = INVEN_HANDS;
143         break;
144     case 8:
145         t = INVEN_FEET;
146         break;
147     }
148
149     object_type *o_ptr;
150     o_ptr = &target_ptr->inventory_list[t];
151     if (!o_ptr->k_idx)
152         return FALSE;
153
154     if (!object_is_weapon_armour_ammo(target_ptr, o_ptr))
155         return FALSE;
156
157     if ((o_ptr->to_h <= 0) && (o_ptr->to_d <= 0) && (o_ptr->to_a <= 0) && (o_ptr->pval <= 1)) {
158         return FALSE;
159     }
160
161     GAME_TEXT o_name[MAX_NLEN];
162     object_desc(target_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
163     if (object_is_artifact(o_ptr) && (randint0(100) < 71)) {
164 #ifdef JP
165         msg_format("%s(%c)は劣化を跳ね返した!", o_name, index_to_label(t));
166 #else
167         msg_format("Your %s (%c) resist%s disenchantment!", o_name, index_to_label(t), ((o_ptr->number != 1) ? "" : "s"));
168 #endif
169         return TRUE;
170     }
171
172     int to_h = o_ptr->to_h;
173     int to_d = o_ptr->to_d;
174     int to_a = o_ptr->to_a;
175     int pval = o_ptr->pval;
176
177     if (o_ptr->to_h > 0)
178         o_ptr->to_h--;
179     if ((o_ptr->to_h > 5) && (randint0(100) < 20))
180         o_ptr->to_h--;
181
182     if (o_ptr->to_d > 0)
183         o_ptr->to_d--;
184     if ((o_ptr->to_d > 5) && (randint0(100) < 20))
185         o_ptr->to_d--;
186
187     if (o_ptr->to_a > 0)
188         o_ptr->to_a--;
189     if ((o_ptr->to_a > 5) && (randint0(100) < 20))
190         o_ptr->to_a--;
191
192     if ((o_ptr->pval > 1) && one_in_(13) && !(mode & 0x01))
193         o_ptr->pval--;
194
195     bool is_actually_disenchanted = to_h != o_ptr->to_h;
196     is_actually_disenchanted |= to_d != o_ptr->to_d;
197     is_actually_disenchanted |= to_a != o_ptr->to_a;
198     is_actually_disenchanted |= pval != o_ptr->pval;
199     if (!is_actually_disenchanted)
200         return TRUE;
201
202 #ifdef JP
203     msg_format("%s(%c)は劣化してしまった!", o_name, index_to_label(t));
204 #else
205     msg_format("Your %s (%c) %s disenchanted!", o_name, index_to_label(t), ((o_ptr->number != 1) ? "were" : "was"));
206 #endif
207     chg_virtue(target_ptr, V_HARMONY, 1);
208     chg_virtue(target_ptr, V_ENCHANT, -2);
209     target_ptr->update |= (PU_BONUS);
210     target_ptr->window |= (PW_EQUIP | PW_PLAYER);
211
212     calc_android_exp(target_ptr);
213     return TRUE;
214 }
215
216 /*!
217  * @brief アイテム引き寄せ処理 /
218  * Fetch an item (teleport it right underneath the caster)
219  * @param caster_ptr プレーヤーへの参照ポインタ
220  * @param dir 魔法の発動方向
221  * @param wgt 許容重量
222  * @param require_los 射線の通りを要求するならばTRUE
223  * @return なし
224  */
225 void fetch(player_type *caster_ptr, DIRECTION dir, WEIGHT wgt, bool require_los)
226 {
227     grid_type *g_ptr;
228     object_type *o_ptr;
229     GAME_TEXT o_name[MAX_NLEN];
230
231     if (caster_ptr->current_floor_ptr->grid_array[caster_ptr->y][caster_ptr->x].o_idx) {
232         msg_print(_("自分の足の下にある物は取れません。", "You can't fetch when you're already standing on something."));
233         return;
234     }
235
236     POSITION ty, tx;
237     if (dir == 5 && target_okay(caster_ptr)) {
238         tx = target_col;
239         ty = target_row;
240
241         if (distance(caster_ptr->y, caster_ptr->x, ty, tx) > get_max_range(caster_ptr)) {
242             msg_print(_("そんなに遠くにある物は取れません!", "You can't fetch something that far away!"));
243             return;
244         }
245
246         g_ptr = &caster_ptr->current_floor_ptr->grid_array[ty][tx];
247         if (!g_ptr->o_idx) {
248             msg_print(_("そこには何もありません。", "There is no object at this place."));
249             return;
250         }
251
252         if (g_ptr->info & CAVE_ICKY) {
253             msg_print(_("アイテムがコントロールを外れて落ちた。", "The item slips from your control."));
254             return;
255         }
256
257         if (require_los) {
258             if (!player_has_los_bold(caster_ptr, ty, tx)) {
259                 msg_print(_("そこはあなたの視界に入っていません。", "You have no direct line of sight to that location."));
260                 return;
261             } else if (!projectable(caster_ptr, caster_ptr->y, caster_ptr->x, ty, tx)) {
262                 msg_print(_("そこは壁の向こうです。", "You have no direct line of sight to that location."));
263                 return;
264             }
265         }
266     } else {
267         ty = caster_ptr->y;
268         tx = caster_ptr->x;
269         bool is_first_loop = TRUE;
270         g_ptr = &caster_ptr->current_floor_ptr->grid_array[ty][tx];
271         while (is_first_loop || !g_ptr->o_idx) {
272             is_first_loop = FALSE;
273             ty += ddy[dir];
274             tx += ddx[dir];
275             g_ptr = &caster_ptr->current_floor_ptr->grid_array[ty][tx];
276
277             if ((distance(caster_ptr->y, caster_ptr->x, ty, tx) > get_max_range(caster_ptr))
278                 || !cave_have_flag_bold(caster_ptr->current_floor_ptr, ty, tx, FF_PROJECT))
279                 return;
280         }
281     }
282
283     o_ptr = &caster_ptr->current_floor_ptr->o_list[g_ptr->o_idx];
284     if (o_ptr->weight > wgt) {
285         msg_print(_("そのアイテムは重過ぎます。", "The object is too heavy."));
286         return;
287     }
288
289     OBJECT_IDX i = g_ptr->o_idx;
290     g_ptr->o_idx = o_ptr->next_o_idx;
291     caster_ptr->current_floor_ptr->grid_array[caster_ptr->y][caster_ptr->x].o_idx = i; /* 'move' it */
292
293     o_ptr->next_o_idx = 0;
294     o_ptr->iy = caster_ptr->y;
295     o_ptr->ix = caster_ptr->x;
296
297     object_desc(caster_ptr, o_name, o_ptr, OD_NAME_ONLY);
298     msg_format(_("%^sがあなたの足元に飛んできた。", "%^s flies through the air to your feet."), o_name);
299
300     note_spot(caster_ptr, caster_ptr->y, caster_ptr->x);
301     caster_ptr->redraw |= PR_MAP;
302 }
303
304 /*!
305  * @brief 現実変容処理
306  * @param caster_ptr プレーヤーへの参照ポインタ
307  * @return なし
308  */
309 void reserve_alter_reality(player_type *caster_ptr)
310 {
311     if (caster_ptr->current_floor_ptr->inside_arena || ironman_downward) {
312         msg_print(_("何も起こらなかった。", "Nothing happens."));
313         return;
314     }
315
316     if (caster_ptr->alter_reality) {
317         caster_ptr->alter_reality = 0;
318         msg_print(_("景色が元に戻った...", "The view around you returns to normal..."));
319         caster_ptr->redraw |= PR_STATUS;
320         return;
321     }
322
323     TIME_EFFECT turns = randint0(21) + 15;
324     caster_ptr->alter_reality = turns;
325     msg_print(_("回りの景色が変わり始めた...", "The view around you begins to change..."));
326     caster_ptr->redraw |= PR_STATUS;
327 }
328
329 /*!
330  * @brief アイテムの価値に応じた錬金術処理 /
331  * Turns an object into gold, gain some of its value in a shop
332  * @param caster_ptr プレーヤーへの参照ポインタ
333  * @return 処理が実際に行われたらTRUEを返す
334  */
335 bool alchemy(player_type *caster_ptr)
336 {
337     bool force = FALSE;
338     if (command_arg > 0)
339         force = TRUE;
340
341     concptr q = _("どのアイテムを金に変えますか?", "Turn which item to gold? ");
342     concptr s = _("金に変えられる物がありません。", "You have nothing to turn to gold.");
343     OBJECT_IDX item;
344     object_type *o_ptr;
345     o_ptr = choose_object(caster_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), 0);
346     if (!o_ptr)
347         return FALSE;
348
349     int amt = 1;
350     if (o_ptr->number > 1) {
351         amt = get_quantity(NULL, o_ptr->number);
352         if (amt <= 0)
353             return FALSE;
354     }
355
356     ITEM_NUMBER old_number = o_ptr->number;
357     o_ptr->number = amt;
358     GAME_TEXT o_name[MAX_NLEN];
359     object_desc(caster_ptr, o_name, o_ptr, 0);
360     o_ptr->number = old_number;
361
362     if (!force) {
363         if (confirm_destroy || (object_value(caster_ptr, o_ptr) > 0)) {
364             char out_val[MAX_NLEN + 40];
365             sprintf(out_val, _("本当に%sを金に変えますか?", "Really turn %s to gold? "), o_name);
366             if (!get_check(out_val))
367                 return FALSE;
368         }
369     }
370
371     if (!can_player_destroy_object(caster_ptr, o_ptr)) {
372         msg_format(_("%sを金に変えることに失敗した。", "You fail to turn %s to gold!"), o_name);
373         return FALSE;
374     }
375
376     PRICE price = object_value_real(caster_ptr, o_ptr);
377     if (price <= 0) {
378         msg_format(_("%sをニセの金に変えた。", "You turn %s to fool's gold."), o_name);
379         vary_item(caster_ptr, item, -amt);
380         return TRUE;
381     }
382
383     price /= 3;
384
385     if (amt > 1)
386         price *= amt;
387
388     if (price > 30000)
389         price = 30000;
390     msg_format(_("%sを$%d の金に変えた。", "You turn %s to %ld coins worth of gold."), o_name, price);
391
392     caster_ptr->au += price;
393     caster_ptr->redraw |= PR_GOLD;
394     caster_ptr->window |= PW_PLAYER;
395     vary_item(caster_ptr, item, -amt);
396     return TRUE;
397 }
398
399 /*!
400  * @brief アーティファクト生成の巻物処理 /
401  * @param caster_ptr プレーヤーへの参照ポインタ
402  * @return 生成が実際に試みられたらTRUEを返す
403  */
404 bool artifact_scroll(player_type *caster_ptr)
405 {
406     item_tester_hook = item_tester_hook_nameless_weapon_armour;
407
408     concptr q = _("どのアイテムを強化しますか? ", "Enchant which item? ");
409     concptr s = _("強化できるアイテムがない。", "You have nothing to enchant.");
410     object_type *o_ptr;
411     OBJECT_IDX item;
412     o_ptr = choose_object(caster_ptr, &item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT), 0);
413     if (!o_ptr)
414         return FALSE;
415
416     GAME_TEXT o_name[MAX_NLEN];
417     object_desc(caster_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
418 #ifdef JP
419     msg_format("%s は眩い光を発した!", o_name);
420 #else
421     msg_format("%s %s radiate%s a blinding light!", ((item >= 0) ? "Your" : "The"), o_name, ((o_ptr->number > 1) ? "" : "s"));
422 #endif
423
424     bool okay = FALSE;
425     if (object_is_artifact(o_ptr)) {
426 #ifdef JP
427         msg_format("%sは既に伝説のアイテムです!", o_name);
428 #else
429         msg_format("The %s %s already %s!", o_name, ((o_ptr->number > 1) ? "are" : "is"), ((o_ptr->number > 1) ? "artifacts" : "an artifact"));
430 #endif
431         okay = FALSE;
432     } else if (object_is_ego(o_ptr)) {
433 #ifdef JP
434         msg_format("%sは既に名のあるアイテムです!", o_name);
435 #else
436         msg_format("The %s %s already %s!", o_name, ((o_ptr->number > 1) ? "are" : "is"), ((o_ptr->number > 1) ? "ego items" : "an ego item"));
437 #endif
438         okay = FALSE;
439     } else if (o_ptr->xtra3) {
440 #ifdef JP
441         msg_format("%sは既に強化されています!", o_name);
442 #else
443         msg_format("The %s %s already %s!", o_name, ((o_ptr->number > 1) ? "are" : "is"), ((o_ptr->number > 1) ? "customized items" : "a customized item"));
444 #endif
445     } else {
446         if (o_ptr->number > 1) {
447             msg_print(_("複数のアイテムに魔法をかけるだけのエネルギーはありません!", "Not enough energy to enchant more than one object!"));
448 #ifdef JP
449             msg_format("%d 個の%sが壊れた!", (o_ptr->number) - 1, o_name);
450 #else
451             msg_format("%d of your %s %s destroyed!", (o_ptr->number) - 1, o_name, (o_ptr->number > 2 ? "were" : "was"));
452 #endif
453
454             if (item >= 0) {
455                 inven_item_increase(caster_ptr, item, 1 - (o_ptr->number));
456             } else {
457                 floor_item_increase(caster_ptr->current_floor_ptr, 0 - item, 1 - (o_ptr->number));
458             }
459         }
460
461         okay = become_random_artifact(caster_ptr, o_ptr, TRUE);
462     }
463
464     if (!okay) {
465         if (flush_failure)
466             flush();
467         msg_print(_("強化に失敗した。", "The enchantment failed."));
468         if (one_in_(3))
469             chg_virtue(caster_ptr, V_ENCHANT, -1);
470         calc_android_exp(caster_ptr);
471         return TRUE;
472     }
473
474     if (record_rand_art) {
475         object_desc(caster_ptr, o_name, o_ptr, OD_NAME_ONLY);
476         exe_write_diary(caster_ptr, DIARY_ART_SCROLL, 0, o_name);
477     }
478
479     chg_virtue(caster_ptr, V_ENCHANT, 1);
480     calc_android_exp(caster_ptr);
481     return TRUE;
482 }
483
484 /*!
485  * @brief アイテム凡庸化のメインルーチン処理 /
486  * Identify an object in the inventory (or on the floor)
487  * @param owner_ptr プレーヤーへの参照ポインタ
488  * @param only_equip 装備品のみを対象とするならばTRUEを返す
489  * @return 実際に凡庸化をを行ったならばTRUEを返す
490  * @details
491  * <pre>
492  * Mundanify an object in the inventory (or on the floor)
493  * This routine does *not* automatically combine objects.
494  * Returns TRUE if something was mundanified, else FALSE.
495  * </pre>
496  */
497 bool mundane_spell(player_type *owner_ptr, bool only_equip)
498 {
499     if (only_equip)
500         item_tester_hook = object_is_weapon_armour_ammo;
501
502     OBJECT_IDX item;
503     object_type *o_ptr;
504     concptr q = _("どれを使いますか?", "Use which item? ");
505     concptr s = _("使えるものがありません。", "You have nothing you can use.");
506
507     o_ptr = choose_object(owner_ptr, &item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT), 0);
508     if (!o_ptr)
509         return FALSE;
510
511     msg_print(_("まばゆい閃光が走った!", "There is a bright flash of light!"));
512     POSITION iy = o_ptr->iy;
513     POSITION ix = o_ptr->ix;
514     OBJECT_IDX next_o_idx = o_ptr->next_o_idx;
515     byte marked = o_ptr->marked;
516     WEIGHT weight = o_ptr->number * o_ptr->weight;
517     u16b inscription = o_ptr->inscription;
518
519     object_prep(owner_ptr, o_ptr, o_ptr->k_idx);
520
521     o_ptr->iy = iy;
522     o_ptr->ix = ix;
523     o_ptr->next_o_idx = next_o_idx;
524     o_ptr->marked = marked;
525     o_ptr->inscription = inscription;
526     if (item >= 0)
527         owner_ptr->total_weight += (o_ptr->weight - weight);
528
529     calc_android_exp(owner_ptr);
530     return TRUE;
531 }
532
533 /*!
534  * @brief 魔力充填処理 /
535  * Recharge a wand/staff/rod from the pack or on the floor.
536  * This function has been rewritten in Oangband and ZAngband.
537  * @param caster_ptr プレーヤーへの参照ポインタ
538  * @param power 充填パワー
539  * @return ターン消費を要する処理まで進んだらTRUEを返す
540  *
541  * Sorcery/Arcane -- Recharge  --> recharge(plev * 4)
542  * Chaos -- Arcane Binding     --> recharge(90)
543  *
544  * Scroll of recharging        --> recharge(130)
545  * Artifact activation/Thingol --> recharge(130)
546  *
547  * It is harder to recharge high level, and highly charged wands,
548  * staffs, and rods.  The more wands in a stack, the more easily and
549  * strongly they recharge.  Staffs, however, each get fewer charges if
550  * stacked.
551  *
552  * Beware of "sliding index errors".
553  */
554 bool recharge(player_type *caster_ptr, int power)
555 {
556     item_tester_hook = item_tester_hook_recharge;
557     concptr q = _("どのアイテムに魔力を充填しますか? ", "Recharge which item? ");
558     concptr s = _("魔力を充填すべきアイテムがない。", "You have nothing to recharge.");
559
560     OBJECT_IDX item;
561     object_type *o_ptr;
562     o_ptr = choose_object(caster_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), 0);
563     if (!o_ptr)
564         return FALSE;
565
566     object_kind *k_ptr;
567     k_ptr = &k_info[o_ptr->k_idx];
568     DEPTH lev = k_info[o_ptr->k_idx].level;
569
570     TIME_EFFECT recharge_amount;
571     int recharge_strength;
572     bool is_recharge_successful = TRUE;
573     if (o_ptr->tval == TV_ROD) {
574         recharge_strength = ((power > lev / 2) ? (power - lev / 2) : 0) / 5;
575         if (one_in_(recharge_strength)) {
576             is_recharge_successful = FALSE;
577         } else {
578             recharge_amount = (power * damroll(3, 2));
579             if (o_ptr->timeout > recharge_amount)
580                 o_ptr->timeout -= recharge_amount;
581             else
582                 o_ptr->timeout = 0;
583         }
584     } else {
585         if ((o_ptr->tval == TV_WAND) && (o_ptr->number > 1))
586             recharge_strength = (100 + power - lev - (8 * o_ptr->pval / o_ptr->number)) / 15;
587         else
588             recharge_strength = (100 + power - lev - (8 * o_ptr->pval)) / 15;
589
590         if (recharge_strength < 0)
591             recharge_strength = 0;
592
593         if (one_in_(recharge_strength)) {
594             is_recharge_successful = FALSE;
595         } else {
596             recharge_amount = randint1(1 + k_ptr->pval / 2);
597             if ((o_ptr->tval == TV_WAND) && (o_ptr->number > 1)) {
598                 recharge_amount += (randint1(recharge_amount * (o_ptr->number - 1))) / 2;
599                 if (recharge_amount < 1)
600                     recharge_amount = 1;
601                 if (recharge_amount > 12)
602                     recharge_amount = 12;
603             }
604
605             if ((o_ptr->tval == TV_STAFF) && (o_ptr->number > 1)) {
606                 recharge_amount /= (TIME_EFFECT)o_ptr->number;
607                 if (recharge_amount < 1)
608                     recharge_amount = 1;
609             }
610
611             o_ptr->pval += recharge_amount;
612             o_ptr->ident &= ~(IDENT_KNOWN);
613             o_ptr->ident &= ~(IDENT_EMPTY);
614         }
615     }
616
617     if (!is_recharge_successful) {
618         return update_player(caster_ptr);
619     }
620
621     byte fail_type = 1;
622     GAME_TEXT o_name[MAX_NLEN];
623     if (object_is_fixed_artifact(o_ptr)) {
624         object_desc(caster_ptr, o_name, o_ptr, OD_NAME_ONLY);
625         msg_format(_("魔力が逆流した!%sは完全に魔力を失った。", "The recharging backfires - %s is completely drained!"), o_name);
626         if ((o_ptr->tval == TV_ROD) && (o_ptr->timeout < 10000))
627             o_ptr->timeout = (o_ptr->timeout + 100) * 2;
628         else if ((o_ptr->tval == TV_WAND) || (o_ptr->tval == TV_STAFF))
629             o_ptr->pval = 0;
630         return update_player(caster_ptr);
631     }
632
633     object_desc(caster_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
634
635     if (IS_WIZARD_CLASS(caster_ptr) || caster_ptr->pclass == CLASS_MAGIC_EATER || caster_ptr->pclass == CLASS_BLUE_MAGE) {
636         /* 10% chance to blow up one rod, otherwise draining. */
637         if (o_ptr->tval == TV_ROD) {
638             if (one_in_(10))
639                 fail_type = 2;
640             else
641                 fail_type = 1;
642         }
643         /* 75% chance to blow up one wand, otherwise draining. */
644         else if (o_ptr->tval == TV_WAND) {
645             if (!one_in_(3))
646                 fail_type = 2;
647             else
648                 fail_type = 1;
649         }
650         /* 50% chance to blow up one staff, otherwise no effect. */
651         else if (o_ptr->tval == TV_STAFF) {
652             if (one_in_(2))
653                 fail_type = 2;
654             else
655                 fail_type = 0;
656         }
657     } else {
658         /* 33% chance to blow up one rod, otherwise draining. */
659         if (o_ptr->tval == TV_ROD) {
660             if (one_in_(3))
661                 fail_type = 2;
662             else
663                 fail_type = 1;
664         }
665         /* 20% chance of the entire stack, else destroy one wand. */
666         else if (o_ptr->tval == TV_WAND) {
667             if (one_in_(5))
668                 fail_type = 3;
669             else
670                 fail_type = 2;
671         }
672         /* Blow up one staff. */
673         else if (o_ptr->tval == TV_STAFF) {
674             fail_type = 2;
675         }
676     }
677
678     if (fail_type == 1) {
679         if (o_ptr->tval == TV_ROD) {
680             msg_print(_("魔力が逆噴射して、ロッドからさらに魔力を吸い取ってしまった!", "The recharge backfires, draining the rod further!"));
681
682             if (o_ptr->timeout < 10000)
683                 o_ptr->timeout = (o_ptr->timeout + 100) * 2;
684         } else if (o_ptr->tval == TV_WAND) {
685             msg_format(_("%sは破損を免れたが、魔力が全て失われた。", "You save your %s from destruction, but all charges are lost."), o_name);
686             o_ptr->pval = 0;
687         }
688     }
689
690     if (fail_type == 2) {
691         if (o_ptr->number > 1)
692             msg_format(_("乱暴な魔法のために%sが一本壊れた!", "Wild magic consumes one of your %s!"), o_name);
693         else
694             msg_format(_("乱暴な魔法のために%sが壊れた!", "Wild magic consumes your %s!"), o_name);
695
696         if (o_ptr->tval == TV_ROD)
697             o_ptr->timeout = (o_ptr->number - 1) * k_ptr->pval;
698         if (o_ptr->tval == TV_WAND)
699             o_ptr->pval = 0;
700
701         vary_item(caster_ptr, item, -1);
702     }
703
704     if (fail_type == 3) {
705         if (o_ptr->number > 1)
706             msg_format(_("乱暴な魔法のために%sが全て壊れた!", "Wild magic consumes all your %s!"), o_name);
707         else
708             msg_format(_("乱暴な魔法のために%sが壊れた!", "Wild magic consumes your %s!"), o_name);
709
710         vary_item(caster_ptr, item, -999);
711     }
712
713     return update_player(caster_ptr);
714 }
715
716 /*!
717  * @brief クリーチャー全既知呪文を表示する /
718  * Hack -- Display all known spells in a window
719  * @param caster_ptr 術者の参照ポインタ
720  * return なし
721  * @details
722  * Need to analyze size of the window.
723  * Need more color coding.
724  */
725 void display_spell_list(player_type *caster_ptr)
726 {
727     TERM_LEN y, x;
728     int m[9];
729     const magic_type *s_ptr;
730     GAME_TEXT name[MAX_NLEN];
731     char out_val[160];
732
733     clear_from(0);
734
735     if (caster_ptr->pclass == CLASS_SORCERER)
736         return;
737     if (caster_ptr->pclass == CLASS_RED_MAGE)
738         return;
739     if (caster_ptr->pclass == CLASS_SNIPER) {
740         display_snipe_list(caster_ptr);
741         return;
742     }
743
744     if ((caster_ptr->pclass == CLASS_MINDCRAFTER) || (caster_ptr->pclass == CLASS_BERSERKER) || (caster_ptr->pclass == CLASS_NINJA)
745         || (caster_ptr->pclass == CLASS_MIRROR_MASTER) || (caster_ptr->pclass == CLASS_FORCETRAINER)) {
746         PERCENTAGE minfail = 0;
747         PLAYER_LEVEL plev = caster_ptr->lev;
748         PERCENTAGE chance = 0;
749         mind_type spell;
750         char comment[80];
751         char psi_desc[80];
752         int use_mind;
753         bool use_hp = FALSE;
754
755         y = 1;
756         x = 1;
757
758         prt("", y, x);
759         put_str(_("名前", "Name"), y, x + 5);
760         put_str(_("Lv   MP 失率 効果", "Lv Mana Fail Info"), y, x + 35);
761
762         switch (caster_ptr->pclass) {
763         case CLASS_MINDCRAFTER:
764             use_mind = MIND_MINDCRAFTER;
765             break;
766         case CLASS_FORCETRAINER:
767             use_mind = MIND_KI;
768             break;
769         case CLASS_BERSERKER:
770             use_mind = MIND_BERSERKER;
771             use_hp = TRUE;
772             break;
773         case CLASS_MIRROR_MASTER:
774             use_mind = MIND_MIRROR_MASTER;
775             break;
776         case CLASS_NINJA:
777             use_mind = MIND_NINJUTSU;
778             use_hp = TRUE;
779             break;
780         default:
781             use_mind = 0;
782             break;
783         }
784
785         for (int i = 0; i < MAX_MIND_POWERS; i++) {
786             byte a = TERM_WHITE;
787             spell = mind_powers[use_mind].info[i];
788             if (spell.min_lev > plev)
789                 break;
790
791             chance = spell.fail;
792             chance -= 3 * (caster_ptr->lev - spell.min_lev);
793             chance -= 3 * (adj_mag_stat[caster_ptr->stat_ind[mp_ptr->spell_stat]] - 1);
794             if (!use_hp) {
795                 if (spell.mana_cost > caster_ptr->csp) {
796                     chance += 5 * (spell.mana_cost - caster_ptr->csp);
797                     a = TERM_ORANGE;
798                 }
799             } else {
800                 if (spell.mana_cost > caster_ptr->chp) {
801                     chance += 100;
802                     a = TERM_RED;
803                 }
804             }
805
806             minfail = adj_mag_fail[caster_ptr->stat_ind[mp_ptr->spell_stat]];
807             if (chance < minfail)
808                 chance = minfail;
809
810             if (caster_ptr->stun > 50)
811                 chance += 25;
812             else if (caster_ptr->stun)
813                 chance += 15;
814
815             if (chance > 95)
816                 chance = 95;
817
818             mindcraft_info(caster_ptr, comment, use_mind, i);
819             sprintf(psi_desc, "  %c) %-30s%2d %4d %3d%%%s", I2A(i), spell.name, spell.min_lev, spell.mana_cost, chance, comment);
820
821             Term_putstr(x, y + i + 1, -1, a, psi_desc);
822         }
823
824         return;
825     }
826
827     if (REALM_NONE == caster_ptr->realm1)
828         return;
829
830     for (int j = 0; j < ((caster_ptr->realm2 > REALM_NONE) ? 2 : 1); j++) {
831         m[j] = 0;
832         y = (j < 3) ? 0 : (m[j - 3] + 2);
833         x = 27 * (j % 3);
834         int n = 0;
835         for (int i = 0; i < 32; i++) {
836             byte a = TERM_WHITE;
837
838             if (!is_magic((j < 1) ? caster_ptr->realm1 : caster_ptr->realm2)) {
839                 s_ptr = &technic_info[((j < 1) ? caster_ptr->realm1 : caster_ptr->realm2) - MIN_TECHNIC][i % 32];
840             } else {
841                 s_ptr = &mp_ptr->info[((j < 1) ? caster_ptr->realm1 : caster_ptr->realm2) - 1][i % 32];
842             }
843
844             strcpy(name, exe_spell(caster_ptr, (j < 1) ? caster_ptr->realm1 : caster_ptr->realm2, i % 32, SPELL_NAME));
845
846             if (s_ptr->slevel >= 99) {
847                 strcpy(name, _("(判読不能)", "(illegible)"));
848                 a = TERM_L_DARK;
849             } else if ((j < 1) ? ((caster_ptr->spell_forgotten1 & (1L << i))) : ((caster_ptr->spell_forgotten2 & (1L << (i % 32))))) {
850                 a = TERM_ORANGE;
851             } else if (!((j < 1) ? (caster_ptr->spell_learned1 & (1L << i)) : (caster_ptr->spell_learned2 & (1L << (i % 32))))) {
852                 a = TERM_RED;
853             } else if (!((j < 1) ? (caster_ptr->spell_worked1 & (1L << i)) : (caster_ptr->spell_worked2 & (1L << (i % 32))))) {
854                 a = TERM_YELLOW;
855             }
856
857             sprintf(out_val, "%c/%c) %-20.20s", I2A(n / 8), I2A(n % 8), name);
858
859             m[j] = y + n;
860             Term_putstr(x, m[j], -1, a, out_val);
861             n++;
862         }
863     }
864 }
865
866 /*!
867  * @brief 変身処理向けにモンスターの近隣レベル帯モンスターを返す /
868  * Helper function -- return a "nearby" race for polymorphing
869  * @param floor_ptr 配置するフロアの参照ポインタ
870  * @param r_idx 基準となるモンスター種族ID
871  * @return 変更先のモンスター種族ID
872  * @details
873  * Note that this function is one of the more "dangerous" ones...
874  */
875 static MONRACE_IDX poly_r_idx(player_type *caster_ptr, MONRACE_IDX r_idx)
876 {
877     monster_race *r_ptr = &r_info[r_idx];
878     if ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags1 & RF1_QUESTOR))
879         return (r_idx);
880
881     DEPTH lev1 = r_ptr->level - ((randint1(20) / randint1(9)) + 1);
882     DEPTH lev2 = r_ptr->level + ((randint1(20) / randint1(9)) + 1);
883     MONRACE_IDX r;
884     for (int i = 0; i < 1000; i++) {
885         r = get_mon_num(caster_ptr, (caster_ptr->current_floor_ptr->dun_level + r_ptr->level) / 2 + 5, 0);
886         if (!r)
887             break;
888
889         r_ptr = &r_info[r];
890         if (r_ptr->flags1 & RF1_UNIQUE)
891             continue;
892         if ((r_ptr->level < lev1) || (r_ptr->level > lev2))
893             continue;
894
895         r_idx = r;
896         break;
897     }
898
899     return r_idx;
900 }
901
902 /*!
903  * @brief 指定座標にいるモンスターを変身させる /
904  * Helper function -- return a "nearby" race for polymorphing
905  * @param caster_ptr プレーヤーへの参照ポインタ
906  * @param y 指定のY座標
907  * @param x 指定のX座標
908  * @return 実際に変身したらTRUEを返す
909  */
910 bool polymorph_monster(player_type *caster_ptr, POSITION y, POSITION x)
911 {
912     floor_type *floor_ptr = caster_ptr->current_floor_ptr;
913     grid_type *g_ptr = &floor_ptr->grid_array[y][x];
914     monster_type *m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
915     MONRACE_IDX new_r_idx;
916     MONRACE_IDX old_r_idx = m_ptr->r_idx;
917     bool targeted = (target_who == g_ptr->m_idx) ? TRUE : FALSE;
918     bool health_tracked = (caster_ptr->health_who == g_ptr->m_idx) ? TRUE : FALSE;
919
920     if (floor_ptr->inside_arena || caster_ptr->phase_out)
921         return FALSE;
922     if ((caster_ptr->riding == g_ptr->m_idx) || (m_ptr->mflag2 & MFLAG2_KAGE))
923         return FALSE;
924
925     monster_type back_m = *m_ptr;
926     new_r_idx = poly_r_idx(caster_ptr, old_r_idx);
927     if (new_r_idx == old_r_idx)
928         return FALSE;
929
930     bool preserve_hold_objects = back_m.hold_o_idx ? TRUE : FALSE;
931     OBJECT_IDX this_o_idx, next_o_idx = 0;
932
933     BIT_FLAGS mode = 0L;
934     if (is_friendly(m_ptr))
935         mode |= PM_FORCE_FRIENDLY;
936     if (is_pet(m_ptr))
937         mode |= PM_FORCE_PET;
938     if (m_ptr->mflag2 & MFLAG2_NOPET)
939         mode |= PM_NO_PET;
940
941     m_ptr->hold_o_idx = 0;
942     delete_monster_idx(caster_ptr, g_ptr->m_idx);
943     bool polymorphed = FALSE;
944     if (place_monster_aux(caster_ptr, 0, y, x, new_r_idx, mode)) {
945         floor_ptr->m_list[hack_m_idx_ii].nickname = back_m.nickname;
946         floor_ptr->m_list[hack_m_idx_ii].parent_m_idx = back_m.parent_m_idx;
947         floor_ptr->m_list[hack_m_idx_ii].hold_o_idx = back_m.hold_o_idx;
948         polymorphed = TRUE;
949     } else {
950         if (place_monster_aux(caster_ptr, 0, y, x, old_r_idx, (mode | PM_NO_KAGE | PM_IGNORE_TERRAIN))) {
951             floor_ptr->m_list[hack_m_idx_ii] = back_m;
952             mproc_init(floor_ptr);
953         } else
954             preserve_hold_objects = FALSE;
955     }
956
957     if (preserve_hold_objects) {
958         for (this_o_idx = back_m.hold_o_idx; this_o_idx; this_o_idx = next_o_idx) {
959             object_type *o_ptr = &floor_ptr->o_list[this_o_idx];
960             next_o_idx = o_ptr->next_o_idx;
961             o_ptr->held_m_idx = hack_m_idx_ii;
962         }
963     } else if (back_m.hold_o_idx) {
964         for (this_o_idx = back_m.hold_o_idx; this_o_idx; this_o_idx = next_o_idx) {
965             next_o_idx = floor_ptr->o_list[this_o_idx].next_o_idx;
966             delete_object_idx(caster_ptr, this_o_idx);
967         }
968     }
969
970     if (targeted)
971         target_who = hack_m_idx_ii;
972     if (health_tracked)
973         health_track(caster_ptr, hack_m_idx_ii);
974     return polymorphed;
975 }
976
977 /*!
978  * @brief 皆殺し(全方向攻撃)処理
979  * @param caster_ptr プレーヤーへの参照ポインタ
980  * @return なし
981  */
982 void massacre(player_type *caster_ptr)
983 {
984     grid_type *g_ptr;
985     monster_type *m_ptr;
986     for (DIRECTION dir = 0; dir < 8; dir++) {
987         POSITION y = caster_ptr->y + ddy_ddd[dir];
988         POSITION x = caster_ptr->x + ddx_ddd[dir];
989         g_ptr = &caster_ptr->current_floor_ptr->grid_array[y][x];
990         m_ptr = &caster_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
991         if (g_ptr->m_idx && (m_ptr->ml || cave_have_flag_bold(caster_ptr->current_floor_ptr, y, x, FF_PROJECT)))
992             do_cmd_attack(caster_ptr, y, x, 0);
993     }
994 }
995
996 /*!
997  * 岩石食い
998  * @param caster_ptr プレーヤーへの参照ポインタ
999  * @return コマンドの入力方向に地形があればTRUE
1000  */
1001 bool eat_rock(player_type *caster_ptr)
1002 {
1003     DIRECTION dir;
1004     if (!get_direction(caster_ptr, &dir, FALSE, FALSE))
1005         return FALSE;
1006     POSITION y = caster_ptr->y + ddy[dir];
1007     POSITION x = caster_ptr->x + ddx[dir];
1008     grid_type *g_ptr;
1009     g_ptr = &caster_ptr->current_floor_ptr->grid_array[y][x];
1010     feature_type *f_ptr, *mimic_f_ptr;
1011     f_ptr = &f_info[g_ptr->feat];
1012     mimic_f_ptr = &f_info[get_feat_mimic(g_ptr)];
1013
1014     stop_mouth(caster_ptr);
1015     if (!have_flag(mimic_f_ptr->flags, FF_HURT_ROCK)) {
1016         msg_print(_("この地形は食べられない。", "You cannot eat this feature."));
1017     } else if (have_flag(f_ptr->flags, FF_PERMANENT)) {
1018         msg_format(_("いてっ!この%sはあなたの歯より硬い!", "Ouch!  This %s is harder than your teeth!"), f_name + mimic_f_ptr->name);
1019     } else if (g_ptr->m_idx) {
1020         monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
1021         msg_print(_("何かが邪魔しています!", "There's something in the way!"));
1022
1023         if (!m_ptr->ml || !is_pet(m_ptr))
1024             do_cmd_attack(caster_ptr, y, x, 0);
1025     } else if (have_flag(f_ptr->flags, FF_TREE)) {
1026         msg_print(_("木の味は好きじゃない!", "You don't like the woody taste!"));
1027     } else if (have_flag(f_ptr->flags, FF_GLASS)) {
1028         msg_print(_("ガラスの味は好きじゃない!", "You don't like the glassy taste!"));
1029     } else if (have_flag(f_ptr->flags, FF_DOOR) || have_flag(f_ptr->flags, FF_CAN_DIG)) {
1030         (void)set_food(caster_ptr, caster_ptr->food + 3000);
1031     } else if (have_flag(f_ptr->flags, FF_MAY_HAVE_GOLD) || have_flag(f_ptr->flags, FF_HAS_GOLD)) {
1032         (void)set_food(caster_ptr, caster_ptr->food + 5000);
1033     } else {
1034         msg_format(_("この%sはとてもおいしい!", "This %s is very filling!"), f_name + mimic_f_ptr->name);
1035         (void)set_food(caster_ptr, caster_ptr->food + 10000);
1036     }
1037
1038     cave_alter_feat(caster_ptr, y, x, FF_HURT_ROCK);
1039     (void)move_player_effect(caster_ptr, y, x, MPE_DONT_PICKUP);
1040     return TRUE;
1041 }
1042
1043 bool shock_power(player_type *caster_ptr)
1044 {
1045     int boost = get_current_ki(caster_ptr);
1046     if (heavy_armor(caster_ptr))
1047         boost /= 2;
1048
1049     project_length = 1;
1050     DIRECTION dir;
1051     if (!get_aim_dir(caster_ptr, &dir))
1052         return FALSE;
1053
1054     POSITION y = caster_ptr->y + ddy[dir];
1055     POSITION x = caster_ptr->x + ddx[dir];
1056     PLAYER_LEVEL plev = caster_ptr->lev;
1057     HIT_POINT dam = damroll(8 + ((plev - 5) / 4) + boost / 12, 8);
1058     fire_beam(caster_ptr, GF_MISSILE, dir, dam);
1059     if (!caster_ptr->current_floor_ptr->grid_array[y][x].m_idx)
1060         return TRUE;
1061
1062     POSITION ty = y, tx = x;
1063     POSITION oy = y, ox = x;
1064     MONSTER_IDX m_idx = caster_ptr->current_floor_ptr->grid_array[y][x].m_idx;
1065     monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[m_idx];
1066     monster_race *r_ptr = &r_info[m_ptr->r_idx];
1067     GAME_TEXT m_name[MAX_NLEN];
1068     monster_desc(caster_ptr, m_name, m_ptr, 0);
1069
1070     if (randint1(r_ptr->level * 3 / 2) > randint0(dam / 2) + dam / 2) {
1071         msg_format(_("%sは飛ばされなかった。", "%^s was not blown away."), m_name);
1072         return TRUE;
1073     }
1074
1075     for (int i = 0; i < 5; i++) {
1076         y += ddy[dir];
1077         x += ddx[dir];
1078         if (is_cave_empty_bold(caster_ptr, y, x)) {
1079             ty = y;
1080             tx = x;
1081         } else {
1082             break;
1083         }
1084     }
1085
1086     bool is_shock_successful = ty != oy;
1087     is_shock_successful |= tx != ox;
1088     if (is_shock_successful)
1089         return TRUE;
1090
1091     msg_format(_("%sを吹き飛ばした!", "You blow %s away!"), m_name);
1092     caster_ptr->current_floor_ptr->grid_array[oy][ox].m_idx = 0;
1093     caster_ptr->current_floor_ptr->grid_array[ty][tx].m_idx = m_idx;
1094     m_ptr->fy = ty;
1095     m_ptr->fx = tx;
1096
1097     update_monster(caster_ptr, m_idx, TRUE);
1098     lite_spot(caster_ptr, oy, ox);
1099     lite_spot(caster_ptr, ty, tx);
1100
1101     if (r_ptr->flags7 & (RF7_LITE_MASK | RF7_DARK_MASK))
1102         caster_ptr->update |= (PU_MON_LITE);
1103     return TRUE;
1104 }
1105
1106 bool fetch_monster(player_type *caster_ptr)
1107 {
1108     monster_type *m_ptr;
1109     MONSTER_IDX m_idx;
1110     GAME_TEXT m_name[MAX_NLEN];
1111     int i;
1112     int path_n;
1113     u16b path_g[512];
1114     POSITION ty, tx;
1115
1116     if (!target_set(caster_ptr, TARGET_KILL))
1117         return FALSE;
1118     m_idx = caster_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx;
1119     if (!m_idx)
1120         return FALSE;
1121     if (m_idx == caster_ptr->riding)
1122         return FALSE;
1123     if (!player_has_los_bold(caster_ptr, target_row, target_col))
1124         return FALSE;
1125     if (!projectable(caster_ptr, caster_ptr->y, caster_ptr->x, target_row, target_col))
1126         return FALSE;
1127     m_ptr = &caster_ptr->current_floor_ptr->m_list[m_idx];
1128     monster_desc(caster_ptr, m_name, m_ptr, 0);
1129     msg_format(_("%sを引き戻した。", "You pull back %s."), m_name);
1130     path_n = project_path(caster_ptr, path_g, get_max_range(caster_ptr), target_row, target_col, caster_ptr->y, caster_ptr->x, 0);
1131     ty = target_row, tx = target_col;
1132     for (i = 1; i < path_n; i++) {
1133         POSITION ny = GRID_Y(path_g[i]);
1134         POSITION nx = GRID_X(path_g[i]);
1135         grid_type *g_ptr = &caster_ptr->current_floor_ptr->grid_array[ny][nx];
1136
1137         if (in_bounds(caster_ptr->current_floor_ptr, ny, nx) && is_cave_empty_bold(caster_ptr, ny, nx) && !(g_ptr->info & CAVE_OBJECT)
1138             && !pattern_tile(caster_ptr->current_floor_ptr, ny, nx)) {
1139             ty = ny;
1140             tx = nx;
1141         }
1142     }
1143
1144     caster_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx = 0;
1145     caster_ptr->current_floor_ptr->grid_array[ty][tx].m_idx = m_idx;
1146     m_ptr->fy = ty;
1147     m_ptr->fx = tx;
1148     (void)set_monster_csleep(caster_ptr, m_idx, 0);
1149     update_monster(caster_ptr, m_idx, TRUE);
1150     lite_spot(caster_ptr, target_row, target_col);
1151     lite_spot(caster_ptr, ty, tx);
1152     if (r_info[m_ptr->r_idx].flags7 & (RF7_LITE_MASK | RF7_DARK_MASK))
1153         caster_ptr->update |= (PU_MON_LITE);
1154
1155     if (m_ptr->ml) {
1156         if (!caster_ptr->image)
1157             monster_race_track(caster_ptr, m_ptr->ap_r_idx);
1158
1159         health_track(caster_ptr, m_idx);
1160     }
1161
1162     return TRUE;
1163 }
1164
1165 bool booze(player_type *creature_ptr)
1166 {
1167     bool ident = FALSE;
1168     if (creature_ptr->pclass != CLASS_MONK)
1169         chg_virtue(creature_ptr, V_HARMONY, -1);
1170     else if (!creature_ptr->resist_conf)
1171         creature_ptr->special_attack |= ATTACK_SUIKEN;
1172     if (!creature_ptr->resist_conf && set_confused(creature_ptr, randint0(20) + 15)) {
1173         ident = TRUE;
1174     }
1175
1176     if (creature_ptr->resist_chaos) {
1177         return ident;
1178     }
1179
1180     if (one_in_(2) && set_image(creature_ptr, creature_ptr->image + randint0(150) + 150)) {
1181         ident = TRUE;
1182     }
1183
1184     if (one_in_(13) && (creature_ptr->pclass != CLASS_MONK)) {
1185         ident = TRUE;
1186         if (one_in_(3))
1187             lose_all_info(creature_ptr);
1188         else
1189             wiz_dark(creature_ptr);
1190         (void)teleport_player_aux(creature_ptr, 100, FALSE, TELEPORT_NONMAGICAL | TELEPORT_PASSIVE);
1191         wiz_dark(creature_ptr);
1192         msg_print(_("知らない場所で目が醒めた。頭痛がする。", "You wake up somewhere with a sore head..."));
1193         msg_print(_("何も思い出せない。どうやってここへ来たのかも分からない!", "You can't remember a thing or how you got here!"));
1194     }
1195
1196     return ident;
1197 }
1198
1199 bool detonation(player_type *creature_ptr)
1200 {
1201     msg_print(_("体の中で激しい爆発が起きた!", "Massive explosions rupture your body!"));
1202     take_hit(creature_ptr, DAMAGE_NOESCAPE, damroll(50, 20), _("爆発の薬", "a potion of Detonation"), -1);
1203     (void)set_stun(creature_ptr, creature_ptr->stun + 75);
1204     (void)set_cut(creature_ptr, creature_ptr->cut + 5000);
1205     return TRUE;
1206 }
1207
1208 void blood_curse_to_enemy(player_type *caster_ptr, MONSTER_IDX m_idx)
1209 {
1210     monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[m_idx];
1211     grid_type *g_ptr = &caster_ptr->current_floor_ptr->grid_array[m_ptr->fy][m_ptr->fx];
1212     BIT_FLAGS curse_flg = (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP);
1213     int count = 0;
1214     bool is_first_loop = TRUE;
1215     while (is_first_loop || one_in_(5)) {
1216         is_first_loop = FALSE;
1217         switch (randint1(28)) {
1218         case 1:
1219         case 2:
1220             if (!count) {
1221                 msg_print(_("地面が揺れた...", "The ground trembles..."));
1222                 earthquake(caster_ptr, m_ptr->fy, m_ptr->fx, 4 + randint0(4), 0);
1223                 if (!one_in_(6))
1224                     break;
1225             }
1226             /* Fall through */
1227         case 3:
1228         case 4:
1229         case 5:
1230         case 6:
1231             if (!count) {
1232                 int extra_dam = damroll(10, 10);
1233                 msg_print(_("純粋な魔力の次元への扉が開いた!", "A portal opens to a plane of raw mana!"));
1234
1235                 project(caster_ptr, 0, 8, m_ptr->fy, m_ptr->fx, extra_dam, GF_MANA, curse_flg, -1);
1236                 if (!one_in_(6))
1237                     break;
1238             }
1239             /* Fall through */
1240         case 7:
1241         case 8:
1242             if (!count) {
1243                 msg_print(_("空間が歪んだ!", "Space warps about you!"));
1244
1245                 if (m_ptr->r_idx)
1246                     teleport_away(caster_ptr, g_ptr->m_idx, damroll(10, 10), TELEPORT_PASSIVE);
1247                 if (one_in_(13))
1248                     count += activate_hi_summon(caster_ptr, m_ptr->fy, m_ptr->fx, TRUE);
1249                 if (!one_in_(6))
1250                     break;
1251             }
1252             /* Fall through */
1253         case 9:
1254         case 10:
1255         case 11:
1256             msg_print(_("エネルギーのうねりを感じた!", "You feel a surge of energy!"));
1257             project(caster_ptr, 0, 7, m_ptr->fy, m_ptr->fx, 50, GF_DISINTEGRATE, curse_flg, -1);
1258             if (!one_in_(6))
1259                 break;
1260             /* Fall through */
1261         case 12:
1262         case 13:
1263         case 14:
1264         case 15:
1265         case 16:
1266             aggravate_monsters(caster_ptr, 0);
1267             if (!one_in_(6))
1268                 break;
1269             /* Fall through */
1270         case 17:
1271         case 18:
1272             count += activate_hi_summon(caster_ptr, m_ptr->fy, m_ptr->fx, TRUE);
1273             if (!one_in_(6))
1274                 break;
1275             /* Fall through */
1276         case 19:
1277         case 20:
1278         case 21:
1279         case 22: {
1280             bool pet = !one_in_(3);
1281             BIT_FLAGS mode = PM_ALLOW_GROUP;
1282
1283             if (pet)
1284                 mode |= PM_FORCE_PET;
1285             else
1286                 mode |= (PM_NO_PET | PM_FORCE_FRIENDLY);
1287
1288             count += summon_specific(caster_ptr, (pet ? -1 : 0), caster_ptr->y, caster_ptr->x,
1289                 (pet ? caster_ptr->lev * 2 / 3 + randint1(caster_ptr->lev / 2) : caster_ptr->current_floor_ptr->dun_level), 0, mode);
1290             if (!one_in_(6))
1291                 break;
1292         }
1293             /* Fall through */
1294         case 23:
1295         case 24:
1296         case 25:
1297             if (caster_ptr->hold_exp && (randint0(100) < 75))
1298                 break;
1299             msg_print(_("経験値が体から吸い取られた気がする!", "You feel your experience draining away..."));
1300
1301             if (caster_ptr->hold_exp)
1302                 lose_exp(caster_ptr, caster_ptr->exp / 160);
1303             else
1304                 lose_exp(caster_ptr, caster_ptr->exp / 16);
1305             if (!one_in_(6))
1306                 break;
1307             /* Fall through */
1308         case 26:
1309         case 27:
1310         case 28: {
1311             if (one_in_(13)) {
1312                 for (int i = 0; i < A_MAX; i++) {
1313                     bool is_first_dec_stat = TRUE;
1314                     while (is_first_dec_stat || one_in_(2)) {
1315                         (void)do_dec_stat(caster_ptr, i);
1316                     }
1317                 }
1318             } else {
1319                 (void)do_dec_stat(caster_ptr, randint0(6));
1320             }
1321
1322             break;
1323         }
1324         }
1325     }
1326 }
1327
1328 /*!
1329  * @brief クリムゾンを発射する / Fire Crimson, evoluting gun.
1330  @ @param shooter_ptr 射撃を行うクリーチャー参照
1331  * @return キャンセルした場合 false.
1332  * @details
1333  * Need to analyze size of the window.
1334  * Need more color coding.
1335  */
1336 bool fire_crimson(player_type *shooter_ptr)
1337 {
1338     DIRECTION dir;
1339     if (!get_aim_dir(shooter_ptr, &dir))
1340         return FALSE;
1341
1342     POSITION tx = shooter_ptr->x + 99 * ddx[dir];
1343     POSITION ty = shooter_ptr->y + 99 * ddy[dir];
1344     if ((dir == 5) && target_okay(shooter_ptr)) {
1345         tx = target_col;
1346         ty = target_row;
1347     }
1348
1349     int num = 1;
1350     if (shooter_ptr->pclass == CLASS_ARCHER) {
1351         if (shooter_ptr->lev >= 10)
1352             num++;
1353         if (shooter_ptr->lev >= 30)
1354             num++;
1355         if (shooter_ptr->lev >= 45)
1356             num++;
1357     }
1358
1359     BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
1360     for (int i = 0; i < num; i++)
1361         project(shooter_ptr, 0, shooter_ptr->lev / 20 + 1, ty, tx, shooter_ptr->lev * shooter_ptr->lev * 6 / 50, GF_ROCKET, flg, -1);
1362
1363     return TRUE;
1364 }
1365
1366 /*!
1367  * @brief 町間のテレポートを行うメインルーチン
1368  * @param caster_ptr プレーヤーへの参照ポインタ
1369  * @return テレポート処理を決定したか否か
1370  */
1371 bool tele_town(player_type *caster_ptr)
1372 {
1373     if (caster_ptr->current_floor_ptr->dun_level) {
1374         msg_print(_("この魔法は地上でしか使えない!", "This spell can only be used on the surface!"));
1375         return FALSE;
1376     }
1377
1378     if (caster_ptr->current_floor_ptr->inside_arena || caster_ptr->phase_out) {
1379         msg_print(_("この魔法は外でしか使えない!", "This spell can only be used outside!"));
1380         return FALSE;
1381     }
1382
1383     screen_save();
1384     clear_bldg(4, 10);
1385
1386     int i;
1387     int num = 0;
1388     for (i = 1; i < max_towns; i++) {
1389         char buf[80];
1390
1391         if ((i == NO_TOWN) || (i == SECRET_TOWN) || (i == caster_ptr->town_num) || !(caster_ptr->visit & (1L << (i - 1))))
1392             continue;
1393
1394         sprintf(buf, "%c) %-20s", I2A(i - 1), town_info[i].name);
1395         prt(buf, 5 + i, 5);
1396         num++;
1397     }
1398
1399     if (num == 0) {
1400         msg_print(_("まだ行けるところがない。", "You have not yet visited any town."));
1401         msg_print(NULL);
1402         screen_load();
1403         return FALSE;
1404     }
1405
1406     prt(_("どこに行きますか:", "Where do you want to go: "), 0, 0);
1407     while (TRUE) {
1408         i = inkey();
1409
1410         if (i == ESCAPE) {
1411             screen_load();
1412             return FALSE;
1413         }
1414
1415         else if ((i < 'a') || (i > ('a' + max_towns - 2)))
1416             continue;
1417         else if (((i - 'a' + 1) == caster_ptr->town_num) || ((i - 'a' + 1) == NO_TOWN) || ((i - 'a' + 1) == SECRET_TOWN)
1418             || !(caster_ptr->visit & (1L << (i - 'a'))))
1419             continue;
1420         break;
1421     }
1422
1423     for (POSITION y = 0; y < current_world_ptr->max_wild_y; y++) {
1424         for (POSITION x = 0; x < current_world_ptr->max_wild_x; x++) {
1425             if (wilderness[y][x].town == (i - 'a' + 1)) {
1426                 caster_ptr->wilderness_y = y;
1427                 caster_ptr->wilderness_x = x;
1428             }
1429         }
1430     }
1431
1432     caster_ptr->leaving = TRUE;
1433     caster_ptr->leave_bldg = TRUE;
1434     caster_ptr->teleport_town = TRUE;
1435     screen_load();
1436     return TRUE;
1437 }