X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fobject2.c;h=7c2be2aeb25294113903e2d5f79f2152940b9cd8;hb=1cb863682cba91dc9928eef55e7ef552e4d1651f;hp=9fd5d98d1e29ea51a895a75fb6bbd1a1519cf73d;hpb=00270f604be6681a5fc221a0e2c687c1e69e93c7;p=hengband%2Fhengband.git diff --git a/src/object2.c b/src/object2.c index 9fd5d98d1..7c2be2aeb 100644 --- a/src/object2.c +++ b/src/object2.c @@ -12,17 +12,36 @@ */ #include "angband.h" +#include "util.h" +#include "world.h" +#include "term.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 "player-class.h" +#include "player-personality.h" +#include "monster.h" #include "monsterrace-hook.h" +#include "object-ego.h" +#include "view-mainwindow.h" /*! * @brief 床上、モンスター所持でスタックされたアイテムを削除しスタックを補完する / Excise a dungeon object from any stacks @@ -37,18 +56,18 @@ void excise_object_idx(OBJECT_IDX o_idx) OBJECT_IDX prev_o_idx = 0; /* Object */ - j_ptr = ¤t_floor_ptr->o_list[o_idx]; + j_ptr = &p_ptr->current_floor_ptr->o_list[o_idx]; - if (j_ptr->held_m_idx) + if (OBJECT_IS_HELD_MONSTER(j_ptr)) { monster_type *m_ptr; - m_ptr = ¤t_floor_ptr->m_list[j_ptr->held_m_idx]; + m_ptr = &p_ptr->current_floor_ptr->m_list[j_ptr->held_m_idx]; /* Scan all objects in the grid */ for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) { object_type *o_ptr; - o_ptr = ¤t_floor_ptr->o_list[this_o_idx]; + o_ptr = &p_ptr->current_floor_ptr->o_list[this_o_idx]; next_o_idx = o_ptr->next_o_idx; if (this_o_idx == o_idx) @@ -66,7 +85,7 @@ void excise_object_idx(OBJECT_IDX o_idx) object_type *k_ptr; /* Previous object */ - k_ptr = ¤t_floor_ptr->o_list[prev_o_idx]; + k_ptr = &p_ptr->current_floor_ptr->o_list[prev_o_idx]; /* Remove from list */ k_ptr->next_o_idx = next_o_idx; @@ -91,13 +110,13 @@ void excise_object_idx(OBJECT_IDX o_idx) POSITION y = j_ptr->iy; POSITION x = j_ptr->ix; - g_ptr = ¤t_floor_ptr->grid_array[y][x]; + g_ptr = &p_ptr->current_floor_ptr->grid_array[y][x]; /* Scan all objects in the grid */ for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) { object_type *o_ptr; - o_ptr = ¤t_floor_ptr->o_list[this_o_idx]; + o_ptr = &p_ptr->current_floor_ptr->o_list[this_o_idx]; next_o_idx = o_ptr->next_o_idx; if (this_o_idx == o_idx) @@ -115,7 +134,7 @@ void excise_object_idx(OBJECT_IDX o_idx) object_type *k_ptr; /* Previous object */ - k_ptr = ¤t_floor_ptr->o_list[prev_o_idx]; + k_ptr = &p_ptr->current_floor_ptr->o_list[prev_o_idx]; /* Remove from list */ k_ptr->next_o_idx = next_o_idx; @@ -149,10 +168,10 @@ void delete_object_idx(OBJECT_IDX o_idx) excise_object_idx(o_idx); /* Object */ - j_ptr = ¤t_floor_ptr->o_list[o_idx]; + j_ptr = &p_ptr->current_floor_ptr->o_list[o_idx]; /* Dungeon floor */ - if (!(j_ptr->held_m_idx)) + if (!OBJECT_IS_HELD_MONSTER(j_ptr)) { POSITION y, x; y = j_ptr->iy; @@ -162,7 +181,7 @@ void delete_object_idx(OBJECT_IDX o_idx) object_wipe(j_ptr); /* Count objects */ - o_cnt--; + p_ptr->current_floor_ptr->o_cnt--; } @@ -179,20 +198,20 @@ void delete_object(POSITION y, POSITION x) OBJECT_IDX this_o_idx, next_o_idx = 0; /* Refuse "illegal" locations */ - if (!in_bounds(y, x)) return; + if (!in_bounds(p_ptr->current_floor_ptr, y, x)) return; - g_ptr = ¤t_floor_ptr->grid_array[y][x]; + g_ptr = &p_ptr->current_floor_ptr->grid_array[y][x]; /* Scan all objects in the grid */ for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) { object_type *o_ptr; - o_ptr = ¤t_floor_ptr->o_list[this_o_idx]; + o_ptr = &p_ptr->current_floor_ptr->o_list[this_o_idx]; next_o_idx = o_ptr->next_o_idx; object_wipe(o_ptr); /* Count objects */ - o_cnt--; + p_ptr->current_floor_ptr->o_cnt--; } /* Objects are gone */ @@ -219,9 +238,9 @@ 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 < p_ptr->current_floor_ptr->o_max; i++) { - o_ptr = ¤t_floor_ptr->o_list[i]; + o_ptr = &p_ptr->current_floor_ptr->o_list[i]; /* Skip "dead" objects */ if (!o_ptr->k_idx) continue; @@ -233,14 +252,12 @@ static void compact_objects_aux(OBJECT_IDX i1, OBJECT_IDX i2) o_ptr->next_o_idx = i2; } } - o_ptr = ¤t_floor_ptr->o_list[i1]; + o_ptr = &p_ptr->current_floor_ptr->o_list[i1]; - if (o_ptr->held_m_idx) + if (OBJECT_IS_HELD_MONSTER(o_ptr)) { monster_type *m_ptr; - - /* Acquire monster */ - m_ptr = ¤t_floor_ptr->m_list[o_ptr->held_m_idx]; + m_ptr = &p_ptr->current_floor_ptr->m_list[o_ptr->held_m_idx]; /* Repair monster */ if (m_ptr->hold_o_idx == i1) @@ -260,7 +277,7 @@ static void compact_objects_aux(OBJECT_IDX i1, OBJECT_IDX i2) x = o_ptr->ix; /* Acquire grid */ - g_ptr = ¤t_floor_ptr->grid_array[y][x]; + g_ptr = &p_ptr->current_floor_ptr->grid_array[y][x]; /* Repair grid */ if (g_ptr->o_idx == i1) @@ -271,7 +288,7 @@ static void compact_objects_aux(OBJECT_IDX i1, OBJECT_IDX i2) } /* Structure copy */ - current_floor_ptr->o_list[i2] = current_floor_ptr->o_list[i1]; + p_ptr->current_floor_ptr->o_list[i2] = p_ptr->current_floor_ptr->o_list[i1]; /* Wipe the hole */ object_wipe(o_ptr); @@ -321,22 +338,19 @@ void compact_objects(int size) cur_dis = 5 * (20 - cnt); /* Examine the objects */ - for (i = 1; i < o_max; i++) + for (i = 1; i < p_ptr->current_floor_ptr->o_max; i++) { - o_ptr = ¤t_floor_ptr->o_list[i]; + o_ptr = &p_ptr->current_floor_ptr->o_list[i]; - /* Skip dead objects */ - if (!o_ptr->k_idx) continue; + if (!OBJECT_IS_VALID(o_ptr)) continue; /* Hack -- High level objects start out "immune" */ if (k_info[o_ptr->k_idx].level > cur_lev) continue; - if (o_ptr->held_m_idx) + if (OBJECT_IS_HELD_MONSTER(o_ptr)) { monster_type *m_ptr; - - /* Acquire monster */ - m_ptr = ¤t_floor_ptr->m_list[o_ptr->held_m_idx]; + m_ptr = &p_ptr->current_floor_ptr->m_list[o_ptr->held_m_idx]; y = m_ptr->fy; x = m_ptr->fx; @@ -374,92 +388,21 @@ void compact_objects(int size) /* Excise dead objects (backwards!) */ - for (i = o_max - 1; i >= 1; i--) + for (i = p_ptr->current_floor_ptr->o_max - 1; i >= 1; i--) { - o_ptr = ¤t_floor_ptr->o_list[i]; + o_ptr = &p_ptr->current_floor_ptr->o_list[i]; /* Skip real objects */ if (o_ptr->k_idx) continue; /* Move last object into open hole */ - compact_objects_aux(o_max - 1, i); + compact_objects_aux(p_ptr->current_floor_ptr->o_max - 1, i); - /* Compress "o_max" */ - o_max--; + /* Compress "p_ptr->current_floor_ptr->o_max" */ + p_ptr->current_floor_ptr->o_max--; } } - -/*! - * @brief グローバルオブジェクト配列を初期化する / - * Delete all the items when player leaves the level - * @note we do NOT visually reflect these (irrelevant) changes - * @details - * Hack -- we clear the "g_ptr->o_idx" field for every grid, - * and the "m_ptr->next_o_idx" field for every monster, since - * we know we are clearing every object. Technically, we only - * clear those fields for grids/monsters containing objects, - * and we clear it once for every such object. - * @return なし - */ -void wipe_o_list(void) -{ - int i; - - /* Delete the existing objects */ - for (i = 1; i < o_max; i++) - { - object_type *o_ptr = ¤t_floor_ptr->o_list[i]; - - /* Skip dead objects */ - if (!o_ptr->k_idx) continue; - - /* Mega-Hack -- preserve artifacts */ - if (!character_dungeon || preserve_mode) - { - /* Hack -- Preserve unknown artifacts */ - if (object_is_fixed_artifact(o_ptr) && !object_is_known(o_ptr)) - { - /* Mega-Hack -- Preserve the artifact */ - a_info[o_ptr->name1].cur_num = 0; - } - } - - if (o_ptr->held_m_idx) - { - monster_type *m_ptr; - m_ptr = ¤t_floor_ptr->m_list[o_ptr->held_m_idx]; - - /* Hack -- see above */ - m_ptr->hold_o_idx = 0; - } - - /* Dungeon */ - else - { - grid_type *g_ptr; - - /* Access location */ - POSITION y = o_ptr->iy; - POSITION x = o_ptr->ix; - - /* Access grid */ - g_ptr = ¤t_floor_ptr->grid_array[y][x]; - - /* Hack -- see above */ - g_ptr->o_idx = 0; - } - object_wipe(o_ptr); - } - - /* Reset "o_max" */ - o_max = 1; - - /* Reset "o_cnt" */ - o_cnt = 0; -} - - /*! * @brief グローバルオブジェクト配列から空きを取得する / * Acquires and returns the index of a "free" object. @@ -473,16 +416,16 @@ OBJECT_IDX o_pop(void) OBJECT_IDX i; /* Initial allocation */ - if (o_max < current_floor_ptr->max_o_idx) + if (p_ptr->current_floor_ptr->o_max < current_world_ptr->max_o_idx) { /* Get next space */ - i = o_max; + i = p_ptr->current_floor_ptr->o_max; /* Expand object array */ - o_max++; + p_ptr->current_floor_ptr->o_max++; /* Count objects */ - o_cnt++; + p_ptr->current_floor_ptr->o_cnt++; /* Use this object */ return (i); @@ -490,16 +433,16 @@ OBJECT_IDX o_pop(void) /* Recycle dead objects */ - for (i = 1; i < o_max; i++) + for (i = 1; i < p_ptr->current_floor_ptr->o_max; i++) { object_type *o_ptr; - o_ptr = ¤t_floor_ptr->o_list[i]; + o_ptr = &p_ptr->current_floor_ptr->o_list[i]; /* Skip live objects */ if (o_ptr->k_idx) continue; /* Count objects */ - o_cnt++; + p_ptr->current_floor_ptr->o_cnt++; /* Use this object */ return (i); @@ -507,11 +450,15 @@ OBJECT_IDX o_pop(void) /* Warn the player (except during dungeon creation) */ - if (character_dungeon) msg_print(_("アイテムが多すぎる!", "Too many objects!")); + if (current_world_ptr->character_dungeon) msg_print(_("アイテムが多すぎる!", "Too many objects!")); return (0); } +/* + * Hack -- function hook to restrict "get_obj_num_prep()" function + */ +bool(*get_obj_num_hook)(KIND_OBJECT_IDX k_idx); /*! * @brief オブジェクト生成テーブルに生成制約を加える / @@ -567,7 +514,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 +552,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 +631,6 @@ OBJECT_IDX get_obj_num(DEPTH level) return (table[i].index); } - /*! * @brief オブジェクトを鑑定済にする / * Known is true when the "attributes" of an object are "known". @@ -745,7 +690,7 @@ void object_aware(object_type *o_ptr) q_ptr->number = 1; object_desc(o_name, q_ptr, OD_NAME_ONLY); - do_cmd_write_nikki(NIKKI_HANMEI, 0, o_name); + exe_write_diary(p_ptr, NIKKI_HANMEI, 0, o_name); } } @@ -2065,7 +2010,7 @@ void apply_magic_weapon(object_type *o_ptr, DEPTH level, int power) if (power > 1) { if (one_in_(30) || (power > 2)) /* power > 2 is debug only */ - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); else /* Special Ego-item */ o_ptr->name2 = EGO_DIGGING; @@ -2097,7 +2042,7 @@ void apply_magic_weapon(object_type *o_ptr, DEPTH level, int power) { if (one_in_(40) || (power > 2)) /* power > 2 is debug only */ { - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); break; } while (1) @@ -2256,7 +2201,7 @@ void apply_magic_weapon(object_type *o_ptr, DEPTH level, int power) { if (one_in_(20) || (power > 2)) /* power > 2 is debug only */ { - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); break; } o_ptr->name2 = get_random_ego(INVEN_BOW, TRUE); @@ -2275,7 +2220,7 @@ void apply_magic_weapon(object_type *o_ptr, DEPTH level, int power) { if (power > 2) /* power > 2 is debug only */ { - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); break; } @@ -2362,7 +2307,7 @@ static void a_m_aux_2(object_type *o_ptr, DEPTH level, int power) case TV_DRAG_ARMOR: { if (one_in_(50) || (power > 2)) /* power > 2 is debug only */ - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); break; } @@ -2394,7 +2339,7 @@ static void a_m_aux_2(object_type *o_ptr, DEPTH level, int power) if (one_in_(20) || (power > 2)) /* power > 2 is debug only */ { - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); break; } @@ -2482,7 +2427,7 @@ static void a_m_aux_2(object_type *o_ptr, DEPTH level, int power) { if (one_in_(20) || (power > 2)) /* power > 2 is debug only */ { - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); break; } @@ -2528,7 +2473,7 @@ static void a_m_aux_2(object_type *o_ptr, DEPTH level, int power) { if (one_in_(20) || (power > 2)) /* power > 2 is debug only */ { - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); break; } o_ptr->name2 = get_random_ego(INVEN_HANDS, TRUE); @@ -2555,7 +2500,7 @@ static void a_m_aux_2(object_type *o_ptr, DEPTH level, int power) { if (one_in_(20) || (power > 2)) /* power > 2 is debug only */ { - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); break; } o_ptr->name2 = get_random_ego(INVEN_FEET, TRUE); @@ -2586,7 +2531,7 @@ static void a_m_aux_2(object_type *o_ptr, DEPTH level, int power) { if (one_in_(20) || (power > 2)) /* power > 2 is debug only */ { - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); break; } while (1) @@ -2662,7 +2607,7 @@ static void a_m_aux_2(object_type *o_ptr, DEPTH level, int power) { if (one_in_(20) || (power > 2)) /* power > 2 is debug only */ { - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); break; } while (1) @@ -2740,7 +2685,7 @@ static void a_m_aux_2(object_type *o_ptr, DEPTH level, int power) { if (one_in_(20) || (power > 2)) /* power > 2 is debug only */ { - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); break; } o_ptr->name2 = get_random_ego(INVEN_OUTER, TRUE); @@ -3089,7 +3034,7 @@ static void a_m_aux_3(object_type *o_ptr, DEPTH level, int power) { o_ptr->pval = MIN(o_ptr->pval, 4); /* Randart amulet */ - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); } else if ((power == 2) && one_in_(2)) { @@ -3421,7 +3366,7 @@ static void a_m_aux_3(object_type *o_ptr, DEPTH level, int power) { o_ptr->pval = MIN(o_ptr->pval, 4); /* Randart amulet */ - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); } else if ((power == 2) && one_in_(2)) { @@ -3624,7 +3569,7 @@ static void a_m_aux_4(object_type *o_ptr, DEPTH level, int power) if (power > 2) /* power > 2 is debug only */ { - create_artifact(o_ptr, FALSE); + become_random_artifact(o_ptr, FALSE); } else if ((power == 2) || ((power == 1) && one_in_(3))) { @@ -3717,7 +3662,7 @@ static void a_m_aux_4(object_type *o_ptr, DEPTH level, int power) r_ptr = &r_info[i]; - check = (current_floor_ptr->dun_level < r_ptr->level) ? (r_ptr->level - current_floor_ptr->dun_level) : 0; + check = (p_ptr->current_floor_ptr->dun_level < r_ptr->level) ? (r_ptr->level - p_ptr->current_floor_ptr->dun_level) : 0; /* Ignore dead monsters */ if (!r_ptr->rarity) continue; @@ -3763,11 +3708,11 @@ static void a_m_aux_4(object_type *o_ptr, DEPTH level, int power) /* Pick a random non-unique monster race */ while (1) { - i = get_mon_num(current_floor_ptr->dun_level); + i = get_mon_num(p_ptr->current_floor_ptr->dun_level); r_ptr = &r_info[i]; - check = (current_floor_ptr->dun_level < r_ptr->level) ? (r_ptr->level - current_floor_ptr->dun_level) : 0; + check = (p_ptr->current_floor_ptr->dun_level < r_ptr->level) ? (r_ptr->level - p_ptr->current_floor_ptr->dun_level) : 0; /* Ignore dead monsters */ if (!r_ptr->rarity) continue; @@ -3831,7 +3776,7 @@ static void a_m_aux_4(object_type *o_ptr, DEPTH level, int power) o_ptr->pval = randint1(obj_level); if (o_ptr->sval == SV_CHEST_KANDUME) o_ptr->pval = 6; - o_ptr->xtra3 = current_floor_ptr->dun_level + 5; + o_ptr->xtra3 = p_ptr->current_floor_ptr->dun_level + 5; /* Never exceed "difficulty" of 55 to 59 */ if (o_ptr->pval > 55) o_ptr->pval = 55 + (byte)randint0(5); @@ -3987,7 +3932,7 @@ void apply_magic(object_type *o_ptr, DEPTH lev, BIT_FLAGS mode) a_ptr->cur_num = 1; /* Hack -- Memorize location of artifact in saved floors */ - if (character_dungeon) + if (current_world_ptr->character_dungeon) a_ptr->floor_id = p_ptr->floor_id; /* Extract the other fields */ @@ -4286,7 +4231,7 @@ void apply_magic(object_type *o_ptr, DEPTH lev, BIT_FLAGS mode) * @return 生成に成功したらTRUEを返す。 * @details * This routine plays nasty games to generate the "special artifacts".\n - * This routine uses "current_floor_ptr->object_level" for the "generation level".\n + * This routine uses "p_ptr->current_floor_ptr->object_level" for the "generation level".\n * We assume that the given object has been "wiped".\n */ bool make_object(object_type *j_ptr, BIT_FLAGS mode) @@ -4299,7 +4244,7 @@ bool make_object(object_type *j_ptr, BIT_FLAGS mode) prob = ((mode & AM_GOOD) ? 10 : 1000); /* Base level for the object */ - base = ((mode & AM_GOOD) ? (current_floor_ptr->object_level + 10) : current_floor_ptr->object_level); + base = ((mode & AM_GOOD) ? (p_ptr->current_floor_ptr->object_level + 10) : p_ptr->current_floor_ptr->object_level); /* Generate a special object, or a normal object */ @@ -4318,7 +4263,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) @@ -4338,7 +4283,7 @@ bool make_object(object_type *j_ptr, BIT_FLAGS mode) } /* Apply magic (allow artifacts) */ - apply_magic(j_ptr, current_floor_ptr->object_level, mode); + apply_magic(j_ptr, p_ptr->current_floor_ptr->object_level, mode); /* Hack -- generate multiple spikes/missiles */ switch (j_ptr->tval) @@ -4369,7 +4314,7 @@ bool make_object(object_type *j_ptr, BIT_FLAGS mode) * @return 生成に成功したらTRUEを返す。 * @details * This routine plays nasty games to generate the "special artifacts".\n - * This routine uses "current_floor_ptr->object_level" for the "generation level".\n + * This routine uses "p_ptr->current_floor_ptr->object_level" for the "generation level".\n * This routine requires a clean floor grid destination.\n */ void place_object(POSITION y, POSITION x, BIT_FLAGS mode) @@ -4377,17 +4322,17 @@ void place_object(POSITION y, POSITION x, BIT_FLAGS mode) OBJECT_IDX o_idx; /* Acquire grid */ - grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x]; + grid_type *g_ptr = &p_ptr->current_floor_ptr->grid_array[y][x]; object_type forge; object_type *q_ptr; /* Paranoia -- check bounds */ - if (!in_bounds(y, x)) return; + if (!in_bounds(p_ptr->current_floor_ptr, y, x)) return; /* Require floor space */ - if (!cave_drop_bold(y, x)) return; + if (!cave_drop_bold(p_ptr->current_floor_ptr, y, x)) return; /* Avoid stacking on other objects */ if (g_ptr->o_idx) return; @@ -4398,15 +4343,13 @@ 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 */ if (o_idx) { object_type *o_ptr; - o_ptr = ¤t_floor_ptr->o_list[o_idx]; + o_ptr = &p_ptr->current_floor_ptr->o_list[o_idx]; /* Structure Copy */ object_copy(o_ptr, q_ptr); @@ -4432,6 +4375,8 @@ void place_object(POSITION y, POSITION x, BIT_FLAGS mode) } +OBJECT_SUBTYPE_VALUE coin_type; /* Hack -- force coin type */ + /*! * @brief 生成階に応じた財宝オブジェクトの生成を行う。 * Make a treasure object @@ -4446,12 +4391,12 @@ bool make_gold(object_type *j_ptr) s32b base; /* Hack -- Pick a Treasure variety */ - i = ((randint1(current_floor_ptr->object_level + 2) + 2) / 2) - 1; + i = ((randint1(p_ptr->current_floor_ptr->object_level + 2) + 2) / 2) - 1; /* Apply "extra" magic */ if (one_in_(GREAT_OBJ)) { - i += randint1(current_floor_ptr->object_level + 1); + i += randint1(p_ptr->current_floor_ptr->object_level + 1); } /* Hack -- Creeping Coins only generate "themselves" */ @@ -4488,17 +4433,17 @@ void place_gold(POSITION y, POSITION x) OBJECT_IDX o_idx; /* Acquire grid */ - grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x]; + grid_type *g_ptr = &p_ptr->current_floor_ptr->grid_array[y][x]; object_type forge; object_type *q_ptr; /* Paranoia -- check bounds */ - if (!in_bounds(y, x)) return; + if (!in_bounds(p_ptr->current_floor_ptr, y, x)) return; /* Require floor space */ - if (!cave_drop_bold(y, x)) return; + if (!cave_drop_bold(p_ptr->current_floor_ptr, y, x)) return; /* Avoid stacking on other objects */ if (g_ptr->o_idx) return; @@ -4509,16 +4454,13 @@ void place_gold(POSITION y, POSITION x) /* Make some gold */ if (!make_gold(q_ptr)) return; - /* Make an object */ o_idx = o_pop(); /* Success */ if (o_idx) { object_type *o_ptr; - o_ptr = ¤t_floor_ptr->o_list[o_idx]; - - /* Copy the object */ + o_ptr = &p_ptr->current_floor_ptr->o_list[o_idx]; object_copy(o_ptr, q_ptr); /* Save location */ @@ -4539,12 +4481,12 @@ 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 ドロップの成功率(%) + * @param chance ドロップの消滅率(%) * @param y 配置したいフロアのY座標 * @param x 配置したいフロアのX座標 * @return 生成に成功したらオブジェクトのIDを返す。 * @details - * The initial location is assumed to be "in_bounds()".\n + * The initial location is assumed to be "in_bounds(p_ptr->current_floor_ptr, )".\n *\n * This function takes a parameter "chance". This is the percentage\n * chance that the item will "disappear" instead of drop. If the object\n @@ -4593,7 +4535,7 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION #else msg_format("The %s disappear%s.", o_name, (plural ? "" : "s")); #endif - if (p_ptr->wizard) msg_print(_("(破損)", "(breakage)")); + if (current_world_ptr->wizard) msg_print(_("(破損)", "(breakage)")); /* Failure */ return (0); @@ -4627,17 +4569,16 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION ty = y + dy; tx = x + dx; - /* Skip illegal grids */ - if (!in_bounds(ty, tx)) continue; + if (!in_bounds(p_ptr->current_floor_ptr, ty, tx)) continue; /* Require line of projection */ - if (!projectable(y, x, ty, tx)) continue; + if (!projectable(p_ptr->current_floor_ptr, y, x, ty, tx)) continue; /* Obtain grid */ - g_ptr = ¤t_floor_ptr->grid_array[ty][tx]; + g_ptr = &p_ptr->current_floor_ptr->grid_array[ty][tx]; /* Require floor space */ - if (!cave_drop_bold(ty, tx)) continue; + if (!cave_drop_bold(p_ptr->current_floor_ptr, ty, tx)) continue; /* No objects */ k = 0; @@ -4646,7 +4587,7 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) { object_type *o_ptr; - o_ptr = ¤t_floor_ptr->o_list[this_o_idx]; + o_ptr = &p_ptr->current_floor_ptr->o_list[this_o_idx]; next_o_idx = o_ptr->next_o_idx; /* Check for possible combination */ @@ -4693,7 +4634,7 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION msg_format("The %s disappear%s.", o_name, (plural ? "" : "s")); #endif - if (p_ptr->wizard) msg_print(_("(床スペースがない)", "(no floor space)")); + if (current_world_ptr->wizard) msg_print(_("(床スペースがない)", "(no floor space)")); /* Failure */ return (0); @@ -4707,14 +4648,14 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION ty = rand_spread(by, 1); tx = rand_spread(bx, 1); - if (!in_bounds(ty, tx)) continue; + if (!in_bounds(p_ptr->current_floor_ptr, ty, tx)) continue; /* Bounce to that location */ by = ty; bx = tx; /* Require floor space */ - if (!cave_drop_bold(by, bx)) continue; + if (!cave_drop_bold(p_ptr->current_floor_ptr, by, bx)) continue; flag = TRUE; } @@ -4724,12 +4665,12 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION { int candidates = 0, pick; - for (ty = 1; ty < current_floor_ptr->height - 1; ty++) + for (ty = 1; ty < p_ptr->current_floor_ptr->height - 1; ty++) { - for (tx = 1; tx < current_floor_ptr->width - 1; tx++) + for (tx = 1; tx < p_ptr->current_floor_ptr->width - 1; tx++) { /* A valid space found */ - if (cave_drop_bold(ty, tx)) candidates++; + if (cave_drop_bold(p_ptr->current_floor_ptr, ty, tx)) candidates++; } } @@ -4742,7 +4683,7 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION msg_format("The %s disappear%s.", o_name, (plural ? "" : "s")); #endif - if (p_ptr->wizard) msg_print(_("(床スペースがない)", "(no floor space)")); + if (current_world_ptr->wizard) msg_print(_("(床スペースがない)", "(no floor space)")); /* Mega-Hack -- preserve artifacts */ if (preserve_mode) @@ -4762,11 +4703,11 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION /* Choose a random one */ pick = randint1(candidates); - for (ty = 1; ty < current_floor_ptr->height - 1; ty++) + for (ty = 1; ty < p_ptr->current_floor_ptr->height - 1; ty++) { - for (tx = 1; tx < current_floor_ptr->width - 1; tx++) + for (tx = 1; tx < p_ptr->current_floor_ptr->width - 1; tx++) { - if (cave_drop_bold(ty, tx)) + if (cave_drop_bold(p_ptr->current_floor_ptr, ty, tx)) { pick--; @@ -4783,13 +4724,13 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION } - g_ptr = ¤t_floor_ptr->grid_array[by][bx]; + g_ptr = &p_ptr->current_floor_ptr->grid_array[by][bx]; /* Scan objects in that grid for combination */ for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) { object_type *o_ptr; - o_ptr = ¤t_floor_ptr->o_list[this_o_idx]; + o_ptr = &p_ptr->current_floor_ptr->o_list[this_o_idx]; next_o_idx = o_ptr->next_o_idx; /* Check for combination */ @@ -4815,7 +4756,7 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION msg_format("The %s disappear%s.", o_name, (plural ? "" : "s")); #endif - if (p_ptr->wizard) msg_print(_("(アイテムが多過ぎる)", "(too many objects)")); + if (current_world_ptr->wizard) msg_print(_("(アイテムが多過ぎる)", "(too many objects)")); /* Hack -- Preserve artifacts */ if (object_is_fixed_artifact(j_ptr)) @@ -4831,10 +4772,10 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION if (!done) { /* Structure copy */ - object_copy(¤t_floor_ptr->o_list[o_idx], j_ptr); + object_copy(&p_ptr->current_floor_ptr->o_list[o_idx], j_ptr); /* Access new object */ - j_ptr = ¤t_floor_ptr->o_list[o_idx]; + j_ptr = &p_ptr->current_floor_ptr->o_list[o_idx]; /* Locate */ j_ptr->iy = by; @@ -4858,7 +4799,7 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION /* Mega-Hack -- no message if "dropped" by player */ /* Message when an object falls under the player */ - if (chance && player_bold(by, bx)) + if (chance && player_bold(p_ptr, by, bx)) { msg_print(_("何かが足下に転がってきた。", "You feel something roll beneath your feet.")); } @@ -4874,7 +4815,7 @@ OBJECT_IDX drop_near(object_type *j_ptr, PERCENTAGE chance, POSITION y, POSITION */ 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; @@ -4915,7 +4856,7 @@ void inven_item_charges(INVENTORY_IDX item) */ 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); @@ -4938,6 +4879,22 @@ void inven_item_describe(INVENTORY_IDX item) } +void vary_item(INVENTORY_IDX item, ITEM_NUMBER num) +{ + if (item >= 0) + { + inven_item_increase(item, num); + inven_item_describe(item); + inven_item_optimize(item); + } + else + { + floor_item_increase(0 - item, num); + floor_item_describe(0 - item); + floor_item_optimize(0 - item); + } +} + /*! * @brief アイテムを増減させ残り所持数メッセージを表示する / * Increase the "number" of an item in the inventory @@ -4947,7 +4904,7 @@ void inven_item_describe(INVENTORY_IDX item) */ 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; @@ -4977,10 +4934,10 @@ void inven_item_increase(INVENTORY_IDX item, ITEM_NUMBER num) { if ((item == INVEN_RARM) || (item == INVEN_LARM)) { - if (!has_melee_weapon(INVEN_RARM + INVEN_LARM - item)) + if (!has_melee_weapon(p_ptr, INVEN_RARM + INVEN_LARM - item)) { /* Clear all temporary elemental brands */ - set_ele_attack(0, 0); + set_ele_attack(p_ptr, 0, 0); } } } @@ -4995,7 +4952,7 @@ void inven_item_increase(INVENTORY_IDX item, ITEM_NUMBER num) */ 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 +4966,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 +4985,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); @@ -5050,7 +5007,7 @@ void inven_item_optimize(INVENTORY_IDX item) */ void floor_item_charges(INVENTORY_IDX item) { - object_type *o_ptr = ¤t_floor_ptr->o_list[item]; + object_type *o_ptr = &p_ptr->current_floor_ptr->o_list[item]; /* Require staff/wand */ if ((o_ptr->tval != TV_STAFF) && (o_ptr->tval != TV_WAND)) return; @@ -5091,7 +5048,7 @@ void floor_item_charges(INVENTORY_IDX item) */ void floor_item_describe(INVENTORY_IDX item) { - object_type *o_ptr = ¤t_floor_ptr->o_list[item]; + object_type *o_ptr = &p_ptr->current_floor_ptr->o_list[item]; GAME_TEXT o_name[MAX_NLEN]; object_desc(o_name, o_ptr, 0); @@ -5122,7 +5079,7 @@ void floor_item_describe(INVENTORY_IDX item) */ void floor_item_increase(INVENTORY_IDX item, ITEM_NUMBER num) { - object_type *o_ptr = ¤t_floor_ptr->o_list[item]; + object_type *o_ptr = &p_ptr->current_floor_ptr->o_list[item]; /* Apply */ num += o_ptr->number; @@ -5147,7 +5104,7 @@ void floor_item_increase(INVENTORY_IDX item, ITEM_NUMBER num) */ void floor_item_optimize(INVENTORY_IDX item) { - object_type *o_ptr = ¤t_floor_ptr->o_list[item]; + object_type *o_ptr = &p_ptr->current_floor_ptr->o_list[item]; /* Paranoia -- be sure it exists */ if (!o_ptr->k_idx) return; @@ -5170,14 +5127,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 */ @@ -5307,9 +5262,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 +5282,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 +5306,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 +5316,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 +5345,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); @@ -5428,14 +5381,12 @@ 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 */ if (amt > o_ptr->number) amt = o_ptr->number; q_ptr = &forge; - - /* Obtain a local object */ object_copy(q_ptr, o_ptr); /* Modify quantity */ @@ -5505,7 +5456,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 +5471,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; @@ -5542,10 +5493,7 @@ void inven_drop(INVENTORY_IDX item, ITEM_NUMBER amt) /* Drop it near the player */ (void)drop_near(q_ptr, 0, p_ptr->y, p_ptr->x); - /* Modify, Describe, Optimize */ - inven_item_increase(item, -amt); - inven_item_describe(item); - inven_item_optimize(item); + vary_item(item, -amt); } @@ -5556,7 +5504,7 @@ void inven_drop(INVENTORY_IDX item, ITEM_NUMBER amt) * @details * Note special handling of the "overflow" slot */ -void combine_pack(void) +void combine_pack(player_type *owner_ptr) { int i, j, k; object_type *o_ptr; @@ -5570,7 +5518,7 @@ void combine_pack(void) /* Combine the pack (backwards) */ for (i = INVEN_PACK; i > 0; i--) { - o_ptr = &inventory[i]; + o_ptr = &owner_ptr->inventory_list[i]; /* Skip empty items */ if (!o_ptr->k_idx) continue; @@ -5580,7 +5528,7 @@ void combine_pack(void) { int max_num; - j_ptr = &inventory[j]; + j_ptr = &owner_ptr->inventory_list[j]; /* Skip empty items */ if (!j_ptr->k_idx) continue; @@ -5603,17 +5551,17 @@ void combine_pack(void) object_absorb(j_ptr, o_ptr); /* One object is gone */ - inven_cnt--; + owner_ptr->inven_cnt--; /* Slide everything down */ for (k = i; k < INVEN_PACK; k++) { /* Structure copy */ - inventory[k] = inventory[k+1]; + owner_ptr->inventory_list[k] = owner_ptr->inventory_list[k+1]; } /* Erase the "final" slot */ - object_wipe(&inventory[k]); + object_wipe(&owner_ptr->inventory_list[k]); } else { @@ -5641,7 +5589,7 @@ void combine_pack(void) } } - p_ptr->window |= (PW_INVEN); + owner_ptr->window |= (PW_INVEN); /* Take note */ combined = TRUE; @@ -5677,9 +5625,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 +5638,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 +5649,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); } @@ -5791,7 +5739,7 @@ void display_koff(KIND_OBJECT_IDX k_idx) } /* Print spells */ - print_spells(0, spells, num, 2, 0, use_realm); + print_spells(p_ptr, 0, spells, num, 2, 0, use_realm); } } @@ -5850,3 +5798,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; +}