1 #include "world/world-object.h"
2 #include "dungeon/dungeon-flag-types.h"
3 #include "object-enchant/item-apply-magic.h"
4 #include "object/tval-types.h"
5 #include "system/alloc-entries.h"
6 #include "system/baseitem-info.h"
7 #include "system/dungeon-info.h"
8 #include "system/floor-type-definition.h"
9 #include "system/item-entity.h"
10 #include "system/player-type-definition.h"
11 #include "util/probability-table.h"
12 #include "view/display-messages.h"
13 #include "world/world.h"
17 * @brief グローバルオブジェクト配列から空きを取得する /
18 * Acquires and returns the index of a "free" object.
19 * @param floo_ptr 現在フロアへの参照ポインタ
20 * @return 開いているオブジェクト要素のID
22 * This routine should almost never fail, but in case it does,
23 * we must be sure to handle "failure" of this routine.
25 OBJECT_IDX o_pop(FloorType *floor_ptr)
27 if (floor_ptr->o_max < w_ptr->max_o_idx) {
28 OBJECT_IDX i = floor_ptr->o_max;
34 for (OBJECT_IDX i = 1; i < floor_ptr->o_max; i++) {
35 if (floor_ptr->o_list[i].is_valid()) {
43 if (w_ptr->character_dungeon) {
44 msg_print(_("アイテムが多すぎる!", "Too many objects!"));
51 * @brief オブジェクト生成テーブルからアイテムを取得する /
52 * Choose an object kind that seems "appropriate" to the given level
53 * @param player_ptr プレイヤーへの参照ポインタ
55 * @return 選ばれたオブジェクトベースID
57 * This function uses the "prob2" field of the "object allocation table",\n
58 * and various local information, to calculate the "prob3" field of the\n
59 * same table, which is then used to choose an "appropriate" object, in\n
60 * a relatively efficient manner.\n
62 * It is (slightly) more likely to acquire an object of the given level\n
63 * than one of a lower level. This is done by choosing several objects\n
64 * appropriate to the given level and keeping the "hardest" one.\n
66 * Note that if no objects are "appropriate", then this function will\n
67 * fail, and return zero, but this should *almost* never happen.\n
69 OBJECT_IDX get_obj_index(const FloorType *floor_ptr, DEPTH level, BIT_FLAGS mode)
71 if (level > MAX_DEPTH - 1) {
72 level = MAX_DEPTH - 1;
75 if ((level > 0) && floor_ptr->get_dungeon_definition().flags.has_not(DungeonFeatureType::BEGINNER)) {
76 if (one_in_(CHANCE_BASEITEM_LEVEL_BOOST)) {
77 level = 1 + (level * MAX_DEPTH / randint1(MAX_DEPTH));
82 ProbabilityTable<int> prob_table;
83 for (auto i = 0U; i < alloc_kind_table.size(); i++) {
84 const auto &entry = alloc_kind_table[i];
85 if (entry.level > level) {
89 const auto &baseitem = entry.get_baseitem();
90 if ((mode & AM_FORBID_CHEST) && (baseitem.bi_key.tval() == ItemKindType::CHEST)) {
94 prob_table.entry_item(i, entry.prob2);
98 if (prob_table.empty()) {
102 // 40%で1回、50%で2回、10%で3回抽選し、その中で一番レベルが高いアイテムを選択する
105 const int p = randint0(100);
113 std::vector<int> result;
114 ProbabilityTable<int>::lottery(std::back_inserter(result), prob_table, n);
116 auto it = std::max_element(result.begin(), result.end(), [](int a, int b) { return alloc_kind_table[a].level < alloc_kind_table[b].level; });
118 return alloc_kind_table[*it].index;