3 * @brief プレイヤーのアイテムに関するコマンドの実装2 / Spell/Prayer commands
7 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
8 * This software may be copied and distributed for educational, research,
9 * and not for profit purposes provided that this copyright and statement
10 * are included in all such copies. Other copyrights may also apply.
11 * 2014 Deskull rearranged comment for Doxygen.\n
15 * This file includes code for eating food, drinking potions,
16 * reading scrolls, aiming wands, using staffs, zapping rods,
17 * and activating artifacts.
19 * In all cases, if the player becomes "aware" of the item's use
20 * by testing it, mark it as "aware" and reward some experience
21 * based on the object's level, always rounding up. If the player
22 * remains "unaware", mark that object "kind" as "tried".
24 * This code now correctly handles the unstacking of wands, staffs,
25 * and rods. Note the overly paranoid warning about potential pack
26 * overflow, which allows the player to use and drop a stacked item.
28 * In all "unstacking" scenarios, the "used" object is "carried" as if
29 * the player had just picked it up. In particular, this means that if
30 * the use of an item induces pack overflow, that item will be dropped.
32 * For simplicity, these routines induce a full "pack reorganization"
33 * which not only combines similar items, but also reorganizes various
34 * items to obey the current "sorting" method. This may require about
35 * 400 item comparisons, but only occasionally.
37 * There may be a BIG problem with any "effect" that can cause "changes"
38 * to the inventory. For example, a "scroll of recharging" can cause
39 * a wand/staff to "disappear", moving the inventory up. Luckily, the
40 * scrolls all appear BEFORE the staffs/wands, so this is not a problem.
41 * But, for example, a "staff of recharging" could cause MAJOR problems.
42 * In such a case, it will be best to either (1) "postpone" the effect
43 * until the end of the function, or (2) "change" the effect, say, into
44 * giving a staff "negative" charges, or "turning a staff into a stick".
45 * It seems as though a "rod of recharging" might in fact cause problems.
46 * The basic problem is that the act of recharging (and destroying) an
47 * item causes the inducer of that action to "move", causing "o_ptr" to
48 * no longer point at the correct item, with horrifying results.
50 * Note that food/potions/scrolls no longer use bit-flags for effects,
51 * but instead use the "sval" (which is also used to sort the objects).
57 #include "cmd-activate.h"
59 #include "cmd-quaff.h"
61 #include "cmd-usestaff.h"
62 #include "cmd-zaprod.h"
63 #include "cmd-zapwand.h"
67 * @brief 『一つの指輪』の効果処理 /
68 * Hack -- activate the ring of power
72 void ring_of_power(int dir)
74 /* Pick a random effect */
81 msg_print(_("あなたは悪性のオーラに包み込まれた。", "You are surrounded by a malignant aura."));
84 /* Decrease all stats (permanently) */
85 (void)dec_stat(A_STR, 50, TRUE);
86 (void)dec_stat(A_INT, 50, TRUE);
87 (void)dec_stat(A_WIS, 50, TRUE);
88 (void)dec_stat(A_DEX, 50, TRUE);
89 (void)dec_stat(A_CON, 50, TRUE);
90 (void)dec_stat(A_CHR, 50, TRUE);
92 /* Lose some experience (permanently) */
93 p_ptr->exp -= (p_ptr->exp / 4);
94 p_ptr->max_exp -= (p_ptr->exp / 4);
103 msg_print(_("あなたは強力なオーラに包み込まれた。", "You are surrounded by a powerful aura."));
105 /* Dispel monsters */
106 dispel_monsters(1000);
116 fire_ball(GF_MANA, dir, 600, 3);
127 fire_bolt(GF_MANA, dir, 500);
135 * @brief オブジェクトをプレイヤーが簡易使用コマンドで利用できるかを判定する /
136 * Hook to determine if an object is useable
137 * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
138 * @return 利用可能ならばTRUEを返す
140 static bool item_tester_hook_use(object_type *o_ptr)
142 u32b flgs[TR_FLAG_SIZE];
145 if (o_ptr->tval == p_ptr->tval_ammo)
167 if (!object_is_known(o_ptr)) return (FALSE);
169 /* HACK - only items from the equipment can be activated */
170 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
172 if (&inventory[i] == o_ptr)
174 /* Extract the flags */
175 object_flags(o_ptr, flgs);
177 /* Check activation flag */
178 if (have_flag(flgs, TR_ACTIVATE)) return (TRUE);
190 * @brief アイテムを汎用的に「使う」コマンドのメインルーチン /
194 * XXX - Add actions for other item types
196 void do_cmd_use(void)
202 if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
204 set_action(ACTION_NONE);
207 item_tester_no_ryoute = TRUE;
208 /* Prepare the hook */
209 item_tester_hook = item_tester_hook_use;
212 q = _("どれを使いますか?", "Use which item? ");
213 s = _("使えるものがありません。", "You have nothing to use.");
215 if (!get_item(&item, q, s, (USE_INVEN | USE_EQUIP | USE_FLOOR))) return;
217 /* Get the item (in the pack) */
220 o_ptr = &inventory[item];
222 /* Get the item (on the floor) */
225 o_ptr = &o_list[0 - item];
240 do_cmd_eat_food_aux(item);
247 do_cmd_aim_wand_aux(item);
254 do_cmd_use_staff_aux(item);
261 do_cmd_zap_rod_aux(item);
268 do_cmd_quaff_potion_aux(item);
275 /* Check some conditions */
278 msg_print(_("目が見えない。", "You can't see anything."));
283 msg_print(_("明かりがないので、暗くて読めない。", "You have no light to read by."));
288 msg_print(_("混乱していて読めない!", "You are too confused!"));
292 do_cmd_read_scroll_aux(item, TRUE);
301 do_cmd_fire_aux(item, &inventory[INVEN_BOW]);
305 /* Activate an artifact */
308 do_cmd_activate_aux(item);
315 * @brief 魔道具術師の取り込んだ魔力一覧から選択/閲覧する /
316 * @param only_browse 閲覧するだけならばTRUE
317 * @return 選択した魔力のID、キャンセルならば-1を返す
319 static OBJECT_SUBTYPE_VALUE select_magic_eater(bool only_browse)
321 OBJECT_SUBTYPE_VALUE ext = 0;
323 bool flag, request_list;
324 OBJECT_TYPE_VALUE tval = 0;
326 OBJECT_SUBTYPE_VALUE i = 0;
329 int menu_line = (use_menu ? 1 : 0);
333 if (repeat_pull(&sn))
335 /* Verify the spell */
336 if (sn >= EATER_EXT*2 && !(p_ptr->magic_num1[sn] > k_info[lookup_kind(TV_ROD, sn-EATER_EXT*2)].pval * (p_ptr->magic_num2[sn] - 1) * EATER_ROD_CHARGE))
338 else if (sn < EATER_EXT*2 && !(p_ptr->magic_num1[sn] < EATER_CHARGE))
342 #endif /* ALLOW_REPEAT */
344 for (i = 0; i < 108; i++)
346 if (p_ptr->magic_num2[i]) break;
350 msg_print(_("魔法を覚えていない!", "You don't have any magic!"));
361 prt(format(" %s 杖", (menu_line == 1) ? "》" : " "), 2, 14);
362 prt(format(" %s 魔法棒", (menu_line == 2) ? "》" : " "), 3, 14);
363 prt(format(" %s ロッド", (menu_line == 3) ? "》" : " "), 4, 14);
365 prt(format(" %s staff", (menu_line == 1) ? "> " : " "), 2, 14);
366 prt(format(" %s wand", (menu_line == 2) ? "> " : " "), 3, 14);
367 prt(format(" %s rod", (menu_line == 3) ? "> " : " "), 4, 14);
370 if (only_browse) prt(_("どの種類の魔法を見ますか?", "Which type of magic do you browse?"), 0, 0);
371 else prt(_("どの種類の魔法を使いますか?", "Which type of magic do you use?"), 0, 0);
394 ext = (menu_line-1)*EATER_EXT;
395 if (menu_line == 1) tval = TV_STAFF;
396 else if (menu_line == 2) tval = TV_WAND;
400 if (menu_line > 3) menu_line -= 3;
408 if (!get_com(_("[A] 杖, [B] 魔法棒, [C] ロッド:", "[A] staff, [B] wand, [C] rod:"), &choice, TRUE))
412 if (choice == 'A' || choice == 'a')
418 if (choice == 'B' || choice == 'b')
424 if (choice == 'C' || choice == 'c')
432 for (i = ext; i < ext + EATER_EXT; i++)
434 if (p_ptr->magic_num2[i])
436 if (use_menu) menu_line = i-ext+1;
440 if (i == ext+EATER_EXT)
442 msg_print(_("その種類の魔法は覚えていない!", "You don't have that type of magic!"));
446 /* Nothing chosen yet */
450 if (only_browse) strnfmt(out_val, 78, _("('*'で一覧, ESCで中断) どの魔力を見ますか?",
451 "(*=List, ESC=exit) Browse which power? "));
452 else strnfmt(out_val, 78, _("('*'で一覧, ESCで中断) どの魔力を使いますか?",
453 "(*=List, ESC=exit) Use which power? "));
455 /* Save the screen */
458 request_list = always_show_list;
460 /* Get a spell from the user */
464 if (request_list || use_menu)
467 OBJECT_SUBTYPE_VALUE ctr;
477 for (y = 1; y < 20; y++)
482 /* Print header(s) */
484 prt(format(" %s 失率 %s 失率", (tval == TV_ROD ? " 状態 " : "使用回数"), (tval == TV_ROD ? " 状態 " : "使用回数")), y++, x);
486 prt(format(" %s Fail %s Fail", (tval == TV_ROD ? " Stat " : " Charges"), (tval == TV_ROD ? " Stat " : " Charges")), y++, x);
490 for (ctr = 0; ctr < EATER_EXT; ctr++)
492 if (!p_ptr->magic_num2[ctr+ext]) continue;
494 k_idx = lookup_kind(tval, ctr);
498 if (ctr == (menu_line-1))
499 strcpy(dummy, _("》", "> "));
503 /* letter/number for power selection */
510 letter = '0' + ctr - 26;
511 sprintf(dummy, "%c)",letter);
513 x1 = ((ctr < EATER_EXT/2) ? x : x + 40);
514 y1 = ((ctr < EATER_EXT/2) ? y + ctr : y + ctr - EATER_EXT/2);
515 level = (tval == TV_ROD ? k_info[k_idx].level * 5 / 6 - 5 : k_info[k_idx].level);
516 chance = level * 4 / 5 + 20;
517 chance -= 3 * (adj_mag_stat[p_ptr->stat_ind[mp_ptr->spell_stat]] - 1);
519 if (p_ptr->lev > level)
521 chance -= 3 * (p_ptr->lev - level);
523 chance = mod_spell_chance_1(chance);
524 chance = MAX(chance, adj_mag_fail[p_ptr->stat_ind[mp_ptr->spell_stat]]);
525 /* Stunning makes spells harder */
526 if (p_ptr->stun > 50) chance += 25;
527 else if (p_ptr->stun) chance += 15;
529 if (chance > 95) chance = 95;
531 chance = mod_spell_chance_2(chance);
539 strcat(dummy, format(
540 _(" %-22.22s 充填:%2d/%2d%3d%%", " %-22.22s (%2d/%2d) %3d%%"),
541 k_name + k_info[k_idx].name,
542 p_ptr->magic_num1[ctr+ext] ?
543 (p_ptr->magic_num1[ctr+ext] - 1) / (EATER_ROD_CHARGE * k_info[k_idx].pval) +1 : 0,
544 p_ptr->magic_num2[ctr+ext], chance));
545 if (p_ptr->magic_num1[ctr+ext] > k_info[k_idx].pval * (p_ptr->magic_num2[ctr+ext]-1) * EATER_ROD_CHARGE) col = TERM_RED;
549 strcat(dummy, format(" %-22.22s %2d/%2d %3d%%", k_name + k_info[k_idx].name, (s16b)(p_ptr->magic_num1[ctr+ext]/EATER_CHARGE), p_ptr->magic_num2[ctr+ext], chance));
550 if (p_ptr->magic_num1[ctr+ext] < EATER_CHARGE) col = TERM_RED;
555 c_prt(col, dummy, y1, x1);
559 if (!get_com(out_val, &choice, FALSE)) break;
561 if (use_menu && choice != ' ')
577 menu_line += EATER_EXT - 1;
578 if (menu_line > EATER_EXT) menu_line -= EATER_EXT;
579 } while(!p_ptr->magic_num2[menu_line+ext-1]);
590 if (menu_line > EATER_EXT) menu_line -= EATER_EXT;
591 } while(!p_ptr->magic_num2[menu_line+ext-1]);
602 bool reverse = FALSE;
603 if ((choice == '4') || (choice == 'h') || (choice == 'H')) reverse = TRUE;
604 if (menu_line > EATER_EXT/2)
606 menu_line -= EATER_EXT/2;
609 else menu_line+=EATER_EXT/2;
610 while(!p_ptr->magic_num2[menu_line+ext-1])
615 if (menu_line < 2) reverse = FALSE;
620 if (menu_line > EATER_EXT-1) reverse = TRUE;
638 if (use_menu && ask) continue;
641 if (!use_menu && ((choice == ' ') || (choice == '*') || (choice == '?')))
647 request_list = FALSE;
649 /* Restore the screen */
665 ask = (isupper(choice));
668 if (ask) choice = (char)tolower(choice);
670 /* Extract request */
671 i = (islower(choice) ? A2I(choice) : -1);
675 ask = FALSE; /* Can't uppercase digits */
677 i = choice - '0' + 26;
681 /* Totally Illegal */
682 if ((i < 0) || (i > EATER_EXT) || !p_ptr->magic_num2[i+ext])
696 (void) strnfmt(tmp_val, 78, _("%sを使いますか? ", "Use %s?"), k_name + k_info[lookup_kind(tval ,i)].name);
698 /* Belay that order */
699 if (!get_check(tmp_val)) continue;
703 if (p_ptr->magic_num1[ext+i] > k_info[lookup_kind(tval, i)].pval * (p_ptr->magic_num2[ext+i] - 1) * EATER_ROD_CHARGE)
705 msg_print(_("その魔法はまだ充填している最中だ。", "The magic are still charging."));
707 if (use_menu) ask = TRUE;
713 if (p_ptr->magic_num1[ext+i] < EATER_CHARGE)
715 msg_print(_("その魔法は使用回数が切れている。", "The magic has no charges left."));
717 if (use_menu) ask = TRUE;
729 /* Clear lines, position cursor (really should use strlen here) */
730 Term_erase(7, 23, 255);
731 Term_erase(7, 22, 255);
732 Term_erase(7, 21, 255);
733 Term_erase(7, 20, 255);
735 roff_to_buf(k_text + k_info[lookup_kind(tval, i)].text, 62, temp, sizeof(temp));
736 for (j = 0, line = 21; temp[j]; j += 1 + strlen(&temp[j]))
738 prt(&temp[j], line, 10);
749 /* Restore the screen */
752 if (!flag) return -1;
756 #endif /* ALLOW_REPEAT */
762 * @brief 取り込んだ魔力を利用するコマンドのメインルーチン /
763 * Use eaten rod, wand or staff
764 * @param only_browse 閲覧するだけならばTRUE
765 * @param powerful 強力発動中の処理ならばTRUE
766 * @return 実際にコマンドを実行したならばTRUEを返す。
768 bool do_cmd_magic_eater(bool only_browse, bool powerful)
770 OBJECT_SUBTYPE_VALUE item;
774 OBJECT_TYPE_VALUE tval;
775 OBJECT_SUBTYPE_VALUE sval;
776 bool use_charge = TRUE;
778 /* Not when confused */
779 if (!only_browse && p_ptr->confused)
781 msg_print(_("混乱していて唱えられない!", "You are too confused!"));
785 item = select_magic_eater(only_browse);
788 p_ptr->energy_use = 0;
791 if (item >= EATER_EXT*2) {tval = TV_ROD;sval = item - EATER_EXT*2;}
792 else if (item >= EATER_EXT) {tval = TV_WAND;sval = item - EATER_EXT;}
793 else {tval = TV_STAFF; sval = item;}
794 k_idx = lookup_kind(tval, sval);
796 level = (tval == TV_ROD ? k_info[k_idx].level * 5 / 6 - 5 : k_info[k_idx].level);
797 chance = level * 4 / 5 + 20;
798 chance -= 3 * (adj_mag_stat[p_ptr->stat_ind[mp_ptr->spell_stat]] - 1);
800 if (p_ptr->lev > level)
802 chance -= 3 * (p_ptr->lev - level);
804 chance = mod_spell_chance_1(chance);
805 chance = MAX(chance, adj_mag_fail[p_ptr->stat_ind[mp_ptr->spell_stat]]);
806 /* Stunning makes spells harder */
807 if (p_ptr->stun > 50) chance += 25;
808 else if (p_ptr->stun) chance += 15;
810 if (chance > 95) chance = 95;
812 chance = mod_spell_chance_2(chance);
814 if (randint0(100) < chance)
816 if (flush_failure) flush();
818 msg_print(_("呪文をうまく唱えられなかった!", "You failed to get the magic off!"));
820 if (randint1(100) >= chance)
821 chg_virtue(V_CHANCE,-1);
822 p_ptr->energy_use = 100;
832 if ((sval >= SV_ROD_MIN_DIRECTION) && (sval != SV_ROD_HAVOC) && (sval != SV_ROD_AGGRAVATE) && (sval != SV_ROD_PESTICIDE))
833 if (!get_aim_dir(&dir)) return FALSE;
834 rod_effect(sval, dir, &use_charge, powerful, TRUE);
835 if (!use_charge) return FALSE;
837 else if (tval == TV_WAND)
839 if (!get_aim_dir(&dir)) return FALSE;
840 wand_effect(sval, dir, powerful, TRUE);
844 staff_effect(sval, &use_charge, powerful, TRUE, TRUE);
845 if (!use_charge) return FALSE;
847 if (randint1(100) < chance)
848 chg_virtue(V_CHANCE,1);
850 p_ptr->energy_use = 100;
851 if (tval == TV_ROD) p_ptr->magic_num1[item] += k_info[k_idx].pval * EATER_ROD_CHARGE;
852 else p_ptr->magic_num1[item] -= EATER_CHARGE;