OSDN Git Service

[Refactor] #37353 cmd6.cをcmd-magiceat.cに改名しつつ整理。 / Refactor to rename cmd6.c to cmd...
authorDeskull <deskull@users.sourceforge.jp>
Sat, 8 Sep 2018 11:31:13 +0000 (20:31 +0900)
committerDeskull <deskull@users.sourceforge.jp>
Sat, 8 Sep 2018 11:31:13 +0000 (20:31 +0900)
16 files changed:
Hengband_vcs2015/Hengband/Hengband.vcxproj
Hengband_vcs2015/Hengband/Hengband.vcxproj.filters
src/cmd-activate.c [new file with mode: 0644]
src/cmd-activate.h [new file with mode: 0644]
src/cmd-magiceat.c [moved from src/cmd6.c with 77% similarity]
src/cmd-magiceat.h [new file with mode: 0644]
src/cmd-zaprod.c [new file with mode: 0644]
src/cmd-zaprod.h [new file with mode: 0644]
src/cmd-zapwand.c [new file with mode: 0644]
src/cmd-zapwand.h [new file with mode: 0644]
src/cmd3.c
src/dungeon.c
src/externs.h
src/racial.c
src/spells2.c
src/store.c

index 190d9d7..2793217 100644 (file)
     <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
index 18583e1..70401f8 100644 (file)
@@ -34,9 +34,6 @@
     <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
diff --git a/src/cmd-activate.c b/src/cmd-activate.c
new file mode 100644 (file)
index 0000000..11f5b84
--- /dev/null
@@ -0,0 +1,418 @@
+/*!
+* @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);
+}
+
+
+
diff --git a/src/cmd-activate.h b/src/cmd-activate.h
new file mode 100644 (file)
index 0000000..2f01fec
--- /dev/null
@@ -0,0 +1,4 @@
+extern void do_cmd_activate(void);
+extern void do_cmd_activate_aux(int item);
+
+
similarity index 77%
rename from src/cmd6.c
rename to src/cmd-magiceat.c
index 223e195..00e398b 100644 (file)
  */
 
 #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を返す
diff --git a/src/cmd-magiceat.h b/src/cmd-magiceat.h
new file mode 100644 (file)
index 0000000..6ef0363
--- /dev/null
@@ -0,0 +1 @@
+extern bool do_cmd_magic_eater(bool only_browse, bool powerful);
diff --git a/src/cmd-zaprod.c b/src/cmd-zaprod.c
new file mode 100644 (file)
index 0000000..89c4cb3
--- /dev/null
@@ -0,0 +1,432 @@
+#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);
+}
diff --git a/src/cmd-zaprod.h b/src/cmd-zaprod.h
new file mode 100644 (file)
index 0000000..a2de8ca
--- /dev/null
@@ -0,0 +1,3 @@
+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);
diff --git a/src/cmd-zapwand.c b/src/cmd-zapwand.c
new file mode 100644 (file)
index 0000000..fd6e8af
--- /dev/null
@@ -0,0 +1,476 @@
+#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);
+}
diff --git a/src/cmd-zapwand.h b/src/cmd-zapwand.h
new file mode 100644 (file)
index 0000000..261efa5
--- /dev/null
@@ -0,0 +1,3 @@
+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);
index a80147b..cd1a67e 100644 (file)
 
 
 #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"
 
 
 
@@ -2053,3 +2061,183 @@ void do_cmd_query_symbol(void)
 }
 
 
+/*!
+* @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;
+               }
+       }
+}
+
index b3e6fdc..f24b3f4 100644 (file)
@@ -13,6 +13,7 @@
 #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"
index a6114e5..9445959 100644 (file)
@@ -758,6 +758,7 @@ extern void do_cmd_query_symbol(void);
 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
@@ -803,13 +804,6 @@ extern int calculate_upkeep(void);
 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);
@@ -1202,6 +1196,7 @@ extern void discharge_minion(void);
 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);
@@ -1721,6 +1716,8 @@ extern void spoil_random_artifact(cptr fname);
 
 /* 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);
index b0eccfb..113209e 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "angband.h"
+#include "cmd-magiceat.h"
 #include "cmd-zapwand.h"
 
 /*!
index 975e3ff..1cbf7ba 100644 (file)
@@ -4253,3 +4253,72 @@ void remove_all_mirrors(bool explode)
                }
        }
 }
+
+/*!
+ * @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;
+       }
+       }
+}
+
index 25b2e3d..cb83300 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "angband.h"
 #include "cmd-zapwand.h"
+#include "cmd-magiceat.h"
 
 #define MIN_STOCK 12