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