From aee45f109c97177c77f7b5924f80d18a5cf01a4e Mon Sep 17 00:00:00 2001 From: deskull Date: Sat, 4 Jan 2020 17:12:39 +0900 Subject: [PATCH] =?utf8?q?[Refactor]=20#38997=20compact=5Fobjects()=20?= =?utf8?q?=E3=81=AB=20floor=5Ftype=20*=20=E5=BC=95=E6=95=B0=E3=82=92?= =?utf8?q?=E8=BF=BD=E5=8A=A0=EF=BC=8E=20/=20Add=20floor=5Ftype=20*=20argum?= =?utf8?q?ent=20to=20compact=5Fobjects().?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/core.c | 4 +- src/floor.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/floor.h | 1 + src/object.h | 1 - src/object2.c | 182 --------------------------------------------------------- src/save.c | 4 +- 6 files changed, 188 insertions(+), 187 deletions(-) diff --git a/src/core.c b/src/core.c index 647d244c1..0fa433382 100644 --- a/src/core.c +++ b/src/core.c @@ -5062,10 +5062,10 @@ static void dungeon(player_type *player_ptr, bool load_game) /* Hack -- Compact the object list occasionally */ - if (player_ptr->current_floor_ptr->o_cnt + 32 > current_world_ptr->max_o_idx) compact_objects(64); + if (player_ptr->current_floor_ptr->o_cnt + 32 > current_world_ptr->max_o_idx) compact_objects(player_ptr->current_floor_ptr, 64); /* Hack -- Compress the object list occasionally */ - if (player_ptr->current_floor_ptr->o_cnt + 32 < player_ptr->current_floor_ptr->o_max) compact_objects(0); + if (player_ptr->current_floor_ptr->o_cnt + 32 < player_ptr->current_floor_ptr->o_max) compact_objects(player_ptr->current_floor_ptr, 0); /* Process the player */ process_player(player_ptr); diff --git a/src/floor.c b/src/floor.c index 4e59a7c85..35dd73e18 100644 --- a/src/floor.c +++ b/src/floor.c @@ -1740,3 +1740,186 @@ void delete_monster(floor_type *floor_ptr, POSITION y, POSITION x) /* Delete the monster (if any) */ if (g_ptr->m_idx) delete_monster_idx(g_ptr->m_idx); } + + + +/*! + * @brief グローバルオブジェクト配列に対し指定範囲のオブジェクトを整理してIDの若い順に寄せる / + * Move an object from index i1 to index i2 in the object list + * @param i1 整理したい配列の始点 + * @param i2 整理したい配列の終点 + * @return なし + */ +static void compact_objects_aux(OBJECT_IDX i1, OBJECT_IDX i2) +{ + OBJECT_IDX i; + grid_type *g_ptr; + object_type *o_ptr; + + /* Do nothing */ + if (i1 == i2) return; + + /* Repair objects */ + for (i = 1; i < p_ptr->current_floor_ptr->o_max; i++) + { + o_ptr = &p_ptr->current_floor_ptr->o_list[i]; + + /* Skip "dead" objects */ + if (!o_ptr->k_idx) continue; + + /* Repair "next" pointers */ + if (o_ptr->next_o_idx == i1) + { + /* Repair */ + o_ptr->next_o_idx = i2; + } + } + o_ptr = &p_ptr->current_floor_ptr->o_list[i1]; + + if (OBJECT_IS_HELD_MONSTER(o_ptr)) + { + monster_type *m_ptr; + m_ptr = &p_ptr->current_floor_ptr->m_list[o_ptr->held_m_idx]; + + /* Repair monster */ + if (m_ptr->hold_o_idx == i1) + { + /* Repair */ + m_ptr->hold_o_idx = i2; + } + } + + /* Dungeon */ + else + { + POSITION y, x; + + /* Acquire location */ + y = o_ptr->iy; + x = o_ptr->ix; + + /* Acquire grid */ + g_ptr = &p_ptr->current_floor_ptr->grid_array[y][x]; + + /* Repair grid */ + if (g_ptr->o_idx == i1) + { + /* Repair */ + g_ptr->o_idx = i2; + } + } + + /* Structure copy */ + p_ptr->current_floor_ptr->o_list[i2] = p_ptr->current_floor_ptr->o_list[i1]; + + /* Wipe the hole */ + object_wipe(o_ptr); +} + +/*! + * @brief グローバルオブジェクト配列から優先度の低いものを削除し、データを圧縮する。 / + * Compact and Reorder the object list. + * @param size 最低でも減らしたいオブジェクト数の水準 + * @return なし + * @details + * (危険なので使用には注意すること) + * This function can be very dangerous, use with caution!\n + *\n + * When actually "compacting" objects, we base the saving throw on a\n + * combination of object level, distance from player, and current\n + * "desperation".\n + *\n + * After "compacting" (if needed), we "reorder" the objects into a more\n + * compact order, and we reset the allocation info, and the "live" array.\n + */ +void compact_objects(floor_type *floor_ptr, int size) +{ + OBJECT_IDX i; + POSITION y, x; + int num, cnt; + int cur_lev, cur_dis, chance; + object_type *o_ptr; + + /* Compact */ + if (size) + { + msg_print(_("アイテム情報を圧縮しています...", "Compacting objects...")); + p_ptr->redraw |= (PR_MAP); + p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON); + } + + + /* Compact at least 'size' objects */ + for (num = 0, cnt = 1; num < size; cnt++) + { + /* Get more vicious each iteration */ + cur_lev = 5 * cnt; + + /* Get closer each iteration */ + cur_dis = 5 * (20 - cnt); + + /* Examine the objects */ + for (i = 1; i < floor_ptr->o_max; i++) + { + o_ptr = &floor_ptr->o_list[i]; + + 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 (OBJECT_IS_HELD_MONSTER(o_ptr)) + { + monster_type *m_ptr; + m_ptr = &floor_ptr->m_list[o_ptr->held_m_idx]; + + y = m_ptr->fy; + x = m_ptr->fx; + + /* Monsters protect their objects */ + if (randint0(100) < 90) continue; + } + + /* Dungeon */ + else + { + y = o_ptr->iy; + x = o_ptr->ix; + } + + /* Nearby objects start out "immune" */ + if ((cur_dis > 0) && (distance(p_ptr->y, p_ptr->x, y, x) < cur_dis)) continue; + + /* Saving throw */ + chance = 90; + + /* Hack -- only compact artifacts in emergencies */ + if ((object_is_fixed_artifact(o_ptr) || o_ptr->art_name) && + (cnt < 1000)) chance = 100; + + /* Apply the saving throw */ + if (randint0(100) < chance) continue; + + delete_object_idx(i); + + /* Count it */ + num++; + } + } + + + /* Excise dead objects (backwards!) */ + for (i = floor_ptr->o_max - 1; i >= 1; i--) + { + o_ptr = &floor_ptr->o_list[i]; + + /* Skip real objects */ + if (o_ptr->k_idx) continue; + + /* Move last object into open hole */ + compact_objects_aux(floor_ptr->o_max - 1, i); + + /* Compress "floor_ptr->o_max" */ + floor_ptr->o_max--; + } +} diff --git a/src/floor.h b/src/floor.h index c594dcb9a..fcab25f69 100644 --- a/src/floor.h +++ b/src/floor.h @@ -426,3 +426,4 @@ extern void set_floor(floor_type *floor_ptr, POSITION x, POSITION y); extern void place_object(floor_type *floor_ptr, POSITION y, POSITION x, BIT_FLAGS mode); extern void place_gold(floor_type *floor_ptr, POSITION y, POSITION x); extern void delete_monster(floor_type *floor_ptr, POSITION y, POSITION x); +extern void compact_objects(floor_type *floor_ptr, int size); diff --git a/src/object.h b/src/object.h index 69a562a94..dc56cf9bb 100644 --- a/src/object.h +++ b/src/object.h @@ -432,7 +432,6 @@ extern int bow_tval_ammo(object_type *o_ptr); extern void excise_object_idx(OBJECT_IDX o_idx); extern void delete_object_idx(OBJECT_IDX o_idx); extern void delete_object(POSITION y, POSITION x); -extern void compact_objects(int size); extern OBJECT_IDX o_pop(void); extern OBJECT_IDX get_obj_num(DEPTH level, BIT_FLAGS mode); diff --git a/src/object2.c b/src/object2.c index 95d7513f3..638e00b59 100644 --- a/src/object2.c +++ b/src/object2.c @@ -222,188 +222,6 @@ void delete_object(POSITION y, POSITION x) /*! - * @brief グローバルオブジェクト配列に対し指定範囲のオブジェクトを整理してIDの若い順に寄せる / - * Move an object from index i1 to index i2 in the object list - * @param i1 整理したい配列の始点 - * @param i2 整理したい配列の終点 - * @return なし - */ -static void compact_objects_aux(OBJECT_IDX i1, OBJECT_IDX i2) -{ - OBJECT_IDX i; - grid_type *g_ptr; - object_type *o_ptr; - - /* Do nothing */ - if (i1 == i2) return; - - /* Repair objects */ - for (i = 1; i < p_ptr->current_floor_ptr->o_max; i++) - { - o_ptr = &p_ptr->current_floor_ptr->o_list[i]; - - /* Skip "dead" objects */ - if (!o_ptr->k_idx) continue; - - /* Repair "next" pointers */ - if (o_ptr->next_o_idx == i1) - { - /* Repair */ - o_ptr->next_o_idx = i2; - } - } - o_ptr = &p_ptr->current_floor_ptr->o_list[i1]; - - if (OBJECT_IS_HELD_MONSTER(o_ptr)) - { - monster_type *m_ptr; - m_ptr = &p_ptr->current_floor_ptr->m_list[o_ptr->held_m_idx]; - - /* Repair monster */ - if (m_ptr->hold_o_idx == i1) - { - /* Repair */ - m_ptr->hold_o_idx = i2; - } - } - - /* Dungeon */ - else - { - POSITION y, x; - - /* Acquire location */ - y = o_ptr->iy; - x = o_ptr->ix; - - /* Acquire grid */ - g_ptr = &p_ptr->current_floor_ptr->grid_array[y][x]; - - /* Repair grid */ - if (g_ptr->o_idx == i1) - { - /* Repair */ - g_ptr->o_idx = i2; - } - } - - /* Structure copy */ - p_ptr->current_floor_ptr->o_list[i2] = p_ptr->current_floor_ptr->o_list[i1]; - - /* Wipe the hole */ - object_wipe(o_ptr); -} - - -/*! - * @brief グローバルオブジェクト配列から優先度の低いものを削除し、データを圧縮する。 / - * Compact and Reorder the object list. - * @param size 最低でも減らしたいオブジェクト数の水準 - * @return なし - * @details - * (危険なので使用には注意すること) - * This function can be very dangerous, use with caution!\n - *\n - * When actually "compacting" objects, we base the saving throw on a\n - * combination of object level, distance from player, and current\n - * "desperation".\n - *\n - * After "compacting" (if needed), we "reorder" the objects into a more\n - * compact order, and we reset the allocation info, and the "live" array.\n - */ -void compact_objects(int size) -{ - OBJECT_IDX i; - POSITION y, x; - int num, cnt; - int cur_lev, cur_dis, chance; - object_type *o_ptr; - - /* Compact */ - if (size) - { - msg_print(_("アイテム情報を圧縮しています...", "Compacting objects...")); - p_ptr->redraw |= (PR_MAP); - p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON); - } - - - /* Compact at least 'size' objects */ - for (num = 0, cnt = 1; num < size; cnt++) - { - /* Get more vicious each iteration */ - cur_lev = 5 * cnt; - - /* Get closer each iteration */ - cur_dis = 5 * (20 - cnt); - - /* Examine the objects */ - for (i = 1; i < p_ptr->current_floor_ptr->o_max; i++) - { - o_ptr = &p_ptr->current_floor_ptr->o_list[i]; - - 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 (OBJECT_IS_HELD_MONSTER(o_ptr)) - { - monster_type *m_ptr; - m_ptr = &p_ptr->current_floor_ptr->m_list[o_ptr->held_m_idx]; - - y = m_ptr->fy; - x = m_ptr->fx; - - /* Monsters protect their objects */ - if (randint0(100) < 90) continue; - } - - /* Dungeon */ - else - { - y = o_ptr->iy; - x = o_ptr->ix; - } - - /* Nearby objects start out "immune" */ - if ((cur_dis > 0) && (distance(p_ptr->y, p_ptr->x, y, x) < cur_dis)) continue; - - /* Saving throw */ - chance = 90; - - /* Hack -- only compact artifacts in emergencies */ - if ((object_is_fixed_artifact(o_ptr) || o_ptr->art_name) && - (cnt < 1000)) chance = 100; - - /* Apply the saving throw */ - if (randint0(100) < chance) continue; - - delete_object_idx(i); - - /* Count it */ - num++; - } - } - - - /* Excise dead objects (backwards!) */ - for (i = p_ptr->current_floor_ptr->o_max - 1; i >= 1; 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(p_ptr->current_floor_ptr->o_max - 1, i); - - /* Compress "p_ptr->current_floor_ptr->o_max" */ - p_ptr->current_floor_ptr->o_max--; - } -} - -/*! * @brief グローバルオブジェクト配列から空きを取得する / * Acquires and returns the index of a "free" object. * @return 開いているオブジェクト要素のID diff --git a/src/save.c b/src/save.c index 48c0b497b..7a362d3e1 100644 --- a/src/save.c +++ b/src/save.c @@ -1222,7 +1222,7 @@ static bool wr_savefile_new(void) KIND_OBJECT_IDX k_idx; /* Compact the objects */ - compact_objects(0); + compact_objects(p_ptr->current_floor_ptr, 0); /* Compact the monsters */ compact_monsters(0); @@ -2000,7 +2000,7 @@ static bool save_floor_aux(saved_floor_type *sf_ptr) byte tmp8u; /* Compact the objects */ - compact_objects(0); + compact_objects(p_ptr->current_floor_ptr, 0); /* Compact the monsters */ compact_monsters(0); -- 2.11.0