OSDN Git Service

[Refactor] #39068 グローバル変数 opening_chest による引数渡しを, AM_FORBID_CHEST に置換.
[hengband/hengband.git] / src / object2.c
index 8b26ec8..ff4528d 100644 (file)
  */
 
 #include "angband.h"
+#include "util.h"
+
+#include "object.h"
+
+#include "cmd-dump.h"
+#include "cmd-spell.h"
+#include "spells.h"
+#include "dungeon.h"
 #include "floor.h"
+#include "grid.h"
+#include "objectkind.h"
 #include "object-boost.h"
+#include "object-ego.h"
+#include "object-flavor.h"
 #include "object-hook.h"
 #include "object-curse.h"
 #include "objectkind-hook.h"
 #include "artifact.h"
-#include "player-status.h"
 #include "feature.h"
+#include "player-status.h"
 #include "player-move.h"
+#include "player-effects.h"
 #include "monster.h"
 #include "monsterrace-hook.h"
+#include "object-ego.h"
 
 /*!
  * @brief 床上、モンスター所持でスタックされたアイテムを削除しスタックを補完する / Excise a dungeon object from any stacks
@@ -162,7 +176,7 @@ void delete_object_idx(OBJECT_IDX o_idx)
        object_wipe(j_ptr);
 
        /* Count objects */
-       o_cnt--;
+       current_floor_ptr->o_cnt--;
 }
 
 
@@ -192,7 +206,7 @@ void delete_object(POSITION y, POSITION x)
                object_wipe(o_ptr);
 
                /* Count objects */
-               o_cnt--;
+               current_floor_ptr->o_cnt--;
        }
 
        /* Objects are gone */
@@ -219,7 +233,7 @@ static void compact_objects_aux(OBJECT_IDX i1, OBJECT_IDX i2)
        if (i1 == i2) return;
 
        /* Repair objects */
-       for (i = 1; i < o_max; i++)
+       for (i = 1; i < current_floor_ptr->o_max; i++)
        {
                o_ptr = &current_floor_ptr->o_list[i];
 
@@ -321,7 +335,7 @@ void compact_objects(int size)
                cur_dis = 5 * (20 - cnt);
 
                /* Examine the objects */
-               for (i = 1; i < o_max; i++)
+               for (i = 1; i < current_floor_ptr->o_max; i++)
                {
                        o_ptr = &current_floor_ptr->o_list[i];
 
@@ -374,7 +388,7 @@ void compact_objects(int size)
 
 
        /* Excise dead objects (backwards!) */
-       for (i = o_max - 1; i >= 1; i--)
+       for (i = current_floor_ptr->o_max - 1; i >= 1; i--)
        {
                o_ptr = &current_floor_ptr->o_list[i];
 
@@ -382,10 +396,10 @@ void compact_objects(int size)
                if (o_ptr->k_idx) continue;
 
                /* Move last object into open hole */
-               compact_objects_aux(o_max - 1, i);
+               compact_objects_aux(current_floor_ptr->o_max - 1, i);
 
-               /* Compress "o_max" */
-               o_max--;
+               /* Compress "current_floor_ptr->o_max" */
+               current_floor_ptr->o_max--;
        }
 }
 
@@ -407,7 +421,7 @@ void wipe_o_list(void)
        int i;
 
        /* Delete the existing objects */
-       for (i = 1; i < o_max; i++)
+       for (i = 1; i < current_floor_ptr->o_max; i++)
        {
                object_type *o_ptr = &current_floor_ptr->o_list[i];
 
@@ -452,11 +466,11 @@ void wipe_o_list(void)
                object_wipe(o_ptr);
        }
 
-       /* Reset "o_max" */
-       o_max = 1;
+       /* Reset "current_floor_ptr->o_max" */
+       current_floor_ptr->o_max = 1;
 
-       /* Reset "o_cnt" */
-       o_cnt = 0;
+       /* Reset "current_floor_ptr->o_cnt" */
+       current_floor_ptr->o_cnt = 0;
 }
 
 
@@ -473,16 +487,16 @@ OBJECT_IDX o_pop(void)
        OBJECT_IDX i;
 
        /* Initial allocation */
-       if (o_max < current_floor_ptr->max_o_idx)
+       if (current_floor_ptr->o_max < current_floor_ptr->max_o_idx)
        {
                /* Get next space */
-               i = o_max;
+               i = current_floor_ptr->o_max;
 
                /* Expand object array */
-               o_max++;
+               current_floor_ptr->o_max++;
 
                /* Count objects */
-               o_cnt++;
+               current_floor_ptr->o_cnt++;
 
                /* Use this object */
                return (i);
@@ -490,7 +504,7 @@ OBJECT_IDX o_pop(void)
 
 
        /* Recycle dead objects */
-       for (i = 1; i < o_max; i++)
+       for (i = 1; i < current_floor_ptr->o_max; i++)
        {
                object_type *o_ptr;
                o_ptr = &current_floor_ptr->o_list[i];
@@ -499,7 +513,7 @@ OBJECT_IDX o_pop(void)
                if (o_ptr->k_idx) continue;
 
                /* Count objects */
-               o_cnt++;
+               current_floor_ptr->o_cnt++;
 
                /* Use this object */
                return (i);
@@ -567,7 +581,7 @@ static errr get_obj_num_prep(void)
  * Note that if no objects are "appropriate", then this function will\n
  * fail, and return zero, but this should *almost* never happen.\n
  */
-OBJECT_IDX get_obj_num(DEPTH level)
+OBJECT_IDX get_obj_num(DEPTH level, BIT_FLAGS mode)
 {
        int i, j, p;
        KIND_OBJECT_IDX k_idx;
@@ -605,8 +619,7 @@ OBJECT_IDX get_obj_num(DEPTH level)
                /* Access the actual kind */
                k_ptr = &k_info[k_idx];
 
-               /* Hack -- prevent embedded chests */
-               if (opening_chest && (k_ptr->tval == TV_CHEST)) continue;
+               if ((mode & AM_FORBID_CHEST) && (k_ptr->tval == TV_CHEST)) continue;
 
                /* Accept */
                table[i].prob3 = table[i].prob2;
@@ -685,7 +698,6 @@ OBJECT_IDX get_obj_num(DEPTH level)
        return (table[i].index);
 }
 
-
 /*!
  * @brief オブジェクトを鑑定済にする /
  * Known is true when the "attributes" of an object are "known".
@@ -4318,7 +4330,7 @@ bool make_object(object_type *j_ptr, BIT_FLAGS mode)
                if (get_obj_num_hook) get_obj_num_prep();
 
                /* Pick a random object */
-               k_idx = get_obj_num(base);
+               k_idx = get_obj_num(base, mode);
 
                /* Restricted objects */
                if (get_obj_num_hook)
@@ -4398,8 +4410,6 @@ void place_object(POSITION y, POSITION x, BIT_FLAGS mode)
        /* Make an object (if possible) */
        if (!make_object(q_ptr, mode)) return;
 
-
-       /* Make an object */
        o_idx = o_pop();
 
        /* Success */
@@ -4509,7 +4519,6 @@ void place_gold(POSITION y, POSITION x)
        /* Make some gold */
        if (!make_gold(q_ptr)) return;
 
-       /* Make an object */
        o_idx = o_pop();
 
        /* Success */
@@ -4517,8 +4526,6 @@ void place_gold(POSITION y, POSITION x)
        {
                object_type *o_ptr;
                o_ptr = &current_floor_ptr->o_list[o_idx];
-
-               /* Copy the object */
                object_copy(o_ptr, q_ptr);
 
                /* Save location */
@@ -4539,7 +4546,7 @@ void place_gold(POSITION y, POSITION x)
  * @brief 生成済のオブジェクトをフロアの所定の位置に落とす。
  * Let an object fall to the ground at or near a location.
  * @param j_ptr 落としたいオブジェクト構造体の参照ポインタ
- * @param chance ã\83\89ã\83­ã\83\83ã\83\97ã\81®æ\88\90å\8a\9f率(%)
+ * @param chance ã\83\89ã\83­ã\83\83ã\83\97ã\81®æ\88æ»\85率(%)
  * @param y 配置したいフロアのY座標
  * @param x 配置したいフロアのX座標
  * @return 生成に成功したらオブジェクトのIDを返す。
@@ -4868,13 +4875,13 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION
 
 /*!
  * @brief 魔道具の使用回数の残量を示すメッセージを表示する /
- * Describe the charges on an item in the inventory.
+ * Describe the charges on an item in the p_ptr->inventory_list.
  * @param item 残量を表示したいプレイヤーのアイテム所持スロット
  * @return なし
  */
 void inven_item_charges(INVENTORY_IDX item)
 {
-       object_type *o_ptr = &inventory[item];
+       object_type *o_ptr = &p_ptr->inventory_list[item];
 
        /* Require staff/wand */
        if ((o_ptr->tval != TV_STAFF) && (o_ptr->tval != TV_WAND)) return;
@@ -4909,13 +4916,13 @@ void inven_item_charges(INVENTORY_IDX item)
 
 /*!
  * @brief アイテムの残り所持数メッセージを表示する /
- * Describe an item in the inventory.
+ * Describe an item in the p_ptr->inventory_list.
  * @param item 残量を表示したいプレイヤーのアイテム所持スロット
  * @return なし
  */
 void inven_item_describe(INVENTORY_IDX item)
 {
-       object_type *o_ptr = &inventory[item];
+       object_type *o_ptr = &p_ptr->inventory_list[item];
        GAME_TEXT o_name[MAX_NLEN];
 
        object_desc(o_name, o_ptr, 0);
@@ -4940,14 +4947,14 @@ void inven_item_describe(INVENTORY_IDX item)
 
 /*!
  * @brief アイテムを増減させ残り所持数メッセージを表示する /
- * Increase the "number" of an item in the inventory
+ * Increase the "number" of an item in the p_ptr->inventory_list
  * @param item 所持数を増やしたいプレイヤーのアイテム所持スロット
  * @param num 増やしたい量
  * @return なし
  */
 void inven_item_increase(INVENTORY_IDX item, ITEM_NUMBER num)
 {
-       object_type *o_ptr = &inventory[item];
+       object_type *o_ptr = &p_ptr->inventory_list[item];
 
        /* Apply */
        num += o_ptr->number;
@@ -4989,13 +4996,13 @@ void inven_item_increase(INVENTORY_IDX item, ITEM_NUMBER num)
 
 /*!
  * @brief 所持アイテムスロットから所持数のなくなったアイテムを消去する /
- * Erase an inventory slot if it has no more items
+ * Erase an p_ptr->inventory_list slot if it has no more items
  * @param item 消去したいプレイヤーのアイテム所持スロット
  * @return なし
  */
 void inven_item_optimize(INVENTORY_IDX item)
 {
-       object_type *o_ptr = &inventory[item];
+       object_type *o_ptr = &p_ptr->inventory_list[item];
 
        /* Only optimize real items */
        if (!o_ptr->k_idx) return;
@@ -5009,17 +5016,17 @@ void inven_item_optimize(INVENTORY_IDX item)
                int i;
 
                /* One less item */
-               inven_cnt--;
+               p_ptr->inven_cnt--;
 
                /* Slide everything down */
                for (i = item; i < INVEN_PACK; i++)
                {
                        /* Structure copy */
-                       inventory[i] = inventory[i+1];
+                       p_ptr->inventory_list[i] = p_ptr->inventory_list[i+1];
                }
 
                /* Erase the "final" slot */
-               object_wipe(&inventory[i]);
+               object_wipe(&p_ptr->inventory_list[i]);
 
                p_ptr->window |= (PW_INVEN);
        }
@@ -5028,10 +5035,10 @@ void inven_item_optimize(INVENTORY_IDX item)
        else
        {
                /* One less item */
-               equip_cnt--;
+               p_ptr->equip_cnt--;
 
                /* Erase the empty slot */
-               object_wipe(&inventory[item]);
+               object_wipe(&p_ptr->inventory_list[item]);
                p_ptr->update |= (PU_BONUS);
                p_ptr->update |= (PU_TORCH);
                p_ptr->update |= (PU_MANA);
@@ -5170,14 +5177,12 @@ bool inven_carry_okay(object_type *o_ptr)
        int j;
 
        /* Empty slot? */
-       if (inven_cnt < INVEN_PACK) return (TRUE);
+       if (p_ptr->inven_cnt < INVEN_PACK) return (TRUE);
 
        /* Similar slot? */
        for (j = 0; j < INVEN_PACK; j++)
        {
-               object_type *j_ptr = &inventory[j];
-
-               /* Skip non-objects */
+               object_type *j_ptr = &p_ptr->inventory_list[j];
                if (!j_ptr->k_idx) continue;
 
                /* Check if the two items can be combined */
@@ -5278,13 +5283,13 @@ bool object_sort_comp(object_type *o_ptr, s32b o_value, object_type *j_ptr)
 
 /*!
  * @brief オブジェクトをプレイヤーが拾って所持スロットに納めるメインルーチン /
- * Add an item to the players inventory, and return the slot used.
+ * Add an item to the players p_ptr->inventory_list, and return the slot used.
  * @param o_ptr 拾うオブジェクトの構造体参照ポインタ
  * @return 収められた所持スロットのID、拾うことができなかった場合-1を返す。
  * @details
- * If the new item can combine with an existing item in the inventory,\n
+ * If the new item can combine with an existing item in the p_ptr->inventory_list,\n
  * it will do so, using "object_similar()" and "object_absorb()", else,\n
- * the item will be placed into the "proper" location in the inventory.\n
+ * the item will be placed into the "proper" location in the p_ptr->inventory_list.\n
  *\n
  * This function can be used to "over-fill" the player's pack, but only\n
  * once, and such an action must trigger the "overflow" code immediately.\n
@@ -5294,7 +5299,7 @@ bool object_sort_comp(object_type *o_ptr, s32b o_value, object_type *j_ptr)
  * combined.  This may be tricky.  See "dungeon.c" for info.\n
  *\n
  * Note that this code must remove any location/stack information\n
- * from the object once it is placed into the inventory.\n
+ * from the object once it is placed into the p_ptr->inventory_list.\n
  */
 s16b inven_carry(object_type *o_ptr)
 {
@@ -5307,9 +5312,7 @@ s16b inven_carry(object_type *o_ptr)
        /* Check for combining */
        for (j = 0; j < INVEN_PACK; j++)
        {
-               j_ptr = &inventory[j];
-
-               /* Skip non-objects */
+               j_ptr = &p_ptr->inventory_list[j];
                if (!j_ptr->k_idx) continue;
 
                /* Hack -- track last item */
@@ -5329,12 +5332,12 @@ s16b inven_carry(object_type *o_ptr)
                }
        }
 
-       if (inven_cnt > INVEN_PACK) return (-1);
+       if (p_ptr->inven_cnt > INVEN_PACK) return (-1);
 
        /* Find an empty slot */
        for (j = 0; j <= INVEN_PACK; j++)
        {
-               j_ptr = &inventory[j];
+               j_ptr = &p_ptr->inventory_list[j];
 
                /* Use it if found */
                if (!j_ptr->k_idx) break;
@@ -5353,7 +5356,7 @@ s16b inven_carry(object_type *o_ptr)
                /* Scan every occupied slot */
                for (j = 0; j < INVEN_PACK; j++)
                {
-                       if (object_sort_comp(o_ptr, o_value, &inventory[j])) break;
+                       if (object_sort_comp(o_ptr, o_value, &p_ptr->inventory_list[j])) break;
                }
 
                /* Use that slot */
@@ -5363,19 +5366,19 @@ s16b inven_carry(object_type *o_ptr)
                for (k = n; k >= i; k--)
                {
                        /* Hack -- Slide the item */
-                       object_copy(&inventory[k+1], &inventory[k]);
+                       object_copy(&p_ptr->inventory_list[k+1], &p_ptr->inventory_list[k]);
                }
 
                /* Wipe the empty slot */
-               object_wipe(&inventory[i]);
+               object_wipe(&p_ptr->inventory_list[i]);
        }
 
 
        /* Copy the item */
-       object_copy(&inventory[i], o_ptr);
+       object_copy(&p_ptr->inventory_list[i], o_ptr);
 
        /* Access new object */
-       j_ptr = &inventory[i];
+       j_ptr = &p_ptr->inventory_list[i];
 
        /* Forget stack */
        j_ptr->next_o_idx = 0;
@@ -5392,7 +5395,7 @@ s16b inven_carry(object_type *o_ptr)
        p_ptr->total_weight += (j_ptr->number * j_ptr->weight);
 
        /* Count the items */
-       inven_cnt++;
+       p_ptr->inven_cnt++;
        p_ptr->update |= (PU_BONUS | PU_COMBINE | PU_REORDER);
        p_ptr->window |= (PW_INVEN);
 
@@ -5411,7 +5414,7 @@ s16b inven_carry(object_type *o_ptr)
  * Note that only one item at a time can be wielded per slot.\n
  * Note that taking off an item when "full" may cause that item\n
  * to fall to the ground.\n
- * Return the inventory slot into which the item is placed.\n
+ * Return the p_ptr->inventory_list slot into which the item is placed.\n
  */
 INVENTORY_IDX inven_takeoff(INVENTORY_IDX item, ITEM_NUMBER amt)
 {
@@ -5428,7 +5431,7 @@ INVENTORY_IDX inven_takeoff(INVENTORY_IDX item, ITEM_NUMBER amt)
 
 
        /* Get the item to take off */
-       o_ptr = &inventory[item];
+       o_ptr = &p_ptr->inventory_list[item];
        if (amt <= 0) return (-1);
 
        /* Verify */
@@ -5489,7 +5492,7 @@ INVENTORY_IDX inven_takeoff(INVENTORY_IDX item, ITEM_NUMBER amt)
 
 /*!
  * @brief 所持スロットから床下にオブジェクトを落とすメインルーチン /
- * Drop (some of) a non-cursed inventory/equipment item
+ * Drop (some of) a non-cursed p_ptr->inventory_list/equipment item
  * @param item 所持テーブルのID
  * @param amt 落としたい個数
  * @return なし
@@ -5505,7 +5508,7 @@ void inven_drop(INVENTORY_IDX item, ITEM_NUMBER amt)
        GAME_TEXT o_name[MAX_NLEN];
 
        /* Access original object */
-       o_ptr = &inventory[item];
+       o_ptr = &p_ptr->inventory_list[item];
 
        /* Error check */
        if (amt <= 0) return;
@@ -5520,7 +5523,7 @@ void inven_drop(INVENTORY_IDX item, ITEM_NUMBER amt)
                item = inven_takeoff(item, amt);
 
                /* Access original object */
-               o_ptr = &inventory[item];
+               o_ptr = &p_ptr->inventory_list[item];
        }
 
        q_ptr = &forge;
@@ -5570,7 +5573,7 @@ void combine_pack(void)
                /* Combine the pack (backwards) */
                for (i = INVEN_PACK; i > 0; i--)
                {
-                       o_ptr = &inventory[i];
+                       o_ptr = &p_ptr->inventory_list[i];
 
                        /* Skip empty items */
                        if (!o_ptr->k_idx) continue;
@@ -5580,7 +5583,7 @@ void combine_pack(void)
                        {
                                int max_num;
 
-                               j_ptr = &inventory[j];
+                               j_ptr = &p_ptr->inventory_list[j];
 
                                /* Skip empty items */
                                if (!j_ptr->k_idx) continue;
@@ -5603,17 +5606,17 @@ void combine_pack(void)
                                                object_absorb(j_ptr, o_ptr);
 
                                                /* One object is gone */
-                                               inven_cnt--;
+                                               p_ptr->inven_cnt--;
 
                                                /* Slide everything down */
                                                for (k = i; k < INVEN_PACK; k++)
                                                {
                                                        /* Structure copy */
-                                                       inventory[k] = inventory[k+1];
+                                                       p_ptr->inventory_list[k] = p_ptr->inventory_list[k+1];
                                                }
 
                                                /* Erase the "final" slot */
-                                               object_wipe(&inventory[k]);
+                                               object_wipe(&p_ptr->inventory_list[k]);
                                        }
                                        else
                                        {
@@ -5677,9 +5680,9 @@ void reorder_pack(void)
        for (i = 0; i < INVEN_PACK; i++)
        {
                /* Mega-Hack -- allow "proper" over-flow */
-               if ((i == INVEN_PACK) && (inven_cnt == INVEN_PACK)) break;
+               if ((i == INVEN_PACK) && (p_ptr->inven_cnt == INVEN_PACK)) break;
 
-               o_ptr = &inventory[i];
+               o_ptr = &p_ptr->inventory_list[i];
 
                /* Skip empty slots */
                if (!o_ptr->k_idx) continue;
@@ -5690,7 +5693,7 @@ void reorder_pack(void)
                /* Scan every occupied slot */
                for (j = 0; j < INVEN_PACK; j++)
                {
-                       if (object_sort_comp(o_ptr, o_value, &inventory[j])) break;
+                       if (object_sort_comp(o_ptr, o_value, &p_ptr->inventory_list[j])) break;
                }
 
                /* Never move down */
@@ -5701,17 +5704,17 @@ void reorder_pack(void)
                q_ptr = &forge;
 
                /* Save a copy of the moving item */
-               object_copy(q_ptr, &inventory[i]);
+               object_copy(q_ptr, &p_ptr->inventory_list[i]);
 
                /* Slide the objects */
                for (k = i; k > j; k--)
                {
                        /* Slide the item */
-                       object_copy(&inventory[k], &inventory[k-1]);
+                       object_copy(&p_ptr->inventory_list[k], &p_ptr->inventory_list[k-1]);
                }
 
                /* Insert the moving item */
-               object_copy(&inventory[j], q_ptr);
+               object_copy(&p_ptr->inventory_list[j], q_ptr);
 
                p_ptr->window |= (PW_INVEN);
        }
@@ -5850,3 +5853,40 @@ void torch_lost_fuel(object_type *o_ptr)
                if (o_ptr->xtra4 < 0) o_ptr->xtra4 = 0;
        }
 }
+
+/*!
+ * @brief 射撃武器に対応する矢/弾薬のベースアイテムIDを返す /
+ * @param o_ptr 判定する射撃武器のアイテム情報参照ポインタ
+ * @return 対応する矢/弾薬のベースアイテムID
+ */
+int bow_tval_ammo(object_type *o_ptr)
+{
+       /* Analyze the launcher */
+       switch (o_ptr->sval)
+       {
+       case SV_SLING:
+       {
+               return TV_SHOT;
+       }
+
+       case SV_SHORT_BOW:
+       case SV_LONG_BOW:
+       case SV_NAMAKE_BOW:
+       {
+               return TV_ARROW;
+       }
+
+       case SV_LIGHT_XBOW:
+       case SV_HEAVY_XBOW:
+       {
+               return TV_BOLT;
+       }
+       case SV_CRIMSON:
+       case SV_HARP:
+       {
+               return TV_NO_AMMO;
+       }
+       }
+
+       return 0;
+}