1 #include "core/object-compressor.h"
2 #include "core/window-redrawer.h"
3 #include "floor/floor-object.h"
4 #include "floor/geometry.h"
6 #include "system/baseitem-info.h"
7 #include "system/floor-type-definition.h"
8 #include "system/item-entity.h"
9 #include "system/monster-entity.h"
10 #include "system/player-type-definition.h"
11 #include "system/redrawing-flags-updater.h"
12 #include "view/display-messages.h"
16 * @brief グローバルオブジェクト配列の要素番号i1のオブジェクトを要素番号i2に移動する /
17 * Move an object from index i1 to index i2 in the object list
18 * @param i1 オブジェクト移動元の要素番号
19 * @param i2 オブジェクト移動先の要素番号
21 static void compact_objects_aux(FloorType *floor_ptr, OBJECT_IDX i1, OBJECT_IDX i2)
27 auto *o_ptr = &floor_ptr->o_list[i1];
29 // モンスター所為アイテムリストもしくは床上アイテムリストの要素番号i1をi2に書き換える
30 auto &list = get_o_idx_list_contains(floor_ptr, i1);
31 std::replace(list.begin(), list.end(), i1, i2);
33 // 要素番号i1のオブジェクトを要素番号i2に移動
34 floor_ptr->o_list[i2] = floor_ptr->o_list[i1];
39 * @brief グローバルオブジェクト配列から優先度の低いものを削除し、データを圧縮する。 /
40 * Compact and Reorder the object list.
41 * @param player_ptr プレイヤーへの参照ポインタ
42 * @param size 最低でも減らしたいオブジェクト数の水準
45 * This function can be very dangerous, use with caution!\n
47 * When actually "compacting" objects, we base the saving throw on a\n
48 * combination of object level, distance from player, and current\n
51 * After "compacting" (if needed), we "reorder" the objects into a more\n
52 * compact order, and we reset the allocation info, and the "live" array.\n
54 void compact_objects(PlayerType *player_ptr, int size)
58 msg_print(_("アイテム情報を圧縮しています...", "Compacting objects..."));
59 auto &rfu = RedrawingFlagsUpdater::get_instance();
60 rfu.set_flag(MainWindowRedrawingFlag::MAP);
61 player_ptr->window_flags |= PW_OVERHEAD | PW_DUNGEON;
64 auto *floor_ptr = player_ptr->current_floor_ptr;
65 for (int num = 0, cnt = 1; num < size; cnt++) {
66 int cur_lev = 5 * cnt;
67 int cur_dis = 5 * (20 - cnt);
68 for (OBJECT_IDX i = 1; i < floor_ptr->o_max; i++) {
69 o_ptr = &floor_ptr->o_list[i];
71 if (!o_ptr->is_valid() || (o_ptr->get_baseitem().level > cur_lev)) {
76 if (o_ptr->is_held_by_monster()) {
78 m_ptr = &floor_ptr->m_list[o_ptr->held_m_idx];
82 if (randint0(100) < 90) {
90 if ((cur_dis > 0) && (distance(player_ptr->y, player_ptr->x, y, x) < cur_dis)) {
95 if (o_ptr->is_fixed_or_random_artifact() && (cnt < 1000)) {
99 if (randint0(100) < chance) {
103 delete_object_idx(player_ptr, i);
108 for (OBJECT_IDX i = floor_ptr->o_max - 1; i >= 1; i--) {
109 o_ptr = &floor_ptr->o_list[i];
110 if (o_ptr->is_valid()) {
114 compact_objects_aux(floor_ptr, floor_ptr->o_max - 1, i);