<ClCompile Include="..\..\src\cmd-usestaff.c" />\r
<ClCompile Include="..\..\src\cmd-zaprod.c" />\r
<ClCompile Include="..\..\src\cmd-zapwand.c" />\r
+ <ClInclude Include="..\..\src\cmd-magiceat.h" />\r
<ClInclude Include="..\..\src\cmd-zaprod.h" />\r
<ClInclude Include="..\..\src\cmd-zapwand.h">\r
<FileType>CppCode</FileType>\r
<ClCompile Include="..\..\src\cmd3.c" />\r
<ClCompile Include="..\..\src\cmd4.c" />\r
<ClCompile Include="..\..\src\cmd5.c" />\r
- <ClCompile Include="..\..\src\cmd6.c" />\r
+ <ClCompile Include="..\..\src\cmd-magiceat.c" />\r
<ClCompile Include="..\..\src\do-spell.c" />\r
<ClCompile Include="..\..\src\dungeon.c" />\r
<ClCompile Include="..\..\src\effects.c" />\r
<ClCompile Include="..\..\src\cmd3.c">\r
<Filter>Source</Filter>\r
</ClCompile>\r
- <ClCompile Include="..\..\src\cmd6.c">\r
- <Filter>Source</Filter>\r
- </ClCompile>\r
<ClCompile Include="..\..\src\cmd5.c">\r
<Filter>Source</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\src\cmd-zaprod.c">\r
<Filter>Source</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\src\cmd-magiceat.c">\r
+ <Filter>Source</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="..\..\src\angband.h">\r
<ClInclude Include="..\..\src\cmd-zaprod.h">\r
<Filter>Header</Filter>\r
</ClInclude>\r
+ <ClInclude Include="..\..\src\cmd-magiceat.h">\r
+ <Filter>Header</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<ResourceCompile Include="..\..\src\angband.rc" />\r
--- /dev/null
+/*!
+* @file cmd-activate.c
+* @brief プレイヤーの発動コマンド実装
+* @date 2018/09/07
+* @details
+* cmd6.cより分離。
+*/
+
+#include "angband.h"
+
+/*!
+* @brief ペット入りモンスターボールをソートするための比較関数
+* @param u 所持品配列の参照ポインタ
+* @param v 未使用
+* @param a 所持品ID1
+* @param b 所持品ID2
+* @return 1の方が大であればTRUE
+*/
+static bool ang_sort_comp_pet(vptr u, vptr v, int a, int b)
+{
+ u16b *who = (u16b*)(u);
+
+ int w1 = who[a];
+ int w2 = who[b];
+
+ monster_type *m_ptr1 = &m_list[w1];
+ monster_type *m_ptr2 = &m_list[w2];
+ monster_race *r_ptr1 = &r_info[m_ptr1->r_idx];
+ monster_race *r_ptr2 = &r_info[m_ptr2->r_idx];
+
+ /* Unused */
+ (void)v;
+
+ if (m_ptr1->nickname && !m_ptr2->nickname) return TRUE;
+ if (m_ptr2->nickname && !m_ptr1->nickname) return FALSE;
+
+ if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return TRUE;
+ if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return FALSE;
+
+ if (r_ptr1->level > r_ptr2->level) return TRUE;
+ if (r_ptr2->level > r_ptr1->level) return FALSE;
+
+ if (m_ptr1->hp > m_ptr2->hp) return TRUE;
+ if (m_ptr2->hp > m_ptr1->hp) return FALSE;
+
+ return w1 <= w2;
+}
+
+/*!
+* @brief オブジェクトをプレイヤーが魔道具として発動できるかを判定する /
+* Hook to determine if an object is activatable
+* @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
+* @return 魔道具として発動可能ならばTRUEを返す
+*/
+static bool item_tester_hook_activate(object_type *o_ptr)
+{
+ u32b flgs[TR_FLAG_SIZE];
+
+ /* Not known */
+ if (!object_is_known(o_ptr)) return (FALSE);
+
+ /* Extract the flags */
+ object_flags(o_ptr, flgs);
+
+ /* Check activation flag */
+ if (have_flag(flgs, TR_ACTIVATE)) return (TRUE);
+
+ /* Assume not */
+ return (FALSE);
+}
+
+/*!
+ * @brief 装備を発動するコマンドのサブルーチン /
+ * Activate a wielded object. Wielded objects never stack.
+ * And even if they did, activatable objects never stack.
+ * @param item 発動するオブジェクトの所持品ID
+ * @return なし
+ * @details
+ * <pre>
+ * Currently, only (some) artifacts, and Dragon Scale Mail, can be activated.
+ * But one could, for example, easily make an activatable "Ring of Plasma".
+ * Note that it always takes a turn to activate an artifact, even if
+ * the user hits "escape" at the "direction" prompt.
+ * </pre>
+ */
+void do_cmd_activate_aux(int item)
+{
+ int dir, lev, chance, fail;
+ object_type *o_ptr;
+ bool success;
+
+
+ /* Get the item (in the pack) */
+ if (item >= 0)
+ {
+ o_ptr = &inventory[item];
+ }
+
+ /* Get the item (on the floor) */
+ else
+ {
+ o_ptr = &o_list[0 - item];
+ }
+
+ /* Take a turn */
+ p_ptr->energy_use = 100;
+
+ /* Extract the item level */
+ lev = k_info[o_ptr->k_idx].level;
+
+ /* Hack -- use artifact level instead */
+ if (object_is_fixed_artifact(o_ptr)) lev = a_info[o_ptr->name1].level;
+ else if (object_is_random_artifact(o_ptr))
+ {
+ const activation_type* const act_ptr = find_activation_info(o_ptr);
+ if (act_ptr) {
+ lev = act_ptr->level;
+ }
+ }
+ else if (((o_ptr->tval == TV_RING) || (o_ptr->tval == TV_AMULET)) && o_ptr->name2) lev = e_info[o_ptr->name2].level;
+
+ /* Base chance of success */
+ chance = p_ptr->skill_dev;
+
+ /* Confusion hurts skill */
+ if (p_ptr->confused) chance = chance / 2;
+
+ fail = lev+5;
+ if (chance > fail) fail -= (chance - fail)*2;
+ else chance -= (fail - chance)*2;
+ if (fail < USE_DEVICE) fail = USE_DEVICE;
+ if (chance < USE_DEVICE) chance = USE_DEVICE;
+
+ if (world_player)
+ {
+ if (flush_failure) flush();
+ msg_print(_("止まった時の中ではうまく働かないようだ。", "It shows no reaction."));
+ sound(SOUND_FAIL);
+ return;
+ }
+
+ if (p_ptr->pclass == CLASS_BERSERKER) success = FALSE;
+ else if (chance > fail)
+ {
+ if (randint0(chance*2) < fail) success = FALSE;
+ else success = TRUE;
+ }
+ else
+ {
+ if (randint0(fail*2) < chance) success = TRUE;
+ else success = FALSE;
+ }
+
+ /* Roll for usage */
+ if (!success)
+ {
+ if (flush_failure) flush();
+ msg_print(_("うまく始動させることができなかった。", "You failed to activate it properly."));
+ sound(SOUND_FAIL);
+ return;
+ }
+
+ /* Check the recharge */
+ if (o_ptr->timeout)
+ {
+ msg_print(_("それは微かに音を立て、輝き、消えた...", "It whines, glows and fades..."));
+ return;
+ }
+
+ /* Some lights need enough fuel for activation */
+ if (!o_ptr->xtra4 && (o_ptr->tval == TV_FLASK) &&
+ ((o_ptr->sval == SV_LITE_TORCH) || (o_ptr->sval == SV_LITE_LANTERN)))
+ {
+ msg_print(_("燃料がない。", "It has no fuel."));
+ p_ptr->energy_use = 0;
+ return;
+ }
+
+ /* Activate the artifact */
+ msg_print(_("始動させた...", "You activate it..."));
+
+ /* Sound */
+ sound(SOUND_ZAP);
+
+ /* Activate object */
+ if (activation_index(o_ptr))
+ {
+ (void)activate_random_artifact(o_ptr);
+
+ /* Window stuff */
+ p_ptr->window |= (PW_INVEN | PW_EQUIP);
+
+ /* Success */
+ return;
+ }
+
+ /* Special items */
+ else if (o_ptr->tval == TV_WHISTLE)
+ {
+ if (music_singing_any()) stop_singing();
+ if (hex_spelling_any()) stop_hex_spell_all();
+
+#if 0
+ if (object_is_cursed(o_ptr))
+ {
+ msg_print(_("カン高い音が響き渡った。", "You produce a shrill whistling sound."));
+ aggravate_monsters(0);
+ }
+ else
+#endif
+ {
+ IDX pet_ctr, i;
+ IDX *who;
+ int max_pet = 0;
+ u16b dummy_why;
+
+ /* Allocate the "who" array */
+ C_MAKE(who, max_m_idx, IDX);
+
+ /* Process the monsters (backwards) */
+ for (pet_ctr = m_max - 1; pet_ctr >= 1; pet_ctr--)
+ {
+ if (is_pet(&m_list[pet_ctr]) && (p_ptr->riding != pet_ctr))
+ who[max_pet++] = pet_ctr;
+ }
+
+ /* Select the sort method */
+ ang_sort_comp = ang_sort_comp_pet;
+ ang_sort_swap = ang_sort_swap_hook;
+
+ ang_sort(who, &dummy_why, max_pet);
+
+ /* Process the monsters (backwards) */
+ for (i = 0; i < max_pet; i++)
+ {
+ pet_ctr = who[i];
+ teleport_monster_to(pet_ctr, p_ptr->y, p_ptr->x, 100, TELEPORT_PASSIVE);
+ }
+
+ /* Free the "who" array */
+ C_KILL(who, max_m_idx, IDX);
+ }
+ o_ptr->timeout = 100+randint1(100);
+ return;
+ }
+ else if (o_ptr->tval == TV_CAPTURE)
+ {
+ if(!o_ptr->pval)
+ {
+ bool old_target_pet = target_pet;
+ target_pet = TRUE;
+ if (!get_aim_dir(&dir))
+ {
+ target_pet = old_target_pet;
+ return;
+ }
+ target_pet = old_target_pet;
+
+ if(fire_ball(GF_CAPTURE, dir, 0, 0))
+ {
+ o_ptr->pval = (PARAMETER_VALUE)cap_mon;
+ o_ptr->xtra3 = (XTRA8)cap_mspeed;
+ o_ptr->xtra4 = (XTRA16)cap_hp;
+ o_ptr->xtra5 = (XTRA16)cap_maxhp;
+ if (cap_nickname)
+ {
+ cptr t;
+ char *s;
+ char buf[80] = "";
+
+ if (o_ptr->inscription)
+ strcpy(buf, quark_str(o_ptr->inscription));
+ s = buf;
+ for (s = buf;*s && (*s != '#'); s++)
+ {
+#ifdef JP
+ if (iskanji(*s)) s++;
+#endif
+ }
+ *s = '#';
+ s++;
+#ifdef JP
+ /*nothing*/
+#else
+ *s++ = '\'';
+#endif
+ t = quark_str(cap_nickname);
+ while (*t)
+ {
+ *s = *t;
+ s++;
+ t++;
+ }
+#ifdef JP
+ /*nothing*/
+#else
+ *s++ = '\'';
+#endif
+ *s = '\0';
+ o_ptr->inscription = quark_add(buf);
+ }
+ }
+ }
+ else
+ {
+ success = FALSE;
+ if (!get_rep_dir2(&dir)) return;
+ if (monster_can_enter(p_ptr->y + ddy[dir], p_ptr->x + ddx[dir], &r_info[o_ptr->pval], 0))
+ {
+ if (place_monster_aux(0, p_ptr->y + ddy[dir], p_ptr->x + ddx[dir], o_ptr->pval, (PM_FORCE_PET | PM_NO_KAGE)))
+ {
+ if (o_ptr->xtra3) m_list[hack_m_idx_ii].mspeed = o_ptr->xtra3;
+ if (o_ptr->xtra5) m_list[hack_m_idx_ii].max_maxhp = o_ptr->xtra5;
+ if (o_ptr->xtra4) m_list[hack_m_idx_ii].hp = o_ptr->xtra4;
+ m_list[hack_m_idx_ii].maxhp = m_list[hack_m_idx_ii].max_maxhp;
+ if (o_ptr->inscription)
+ {
+ char buf[80];
+ cptr t;
+#ifndef JP
+ bool quote = FALSE;
+#endif
+
+ t = quark_str(o_ptr->inscription);
+ for (t = quark_str(o_ptr->inscription);*t && (*t != '#'); t++)
+ {
+#ifdef JP
+ if (iskanji(*t)) t++;
+#endif
+ }
+ if (*t)
+ {
+ char *s = buf;
+ t++;
+#ifdef JP
+ /* nothing */
+#else
+ if (*t =='\'')
+ {
+ t++;
+ quote = TRUE;
+ }
+#endif
+ while(*t)
+ {
+ *s = *t;
+ t++;
+ s++;
+ }
+#ifdef JP
+ /* nothing */
+#else
+ if (quote && *(s-1) =='\'')
+ s--;
+#endif
+ *s = '\0';
+ m_list[hack_m_idx_ii].nickname = quark_add(buf);
+ t = quark_str(o_ptr->inscription);
+ s = buf;
+ while(*t && (*t != '#'))
+ {
+ *s = *t;
+ t++;
+ s++;
+ }
+ *s = '\0';
+ o_ptr->inscription = quark_add(buf);
+ }
+ }
+ o_ptr->pval = 0;
+ o_ptr->xtra3 = 0;
+ o_ptr->xtra4 = 0;
+ o_ptr->xtra5 = 0;
+ success = TRUE;
+ }
+ }
+ if (!success)
+ msg_print(_("おっと、解放に失敗した。", "Oops. You failed to release your pet."));
+ }
+ calc_android_exp();
+ return;
+ }
+
+ /* Mistake */
+ msg_print(_("おっと、このアイテムは始動できない。", "Oops. That object cannot be activated."));
+}
+
+/*!
+ * @brief 装備を発動するコマンドのメインルーチン /
+ * @return なし
+ */
+void do_cmd_activate(void)
+{
+ OBJECT_IDX item;
+ cptr q, s;
+
+
+ if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
+ {
+ set_action(ACTION_NONE);
+ }
+
+ item_tester_no_ryoute = TRUE;
+ /* Prepare the hook */
+ item_tester_hook = item_tester_hook_activate;
+
+ /* Get an item */
+ q = _("どのアイテムを始動させますか? ", "Activate which item? ");
+ s = _("始動できるアイテムを装備していない。", "You have nothing to activate.");
+
+ if (!get_item(&item, q, s, (USE_EQUIP))) return;
+
+ /* Activate the item */
+ do_cmd_activate_aux(item);
+}
+
+
+
--- /dev/null
+extern void do_cmd_activate(void);
+extern void do_cmd_activate_aux(int item);
+
+
*/
#include "angband.h"
-#include "selfinfo.h"
-#include "cmd-activate.h"
-#include "cmd-eat.h"
-#include "cmd-quaff.h"
-#include "cmd-read.h"
#include "cmd-usestaff.h"
#include "cmd-zaprod.h"
#include "cmd-zapwand.h"
/*!
- * @brief 『一つの指輪』の効果処理 /
- * Hack -- activate the ring of power
- * @param dir 発動の方向ID
- * @return なし
- */
-void ring_of_power(int dir)
-{
- /* Pick a random effect */
- switch (randint1(10))
- {
- case 1:
- case 2:
- {
- /* Message */
- msg_print(_("あなたは悪性のオーラに包み込まれた。", "You are surrounded by a malignant aura."));
- sound(SOUND_EVIL);
-
- /* Decrease all stats (permanently) */
- (void)dec_stat(A_STR, 50, TRUE);
- (void)dec_stat(A_INT, 50, TRUE);
- (void)dec_stat(A_WIS, 50, TRUE);
- (void)dec_stat(A_DEX, 50, TRUE);
- (void)dec_stat(A_CON, 50, TRUE);
- (void)dec_stat(A_CHR, 50, TRUE);
-
- /* Lose some experience (permanently) */
- p_ptr->exp -= (p_ptr->exp / 4);
- p_ptr->max_exp -= (p_ptr->exp / 4);
- check_experience();
-
- break;
- }
-
- case 3:
- {
- /* Message */
- msg_print(_("あなたは強力なオーラに包み込まれた。", "You are surrounded by a powerful aura."));
-
- /* Dispel monsters */
- dispel_monsters(1000);
-
- break;
- }
-
- case 4:
- case 5:
- case 6:
- {
- /* Mana Ball */
- fire_ball(GF_MANA, dir, 600, 3);
-
- break;
- }
-
- case 7:
- case 8:
- case 9:
- case 10:
- {
- /* Mana Bolt */
- fire_bolt(GF_MANA, dir, 500);
-
- break;
- }
- }
-}
-
-/*!
- * @brief オブジェクトをプレイヤーが簡易使用コマンドで利用できるかを判定する /
- * Hook to determine if an object is useable
- * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
- * @return 利用可能ならばTRUEを返す
- */
-static bool item_tester_hook_use(object_type *o_ptr)
-{
- u32b flgs[TR_FLAG_SIZE];
-
- /* Ammo */
- if (o_ptr->tval == p_ptr->tval_ammo)
- return (TRUE);
-
- /* Useable object */
- switch (o_ptr->tval)
- {
- case TV_SPIKE:
- case TV_STAFF:
- case TV_WAND:
- case TV_ROD:
- case TV_SCROLL:
- case TV_POTION:
- case TV_FOOD:
- {
- return (TRUE);
- }
-
- default:
- {
- int i;
-
- /* Not known */
- if (!object_is_known(o_ptr)) return (FALSE);
-
- /* HACK - only items from the equipment can be activated */
- for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
- {
- if (&inventory[i] == o_ptr)
- {
- /* Extract the flags */
- object_flags(o_ptr, flgs);
-
- /* Check activation flag */
- if (have_flag(flgs, TR_ACTIVATE)) return (TRUE);
- }
- }
- }
- }
-
- /* Assume not */
- return (FALSE);
-}
-
-
-/*!
- * @brief アイテムを汎用的に「使う」コマンドのメインルーチン /
- * Use an item
- * @return なし
- * @details
- * XXX - Add actions for other item types
- */
-void do_cmd_use(void)
-{
- OBJECT_IDX item;
- object_type *o_ptr;
- cptr q, s;
-
- if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
- {
- set_action(ACTION_NONE);
- }
-
- item_tester_no_ryoute = TRUE;
- /* Prepare the hook */
- item_tester_hook = item_tester_hook_use;
-
- /* Get an item */
- q = _("どれを使いますか?", "Use which item? ");
- s = _("使えるものがありません。", "You have nothing to use.");
-
- if (!get_item(&item, q, s, (USE_INVEN | USE_EQUIP | USE_FLOOR))) return;
-
- /* Get the item (in the pack) */
- if (item >= 0)
- {
- o_ptr = &inventory[item];
- }
- /* Get the item (on the floor) */
- else
- {
- o_ptr = &o_list[0 - item];
- }
-
- switch (o_ptr->tval)
- {
- /* Spike a door */
- case TV_SPIKE:
- {
- do_cmd_spike();
- break;
- }
-
- /* Eat some food */
- case TV_FOOD:
- {
- do_cmd_eat_food_aux(item);
- break;
- }
-
- /* Aim a wand */
- case TV_WAND:
- {
- do_cmd_aim_wand_aux(item);
- break;
- }
-
- /* Use a staff */
- case TV_STAFF:
- {
- do_cmd_use_staff_aux(item);
- break;
- }
-
- /* Zap a rod */
- case TV_ROD:
- {
- do_cmd_zap_rod_aux(item);
- break;
- }
-
- /* Quaff a potion */
- case TV_POTION:
- {
- do_cmd_quaff_potion_aux(item);
- break;
- }
-
- /* Read a scroll */
- case TV_SCROLL:
- {
- /* Check some conditions */
- if (p_ptr->blind)
- {
- msg_print(_("目が見えない。", "You can't see anything."));
- return;
- }
- if (no_lite())
- {
- msg_print(_("明かりがないので、暗くて読めない。", "You have no light to read by."));
- return;
- }
- if (p_ptr->confused)
- {
- msg_print(_("混乱していて読めない!", "You are too confused!"));
- return;
- }
-
- do_cmd_read_scroll_aux(item, TRUE);
- break;
- }
-
- /* Fire ammo */
- case TV_SHOT:
- case TV_ARROW:
- case TV_BOLT:
- {
- do_cmd_fire_aux(item, &inventory[INVEN_BOW]);
- break;
- }
-
- /* Activate an artifact */
- default:
- {
- do_cmd_activate_aux(item);
- break;
- }
- }
-}
-
-/*!
* @brief 魔道具術師の取り込んだ魔力一覧から選択/閲覧する /
* @param only_browse 閲覧するだけならばTRUE
* @return 選択した魔力のID、キャンセルならば-1を返す
--- /dev/null
+extern bool do_cmd_magic_eater(bool only_browse, bool powerful);
--- /dev/null
+#include "angband.h"
+
+/*!
+ * @brief \83\8d\83b\83h\82Ì\8cø\89Ê\82ð\94\93®\82·\82é
+ * @param sval \83I\83u\83W\83F\83N\83g\82Ìsval
+ * @param dir \94\93®\96Ú\95W\82Ì\95û\8cüID
+ * @param use_charge \83`\83\83\81[\83W\82ð\8fÁ\94ï\82µ\82½\82©\82Ç\82¤\82©\82ð\95Ô\82·\8eQ\8fÆ\83|\83C\83\93\83^
+ * @param powerful \8b\97Í\94\93®\8fã\82Ì\8f\88\97\9d\82È\82ç\82ÎTRUE
+ * @param magic \96\82\93¹\8bï\8fp\8fã\82Ì\8f\88\97\9d\82È\82ç\82ÎTRUE
+ * @return \94\93®\82É\82æ\82è\8cø\89Ê\93à\97e\82ª\8am\92è\82µ\82½\82È\82ç\82ÎTRUE\82ð\95Ô\82·
+ */
+int rod_effect(OBJECT_SUBTYPE_VALUE sval, int dir, bool *use_charge, bool powerful, bool magic)
+{
+ int ident = FALSE;
+ int lev = powerful ? p_ptr->lev * 2 : p_ptr->lev;
+ int detect_rad = powerful ? DETECT_RAD_DEFAULT * 3 / 2 : DETECT_RAD_DEFAULT;
+ int rad = powerful ? 3 : 2;
+
+ /* Unused */
+ (void)magic;
+
+ /* Analyze the rod */
+ switch (sval)
+ {
+ case SV_ROD_DETECT_TRAP:
+ {
+ if (detect_traps(detect_rad, (bool)(dir ? FALSE : TRUE))) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_DETECT_DOOR:
+ {
+ if (detect_doors(detect_rad)) ident = TRUE;
+ if (detect_stairs(detect_rad)) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_IDENTIFY:
+ {
+ if (powerful) {
+ if (!identify_fully(FALSE)) *use_charge = FALSE;
+ }
+ else {
+ if (!ident_spell(FALSE)) *use_charge = FALSE;
+ }
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_RECALL:
+ {
+ if (!word_of_recall()) *use_charge = FALSE;
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_ILLUMINATION:
+ {
+ if (lite_area(damroll(2, 8), (powerful ? 4 : 2))) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_MAPPING:
+ {
+ map_area(powerful ? DETECT_RAD_MAP * 3 / 2 : DETECT_RAD_MAP);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_DETECTION:
+ {
+ detect_all(detect_rad);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_PROBING:
+ {
+ probing();
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_CURING:
+ {
+ if (set_blind(0)) ident = TRUE;
+ if (set_poisoned(0)) ident = TRUE;
+ if (set_confused(0)) ident = TRUE;
+ if (set_stun(0)) ident = TRUE;
+ if (set_cut(0)) ident = TRUE;
+ if (set_image(0)) ident = TRUE;
+ if (set_shero(0, TRUE)) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_HEALING:
+ {
+ if (hp_player(powerful ? 750 : 500)) ident = TRUE;
+ if (set_stun(0)) ident = TRUE;
+ if (set_cut(0)) ident = TRUE;
+ if (set_shero(0, TRUE)) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_RESTORATION:
+ {
+ if (restore_level()) ident = TRUE;
+ if (do_res_stat(A_STR)) ident = TRUE;
+ if (do_res_stat(A_INT)) ident = TRUE;
+ if (do_res_stat(A_WIS)) ident = TRUE;
+ if (do_res_stat(A_DEX)) ident = TRUE;
+ if (do_res_stat(A_CON)) ident = TRUE;
+ if (do_res_stat(A_CHR)) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_SPEED:
+ {
+ if (set_fast(randint1(30) + (powerful ? 30 : 15), FALSE)) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_PESTICIDE:
+ {
+ if (dispel_monsters(powerful ? 8 : 4)) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_TELEPORT_AWAY:
+ {
+ int distance = MAX_SIGHT * (powerful ? 8 : 5);
+ if (teleport_monster(dir, distance)) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_DISARMING:
+ {
+ if (disarm_trap(dir)) ident = TRUE;
+ if (powerful && disarm_traps_touch()) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_LITE:
+ {
+ HIT_POINT dam = damroll((powerful ? 12 : 6), 8);
+ msg_print(_("\90Â\82\8bP\82\8cõ\90ü\82ª\95ú\82½\82ê\82½\81B", "A line of blue shimmering light appears."));
+ (void)lite_line(dir, dam);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_SLEEP_MONSTER:
+ {
+ if (sleep_monster(dir, lev)) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_SLOW_MONSTER:
+ {
+ if (slow_monster(dir, lev)) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_HYPODYNAMIA:
+ {
+ if (hypodynamic_bolt(dir, 70 + 3 * lev / 2)) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_POLYMORPH:
+ {
+ if (poly_monster(dir, lev)) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_ACID_BOLT:
+ {
+ fire_bolt_or_beam(10, GF_ACID, dir, damroll(6 + lev / 7, 8));
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_ELEC_BOLT:
+ {
+ fire_bolt_or_beam(10, GF_ELEC, dir, damroll(4 + lev / 9, 8));
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_FIRE_BOLT:
+ {
+ fire_bolt_or_beam(10, GF_FIRE, dir, damroll(7 + lev / 6, 8));
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_COLD_BOLT:
+ {
+ fire_bolt_or_beam(10, GF_COLD, dir, damroll(5 + lev / 8, 8));
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_ACID_BALL:
+ {
+ fire_ball(GF_ACID, dir, 60 + lev, rad);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_ELEC_BALL:
+ {
+ fire_ball(GF_ELEC, dir, 40 + lev, rad);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_FIRE_BALL:
+ {
+ fire_ball(GF_FIRE, dir, 70 + lev, rad);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_COLD_BALL:
+ {
+ fire_ball(GF_COLD, dir, 50 + lev, rad);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_HAVOC:
+ {
+ call_chaos();
+ ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_STONE_TO_MUD:
+ {
+ HIT_POINT dam = powerful ? 40 + randint1(60) : 20 + randint1(30);
+ if (wall_to_mud(dir, dam)) ident = TRUE;
+ break;
+ }
+
+ case SV_ROD_AGGRAVATE:
+ {
+ aggravate_monsters(0);
+ ident = TRUE;
+ break;
+ }
+ }
+ return ident;
+}
+
+/*!
+* @brief \83\8d\83b\83h\82ð\8eg\82¤\83R\83}\83\93\83h\82Ì\83T\83u\83\8b\81[\83`\83\93 /
+* Activate (zap) a Rod
+* @param item \8eg\82¤\83I\83u\83W\83F\83N\83g\82Ì\8f\8a\8e\9d\95iID
+* @return \82È\82µ
+* @details
+* <pre>
+* Unstack fully charged rods as needed.
+* Hack -- rods of perception/genocide can be "cancelled"
+* All rods can be cancelled at the "Direction?" prompt
+* pvals are defined for each rod in k_info. -LM-
+* </pre>
+*/
+void do_cmd_zap_rod_aux(int item)
+{
+ int ident, chance, lev, fail;
+ int dir = 0;
+ object_type *o_ptr;
+ bool success;
+
+ /* Hack -- let perception get aborted */
+ bool use_charge = TRUE;
+
+ object_kind *k_ptr;
+
+ /* Get the item (in the pack) */
+ if (item >= 0)
+ {
+ o_ptr = &inventory[item];
+ }
+
+ /* Get the item (on the floor) */
+ else
+ {
+ o_ptr = &o_list[0 - item];
+ }
+
+
+ /* Mega-Hack -- refuse to zap a pile from the ground */
+ if ((item < 0) && (o_ptr->number > 1))
+ {
+ msg_print(_("\82Ü\82¸\82Í\83\8d\83b\83h\82ð\8fE\82í\82È\82¯\82ê\82Î\81B", "You must first pick up the rods."));
+ return;
+ }
+
+
+ /* Get a direction (unless KNOWN not to need it) */
+ if (((o_ptr->sval >= SV_ROD_MIN_DIRECTION) && (o_ptr->sval != SV_ROD_HAVOC) && (o_ptr->sval != SV_ROD_AGGRAVATE) && (o_ptr->sval != SV_ROD_PESTICIDE)) ||
+ !object_is_aware(o_ptr))
+ {
+ /* Get a direction, allow cancel */
+ if (!get_aim_dir(&dir)) return;
+ }
+
+
+ /* Take a turn */
+ p_ptr->energy_use = 100;
+
+ /* Extract the item level */
+ lev = k_info[o_ptr->k_idx].level;
+
+ /* Base chance of success */
+ chance = p_ptr->skill_dev;
+
+ /* Confusion hurts skill */
+ if (p_ptr->confused) chance = chance / 2;
+
+ fail = lev + 5;
+ if (chance > fail) fail -= (chance - fail) * 2;
+ else chance -= (fail - chance) * 2;
+ if (fail < USE_DEVICE) fail = USE_DEVICE;
+ if (chance < USE_DEVICE) chance = USE_DEVICE;
+
+ if (world_player)
+ {
+ if (flush_failure) flush();
+ msg_print(_("\8e~\82Ü\82Á\82½\8e\9e\82Ì\92\86\82Å\82Í\82¤\82Ü\82\93\82©\82È\82¢\82æ\82¤\82¾\81B", "Nothing happen. Maybe this rod is freezing too."));
+ sound(SOUND_FAIL);
+ return;
+ }
+
+ if (p_ptr->pclass == CLASS_BERSERKER) success = FALSE;
+ else if (chance > fail)
+ {
+ if (randint0(chance * 2) < fail) success = FALSE;
+ else success = TRUE;
+ }
+ else
+ {
+ if (randint0(fail * 2) < chance) success = TRUE;
+ else success = FALSE;
+ }
+
+ /* Roll for usage */
+ if (!success)
+ {
+ if (flush_failure) flush();
+ msg_print(_("\82¤\82Ü\82\83\8d\83b\83h\82ð\8eg\82¦\82È\82©\82Á\82½\81B", "You failed to use the rod properly."));
+ sound(SOUND_FAIL);
+ return;
+ }
+
+ k_ptr = &k_info[o_ptr->k_idx];
+
+ /* A single rod is still charging */
+ if ((o_ptr->number == 1) && (o_ptr->timeout))
+ {
+ if (flush_failure) flush();
+ msg_print(_("\82±\82Ì\83\8d\83b\83h\82Í\82Ü\82¾\96\82\97Í\82ð\8f[\93U\82µ\82Ä\82¢\82é\8dÅ\92\86\82¾\81B", "The rod is still charging."));
+ return;
+ }
+ /* A stack of rods lacks enough energy. */
+ else if ((o_ptr->number > 1) && (o_ptr->timeout > k_ptr->pval * (o_ptr->number - 1)))
+ {
+ if (flush_failure) flush();
+ msg_print(_("\82»\82Ì\83\8d\83b\83h\82Í\82Ü\82¾\8f[\93U\92\86\82Å\82·\81B", "The rods are all still charging."));
+ return;
+ }
+
+ /* Sound */
+ sound(SOUND_ZAP);
+
+ ident = rod_effect(o_ptr->sval, dir, &use_charge, FALSE, FALSE);
+
+ /* Increase the timeout by the rod kind's pval. -LM- */
+ if (use_charge) o_ptr->timeout += k_ptr->pval;
+
+ /* Combine / Reorder the pack (later) */
+ p_ptr->notice |= (PN_COMBINE | PN_REORDER);
+
+ if (!(object_is_aware(o_ptr)))
+ {
+ chg_virtue(V_PATIENCE, -1);
+ chg_virtue(V_CHANCE, 1);
+ chg_virtue(V_KNOWLEDGE, -1);
+ }
+
+ /* Tried the object */
+ object_tried(o_ptr);
+
+ /* Successfully determined the object function */
+ if (ident && !object_is_aware(o_ptr))
+ {
+ object_aware(o_ptr);
+ gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev);
+ }
+
+ /* Window stuff */
+ p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
+}
+
+/*!
+* @brief \83\8d\83b\83h\82ð\8eg\82¤\83R\83}\83\93\83h\82Ì\83\81\83C\83\93\83\8b\81[\83`\83\93 /
+* @return \82È\82µ
+*/
+void do_cmd_zap_rod(void)
+{
+ OBJECT_IDX item;
+ cptr q, s;
+
+ if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
+ {
+ set_action(ACTION_NONE);
+ }
+
+ /* Restrict choices to rods */
+ item_tester_tval = TV_ROD;
+
+ /* Get an item */
+ q = _("\82Ç\82Ì\83\8d\83b\83h\82ð\90U\82è\82Ü\82·\82©? ", "Zap which rod? ");
+ s = _("\8eg\82¦\82é\83\8d\83b\83h\82ª\82È\82¢\81B", "You have no rod to zap.");
+
+ if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+
+ /* Zap the rod */
+ do_cmd_zap_rod_aux(item);
+}
--- /dev/null
+extern int rod_effect(OBJECT_SUBTYPE_VALUE sval, int dir, bool *use_charge, bool powerful, bool magic);
+extern void do_cmd_zap_rod_aux(int item);
+extern void do_cmd_zap_rod(void);
--- /dev/null
+#include "angband.h"
+
+
+/*!
+* @brief \96\82\96@\96_\82Ì\8cø\89Ê\82ð\94\93®\82·\82é
+* @param sval \83I\83u\83W\83F\83N\83g\82Ìsval
+* @param dir \94\93®\82Ì\95û\8cüID
+* @param powerful \8b\97Í\94\93®\8fã\82Ì\8f\88\97\9d\82È\82ç\82ÎTRUE
+* @param magic \96\82\93¹\8bï\8fp\8fã\82Ì\8f\88\97\9d\82È\82ç\82ÎTRUE
+* @return \94\93®\82É\82æ\82è\8cø\89Ê\93à\97e\82ª\8am\92è\82µ\82½\82È\82ç\82ÎTRUE\82ð\95Ô\82·
+*/
+int wand_effect(OBJECT_SUBTYPE_VALUE sval, int dir, bool powerful, bool magic)
+{
+ int ident = FALSE;
+ int lev = powerful ? p_ptr->lev * 2 : p_ptr->lev;
+ int rad = powerful ? 3 : 2;
+
+ /* XXX Hack -- Wand of wonder can do anything before it */
+ if (sval == SV_WAND_WONDER)
+ {
+ int vir = virtue_number(V_CHANCE);
+ sval = (OBJECT_SUBTYPE_VALUE)randint0(SV_WAND_WONDER);
+
+ if (vir)
+ {
+ if (p_ptr->virtues[vir - 1] > 0)
+ {
+ while (randint1(300) < p_ptr->virtues[vir - 1]) sval++;
+ if (sval > SV_WAND_COLD_BALL) sval = randint0(4) + SV_WAND_ACID_BALL;
+ }
+ else
+ {
+ while (randint1(300) < (0 - p_ptr->virtues[vir - 1])) sval--;
+ if (sval < SV_WAND_HEAL_MONSTER) sval = randint0(3) + SV_WAND_HEAL_MONSTER;
+ }
+ }
+ if (sval < SV_WAND_TELEPORT_AWAY)
+ chg_virtue(V_CHANCE, 1);
+ }
+
+ /* Analyze the wand */
+ switch (sval)
+ {
+ case SV_WAND_HEAL_MONSTER:
+ {
+ HIT_POINT dam = damroll((powerful ? 20 : 10), 10);
+ if (heal_monster(dir, dam)) ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_HASTE_MONSTER:
+ {
+ if (speed_monster(dir, lev)) ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_CLONE_MONSTER:
+ {
+ if (clone_monster(dir)) ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_TELEPORT_AWAY:
+ {
+ int distance = MAX_SIGHT * (powerful ? 8 : 5);
+ if (teleport_monster(dir, distance)) ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_DISARMING:
+ {
+ if (disarm_trap(dir)) ident = TRUE;
+ if (powerful && disarm_traps_touch()) ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_TRAP_DOOR_DEST:
+ {
+ if (destroy_door(dir)) ident = TRUE;
+ if (powerful && destroy_doors_touch()) ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_STONE_TO_MUD:
+ {
+ HIT_POINT dam = powerful ? 40 + randint1(60) : 20 + randint1(30);
+ if (wall_to_mud(dir, dam)) ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_LITE:
+ {
+ HIT_POINT dam = damroll((powerful ? 12 : 6), 8);
+ msg_print(_("\90Â\82\8bP\82\8cõ\90ü\82ª\95ú\82½\82ê\82½\81B", "A line of blue shimmering light appears."));
+ (void)lite_line(dir, dam);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_SLEEP_MONSTER:
+ {
+ if (sleep_monster(dir, lev)) ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_SLOW_MONSTER:
+ {
+ if (slow_monster(dir, lev)) ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_CONFUSE_MONSTER:
+ {
+ if (confuse_monster(dir, lev)) ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_FEAR_MONSTER:
+ {
+ if (fear_monster(dir, lev)) ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_HYPODYNAMIA:
+ {
+ if (hypodynamic_bolt(dir, 80 + lev)) ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_POLYMORPH:
+ {
+ if (poly_monster(dir, lev)) ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_STINKING_CLOUD:
+ {
+ fire_ball(GF_POIS, dir, 12 + lev / 4, rad);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_MAGIC_MISSILE:
+ {
+ fire_bolt_or_beam(20, GF_MISSILE, dir, damroll(2 + lev / 10, 6));
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_ACID_BOLT:
+ {
+ fire_bolt_or_beam(20, GF_ACID, dir, damroll(6 + lev / 7, 8));
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_CHARM_MONSTER:
+ {
+ if (charm_monster(dir, MAX(20, lev)))
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_FIRE_BOLT:
+ {
+ fire_bolt_or_beam(20, GF_FIRE, dir, damroll(7 + lev / 6, 8));
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_COLD_BOLT:
+ {
+ fire_bolt_or_beam(20, GF_COLD, dir, damroll(5 + lev / 8, 8));
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_ACID_BALL:
+ {
+ fire_ball(GF_ACID, dir, 60 + 3 * lev / 4, rad);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_ELEC_BALL:
+ {
+ fire_ball(GF_ELEC, dir, 40 + 3 * lev / 4, rad);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_FIRE_BALL:
+ {
+ fire_ball(GF_FIRE, dir, 70 + 3 * lev / 4, rad);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_COLD_BALL:
+ {
+ fire_ball(GF_COLD, dir, 50 + 3 * lev / 4, rad);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_WONDER:
+ {
+ msg_print(_("\82¨\82Á\82Æ\81A\93ä\82Ì\96\82\96@\96_\82ð\8en\93®\82³\82¹\82½\81B", "Oops. Wand of wonder activated."));
+ break;
+ }
+
+ case SV_WAND_DRAGON_FIRE:
+ {
+ fire_breath(GF_FIRE, dir, (powerful ? 300 : 200), 3);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_DRAGON_COLD:
+ {
+ fire_breath(GF_COLD, dir, (powerful ? 270 : 180), 3);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_DRAGON_BREATH:
+ {
+ HIT_POINT dam;
+ int typ;
+
+ switch (randint1(5))
+ {
+ case 1:
+ dam = 240;
+ typ = GF_ACID;
+ break;
+ case 2:
+ dam = 210;
+ typ = GF_ELEC;
+ break;
+ case 3:
+ dam = 240;
+ typ = GF_FIRE;
+ break;
+ case 4:
+ dam = 210;
+ typ = GF_COLD;
+ break;
+ default:
+ dam = 180;
+ typ = GF_POIS;
+ break;
+ }
+
+ if (powerful) dam = (dam * 3) / 2;
+
+ fire_ball(typ, dir, dam, -3);
+
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_DISINTEGRATE:
+ {
+ fire_ball(GF_DISINTEGRATE, dir, 200 + randint1(lev * 2), rad);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_ROCKETS:
+ {
+ msg_print(_("\83\8d\83P\83b\83g\82ð\94\8eË\82µ\82½\81I", "You launch a rocket!"));
+ fire_rocket(GF_ROCKET, dir, 250 + lev * 3, rad);
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_STRIKING:
+ {
+ fire_bolt(GF_METEOR, dir, damroll(15 + lev / 3, 13));
+ ident = TRUE;
+ break;
+ }
+
+ case SV_WAND_GENOCIDE:
+ {
+ fire_ball_hide(GF_GENOCIDE, dir, magic ? lev + 50 : 250, 0);
+ ident = TRUE;
+ break;
+ }
+ }
+ return ident;
+}
+
+/*!
+* @brief \96\82\96@\96_\82ð\8eg\82¤\83R\83}\83\93\83h\82Ì\83T\83u\83\8b\81[\83`\83\93 /
+* Aim a wand (from the pack or floor).
+* @param item \8eg\82¤\83I\83u\83W\83F\83N\83g\82Ì\8f\8a\8e\9d\95iID
+* @return \82È\82µ
+* @details
+* <pre>
+* Use a single charge from a single item.
+* Handle "unstacking" in a logical manner.
+* For simplicity, you cannot use a stack of items from the
+* ground. This would require too much nasty code.
+* There are no wands which can "destroy" themselves, in the inventory
+* or on the ground, so we can ignore this possibility. Note that this
+* required giving "wand of wonder" the ability to ignore destruction
+* by electric balls.
+* All wands can be "cancelled" at the "Direction?" prompt for free.
+* Note that the basic "bolt" wands do slightly less damage than the
+* basic "bolt" rods, but the basic "ball" wands do the same damage
+* as the basic "ball" rods.
+* </pre>
+*/
+void do_cmd_aim_wand_aux(int item)
+{
+ int lev, ident, chance, dir;
+ object_type *o_ptr;
+ bool old_target_pet = target_pet;
+
+ /* Get the item (in the pack) */
+ if (item >= 0)
+ {
+ o_ptr = &inventory[item];
+ }
+
+ /* Get the item (on the floor) */
+ else
+ {
+ o_ptr = &o_list[0 - item];
+ }
+
+ /* Mega-Hack -- refuse to aim a pile from the ground */
+ if ((item < 0) && (o_ptr->number > 1))
+ {
+ msg_print(_("\82Ü\82¸\82Í\96\82\96@\96_\82ð\8fE\82í\82È\82¯\82ê\82Î\81B", "You must first pick up the wands."));
+ return;
+ }
+
+
+ /* Allow direction to be cancelled for free */
+ if (object_is_aware(o_ptr) && (o_ptr->sval == SV_WAND_HEAL_MONSTER
+ || o_ptr->sval == SV_WAND_HASTE_MONSTER))
+ target_pet = TRUE;
+ if (!get_aim_dir(&dir))
+ {
+ target_pet = old_target_pet;
+ return;
+ }
+ target_pet = old_target_pet;
+
+ /* Take a turn */
+ p_ptr->energy_use = 100;
+
+ /* Get the level */
+ lev = k_info[o_ptr->k_idx].level;
+ if (lev > 50) lev = 50 + (lev - 50) / 2;
+
+ /* Base chance of success */
+ chance = p_ptr->skill_dev;
+
+ /* Confusion hurts skill */
+ if (p_ptr->confused) chance = chance / 2;
+
+ /* Hight level objects are harder */
+ chance = chance - lev;
+
+ /* Give everyone a (slight) chance */
+ if ((chance < USE_DEVICE) && one_in_(USE_DEVICE - chance + 1))
+ {
+ chance = USE_DEVICE;
+ }
+
+ if (world_player)
+ {
+ if (flush_failure) flush();
+ msg_print(_("\8e~\82Ü\82Á\82½\8e\9e\82Ì\92\86\82Å\82Í\82¤\82Ü\82\93\82©\82È\82¢\82æ\82¤\82¾\81B", "Nothing happen. Maybe this wand is freezing too."));
+ sound(SOUND_FAIL);
+ return;
+ }
+
+ /* Roll for usage */
+ if ((chance < USE_DEVICE) || (randint1(chance) < USE_DEVICE) || (p_ptr->pclass == CLASS_BERSERKER))
+ {
+ if (flush_failure) flush();
+ msg_print(_("\96\82\96@\96_\82ð\82¤\82Ü\82\8eg\82¦\82È\82©\82Á\82½\81B", "You failed to use the wand properly."));
+ sound(SOUND_FAIL);
+ return;
+ }
+
+ /* The wand is already empty! */
+ if (o_ptr->pval <= 0)
+ {
+ if (flush_failure) flush();
+ msg_print(_("\82±\82Ì\96\82\96@\96_\82É\82Í\82à\82¤\96\82\97Í\82ª\8ec\82Á\82Ä\82¢\82È\82¢\81B", "The wand has no charges left."));
+ o_ptr->ident |= (IDENT_EMPTY);
+
+ /* Combine / Reorder the pack (later) */
+ p_ptr->notice |= (PN_COMBINE | PN_REORDER);
+ p_ptr->window |= (PW_INVEN);
+
+ return;
+ }
+
+ /* Sound */
+ sound(SOUND_ZAP);
+
+ ident = wand_effect(o_ptr->sval, dir, FALSE, FALSE);
+
+ /* Combine / Reorder the pack (later) */
+ p_ptr->notice |= (PN_COMBINE | PN_REORDER);
+
+ if (!(object_is_aware(o_ptr)))
+ {
+ chg_virtue(V_PATIENCE, -1);
+ chg_virtue(V_CHANCE, 1);
+ chg_virtue(V_KNOWLEDGE, -1);
+ }
+
+ /* Mark it as tried */
+ object_tried(o_ptr);
+
+ /* Apply identification */
+ if (ident && !object_is_aware(o_ptr))
+ {
+ object_aware(o_ptr);
+ gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev);
+ }
+
+ /* Window stuff */
+ p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
+
+
+ /* Use a single charge */
+ o_ptr->pval--;
+
+ /* Describe the charges in the pack */
+ if (item >= 0)
+ {
+ inven_item_charges(item);
+ }
+
+ /* Describe the charges on the floor */
+ else
+ {
+ floor_item_charges(0 - item);
+ }
+}
+
+/*!
+* @brief \96\82\96@\96_\82ð\8eg\82¤\83R\83}\83\93\83h\82Ì\83\81\83C\83\93\83\8b\81[\83`\83\93 /
+* @return \82È\82µ
+*/
+void do_cmd_aim_wand(void)
+{
+ OBJECT_IDX item;
+ cptr q, s;
+
+ /* Restrict choices to wands */
+ item_tester_tval = TV_WAND;
+
+ if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
+ {
+ set_action(ACTION_NONE);
+ }
+
+ /* Get an item */
+ q = _("\82Ç\82Ì\96\82\96@\96_\82Å\91_\82¢\82Ü\82·\82©? ", "Aim which wand? ");
+ s = _("\8eg\82¦\82é\96\82\96@\96_\82ª\82È\82¢\81B", "You have no wand to aim.");
+
+ if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+
+ /* Aim the wand */
+ do_cmd_aim_wand_aux(item);
+}
--- /dev/null
+extern int wand_effect(OBJECT_SUBTYPE_VALUE sval, int dir, bool powerful, bool magic);
+extern void do_cmd_aim_wand_aux(int item);
+extern void do_cmd_aim_wand(void);
#include "angband.h"
+#include "selfinfo.h"
+#include "cmd-activate.h"
+#include "cmd-eat.h"
+#include "cmd-quaff.h"
+#include "cmd-read.h"
+#include "cmd-usestaff.h"
+#include "cmd-zaprod.h"
+#include "cmd-zapwand.h"
}
+/*!
+* @brief オブジェクトをプレイヤーが簡易使用コマンドで利用できるかを判定する /
+* Hook to determine if an object is useable
+* @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
+* @return 利用可能ならばTRUEを返す
+*/
+static bool item_tester_hook_use(object_type *o_ptr)
+{
+ u32b flgs[TR_FLAG_SIZE];
+
+ /* Ammo */
+ if (o_ptr->tval == p_ptr->tval_ammo)
+ return (TRUE);
+
+ /* Useable object */
+ switch (o_ptr->tval)
+ {
+ case TV_SPIKE:
+ case TV_STAFF:
+ case TV_WAND:
+ case TV_ROD:
+ case TV_SCROLL:
+ case TV_POTION:
+ case TV_FOOD:
+ {
+ return (TRUE);
+ }
+
+ default:
+ {
+ int i;
+
+ /* Not known */
+ if (!object_is_known(o_ptr)) return (FALSE);
+
+ /* HACK - only items from the equipment can be activated */
+ for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
+ {
+ if (&inventory[i] == o_ptr)
+ {
+ /* Extract the flags */
+ object_flags(o_ptr, flgs);
+
+ /* Check activation flag */
+ if (have_flag(flgs, TR_ACTIVATE)) return (TRUE);
+ }
+ }
+ }
+ }
+
+ /* Assume not */
+ return (FALSE);
+}
+
+
+/*!
+ * @brief アイテムを汎用的に「使う」コマンドのメインルーチン /
+ * Use an item
+ * @return なし
+ * @details
+ * XXX - Add actions for other item types
+ */
+void do_cmd_use(void)
+{
+ OBJECT_IDX item;
+ object_type *o_ptr;
+ cptr q, s;
+
+ if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
+ {
+ set_action(ACTION_NONE);
+ }
+
+ item_tester_no_ryoute = TRUE;
+ /* Prepare the hook */
+ item_tester_hook = item_tester_hook_use;
+
+ /* Get an item */
+ q = _("どれを使いますか?", "Use which item? ");
+ s = _("使えるものがありません。", "You have nothing to use.");
+
+ if (!get_item(&item, q, s, (USE_INVEN | USE_EQUIP | USE_FLOOR))) return;
+
+ /* Get the item (in the pack) */
+ if (item >= 0)
+ {
+ o_ptr = &inventory[item];
+ }
+ /* Get the item (on the floor) */
+ else
+ {
+ o_ptr = &o_list[0 - item];
+ }
+
+ switch (o_ptr->tval)
+ {
+ /* Spike a door */
+ case TV_SPIKE:
+ {
+ do_cmd_spike();
+ break;
+ }
+
+ /* Eat some food */
+ case TV_FOOD:
+ {
+ do_cmd_eat_food_aux(item);
+ break;
+ }
+
+ /* Aim a wand */
+ case TV_WAND:
+ {
+ do_cmd_aim_wand_aux(item);
+ break;
+ }
+
+ /* Use a staff */
+ case TV_STAFF:
+ {
+ do_cmd_use_staff_aux(item);
+ break;
+ }
+
+ /* Zap a rod */
+ case TV_ROD:
+ {
+ do_cmd_zap_rod_aux(item);
+ break;
+ }
+
+ /* Quaff a potion */
+ case TV_POTION:
+ {
+ do_cmd_quaff_potion_aux(item);
+ break;
+ }
+
+ /* Read a scroll */
+ case TV_SCROLL:
+ {
+ /* Check some conditions */
+ if (p_ptr->blind)
+ {
+ msg_print(_("目が見えない。", "You can't see anything."));
+ return;
+ }
+ if (no_lite())
+ {
+ msg_print(_("明かりがないので、暗くて読めない。", "You have no light to read by."));
+ return;
+ }
+ if (p_ptr->confused)
+ {
+ msg_print(_("混乱していて読めない!", "You are too confused!"));
+ return;
+ }
+
+ do_cmd_read_scroll_aux(item, TRUE);
+ break;
+ }
+
+ /* Fire ammo */
+ case TV_SHOT:
+ case TV_ARROW:
+ case TV_BOLT:
+ {
+ do_cmd_fire_aux(item, &inventory[INVEN_BOW]);
+ break;
+ }
+
+ /* Activate an artifact */
+ default:
+ {
+ do_cmd_activate_aux(item);
+ break;
+ }
+ }
+}
+
#include "angband.h"
#include "cmd-activate.h"
#include "cmd-eat.h"
+#include "cmd-magiceat.h"
#include "cmd-quaff.h"
#include "cmd-read.h"
#include "cmd-usestaff.h"
extern void kamaenaoshi(int item);
extern bool ang_sort_comp_hook(vptr u, vptr v, int a, int b);
extern void ang_sort_swap_hook(vptr u, vptr v, int a, int b);
+extern void do_cmd_use(void);
/* cmd4.c */
#ifndef JP
extern void do_cmd_pet_dismiss(void);
extern void do_cmd_pet(void);
-/* cmd6.c */
-extern void do_cmd_rerate_aux(void);
-extern void do_cmd_rerate(bool display);
-extern void ring_of_power(int dir);
-extern void do_cmd_use(void);
-extern bool do_cmd_magic_eater(bool only_browse, bool powerful);
-
/* do-spell.c */
extern void stop_singing(void);
extern cptr do_spell(REALM_IDX realm, SPELL_IDX spell, BIT_FLAGS mode);
extern bool kawarimi(bool success);
extern bool rush_attack(bool *mdeath);
extern void remove_all_mirrors(bool explode);
+extern void ring_of_power(int dir);
/* spells3.c */
extern bool teleport_away(MONSTER_IDX m_idx, int dis, BIT_FLAGS mode);
/* wizard2.c */
extern void strip_name(char *buf, KIND_OBJECT_IDX k_idx);
+extern void do_cmd_rerate_aux(void);
+extern void do_cmd_rerate(bool display);
/* avatar.c */
extern bool compare_virtue(int type, int num, int tekitou);
*/
#include "angband.h"
+#include "cmd-magiceat.h"
#include "cmd-zapwand.h"
/*!
}
}
}
+
+/*!
+ * @brief 『一つの指輪』の効果処理 /
+ * Hack -- activate the ring of power
+ * @param dir 発動の方向ID
+ * @return なし
+ */
+void ring_of_power(int dir)
+{
+ /* Pick a random effect */
+ switch (randint1(10))
+ {
+ case 1:
+ case 2:
+ {
+ /* Message */
+ msg_print(_("あなたは悪性のオーラに包み込まれた。", "You are surrounded by a malignant aura."));
+ sound(SOUND_EVIL);
+
+ /* Decrease all stats (permanently) */
+ (void)dec_stat(A_STR, 50, TRUE);
+ (void)dec_stat(A_INT, 50, TRUE);
+ (void)dec_stat(A_WIS, 50, TRUE);
+ (void)dec_stat(A_DEX, 50, TRUE);
+ (void)dec_stat(A_CON, 50, TRUE);
+ (void)dec_stat(A_CHR, 50, TRUE);
+
+ /* Lose some experience (permanently) */
+ p_ptr->exp -= (p_ptr->exp / 4);
+ p_ptr->max_exp -= (p_ptr->exp / 4);
+ check_experience();
+
+ break;
+ }
+
+ case 3:
+ {
+ /* Message */
+ msg_print(_("あなたは強力なオーラに包み込まれた。", "You are surrounded by a powerful aura."));
+
+ /* Dispel monsters */
+ dispel_monsters(1000);
+
+ break;
+ }
+
+ case 4:
+ case 5:
+ case 6:
+ {
+ /* Mana Ball */
+ fire_ball(GF_MANA, dir, 600, 3);
+
+ break;
+ }
+
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ {
+ /* Mana Bolt */
+ fire_bolt(GF_MANA, dir, 500);
+
+ break;
+ }
+ }
+}
+
#include "angband.h"
#include "cmd-zapwand.h"
+#include "cmd-magiceat.h"
#define MIN_STOCK 12