From c6196b25d119a10e79deedef26a73e0d5a021b0e Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Fri, 12 Jun 2015 06:27:05 +0200 Subject: Refactor cave_type and monster_type to use non-intrusive lists We use vectors of object indexes instead of embedding the list within object_type itself. --- src/cave.cc | 111 +++++--------------- src/cave_type.hpp | 37 ++++--- src/cmd1.cc | 72 ++++--------- src/cmd2.cc | 166 ++++++++++------------------- src/cmd2.hpp | 3 +- src/cmd4.cc | 20 +--- src/cmd5.cc | 42 ++++---- src/dungeon.cc | 2 +- src/gen_evol.cc | 4 +- src/generate.cc | 253 ++++++++++++++++++++++---------------------- src/help.cc | 2 +- src/init2.cc | 8 +- src/loadsave.cc | 14 +-- src/melee1.cc | 5 +- src/melee2.cc | 19 ++-- src/monster2.cc | 87 ++++++--------- src/monster3.cc | 44 ++++---- src/monster_type.hpp | 84 ++++++++++----- src/object1.cc | 287 +++++++++++++++++++++++--------------------------- src/object2.cc | 291 +++++++++++---------------------------------------- src/object_type.hpp | 2 - src/q_troll.cc | 7 +- src/q_wight.cc | 4 +- src/spells1.cc | 14 +-- src/spells3.cc | 2 +- src/squeltch.cc | 11 +- src/traps.cc | 31 +++--- src/xtra1.cc | 4 +- src/xtra2.cc | 109 +++++++++---------- 29 files changed, 676 insertions(+), 1059 deletions(-) (limited to 'src') diff --git a/src/cave.cc b/src/cave.cc index d73115f8..1dc5cbdb 100644 --- a/src/cave.cc +++ b/src/cave.cc @@ -366,24 +366,16 @@ bool_ no_lite(void) */ bool_ cave_valid_bold(int y, int x) { - cave_type *c_ptr = &cave[y][x]; - - s16b this_o_idx, next_o_idx = 0; - + cave_type const *c_ptr = &cave[y][x]; /* Forbid perma-grids */ if (cave_perma_grid(c_ptr)) return (FALSE); /* Check objects */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const o_idx: c_ptr->o_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type *o_ptr = &o_list[o_idx]; /* Forbid artifact grids */ if ((o_ptr->art_name) || artifact_p(o_ptr)) return (FALSE); @@ -832,18 +824,6 @@ static byte darker_attrs[16] = static void map_info(int y, int x, byte *ap, char *cp) { - cave_type *c_ptr; - - feature_type *f_ptr; - - s16b this_o_idx, next_o_idx = 0; - - u16b info; - - s16b t_idx; - - byte feat; - byte a; byte c; @@ -851,16 +831,16 @@ static void map_info(int y, int x, byte *ap, char *cp) /**** Preparation ****/ /* Access the grid */ - c_ptr = &cave[y][x]; + cave_type *c_ptr = &cave[y][x]; /* Cache some frequently used values */ /* Grid info */ - info = c_ptr->info; + auto info = c_ptr->info; /* Feature code */ - feat = c_ptr->feat; + auto feat = c_ptr->feat; /* Apply "mimic" field */ if (c_ptr->mimic) @@ -873,7 +853,7 @@ static void map_info(int y, int x, byte *ap, char *cp) } /* Access floor */ - f_ptr = &f_info[feat]; + feature_type *f_ptr = &f_info[feat]; /**** Layer 1 -- Terrain feature ****/ @@ -910,7 +890,7 @@ static void map_info(int y, int x, byte *ap, char *cp) if ((info & (CAVE_TRDT)) && (feat != FEAT_ILLUS_WALL)) { /* Trap index */ - t_idx = c_ptr->t_idx; + auto t_idx = c_ptr->t_idx; /* * If trap is set on a floor grid that is not @@ -1079,15 +1059,10 @@ static void map_info(int y, int x, byte *ap, char *cp) if (feat != FEAT_MON_TRAP) { - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const o_idx: c_ptr->o_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type *o_ptr = &o_list[o_idx]; /* Memorized objects */ if (o_ptr->marked) @@ -1123,10 +1098,8 @@ static void map_info(int y, int x, byte *ap, char *cp) if (r_ptr->flags9 & RF9_MIMIC) { - object_type *o_ptr; - - /* Acquire object */ - o_ptr = &o_list[m_ptr->hold_o_idx]; + /* Acquire object being mimicked */ + object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()]; /* Memorized objects */ if (o_ptr->marked) @@ -1286,18 +1259,6 @@ static void map_info(int y, int x, byte *ap, char *cp) */ void map_info_default(int y, int x, byte *ap, char *cp) { - cave_type *c_ptr; - - feature_type *f_ptr; - - s16b this_o_idx, next_o_idx = 0; - - u16b info; - - s16b t_idx; - - byte feat; - byte a; byte c; @@ -1305,16 +1266,16 @@ void map_info_default(int y, int x, byte *ap, char *cp) /**** Preparation ****/ /* Access the grid */ - c_ptr = &cave[y][x]; + cave_type *c_ptr = &cave[y][x]; /* Cache some frequently used values */ /* Grid info */ - info = c_ptr->info; + auto info = c_ptr->info; /* Feature code */ - feat = c_ptr->feat; + auto feat = c_ptr->feat; /* Apply "mimic" field */ if (c_ptr->mimic) @@ -1327,7 +1288,7 @@ void map_info_default(int y, int x, byte *ap, char *cp) } /* Access floor */ - f_ptr = &f_info[feat]; + feature_type *f_ptr = &f_info[feat]; /**** Layer 1 -- Terrain feature ****/ @@ -1365,7 +1326,7 @@ void map_info_default(int y, int x, byte *ap, char *cp) if ((info & (CAVE_TRDT)) && (feat != FEAT_ILLUS_WALL)) { /* Trap index */ - t_idx = c_ptr->t_idx; + auto t_idx = c_ptr->t_idx; /* * If trap is set on a floor grid that is not @@ -1529,15 +1490,10 @@ void map_info_default(int y, int x, byte *ap, char *cp) if (feat != FEAT_MON_TRAP) { - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: c_ptr->o_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type *o_ptr = &o_list[this_o_idx]; /* Memorized objects */ if (o_ptr->marked) @@ -1574,10 +1530,8 @@ void map_info_default(int y, int x, byte *ap, char *cp) if (r_ptr->flags9 & RF9_MIMIC) { - object_type *o_ptr; - - /* Acquire object */ - o_ptr = &o_list[m_ptr->hold_o_idx]; + /* Acquire object being mimicked */ + object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()]; /* Memorized objects */ if (o_ptr->marked) @@ -1804,20 +1758,15 @@ void note_spot(int y, int x) u16b info = c_ptr->info; - s16b this_o_idx, next_o_idx = 0; - - /* Require "seen" flag */ if (!(info & (CAVE_SEEN))) return; /* Hack -- memorize objects */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: c_ptr->o_idxs) { - object_type * o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + /* Acquire object */ + object_type *o_ptr = &o_list[this_o_idx]; /* Memorize objects */ o_ptr->marked = TRUE; @@ -1830,8 +1779,7 @@ void note_spot(int y, int x) if (r_ptr->flags9 & RF9_MIMIC) { - object_type *o_ptr = &o_list[m_ptr->hold_o_idx]; - + object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()]; o_ptr->marked = TRUE; } } @@ -4086,8 +4034,7 @@ void wiz_lite(void) if (r_ptr->flags9 & RF9_MIMIC) { - object_type *o_ptr = &o_list[m_ptr->hold_o_idx]; - + object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()]; o_ptr->marked = TRUE; } } @@ -4669,7 +4616,7 @@ bool cave_clean_bold(int y, int x) return (f_info[cave[y][x].feat].flags1 & FF1_FLOOR) && (cave[y][x].feat != FEAT_MON_TRAP) && - (cave[y][x].o_idx == 0) && + (cave[y][x].o_idxs.empty()) && !(f_info[cave[y][x].feat].flags1 & FF1_PERMANENT); } @@ -4702,7 +4649,7 @@ bool cave_naked_bold(int y, int x) (f_info[cave[y][x].feat].flags1 & FF1_FLOOR) && (cave[y][x].feat != FEAT_MON_TRAP) && !(f_info[cave[y][x].feat].flags1 & FF1_PERMANENT) && - (cave[y][x].o_idx == 0) && + (cave[y][x].o_idxs.empty()) && (cave[y][x].m_idx == 0); } @@ -4711,7 +4658,7 @@ bool cave_naked_bold2(int y, int x) return (f_info[cave[y][x].feat].flags1 & FF1_FLOOR) && (cave[y][x].feat != FEAT_MON_TRAP) && - (cave[y][x].o_idx == 0) && + (cave[y][x].o_idxs.empty()) && (cave[y][x].m_idx == 0); } diff --git a/src/cave_type.hpp b/src/cave_type.hpp index 912e1091..958ace1d 100644 --- a/src/cave_type.hpp +++ b/src/cave_type.hpp @@ -2,6 +2,9 @@ #include "h-basic.h" +#include +#include + /** * A single "grid" in a Cave. * @@ -27,26 +30,36 @@ */ struct cave_type { - u16b info; /* Hack -- cave flags */ + u16b info = 0; /* Hack -- cave flags */ + + byte feat = 0; /* Hack -- feature type */ + + std::vector o_idxs { }; /* Indexes of objects in this grid */ - byte feat; /* Hack -- feature type */ + s16b m_idx = 0; /* Monster in this grid */ - s16b o_idx; /* Object in this grid */ + s16b t_idx = 0; /* trap index (in t_list) or zero */ - s16b m_idx; /* Monster in this grid */ + s16b special = 0; /* Special cave info */ + s16b special2 = 0; /* Special cave info */ - s16b t_idx; /* trap index (in t_list) or zero */ + s16b inscription = 0; /* Inscription of the grid */ - s16b special, special2; /* Special cave info */ + byte mana = 0; /* Magical energy of the grid */ - s16b inscription; /* Inscription of the grid */ + byte mimic = 0; /* Feature to mimic */ - byte mana; /* Magical energy of the grid */ + byte cost = 0; /* Hack -- cost of flowing */ + byte when = 0; /* Hack -- when cost was computed */ - byte mimic; /* Feature to mimic */ + s16b effect = 0; /* The lasting effects */ - byte cost; /* Hack -- cost of flowing */ - byte when; /* Hack -- when cost was computed */ + /** + * @brief wipe the object's state + */ + void wipe() { + /* Reset to defaults */ + *this = cave_type(); + } - s16b effect; /* The lasting effects */ }; diff --git a/src/cmd1.cc b/src/cmd1.cc index 81e45776..e6494839 100644 --- a/src/cmd1.cc +++ b/src/cmd1.cc @@ -559,30 +559,23 @@ s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, */ void search(void) { - int y, x, chance; - - s16b this_o_idx, next_o_idx = 0; - - cave_type *c_ptr; - - /* Start with base search ability */ - chance = p_ptr->skill_srh; + int chance = p_ptr->skill_srh; /* Penalize various conditions */ if (p_ptr->blind || no_lite()) chance = chance / 10; if (p_ptr->confused || p_ptr->image) chance = chance / 10; /* Search the nearby grids, which are always in bounds */ - for (y = (p_ptr->py - 1); y <= (p_ptr->py + 1); y++) + for (int y = (p_ptr->py - 1); y <= (p_ptr->py + 1); y++) { - for (x = (p_ptr->px - 1); x <= (p_ptr->px + 1); x++) + for (int x = (p_ptr->px - 1); x <= (p_ptr->px + 1); x++) { /* Sometimes, notice things */ if (rand_int(100) < chance) { /* Access the grid */ - c_ptr = &cave[y][x]; + cave_type *c_ptr = &cave[y][x]; /* Invisible trap */ if ((c_ptr->t_idx != 0) && !(c_ptr->info & CAVE_TRDT)) @@ -613,16 +606,9 @@ void search(void) } /* Scan all objects in the grid */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; - this_o_idx = next_o_idx) + for (auto const o_idx: c_ptr->o_idxs) { - object_type * o_ptr; - - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type * o_ptr = &o_list[o_idx]; /* Skip non-chests */ if (o_ptr->tval != TV_CHEST) continue; @@ -4009,9 +3995,6 @@ static bool_ run_test(void) int option = 0, option2 = 0; - cave_type *c_ptr; - - /* Where we came from */ prev_dir = find_prevdir; @@ -4023,9 +4006,6 @@ static bool_ run_test(void) /* Look at every newly adjacent square. */ for (i = -max; i <= max; i++) { - s16b this_o_idx, next_o_idx = 0; - - /* New direction */ new_dir = cycle[chome[prev_dir] + i]; @@ -4034,7 +4014,7 @@ static bool_ run_test(void) col = p_ptr->px + ddx[new_dir]; /* Access grid */ - c_ptr = &cave[row][col]; + cave_type *c_ptr = &cave[row][col]; /* Visible monsters abort running */ @@ -4047,15 +4027,10 @@ static bool_ run_test(void) } /* Visible objects abort running */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const o_idx: c_ptr->o_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type * o_ptr = &o_list[o_idx]; /* Visible object */ if (o_ptr->marked) return (TRUE); @@ -4229,7 +4204,7 @@ static bool_ run_test(void) col = p_ptr->px + ddx[new_dir]; /* Access grid */ - c_ptr = &cave[row][col]; + cave_type *c_ptr = &cave[row][col]; /* Unknown grids or non-obstacle */ if (!see_obstacle_grid(c_ptr)) @@ -4261,7 +4236,7 @@ static bool_ run_test(void) col = p_ptr->px + ddx[new_dir]; /* Access grid */ - c_ptr = &cave[row][col]; + cave_type *c_ptr = &cave[row][col]; /* Unknown grid or non-obstacle */ if (!see_obstacle_grid(c_ptr)) @@ -5019,15 +4994,16 @@ bool_ execute_inscription(byte i, byte y, byte x) { monster_type *m_ptr; monster_race *r_ptr; - cave_type *c_ptr; int ii = x, ij = y; cave_set_feat(ij, ii, FEAT_DARK_PIT); msg_print("A chasm appears in the floor!"); - if (cave[ij][ii].m_idx) + cave_type *c_ptr = &cave[ij][ii]; + + if (c_ptr->m_idx) { - m_ptr = &m_list[cave[ij][ii].m_idx]; + m_ptr = &m_list[c_ptr->m_idx]; r_ptr = race_inf(m_ptr); if (r_ptr->flags7 & RF7_CAN_FLY) @@ -5039,34 +5015,28 @@ bool_ execute_inscription(byte i, byte y, byte x) if (!(r_ptr->flags1 & RF1_UNIQUE)) { msg_print("The monster falls in the chasm!"); - delete_monster_idx(cave[ij][ii].m_idx); + delete_monster_idx(c_ptr->m_idx); } } } - if (cave[ij][ii].o_idx) + if (!c_ptr->o_idxs.empty()) { - s16b this_o_idx, next_o_idx = 0; - - c_ptr = &cave[ij][ii]; + /* Copy list of objects since we're going to be manipulating the list */ + auto const object_idxs(c_ptr->o_idxs); /* Scan all objects in the grid */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; - this_o_idx = next_o_idx) + for (auto const this_o_idx: object_idxs) { - object_type * o_ptr; bool_ plural = FALSE; char o_name[80]; /* Acquire object */ - o_ptr = &o_list[this_o_idx]; + object_type * o_ptr = &o_list[this_o_idx]; if (o_ptr->number > 1) plural = TRUE; - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; - /* Effect "observed" */ if (o_ptr->marked) { diff --git a/src/cmd2.cc b/src/cmd2.cc index b176576d..768e79c0 100644 --- a/src/cmd2.cc +++ b/src/cmd2.cc @@ -614,20 +614,14 @@ static s16b chest_check(int y, int x) { cave_type *c_ptr = &cave[y][x]; - s16b this_o_idx, next_o_idx = 0; - - /* Scan all objects in the grid */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: c_ptr->o_idxs) { object_type * o_ptr; /* Acquire object */ o_ptr = &o_list[this_o_idx]; - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; - /* Skip unknown chests XXX XXX */ /* if (!o_ptr->marked) continue; */ @@ -4642,147 +4636,114 @@ void do_cmd_sacrifice(void) * * Return a list of o_list[] indexes of items of the given monster */ -bool_ scan_monst(int *items, int *item_num, int m_idx) +std::vector scan_monst(int m_idx) { - int this_o_idx, next_o_idx; + constexpr std::size_t max_size = 23; - int num = 0; - - - (*item_num) = 0; + /* Create output vector. */ + std::vector objects; + objects.reserve(std::min(max_size, m_list[m_idx].hold_o_idxs.size())); /* Scan all objects in the grid */ - for (this_o_idx = m_list[m_idx].hold_o_idx; this_o_idx; - this_o_idx = next_o_idx) + for (auto const this_o_idx: m_list[m_idx].hold_o_idxs) { - object_type * o_ptr; - - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; - - /* Accept this item */ - items[num++] = this_o_idx; - - /* XXX Hack -- Enforce limit */ - if (num == 23) break; + objects.push_back(this_o_idx); + if (objects.size() == max_size) break; } - /* Number of items */ - (*item_num) = num; - /* Result */ - return (num != 0); + return objects; } /* * Display a list of the items that the given monster carries. + * Returns the list of objects. */ -byte show_monster_inven(int m_idx, int *monst_list) +std::vector show_monster_inven(int m_idx) { - int i, j, k, l; - - int col, len, lim; - - object_type *o_ptr; - - char o_name[80]; - - char tmp_val[80]; - - int out_index[23]; - byte out_color[23]; - char out_desc[23][80]; - int monst_num; - - /* Default length */ - len = 79 - 50; + int len = 79 - 50; /* Maximum space allowed for descriptions */ - lim = 79 - 3; + int lim = 79 - 3; /* Require space for weight */ lim -= 9; /* Scan for objects on the monster */ - (void)scan_monst(monst_list, &monst_num, m_idx); + std::vector objects = scan_monst(m_idx); + assert(objects.size() <= 23); - /* Display the p_ptr->inventory */ - for (k = 0, i = 0; i < monst_num; i++) + /* Calculate width of object names */ + for (std::size_t i = 0; i < objects.size(); i++) { - o_ptr = &o_list[monst_list[i]]; + object_type *o_ptr = &o_list[objects.at(i)]; /* Describe the object */ + char o_name[80]; object_desc(o_name, o_ptr, TRUE, 3); /* Hack -- enforce max length */ o_name[lim] = '\0'; - /* Save the index */ - out_index[k] = i; - /* Acquire p_ptr->inventory color */ - out_color[k] = tval_to_attr[o_ptr->tval & 0x7F]; + out_color[i] = tval_to_attr[o_ptr->tval & 0x7F]; /* Save the object description */ - strcpy(out_desc[k], o_name); + strcpy(out_desc[i], o_name); /* Find the predicted "line length" */ - l = strlen(out_desc[k]) + 5; + int l = strlen(out_desc[i]) + 5; /* Account for the weight */ l += 9; /* Maintain the maximum length */ if (l > len) len = l; - - /* Advance to next "line" */ - k++; } /* Find the column to start in */ - col = (len > 76) ? 0 : (79 - len); + int col = (len > 76) ? 0 : (79 - len); /* Output each entry */ - for (j = 0; j < k; j++) + std::size_t i = 0; + for (i = 0; i < objects.size(); i++) { - /* Get the index */ - i = monst_list[out_index[j]]; - /* Get the item */ - o_ptr = &o_list[i]; + object_type *o_ptr = &o_list[objects.at(i)]; /* Clear the line */ - prt("", j + 1, col ? col - 2 : col); + prt("", i + 1, col ? col - 2 : col); /* Prepare an index --(-- */ - strnfmt(tmp_val, 80, "%c)", index_to_label(j)); + char tmp_val[80]; + strnfmt(tmp_val, 80, "%c)", index_to_label(i)); /* Clear the line with the (possibly indented) index */ - put_str(tmp_val, j + 1, col); + put_str(tmp_val, i + 1, col); /* Display the entry itself */ - c_put_str(out_color[j], out_desc[j], j + 1, col + 3); + c_put_str(out_color[i], out_desc[i], i + 1, col + 3); /* Display the weight if needed */ { int wgt = o_ptr->weight * o_ptr->number; strnfmt(tmp_val, 80, "%3d.%1d lb", wgt / 10, wgt % 10); - put_str(tmp_val, j + 1, 71); + put_str(tmp_val, i + 1, 71); } } /* Make a "shadow" below the list (only if needed) */ - if (j && (j < 23)) prt("", j + 1, col ? col - 2 : col); + if (i && (i < 23)) + { + prt("", i + 1, col ? col - 2 : col); + } - return monst_num; + return objects; } @@ -4791,26 +4752,16 @@ byte show_monster_inven(int m_idx, int *monst_list) */ void do_cmd_steal() { - int x, y, dir = 0, item = -1, k = -1; - - cave_type *c_ptr; - - monster_type *m_ptr; - - object_type *o_ptr, forge; - - byte num = 0; + int dir = 0, item = -1, k = -1; bool_ done = FALSE; - int monst_list[23]; - - /* Only works on adjacent monsters */ if (!get_rep_dir(&dir)) return; - y = p_ptr->py + ddy[dir]; - x = p_ptr->px + ddx[dir]; - c_ptr = &cave[y][x]; + int y = p_ptr->py + ddy[dir]; + int x = p_ptr->px + ddx[dir]; + + cave_type const *c_ptr = &cave[y][x]; if (!(c_ptr->m_idx)) { @@ -4818,10 +4769,10 @@ void do_cmd_steal() return; } - m_ptr = &m_list[c_ptr->m_idx]; + monster_type *m_ptr = &m_list[c_ptr->m_idx]; /* There were no non-gold items */ - if (!m_ptr->hold_o_idx) + if (m_ptr->hold_o_idxs.empty()) { msg_print("That monster has no objects!"); return; @@ -4836,7 +4787,7 @@ void do_cmd_steal() screen_save(); - num = show_monster_inven(c_ptr->m_idx, monst_list); + std::vector objects = show_monster_inven(c_ptr->m_idx); /* Repeat until done */ while (!done) @@ -4846,7 +4797,7 @@ void do_cmd_steal() /* Build the prompt */ strnfmt(tmp_val, 80, "Choose an item to steal (a-%c) or ESC:", - 'a' - 1 + num); + 'a' - 1 + objects.size()); /* Show the prompt */ prt(tmp_val, 0, 0); @@ -4873,7 +4824,7 @@ void do_cmd_steal() which = tolower(which); k = islower(which) ? A2I(which) : -1; - if (k < 0 || k >= num) + if ((k < 0) || (static_cast(k) >= objects.size())) { bell(); @@ -4881,7 +4832,7 @@ void do_cmd_steal() } /* Verify the item */ - if (ver && !verify("Try", 0 - monst_list[k])) + if (ver && !verify("Try", -objects[k])) { done = TRUE; @@ -4889,7 +4840,7 @@ void do_cmd_steal() } /* Accept that choice */ - item = monst_list[k]; + item = objects[k]; done = TRUE; break; @@ -4927,14 +4878,8 @@ void do_cmd_steal() return; } - /* Reconnect the objects list */ - if (num == 1) m_ptr->hold_o_idx = 0; - else - { - if (k > 0) o_list[monst_list[k - 1]].next_o_idx = monst_list[k + 1]; - if (k + 1 >= num) o_list[monst_list[k - 1]].next_o_idx = 0; - if (k == 0) m_ptr->hold_o_idx = monst_list[k + 1]; - } + /* Remove from the monster's list of objects */ + m_ptr->hold_o_idxs.erase(m_ptr->hold_o_idxs.begin() + k); /* Rogues gain some xp */ if (race_flags1_p(PR1_EASE_STEAL)) @@ -4951,8 +4896,9 @@ void do_cmd_steal() if (get_check("Phase door?")) teleport_player(10); } - /* Get the item */ - o_ptr = &forge; + /* Create the object we're going to copy into */ + object_type forge; + object_type *o_ptr = &forge; /* Special handling for gold */ if (o_list[item].tval == TV_GOLD) @@ -4973,7 +4919,7 @@ void do_cmd_steal() inven_carry(o_ptr, FALSE); } - /* Delete it */ + /* Delete source item */ o_list[item].k_idx = 0; } diff --git a/src/cmd2.hpp b/src/cmd2.hpp index ef82b839..41030995 100644 --- a/src/cmd2.hpp +++ b/src/cmd2.hpp @@ -2,8 +2,9 @@ #include "h-basic.h" #include "object_type_fwd.hpp" +#include -extern byte show_monster_inven(int m_idx, int *monst_list); +extern std::vector show_monster_inven(int m_idx); extern int breakage_chance(object_type *o_ptr); extern void do_cmd_go_up(void); extern void do_cmd_go_down(void); diff --git a/src/cmd4.cc b/src/cmd4.cc index d857c1a0..c18718ae 100644 --- a/src/cmd4.cc +++ b/src/cmd4.cc @@ -3091,18 +3091,11 @@ void do_cmd_knowledge_artifacts(void) { cave_type *c_ptr = &cave[y][x]; - s16b this_o_idx, next_o_idx = 0; - /* Scan all objects in the grid */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: c_ptr->o_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type const * o_ptr = &o_list[this_o_idx]; /* Ignore random artifacts */ if (o_ptr->tval == TV_RANDART) continue; @@ -3129,21 +3122,14 @@ void do_cmd_knowledge_artifacts(void) /* Check monsters in the dungeon */ for (i = 0; i < m_max; i++) { - monster_type *m_ptr = &m_list[i]; - - s16b this_o_idx, next_o_idx = 0; - /* Scan all objects the monster carries */ - for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: m_list[i].hold_o_idxs) { object_type * o_ptr; /* Acquire object */ o_ptr = &o_list[this_o_idx]; - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; - /* Ignore random artifacts */ if (o_ptr->tval == TV_RANDART) continue; diff --git a/src/cmd5.cc b/src/cmd5.cc index 3fcabb09..05483b91 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -429,27 +429,19 @@ void do_poly_self(void) */ void fetch(int dir, int wgt, bool_ require_los) { - int ty, tx, i; - - cave_type *c_ptr; - - object_type *o_ptr; - - char o_name[80]; - - /* Check to see if an object is already there */ - if (cave[p_ptr->py][p_ptr->px].o_idx) + if (!cave[p_ptr->py][p_ptr->px].o_idxs.empty()) { msg_print("You can't fetch when you're already standing on something."); return; } /* Use a target */ + cave_type *c_ptr = nullptr; if ((dir == 5) && target_okay()) { - tx = target_col; - ty = target_row; + int tx = target_col; + int ty = target_row; if (distance(p_ptr->py, p_ptr->px, ty, tx) > MAX_RANGE) { @@ -459,7 +451,7 @@ void fetch(int dir, int wgt, bool_ require_los) c_ptr = &cave[ty][tx]; - if (!c_ptr->o_idx) + if (c_ptr->o_idxs.empty()) { msg_print("There is no object at this place."); return; @@ -474,8 +466,8 @@ void fetch(int dir, int wgt, bool_ require_los) else { /* Use a direction */ - ty = p_ptr->py; /* Where to drop the item */ - tx = p_ptr->px; + int ty = p_ptr->py; /* Where to drop the item */ + int tx = p_ptr->px; while (1) { @@ -486,12 +478,17 @@ void fetch(int dir, int wgt, bool_ require_los) if ((distance(p_ptr->py, p_ptr->px, ty, tx) > MAX_RANGE) || !cave_floor_bold(ty, tx)) return; - if (c_ptr->o_idx) break; + if (!c_ptr->o_idxs.empty()) break; } } - o_ptr = &o_list[c_ptr->o_idx]; + assert(c_ptr != nullptr); + assert(!c_ptr->o_idxs.empty()); + + /* Pick object from the list */ + auto o_idx = c_ptr->o_idxs.front(); + object_type *o_ptr = &o_list[o_idx]; if (o_ptr->weight > wgt) { /* Too heavy to 'fetch' */ @@ -499,13 +496,16 @@ void fetch(int dir, int wgt, bool_ require_los) return; } - i = c_ptr->o_idx; - c_ptr->o_idx = o_ptr->next_o_idx; - cave[p_ptr->py][p_ptr->px].o_idx = i; /* 'move' it */ - o_ptr->next_o_idx = 0; + /* Move the object between the lists */ + c_ptr->o_idxs.erase(c_ptr->o_idxs.begin()); // Remove + cave[p_ptr->py][p_ptr->px].o_idxs.push_back(o_idx); // Add + + /* Update object's location */ o_ptr->iy = p_ptr->py; o_ptr->ix = p_ptr->px; + /* Feedback */ + char o_name[80]; object_desc(o_name, o_ptr, TRUE, 0); msg_format("%^s flies through the air to your feet.", o_name); diff --git a/src/dungeon.cc b/src/dungeon.cc index 7f276b80..62eaf211 100644 --- a/src/dungeon.cc +++ b/src/dungeon.cc @@ -2341,7 +2341,7 @@ static void process_world(void) if (!(dungeon_flags1 & DF1_DAMAGE_FEAT)) { /* If the grid is empty, skip it */ - if ((cave[j][k].o_idx == 0) && + if ((cave[j][k].o_idxs.empty()) && ((j != p_ptr->py) && (i != p_ptr->px))) continue; } diff --git a/src/gen_evol.cc b/src/gen_evol.cc index 0ccd063f..f6cee5a7 100644 --- a/src/gen_evol.cc +++ b/src/gen_evol.cc @@ -51,7 +51,7 @@ void evolve_level(bool_ noise) if (f_info[c_ptr->feat].flags1 & FF1_PERMANENT) continue; /* Avoid evolving grids with object or monster */ - if (c_ptr->o_idx || c_ptr->m_idx) continue; + if ((!c_ptr->o_idxs.empty()) || c_ptr->m_idx) continue; /* Avoid evolving player grid */ if ((j == p_ptr->py) && (i == p_ptr->px)) continue; @@ -85,7 +85,7 @@ void evolve_level(bool_ noise) if (f_info[c_ptr->feat].flags1 & FF1_PERMANENT) continue; /* Avoid evolving grids with object or monster */ - if (c_ptr->o_idx || c_ptr->m_idx) continue; + if ((!c_ptr->o_idxs.empty()) || c_ptr->m_idx) continue; /* Avoid evolving player grid */ if ((j == p_ptr->py) && (i == p_ptr->px)) continue; diff --git a/src/generate.cc b/src/generate.cc index 4d3b2bc8..0f24f7d2 100644 --- a/src/generate.cc +++ b/src/generate.cc @@ -7181,32 +7181,32 @@ bool_ level_generate_dungeon() */ static void replace_all_friends() { - int i; - - if (p_ptr->wild_mode) return; + if (p_ptr->wild_mode) + { + return; + } /* Scan every saved pet */ - for (i = 0; i < max_m_idx; i++) + for (int i = 0; i < max_m_idx; i++) { if ((km_list[i].r_idx) && (km_list[i].status == MSTATUS_COMPANION)) { - int y = p_ptr->py, x = p_ptr->px; - cave_type *c_ptr; - monster_type *m_ptr; + int y = p_ptr->py; + int x = p_ptr->px; /* Find a suitable location */ get_pos_player(5, &y, &x); - c_ptr = &cave[y][x]; + cave_type *c_ptr = &cave[y][x]; /* Get a m_idx to use */ c_ptr->m_idx = m_pop(); - m_ptr = &m_list[c_ptr->m_idx]; + monster_type *m_ptr = &m_list[c_ptr->m_idx]; /* Actualy place the monster */ m_list[c_ptr->m_idx] = km_list[i]; m_ptr->fy = y; m_ptr->fx = x; - m_ptr->hold_o_idx = 0; + m_ptr->hold_o_idxs.clear(); // Objects have been removed previously by caller } } } @@ -7504,6 +7504,87 @@ static void fill_level(bool_ use_floor, byte smooth) } +/** + * @brief double a grid tile. Used for the double-size dungeons + */ +static void supersize_grid_tile(int sy, int sx, int ty, int tx) +{ + /* Displacements for copied grid tiles */ + constexpr std::size_t n_disp = 4; + int disp[n_disp][2] = { + { 0, 0 }, + { 0, +1 }, + { +1, 0 }, + { +1, +1 } + }; + + /* Acquire the grid tile and monster */ + cave_type *cc_ptr = &cave[sy][sx]; + monster_type *m_ptr = &m_list[cc_ptr->m_idx]; + + /* Save the list of objects */ + auto const object_idxs(cc_ptr->o_idxs); + + /* Save the monster */ + auto m_idx = cc_ptr->m_idx; + + /* Create pointers to each of the target grid tiles */ + cave_type *c_ptr[n_disp]; + for (std::size_t i = 0; i < n_disp; i++) + { + c_ptr[i] = &cave[ty + disp[i][0]][tx + disp[i][1]]; + } + + /* Now we copy around the grid tiles. Objects and + monsters are "removed" for now. */ + for (std::size_t i = 0; i < 4; i++) + { + c_ptr[i] = &cave[ty + disp[i][0]][tx + disp[i][1]]; + + /* Copy grid */ + *c_ptr[i] = *cc_ptr; + c_ptr[i]->o_idxs.clear(); // ... except objects in the tile + c_ptr[i]->m_idx = 0; // ... except monsters in the tile + + /* Void gates need special attention */ + if (cc_ptr->feat == FEAT_BETWEEN) + { + int xxx = cc_ptr->special & 0xFF; + int yyy = cc_ptr->special >> 8; + + xxx *= 2; + yyy *= 2; + xxx += disp[i][1]; + yyy += disp[i][0]; + c_ptr[i]->special = xxx + (yyy << 8); + } + } + + /* Scatter objects randomly into the destination grid tiles */ + for (auto const o_idx: object_idxs) + { + std::size_t i = static_cast(rand_int(4)); + /* Put object into grid tile */ + c_ptr[i]->o_idxs.push_back(o_idx); + /* Give object its location */ + object_type *o_ptr = &o_list[o_idx]; + o_ptr->iy = ty + disp[i][0]; + o_ptr->ix = tx + disp[i][1]; + } + + /* Scatter move monster randomly into one of the destination grid tiles */ + if (m_idx != 0) + { + std::size_t i = static_cast(rand_int(4)); + /* Place monster into grid tile */ + c_ptr[i]->m_idx = cc_ptr->m_idx; + /* Give the monster its location */ + m_ptr->fy = ty + disp[i][0]; + m_ptr->fx = tx + disp[i][1]; + } +} + + /* * Generate a new dungeon level * @@ -7511,7 +7592,6 @@ static void fill_level(bool_ use_floor, byte smooth) */ static bool_ cave_gen(void) { - int i, k, y, x, y1, x1, branch; dungeon_info_type *d_ptr = &d_info[dungeon_type]; int max_vault_ok = 2; @@ -7582,14 +7662,14 @@ static bool_ cave_gen(void) /* Generate stairs */ { /* Is there a dungeon branch ? */ - if ((branch = get_branch())) + if (int branch = get_branch()) { /* Place 5 down stair some walls */ alloc_stairs(FEAT_MORE, 5, 3, branch); } /* Is there a father dungeon branch ? */ - if ((branch = get_fbranch())) + if (int branch = get_fbranch()) { /* Place 1 down stair some walls */ alloc_stairs(FEAT_LESS, 5, 3, branch); @@ -7617,7 +7697,7 @@ static bool_ cave_gen(void) process_hooks_new(HOOK_GEN_LEVEL, NULL, NULL); /* Basic "amount" */ - k = (dun_level / 3); + int k = (dun_level / 3); if (k > 10) k = 10; if (k < 2) k = 2; @@ -7627,7 +7707,7 @@ static bool_ cave_gen(void) /* * Pick a base number of monsters */ - i = d_ptr->min_m_alloc_level; + int i = d_ptr->min_m_alloc_level; /* To make small levels a bit more playable */ if ((cur_hgt < MAX_HGT) || (cur_wid < MAX_WID)) @@ -7655,7 +7735,7 @@ static bool_ cave_gen(void) } /* Check fates */ - for (i = 0; i < MAX_FATES; i++) + for (std::size_t i = 0; i < MAX_FATES; i++) { /* Ignore empty slots */ if (fates[i].fate == FATE_NONE) continue; @@ -7788,8 +7868,8 @@ static bool_ cave_gen(void) } } - /* Re scan the list to eliminate the inutile fate */ - for (i = 0; i < MAX_FATES; i++) + /* Re-scan the list to eliminate the inutile fate */ + for (std::size_t i = 0; i < MAX_FATES; i++) { switch (fates[i].fate) { @@ -7921,13 +8001,11 @@ static bool_ cave_gen(void) object_copy(o_ptr, q_ptr); /* Build a stack */ - o_ptr->next_o_idx = m_list[m_idx].hold_o_idx; - o_ptr->held_m_idx = m_idx; o_ptr->ix = 0; o_ptr->iy = 0; - m_list[m_idx].hold_o_idx = o_idx; + m_list[m_idx].hold_o_idxs.push_back(o_idx); } } @@ -7973,13 +8051,11 @@ static bool_ cave_gen(void) object_copy(o_ptr, q_ptr); /* Build a stack */ - o_ptr->next_o_idx = m_list[m_idx].hold_o_idx; - o_ptr->held_m_idx = m_idx; o_ptr->ix = 0; o_ptr->iy = 0; - m_list[m_idx].hold_o_idx = o_idx; + m_list[m_idx].hold_o_idxs.push_back(o_idx); } } } @@ -7990,64 +8066,24 @@ static bool_ cave_gen(void) /* Now double the generated dungeon */ if (dungeon_flags1 & DF1_DOUBLE) { - /* We begin at the bottom-right corner and from there move - * up/left (this way we don't need another array for the - * dungeon data) */ - /* Note: we double the border permanent walls, too. It is - * easier this way and I think it isn't too ugly */ - for (y = cur_hgt - 1, y1 = y * 2; y >= 0; y--, y1 -= 2) - for (x = cur_wid - 1, x1 = x * 2; x >= 0; x--, x1 -= 2) + /* + * We begin at the bottom-right corner and move upwards + * to the left. This avoids the need for an extra copy of + * the cave array. + * + * We double the border permanent walls, too. + */ + int y = cur_hgt - 1; + int y1 = y * 2; + for (; y >= 0; y--, y1 -= 2) + { + int x = cur_wid - 1; + int x1 = x * 2; + for (; x >= 0; x--, x1 -= 2) { - int disp[4][2] = {{0, 0}, {0, + 1}, { + 1, 0}, { + 1, + 1}}; - - cave_type *c_ptr[4], *cc_ptr = &cave[y][x]; - object_type *o_ptr = &o_list[cc_ptr->o_idx]; - monster_type *m_ptr = &m_list[cc_ptr->m_idx]; - - /* - * Now we copy the generated data to the - * appropriate grids - */ - for (i = 0; i < 4; i++) - { - c_ptr[i] = &cave[y1 + disp[i][0]][x1 + disp[i][1]]; - *c_ptr[i] = *cc_ptr; - c_ptr[i]->o_idx = 0; - c_ptr[i]->m_idx = 0; - - if (cc_ptr->feat == FEAT_BETWEEN) - { - int xxx = cc_ptr->special & 0xFF; - int yyy = cc_ptr->special >> 8; - - xxx *= 2; - yyy *= 2; - xxx += disp[i][1]; - yyy += disp[i][0]; - c_ptr[i]->special = xxx + (yyy << 8); - } - } - - /* Objects should be put only in 1 of the - * new grids (otherwise we would segfault - * a lot) ... */ - if (cc_ptr->o_idx != 0) - { - i = rand_int(4); - c_ptr[i]->o_idx = cc_ptr->o_idx; - o_ptr->iy = y1 + disp[i][0]; - o_ptr->ix = x1 + disp[i][1]; - } - - /* ..just like monsters */ - if (cc_ptr->m_idx != 0) - { - i = rand_int(4); - c_ptr[i]->m_idx = cc_ptr->m_idx; - m_ptr->fy = y1 + disp[i][0]; - m_ptr->fx = x1 + disp[i][1]; - } + supersize_grid_tile(y, x, y1, x1); } + } /* Set the width/height ... */ cur_wid *= 2; @@ -8285,33 +8321,11 @@ void generate_cave(void) { for (x = 0; x < MAX_WID; x++) { - /* No flags */ - cave[y][x].info = 0; + /* Wipe */ + cave[y][x].wipe(); /* No features */ cave_set_feat(y, x, FEAT_PERM_INNER); - - /* No objects */ - cave[y][x].o_idx = 0; - - /* No monsters */ - cave[y][x].m_idx = 0; - - /* No traps */ - cave[y][x].t_idx = 0; - - /* No mimic */ - cave[y][x].mimic = 0; - - /* No effects */ - cave[y][x].effect = 0; - - /* No inscription */ - cave[y][x].inscription = 0; - - /* No flow */ - cave[y][x].cost = 0; - cave[y][x].when = 0; } } @@ -8345,33 +8359,11 @@ void generate_cave(void) { for (x = 0; x < MAX_WID; x++) { - /* No flags */ - cave[y][x].info = 0; + /* Wipe */ + cave[y][x].wipe(); /* No features */ cave_set_feat(y, x, FEAT_PERM_INNER); - - /* No objects */ - cave[y][x].o_idx = 0; - - /* No monsters */ - cave[y][x].m_idx = 0; - - /* No traps */ - cave[y][x].t_idx = 0; - - /* No mimic */ - cave[y][x].mimic = 0; - - /* No effect */ - cave[y][x].effect = 0; - - /* No inscription */ - cave[y][x].inscription = 0; - - /* No flow */ - cave[y][x].cost = 0; - cave[y][x].when = 0; } } @@ -8654,7 +8646,10 @@ void generate_cave(void) } /* Put the kept monsters -- DG */ - if (!p_ptr->wild_mode) replace_all_friends(); + if (!p_ptr->wild_mode) + { + replace_all_friends(); + } /* Hack -- Clear used up fates */ for (i = 0; i < MAX_FATES; i++) diff --git a/src/help.cc b/src/help.cc index 9b607b66..29ebf033 100644 --- a/src/help.cc +++ b/src/help.cc @@ -325,7 +325,7 @@ static bool_ trigger_fountain(void *in, void *out) { static bool_ trigger_found_object(void *in, void *out) { hook_move_in *p = (hook_move_in *) in; - return cave[p->y][p->x].o_idx != 0; + return !cave[p->y][p->x].o_idxs.empty(); } static bool_ trigger_found_altar(void *in, void *out) { diff --git a/src/init2.cc b/src/init2.cc index e9508684..f80b832a 100644 --- a/src/init2.cc +++ b/src/init2.cc @@ -828,10 +828,10 @@ static errr init_other(void) o_list = make_array(max_o_idx); /* Allocate and Wipe the monster list */ - m_list = make_array(max_m_idx); + m_list = new monster_type[max_m_idx]; /* Allocate and Wipe the to keep monster list */ - km_list = make_array(max_m_idx); + km_list = new monster_type[max_m_idx]; /* Allocate and Wipe the max dungeon level */ max_dlv = make_array(max_d_idx); @@ -843,11 +843,11 @@ static errr init_other(void) } /* Allocate and wipe each line of the cave */ - cave = make_array(MAX_HGT); + cave = new cave_type *[MAX_HGT]; for (i = 0; i < MAX_HGT; i++) { /* Allocate one row of the cave */ - cave[i] = make_array(MAX_WID); + cave[i] = new cave_type[MAX_WID]; } /*** Pre-allocate the basic "auto-inscriptions" ***/ diff --git a/src/loadsave.cc b/src/loadsave.cc index 584d6dc9..13e4911f 100644 --- a/src/loadsave.cc +++ b/src/loadsave.cc @@ -1498,16 +1498,11 @@ static bool_ do_dungeon(ls_flag_t flag, bool_ no_companions) /* Monster */ if (o_ptr->held_m_idx) { - monster_type *m_ptr; - /* Monster */ - m_ptr = &m_list[o_ptr->held_m_idx]; - - /* Build a stack */ - o_ptr->next_o_idx = m_ptr->hold_o_idx; + monster_type *m_ptr = &m_list[o_ptr->held_m_idx]; /* Place the object */ - m_ptr->hold_o_idx = o_idx; + m_ptr->hold_o_idxs.push_back(o_idx); } /* Dungeon */ @@ -1516,11 +1511,8 @@ static bool_ do_dungeon(ls_flag_t flag, bool_ no_companions) /* Access the item location */ c_ptr = &cave[o_ptr->iy][o_ptr->ix]; - /* Build a stack */ - o_ptr->next_o_idx = c_ptr->o_idx; - /* Place the object */ - c_ptr->o_idx = o_idx; + c_ptr->o_idxs.push_back(o_idx); } } diff --git a/src/melee1.cc b/src/melee1.cc index 0f789988..4eabe223 100644 --- a/src/melee1.cc +++ b/src/melee1.cc @@ -2152,10 +2152,7 @@ bool_ make_attack_normal(int m_idx, byte divis) j_ptr->held_m_idx = m_idx; /* Build stack */ - j_ptr->next_o_idx = m_ptr->hold_o_idx; - - /* Build stack */ - m_ptr->hold_o_idx = o_idx; + m_ptr->hold_o_idxs.push_back(o_idx); } } diff --git a/src/melee2.cc b/src/melee2.cc index da37f760..8e5f09cd 100644 --- a/src/melee2.cc +++ b/src/melee2.cc @@ -6934,8 +6934,6 @@ static void process_monster(int m_idx, bool_ is_frien) /* Creature has been allowed move */ if (do_move) { - s16b this_o_idx, next_o_idx = 0; - /* Take a turn */ do_turn = TRUE; @@ -7005,16 +7003,14 @@ static void process_monster(int m_idx, bool_ is_frien) } else { + /* Copy list of objects; we need a copy because we're mutating the list. */ + auto const object_idxs(c_ptr->o_idxs); + /* Scan all objects in the grid */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: object_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type * o_ptr = &o_list[this_o_idx]; /* Skip gold */ if (o_ptr->tval == TV_GOLD) continue; @@ -7108,11 +7104,8 @@ static void process_monster(int m_idx, bool_ is_frien) /* Memorize monster */ o_ptr->held_m_idx = m_idx; - /* Build a stack */ - o_ptr->next_o_idx = m_ptr->hold_o_idx; - /* Carry object */ - m_ptr->hold_o_idx = this_o_idx; + m_ptr->hold_o_idxs.push_back(this_o_idx); } } diff --git a/src/monster2.cc b/src/monster2.cc index 07048d9d..fe5d8ac1 100644 --- a/src/monster2.cc +++ b/src/monster2.cc @@ -433,21 +433,15 @@ static cptr funny_comments[MAX_COMMENT] = */ void delete_monster_idx(int i) { - int x, y, j; - monster_type *m_ptr = &m_list[i]; monster_race *r_ptr = race_inf(m_ptr); - s16b this_o_idx, next_o_idx = 0; - bool_ had_lite = FALSE; - ; - /* Get location */ - y = m_ptr->fy; - x = m_ptr->fx; + int y = m_ptr->fy; + int x = m_ptr->fx; /* Hack -- Reduce the racial counter */ r_ptr->cur_num--; @@ -469,7 +463,8 @@ void delete_monster_idx(int i) /* Hack -- remove tracked monster */ if (i == p_ptr->control) p_ptr->control = 0; - for (j = m_max - 1; j >= 1; j--) + + for (int j = m_max - 1; j >= 1; j--) { /* Access the monster */ monster_type *t_ptr = &m_list[j]; @@ -483,17 +478,15 @@ void delete_monster_idx(int i) /* Monster is gone */ cave[y][x].m_idx = 0; + /* Copy list of objects; need a copy since we're + * manipulating the list itself below. */ + auto const object_idxs(m_ptr->hold_o_idxs); /* Delete objects */ - for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: object_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type *o_ptr = &o_list[this_o_idx]; /* Hack -- efficiency */ o_ptr->held_m_idx = 0; @@ -518,12 +511,13 @@ void delete_monster_idx(int i) } } } + /* Delete the object */ delete_object_idx(this_o_idx); } /* Wipe the Monster */ - memset(m_ptr, 0, sizeof(monster_type)); + m_ptr->wipe(); /* Count monsters */ m_cnt--; @@ -573,42 +567,27 @@ void delete_monster(int y, int x) */ static void compact_monsters_aux(int i1, int i2) { - int y, x, j; - - cave_type *c_ptr; - - monster_type *m_ptr; - - s16b this_o_idx, next_o_idx = 0; - - /* Do nothing */ if (i1 == i2) return; - /* Old monster */ - m_ptr = &m_list[i1]; + monster_type *m_ptr = &m_list[i1]; /* Location */ - y = m_ptr->fy; - x = m_ptr->fx; + int y = m_ptr->fy; + int x = m_ptr->fx; /* Cave grid */ - c_ptr = &cave[y][x]; + cave_type *c_ptr = &cave[y][x]; /* Update the cave */ c_ptr->m_idx = i2; /* Repair objects being carried by monster */ - for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: m_ptr->hold_o_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type *o_ptr = &o_list[this_o_idx]; /* Reset monster pointer */ o_ptr->held_m_idx = i2; @@ -626,7 +605,7 @@ static void compact_monsters_aux(int i1, int i2) /* Hack -- Update the health bar */ if (health_who == i1) health_track(i2); - for (j = m_max - 1; j >= 1; j--) + for (int j = m_max - 1; j >= 1; j--) { /* Access the monster */ monster_type *t_ptr = &m_list[j]; @@ -641,7 +620,7 @@ static void compact_monsters_aux(int i1, int i2) m_list[i2] = m_list[i1]; /* Wipe the hole */ - memset(&m_list[i1], 0, sizeof(monster_type)); + m_list[i1].wipe(); } @@ -759,7 +738,7 @@ void wipe_m_list(void) cave[m_ptr->fy][m_ptr->fx].m_idx = 0; /* Wipe the Monster */ - memset(m_ptr, 0, sizeof(monster_type)); + m_ptr->wipe(); } /* Reset "m_max" */ @@ -2045,13 +2024,11 @@ void monster_carry(monster_type *m_ptr, int m_idx, object_type *q_ptr) object_copy(o_ptr, q_ptr); /* Build a stack */ - o_ptr->next_o_idx = m_ptr->hold_o_idx; - o_ptr->held_m_idx = m_idx; o_ptr->ix = 0; o_ptr->iy = 0; - m_ptr->hold_o_idx = o_idx; + m_ptr->hold_o_idxs.push_back(o_idx); } else @@ -2367,7 +2344,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) m_ptr->ml = FALSE; /* No objects yet */ - m_ptr->hold_o_idx = 0; + m_ptr->hold_o_idxs.clear(); m_ptr->status = status; @@ -3982,26 +3959,22 @@ s16b player_place(int y, int x) */ void monster_drop_carried_objects(monster_type *m_ptr) { - s16b this_o_idx, next_o_idx = 0; - object_type forge; - object_type *o_ptr; - object_type *q_ptr; - + /* Copy list of objects; we need a copy since + we're manipulating the list itself below. */ + auto const object_idxs(m_ptr->hold_o_idxs); /* Drop objects being carried */ - for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: object_idxs) { /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type *o_ptr = &o_list[this_o_idx]; /* Paranoia */ o_ptr->held_m_idx = 0; /* Get local object */ - q_ptr = &forge; + object_type forge; + object_type *q_ptr = &forge; /* Copy the object */ object_copy(q_ptr, o_ptr); @@ -4014,5 +3987,5 @@ void monster_drop_carried_objects(monster_type *m_ptr) } /* Forget objects */ - m_ptr->hold_o_idx = 0; + m_ptr->hold_o_idxs.clear(); } diff --git a/src/monster3.cc b/src/monster3.cc index 6201f198..e7e8e6da 100644 --- a/src/monster3.cc +++ b/src/monster3.cc @@ -345,12 +345,10 @@ bool_ do_control_walk(void) bool_ do_control_inven(void) { - int monst_list[23]; - if (!p_ptr->control) return FALSE; screen_save(); prt("Carried items", 0, 0); - show_monster_inven(p_ptr->control, monst_list); + (void) show_monster_inven(p_ptr->control); inkey(); screen_load(); return TRUE; @@ -358,24 +356,23 @@ bool_ do_control_inven(void) bool_ do_control_pickup(void) { - int this_o_idx, next_o_idx = 0; + if (!p_ptr->control) return FALSE; + monster_type *m_ptr = &m_list[p_ptr->control]; - cave_type *c_ptr; - bool_ done = FALSE; - if (!p_ptr->control) return FALSE; + cave_type *c_ptr = &cave[m_ptr->fy][m_ptr->fx]; + + /* Copy list of all objects in the grid; we need a + * copy since we're going to be excising objects + * from lists. */ + auto const object_idxs(c_ptr->o_idxs); /* Scan all objects in the grid */ - c_ptr = &cave[m_ptr->fy][m_ptr->fx]; - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + bool done = false; + for (auto const this_o_idx: object_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type *o_ptr = &o_list[this_o_idx]; /* Skip gold */ if (o_ptr->tval == TV_GOLD) continue; @@ -392,14 +389,19 @@ bool_ do_control_pickup(void) /* Memorize monster */ o_ptr->held_m_idx = p_ptr->control; - /* Build a stack */ - o_ptr->next_o_idx = m_ptr->hold_o_idx; - /* Carry object */ - m_ptr->hold_o_idx = this_o_idx; - done = TRUE; + m_ptr->hold_o_idxs.push_back(this_o_idx); + + /* Picked up at least one object */ + done = true; + } + + /* Feedback */ + if (done) + { + msg_print("You pick up all objects on the floor."); } - if (done) msg_print("You pick up all objects on the floor."); + return TRUE; } diff --git a/src/monster_type.hpp b/src/monster_type.hpp index ccb555d4..912c97d0 100644 --- a/src/monster_type.hpp +++ b/src/monster_type.hpp @@ -3,6 +3,9 @@ #include "h-basic.h" #include "monster_blow.hpp" +#include +#include + /** * Monster information for a specific monster. * @@ -13,48 +16,75 @@ */ struct monster_type { - s16b r_idx; /* Monster race index */ + s16b r_idx = 0; /* Monster race index */ + + u16b ego = 0; /* Ego monster type */ + + byte fy = 0; /* Y location on map */ + byte fx = 0; /* X location on map */ + + s32b hp = 0; /* Current Hit points */ + s32b maxhp = 0; /* Max Hit points */ - u16b ego; /* Ego monster type */ + monster_blow blow[4] = { /* Up to four blows per round */ + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + }; - byte fy; /* Y location on map */ - byte fx; /* X location on map */ + byte speed = 0; /* Speed (normally 110) */ + byte level = 0; /* Level of creature */ + s16b ac = 0; /* Armour Class */ + s32b exp = 0; /* Experience */ - s32b hp; /* Current Hit points */ - s32b maxhp; /* Max Hit points */ + s16b csleep = 0; /* Inactive counter */ - monster_blow blow[4]; /* Up to four blows per round */ + byte mspeed = 0; /* Monster "speed" */ + byte energy = 0; /* Monster "energy" */ - byte speed; /* Speed (normally 110) */ - byte level; /* Level of creature */ - s16b ac; /* Armour Class */ - s32b exp; /* Experience */ + byte stunned = 0; /* Monster is stunned */ + byte confused = 0; /* Monster is confused */ + byte monfear = 0; /* Monster is afraid */ - s16b csleep; /* Inactive counter */ + s16b bleeding = 0; /* Monster is bleeding */ + s16b poisoned = 0; /* Monster is poisoned */ - byte mspeed; /* Monster "speed" */ - byte energy; /* Monster "energy" */ + byte cdis = 0; /* Current dis from player */ - byte stunned; /* Monster is stunned */ - byte confused; /* Monster is confused */ - byte monfear; /* Monster is afraid */ + s32b mflag = 0; /* Extra monster flags */ - s16b bleeding; /* Monster is bleeding */ - s16b poisoned; /* Monster is poisoned */ + bool_ ml = FALSE; /* Monster is "visible" */ - byte cdis; /* Current dis from player */ + std::vector hold_o_idxs { }; /* Objects being held */ - s32b mflag; /* Extra monster flags */ + u32b smart = 0; /* Field for "smart_learn" */ - bool_ ml; /* Monster is "visible" */ + s16b status = 0; /* Status(friendly, pet, companion, ..) */ - s16b hold_o_idx; /* Object being held (if any) */ + s16b target = 0; /* Monster target */ - u32b smart; /* Field for "smart_learn" */ + s16b possessor = 0; /* Is it under the control of a possessor ? */ - s16b status; /* Status(friendly, pet, companion, ..) */ + /** + * @brief wipe the object's state + */ + void wipe() + { + /* Reset to defaults */ + *this = monster_type(); + } - s16b target; /* Monster target */ + /** + * Get the o_idx of the object being mimicked + */ + s16b mimic_o_idx() const + { + // We *should* also assert that the monster has flag RF9_MIMIC, + // but it's currently not safe since the functions we need for + // that are a) expensive, and b) side-effecting via statics. + assert(hold_o_idxs.size() == 1); // Mimics are defined by exactly one object + return hold_o_idxs.front(); + } - s16b possessor; /* Is it under the control of a possessor ? */ }; diff --git a/src/object1.cc b/src/object1.cc index 231faa12..0f79d0ee 100644 --- a/src/object1.cc +++ b/src/object1.cc @@ -5029,7 +5029,6 @@ static int get_tag(int *cp, char tag) */ static std::vector scan_floor(int y, int x, object_filter_t const &filter) { - int this_o_idx, next_o_idx; std::vector items; /* Sanity */ @@ -5039,14 +5038,11 @@ static std::vector scan_floor(int y, int x, object_filter_t const &filter) } /* Scan all objects in the grid */ - for (this_o_idx = cave[y][x].o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: cave[y][x].o_idxs) { /* Acquire object */ object_type * o_ptr = &o_list[this_o_idx]; - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; - /* Item tester */ if (!item_tester_okay(o_ptr, filter)) { @@ -5979,21 +5975,19 @@ int wear_ammo(object_type *o_ptr) */ void pickup_ammo() { - s16b this_o_idx, next_o_idx = 0, slot; - char o_name[80]; + /* Copy list of objects since we're manipulating the list */ + auto const object_idxs(cave[p_ptr->py][p_ptr->px].o_idxs); /* Scan the pile of objects */ - for (this_o_idx = cave[p_ptr->py][p_ptr->px].o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: object_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; + object_type *o_ptr = &o_list[this_o_idx]; if (object_similar(o_ptr, &p_ptr->inventory[INVEN_AMMO])) { msg_print("You add the ammo to your quiver."); - slot = wear_ammo(o_ptr); + s16b slot = wear_ammo(o_ptr); if (slot != -1) { @@ -6001,6 +5995,7 @@ void pickup_ammo() o_ptr = &p_ptr->inventory[slot]; /* Describe the object */ + char o_name[80]; object_desc(o_name, o_ptr, TRUE, 3); /* Message */ @@ -6010,9 +6005,6 @@ void pickup_ammo() delete_object_idx(this_o_idx); } } - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; } } @@ -6118,66 +6110,16 @@ void object_pickup(int this_o_idx) } -void py_pickup_floor(int pickup) +static void absorb_gold(cave_type const *c_ptr) { - /* Hack -- ignore monster traps */ - if (cave[p_ptr->py][p_ptr->px].feat == FEAT_MON_TRAP) return; - - /* Try to grab ammo */ - pickup_ammo(); - - /* Build a list of the floor objects. */ - std::vector floor_object_idxs; - { - s16b this_o_idx = cave[p_ptr->py][p_ptr->px].o_idx; - /* Reserve a number of slots if at least one is needed */ - if (this_o_idx) - { - floor_object_idxs.reserve(16); // Avoid resizing in the common case - } - /* Fill in the indexes */ - for (; this_o_idx; this_o_idx = o_list[this_o_idx].next_o_idx) - { - // Note the "-"! We need it for get_object() - // lookups to function correctly. - floor_object_idxs.push_back(0 - this_o_idx); - } - } - - /* Mega Hack -- If we have auto-Id, do an ID sweep *before* squleching, - * so that we don't have to walk over things twice to get them - * squelched. --dsb */ - if (p_ptr->auto_id) - { - for (auto const o_idx : floor_object_idxs) - { - object_type *o_ptr = get_object(o_idx); - object_aware(o_ptr); - object_known(o_ptr); - } - } + /* Copy list of objects since we're going to manipulate the list itself */ + auto const object_idxs(c_ptr->o_idxs); - /* Sense floor tile */ - sense_objects(floor_object_idxs); - - /* Squeltch the floor */ - squeltch_grid(); - - /* Scan the pile of objects */ - s16b next_o_idx = 0; - char o_name[80] = ""; - object_type *o_ptr = 0; - int floor_num = 0; - int floor_o_idx = 0; - - s16b this_o_idx; - for (this_o_idx = cave[p_ptr->py][p_ptr->px].o_idx; this_o_idx; this_o_idx = next_o_idx) + /* Go through everything */ + for (auto const this_o_idx: object_idxs) { /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type *o_ptr = &o_list[this_o_idx]; /* Hack -- disturb */ disturb(0); @@ -6189,7 +6131,7 @@ void py_pickup_floor(int pickup) object_desc(goldname, o_ptr, TRUE, 3); /* Message */ msg_format("You have found %ld gold pieces worth of %s.", - (long)o_ptr->pval, goldname); + (long)o_ptr->pval, goldname); /* Collect the gold */ p_ptr->au += o_ptr->pval; @@ -6202,123 +6144,156 @@ void py_pickup_floor(int pickup) /* Delete the gold */ delete_object_idx(this_o_idx); - - continue; } + } +} - /* Describe */ +static void sense_floor(cave_type const *c_ptr) +{ + /* Build a list of the floor objects. */ + std::vector floor_object_idxs; + { + /* Reserve the correct number of slots */ + floor_object_idxs.reserve(c_ptr->o_idxs.size()); + /* Fill in the indexes */ + for (auto const this_o_idx: c_ptr->o_idxs) { - char testdesc[80]; + // Note the "-"! We need it for get_object() + // lookups to function correctly. + floor_object_idxs.push_back(0 - this_o_idx); + } + } - object_desc(testdesc, o_ptr, TRUE, 3); - if (0 != strncmp(testdesc, "(nothing)", 80)) - { - strncpy(o_name, testdesc, 80); - } + /* Mega Hack -- If we have auto-Id, do an ID sweep *before* squleching, + * so that we don't have to walk over things twice to get them + * squelched. --dsb */ + if (p_ptr->auto_id) + { + for (auto const o_idx: floor_object_idxs) + { + object_type *o_ptr = get_object(o_idx); + object_aware(o_ptr); + object_known(o_ptr); } + } - /* Count non-gold */ - floor_num++; + /* Sense floor tile */ + sense_objects(floor_object_idxs); +} - /* Remember this index */ - floor_o_idx = this_o_idx; +void py_pickup_floor(int pickup) +{ + /* Get the tile */ + auto c_ptr = &cave[p_ptr->py][p_ptr->px]; + + /* Hack -- ignore monster traps */ + if (c_ptr->feat == FEAT_MON_TRAP) + { + return; } - /* There were no non-gold items */ - if (!floor_num) return; + /* Try to grab ammo */ + pickup_ammo(); + + /* Auto-ID and pseudo-ID */ + sense_floor(c_ptr); + + /* Squeltch the floor */ + squeltch_grid(); + + /* Absorb gold on the tile */ + absorb_gold(&cave[p_ptr->py][p_ptr->px]); - /* Mention number of items */ - if (!pickup) + /* We handle 0, 1, or "many" items cases separately */ + if (c_ptr->o_idxs.empty()) + { + /* Nothing to do */ + } + else if (c_ptr->o_idxs.size() == 1) { - /* One item */ - if (floor_num == 1) + /* Acquire object */ + auto floor_o_idx = c_ptr->o_idxs.front(); + auto o_ptr = &o_list[floor_o_idx]; + + /* Describe or pick up? */ + if (!pickup) { - /* Acquire object */ - o_ptr = &o_list[floor_o_idx]; + /* Describe */ + char o_name[80] = ""; + object_desc(o_name, o_ptr, TRUE, 3); /* Message */ msg_format("You see %s.", o_name); } - - /* Multiple items */ else { - /* Message */ - msg_format("You see a pile of %d items.", floor_num); - } - - /* Done */ - return; - } + /* Are we actually going to pick up? */ + bool_ do_pickup = TRUE; - /* Are we actually going to pick up and/or ask about which item to pick up? */ - bool_ do_pickup = TRUE; - bool_ do_ask = TRUE; - - /* One item */ - if (floor_num == 1) - { - /* Hack -- query every item */ - if (carry_query_flag || (!can_carry_heavy(&o_list[floor_o_idx]))) - { - if (!inven_carry_okay(o_ptr) && !object_similar(o_ptr, &p_ptr->inventory[INVEN_AMMO])) + /* Hack -- query every item */ + if (carry_query_flag || (!can_carry_heavy(&o_list[floor_o_idx]))) { + char o_name[80] = ""; object_desc(o_name, o_ptr, TRUE, 3); - msg_format("You have no room for %s.", o_name); - do_pickup = FALSE; + + if (!inven_carry_okay(o_ptr) && !object_similar(o_ptr, &p_ptr->inventory[INVEN_AMMO])) + { + msg_format("You have no room for %s.", o_name); + return; /* Done */ + } + else + { + char out_val[160]; + sprintf(out_val, "Pick up %s? ", o_name); + do_pickup = get_check(out_val); + } } - else + + /* Just pick it up; unless it's a symbiote and we don't have Symbiosis */ + if (do_pickup && ((o_list[floor_o_idx].tval != TV_HYPNOS) || (get_skill(SKILL_SYMBIOTIC)))) { - char out_val[160]; - sprintf(out_val, "Pick up %s? ", o_name); - do_pickup = get_check(out_val); + object_pickup(floor_o_idx); } } - - /* Don't ask */ - do_ask = FALSE; - - if ((o_list[floor_o_idx].tval == TV_HYPNOS) && (!get_skill(SKILL_SYMBIOTIC))) - do_pickup = FALSE; - else - this_o_idx = floor_o_idx; } - - /* Ask */ - if (do_ask) + else { - cptr q, s; - - int item; - - /* Get an item */ - q = "Get which item? "; - s = "You have no room in your pack for any of the items here."; - if (get_item(&item, q, s, (USE_FLOOR), item_tester_hook_getable)) + /* Describe or pick up? */ + if (!pickup) { - this_o_idx = 0 - item; - - if (!can_carry_heavy(&o_list[this_o_idx])) + /* Message */ + msg_format("You see a pile of %d items.", c_ptr->o_idxs.size()); + } + else + { + /* Prompt for the item to pick up */ + cptr q = "Get which item? "; + cptr s = "You have no room in your pack for any of the items here."; + int item; + if (get_item(&item, q, s, (USE_FLOOR), item_tester_hook_getable)) { - char out_val[160]; + s16b this_o_idx = 0 - item; - /* Describe the object */ - object_desc(o_name, &o_list[this_o_idx], TRUE, 3); + bool_ do_pickup = TRUE; + if (!can_carry_heavy(&o_list[this_o_idx])) + { + /* Describe the object */ + char o_name[80] = ""; + object_desc(o_name, &o_list[this_o_idx], TRUE, 3); + + /* Prompt */ + char out_val[160]; + sprintf(out_val, "Pick up %s? ", o_name); + do_pickup = get_check(out_val); + } - sprintf(out_val, "Pick up %s? ", o_name); - do_pickup = get_check(out_val); + /* Pick up the item */ + if (do_pickup) + { + object_pickup(this_o_idx); + } } } - else - { - do_pickup = FALSE; - } - } - - /* Pick up the item */ - if (do_pickup) - { - object_pickup(this_o_idx); } } diff --git a/src/object2.cc b/src/object2.cc index 2d7e5e32..d437d24d 100644 --- a/src/object2.cc +++ b/src/object2.cc @@ -40,6 +40,7 @@ #include "wilderness_map.hpp" #include "xtra1.hpp" +#include #include #include #include @@ -65,123 +66,36 @@ s32b calc_total_weight(void) */ void excise_object_idx(int o_idx) { - object_type *j_ptr; - - s16b this_o_idx, next_o_idx = 0; - - s16b prev_o_idx = 0; - + /* Function to remove from list */ + auto remove_it = [o_idx](std::vector *v) -> void { + v->erase( + std::remove( + v->begin(), + v->end(), + o_idx), + v->end()); + }; /* Object */ - j_ptr = &o_list[o_idx]; + object_type *o_ptr = &o_list[o_idx]; /* Monster */ - if (j_ptr->held_m_idx) + if (o_ptr->held_m_idx) { - monster_type *m_ptr; - /* Monster */ - m_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; - - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; - - /* Done */ - if (this_o_idx == o_idx) - { - /* No previous */ - if (prev_o_idx == 0) - { - /* Remove from list */ - m_ptr->hold_o_idx = next_o_idx; - } + monster_type *m_ptr = &m_list[o_ptr->held_m_idx]; - /* Real previous */ - else - { - object_type *k_ptr; - - /* Previous object */ - k_ptr = &o_list[prev_o_idx]; - - /* Remove from list */ - k_ptr->next_o_idx = next_o_idx; - } - - /* Forget next pointer */ - o_ptr->next_o_idx = 0; - - /* Done */ - break; - } - - /* Save prev_o_idx */ - prev_o_idx = this_o_idx; - } + /* Remove object from list of held objects, if present. */ + remove_it(&m_ptr->hold_o_idxs); } - /* Dungeon */ else { - cave_type *c_ptr; - - int y = j_ptr->iy; - int x = j_ptr->ix; - /* Grid */ - c_ptr = &cave[y][x]; + cave_type *c_ptr = &cave[o_ptr->iy][o_ptr->ix]; - /* Scan all objects in the grid */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) - { - object_type * o_ptr; - - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; - - /* Done */ - if (this_o_idx == o_idx) - { - /* No previous */ - if (prev_o_idx == 0) - { - /* Remove from list */ - c_ptr->o_idx = next_o_idx; - } - - /* Real previous */ - else - { - object_type *k_ptr; - - /* Previous object */ - k_ptr = &o_list[prev_o_idx]; - - /* Remove from list */ - k_ptr->next_o_idx = next_o_idx; - } - - /* Forget next pointer */ - o_ptr->next_o_idx = 0; - - /* Done */ - break; - } - - /* Save prev_o_idx */ - prev_o_idx = this_o_idx; - } + /* Remove object from list of objects in the grid, if present. */ + remove_it(&c_ptr->o_idxs); } } @@ -227,28 +141,17 @@ void delete_object_idx(int o_idx) */ void delete_object(int y, int x) { - cave_type *c_ptr; - - s16b this_o_idx, next_o_idx = 0; - - /* Refuse "illegal" locations */ if (!in_bounds(y, x)) return; - /* Grid */ - c_ptr = &cave[y][x]; + cave_type *c_ptr = &cave[y][x]; /* Scan all objects in the grid */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: c_ptr->o_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type *o_ptr = &o_list[this_o_idx]; /* Wipe the object */ object_wipe(o_ptr); @@ -258,7 +161,7 @@ void delete_object(int y, int x) } /* Objects are gone */ - c_ptr->o_idx = 0; + c_ptr->o_idxs.clear(); /* Visual update */ lite_spot(y, x); @@ -270,76 +173,44 @@ void delete_object(int y, int x) */ static void compact_objects_aux(int i1, int i2) { - int i; - - cave_type *c_ptr; - - object_type *o_ptr; - - /* Do nothing */ if (i1 == i2) return; - - /* Repair objects */ - for (i = 1; i < o_max; i++) - { - /* Acquire object */ - o_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; - } - } - - /* Acquire object */ - o_ptr = &o_list[i1]; - + object_type *o_ptr = &o_list[i1]; /* Monster */ if (o_ptr->held_m_idx) { - monster_type *m_ptr; - /* Acquire monster */ - m_ptr = &m_list[o_ptr->held_m_idx]; + monster_type *m_ptr = &m_list[o_ptr->held_m_idx]; /* Repair monster */ - if (m_ptr->hold_o_idx == i1) + for (auto &hold_o_idx: m_ptr->hold_o_idxs) { - /* Repair */ - m_ptr->hold_o_idx = i2; + if (hold_o_idx == i1) + { + hold_o_idx = i2; + } } } /* Dungeon */ else { - int y, x; - - /* Acquire location */ - y = o_ptr->iy; - x = o_ptr->ix; - /* Acquire grid */ - c_ptr = &cave[y][x]; + cave_type *c_ptr = &cave[o_ptr->iy][o_ptr->ix]; /* Repair grid */ - if (c_ptr->o_idx == i1) + for (auto &o_idx: c_ptr->o_idxs) { - /* Repair */ - c_ptr->o_idx = i2; + if (o_idx == i1) + { + o_idx = i2; + } } } - /* Structure copy */ o_list[i2] = o_list[i1]; @@ -534,13 +405,11 @@ void wipe_o_list(void) /* Monster */ if (o_ptr->held_m_idx) { - monster_type *m_ptr; - /* Monster */ - m_ptr = &m_list[o_ptr->held_m_idx]; + monster_type *m_ptr = &m_list[o_ptr->held_m_idx]; /* Hack -- see above */ - m_ptr->hold_o_idx = 0; + m_ptr->hold_o_idxs.clear(); } /* Dungeon */ @@ -556,11 +425,11 @@ void wipe_o_list(void) c_ptr = &cave[y][x]; /* Hack -- see above */ - c_ptr->o_idx = 0; + c_ptr->o_idxs.clear(); } /* Wipe the object */ - memset(o_ptr, 0, sizeof(object_type)); + object_wipe(o_ptr); } /* Reset "o_max" */ @@ -4996,10 +4865,8 @@ void place_object(int y, int x, bool_ good, bool_ great, int where) /* Success */ if (o_idx) { - object_type *o_ptr; - /* Acquire object */ - o_ptr = &o_list[o_idx]; + object_type *o_ptr = &o_list[o_idx]; /* Structure Copy */ object_copy(o_ptr, q_ptr); @@ -5011,11 +4878,8 @@ void place_object(int y, int x, bool_ good, bool_ great, int where) /* Acquire grid */ c_ptr = &cave[y][x]; - /* Build a stack */ - o_ptr->next_o_idx = c_ptr->o_idx; - /* Place the object */ - c_ptr->o_idx = o_idx; + c_ptr->o_idxs.push_back(o_idx); /* Notice */ note_spot(y, x); @@ -5148,11 +5012,8 @@ void place_gold(int y, int x) /* Acquire grid */ c_ptr = &cave[y][x]; - /* Build a stack */ - o_ptr->next_o_idx = c_ptr->o_idx; - /* Place the object */ - c_ptr->o_idx = o_idx; + c_ptr->o_idxs.push_back(o_idx); /* Notice */ note_spot(y, x); @@ -5188,10 +5049,6 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x) int dy, dx; int ty, tx; - s16b o_idx = 0; - - s16b this_o_idx, next_o_idx = 0; - cave_type *c_ptr; char o_name[80]; @@ -5271,15 +5128,10 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x) k = 0; /* Scan objects in that grid */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: c_ptr->o_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type *o_ptr = &o_list[this_o_idx]; /* Check for possible combination */ if (object_similar(o_ptr, j_ptr)) comb = TRUE; @@ -5377,15 +5229,10 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x) c_ptr = &cave[by][bx]; /* Scan objects in that grid for combination */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: c_ptr->o_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type *o_ptr = &o_list[this_o_idx]; /* Check for combination */ if (object_similar(o_ptr, j_ptr)) @@ -5402,6 +5249,7 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x) } /* Get new object */ + s16b o_idx = 0; if (!done) o_idx = o_pop(); /* Failure */ @@ -5448,11 +5296,8 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x) /* No monster */ j_ptr->held_m_idx = 0; - /* Build a stack */ - j_ptr->next_o_idx = c_ptr->o_idx; - /* Place the object */ - c_ptr->o_idx = o_idx; + c_ptr->o_idxs.push_back(o_idx); /* Success */ done = TRUE; @@ -5992,7 +5837,6 @@ s16b inven_carry(object_type *o_ptr, bool_ final) /* Clean out unused fields */ o_ptr->iy = o_ptr->ix = 0; - o_ptr->next_o_idx = 0; o_ptr->held_m_idx = 0; /* Count the items */ @@ -6382,23 +6226,11 @@ void reorder_pack(void) */ s16b floor_carry(int y, int x, object_type *j_ptr) { - int n = 0; - - s16b o_idx; - - s16b this_o_idx, next_o_idx = 0; - - /* Scan objects in that grid for combination */ - for (this_o_idx = cave[y][x].o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: cave[y][x].o_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type *o_ptr = &o_list[this_o_idx]; /* Check for combination */ if (object_similar(o_ptr, j_ptr)) @@ -6406,27 +6238,25 @@ s16b floor_carry(int y, int x, object_type *j_ptr) /* Combine the items */ object_absorb(o_ptr, j_ptr); - /* Result */ - return (this_o_idx); + /* Done */ + return this_o_idx; } - - /* Count objects */ - n++; } /* The stack is already too large */ - if (n > 23) return (0); + if (cave[y][x].o_idxs.size() > 23) + { + return (0); + } /* Make an object */ - o_idx = o_pop(); + s16b o_idx = o_pop(); /* Success */ if (o_idx) { - object_type *o_ptr; - /* Acquire object */ - o_ptr = &o_list[o_idx]; + object_type *o_ptr = &o_list[o_idx]; /* Structure Copy */ object_copy(o_ptr, j_ptr); @@ -6438,11 +6268,8 @@ s16b floor_carry(int y, int x, object_type *j_ptr) /* Forget monster */ o_ptr->held_m_idx = 0; - /* Build a stack */ - o_ptr->next_o_idx = cave[y][x].o_idx; - /* Place the object */ - cave[y][x].o_idx = o_idx; + cave[y][x].o_idxs.push_back(o_idx); /* Notice */ note_spot(y, x); diff --git a/src/object_type.hpp b/src/object_type.hpp index cadfa6bf..d7f003e6 100644 --- a/src/object_type.hpp +++ b/src/object_type.hpp @@ -92,8 +92,6 @@ struct object_type u32b art_oflags5; /* Obvious Flags, set 5 */ u32b art_oesp; /* Obvious Flags, set esp */ - s16b next_o_idx; /* Next object in stack (if any) */ - s16b held_m_idx; /* Monster holding us (if any) */ byte sense; /* Pseudo-id status */ diff --git a/src/q_troll.cc b/src/q_troll.cc index 7aa27ac5..7227c1c3 100644 --- a/src/q_troll.cc +++ b/src/q_troll.cc @@ -93,14 +93,11 @@ static bool_ quest_troll_gen_hook(void *, void *, void *) /* Structure copy */ object_copy(o_ptr, q_ptr); - /* Build a stack */ - o_ptr->next_o_idx = m_list[m_idx].hold_o_idx; - + /* Add to monster's inventory */ o_ptr->held_m_idx = m_idx; o_ptr->ix = 0; o_ptr->iy = 0; - - m_list[m_idx].hold_o_idx = o_idx; + m_list[m_idx].hold_o_idxs.push_back(o_idx); } else { diff --git a/src/q_wight.cc b/src/q_wight.cc index d0405920..499535ca 100644 --- a/src/q_wight.cc +++ b/src/q_wight.cc @@ -107,13 +107,11 @@ static bool_ quest_wight_gen_hook(void *, void *, void *) object_copy(o_ptr, q_ptr); /* Build a stack */ - o_ptr->next_o_idx = m_list[m_idx].hold_o_idx; - o_ptr->held_m_idx = m_idx; o_ptr->ix = 0; o_ptr->iy = 0; - m_list[m_idx].hold_o_idx = o_idx; + m_list[m_idx].hold_o_idxs.push_back(o_idx); } } } diff --git a/src/spells1.cc b/src/spells1.cc index 773e71b4..ccfb59a2 100644 --- a/src/spells1.cc +++ b/src/spells1.cc @@ -3924,8 +3924,6 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) { cave_type *c_ptr = &cave[y][x]; - s16b this_o_idx, next_o_idx = 0; - bool_ obvious = FALSE; u32b f1, f2, f3, f4, f5, esp; @@ -3945,11 +3943,12 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) /* Check new gods. */ project_check_gods(typ); + /* Copy list of objects since we may destroy during iteration */ + auto const object_idxs(c_ptr->o_idxs); + /* Scan all objects in the grid */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: object_idxs) { - object_type * o_ptr; - bool_ is_art = FALSE; bool_ ignore = FALSE; bool_ plural = FALSE; @@ -3958,10 +3957,7 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) cptr note_kill = NULL; /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type * o_ptr = &o_list[this_o_idx]; /* Extract the flags */ object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); diff --git a/src/spells3.cc b/src/spells3.cc index 8be13b9d..e209feb1 100644 --- a/src/spells3.cc +++ b/src/spells3.cc @@ -503,7 +503,7 @@ casting_result convey_recall() swap_position(y, x); return CAST_OBVIOUS; } - else if (c_ptr->o_idx > 0) + else if (!c_ptr->o_idxs.empty()) { // Set the target target_who = -1; diff --git a/src/squeltch.cc b/src/squeltch.cc index f2366813..8e8c5b8f 100644 --- a/src/squeltch.cc +++ b/src/squeltch.cc @@ -64,11 +64,11 @@ void squeltch_grid(void) return; } + // Copy list of objects since we may modify it + auto const object_idxs(cave[p_ptr->py][p_ptr->px].o_idxs); + // Scan the pile of objects - s16b next_o_idx = 0; - for (s16b this_o_idx = cave[p_ptr->py][p_ptr->px].o_idx; - this_o_idx; - this_o_idx = next_o_idx) + for (auto const this_o_idx: object_idxs) { // Acquire object object_type * o_ptr = &o_list[this_o_idx]; @@ -79,9 +79,6 @@ void squeltch_grid(void) object_aware(o_ptr); } - // Acquire next object - next_o_idx = o_ptr->next_o_idx; - // Apply rules automatizer->apply_rules(o_ptr, -this_o_idx); } diff --git a/src/traps.cc b/src/traps.cc index 49d07cbf..b336a770 100644 --- a/src/traps.cc +++ b/src/traps.cc @@ -656,17 +656,14 @@ bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item) /* Teleport Away Trap */ case TRAP_OF_TELEPORT_AWAY: { - int item, amt; - object_type *o_ptr; - /* teleport away all items */ - while (cave[y][x].o_idx != 0) + while (!cave[y][x].o_idxs.empty()) { - item = cave[y][x].o_idx; + auto item = cave[y][x].o_idxs.front(); - o_ptr = &o_list[item]; + object_type *o_ptr = &o_list[item]; - amt = o_ptr->number; + int amt = o_ptr->number; ident = do_trap_teleport_away(o_ptr, y, x); @@ -1182,7 +1179,7 @@ bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item) cv_ptr2 = &cave[cy][cx]; - if (!cave_valid_bold(cy, cx) || cv_ptr2->o_idx != 0) continue; + if (!cave_valid_bold(cy, cx) || (!cv_ptr2->o_idxs.empty())) continue; /* don't put anything in vaults */ if (cv_ptr2->info & CAVE_ICKY) continue; @@ -2730,8 +2727,6 @@ bool_ mon_hit_trap(int m_idx) monster_type *m_ptr = &m_list[m_idx]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; - object_type *kit_o_ptr, *load_o_ptr, *j_ptr; - u32b f1, f2, f3, f4, f5, esp; object_type object_type_body; @@ -2758,9 +2753,10 @@ bool_ mon_hit_trap(int m_idx) int cost = 0; /* Get the trap objects */ - kit_o_ptr = &o_list[cave[my][mx].special2]; - load_o_ptr = &o_list[cave[my][mx].special]; - j_ptr = &object_type_body; + auto kit_o_idx = cave[my][mx].special2; + auto kit_o_ptr = &o_list[kit_o_idx]; + auto load_o_ptr = &o_list[cave[my][mx].special]; + auto j_ptr = &object_type_body; /* Get trap properties */ object_flags(kit_o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); @@ -3000,8 +2996,7 @@ bool_ mon_hit_trap(int m_idx) if (load_o_ptr->number <= 0) { remove = TRUE; - delete_object_idx(kit_o_ptr->next_o_idx); - kit_o_ptr->next_o_idx = 0; + delete_object_idx(kit_o_idx); } /* Drop (or break) near that location */ @@ -3046,8 +3041,7 @@ bool_ mon_hit_trap(int m_idx) if (load_o_ptr->number <= 0) { remove = TRUE; - delete_object_idx(kit_o_ptr->next_o_idx); - kit_o_ptr->next_o_idx = 0; + delete_object_idx(kit_o_idx); } } @@ -3088,8 +3082,7 @@ bool_ mon_hit_trap(int m_idx) if (load_o_ptr->number <= 0) { remove = TRUE; - delete_object_idx(kit_o_ptr->next_o_idx); - kit_o_ptr->next_o_idx = 0; + delete_object_idx(kit_o_idx); } } diff --git a/src/xtra1.cc b/src/xtra1.cc index caa6abd3..25cf66e7 100644 --- a/src/xtra1.cc +++ b/src/xtra1.cc @@ -1397,10 +1397,8 @@ static void fix_m_list(void) /* Skip unseen monsters */ if (r_ptr->flags9 & RF9_MIMIC) { - object_type *o_ptr; - /* Acquire object */ - o_ptr = &o_list[m_ptr->hold_o_idx]; + object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()]; /* Memorized objects */ if (!o_ptr->marked) continue; diff --git a/src/xtra2.cc b/src/xtra2.cc index 7bddc54d..6ddf4ac9 100644 --- a/src/xtra2.cc +++ b/src/xtra2.cc @@ -2508,8 +2508,6 @@ void monster_death(int m_idx) int dump_item = 0; int dump_gold = 0; - s16b this_o_idx, next_o_idx = 0; - monster_type *m_ptr = &m_list[m_idx]; monster_race *r_ptr = race_inf(m_ptr); @@ -2565,16 +2563,14 @@ void monster_death(int m_idx) /* If the doppleganger die, the variable must be set accordingly */ if (r_ptr->flags9 & RF9_DOPPLEGANGER) doppleganger = 0; + /* Need copy of object list since we're going to mutate it */ + auto const object_idxs(m_ptr->hold_o_idxs); + /* Drop objects being carried */ - for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: object_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type * o_ptr = &o_list[this_o_idx]; /* Paranoia */ o_ptr->held_m_idx = 0; @@ -2596,7 +2592,7 @@ void monster_death(int m_idx) } /* Forget objects */ - m_ptr->hold_o_idx = 0; + m_ptr->hold_o_idxs.clear(); /* Average dungeon and monster levels */ object_level = (dun_level + m_ptr->level) / 2; @@ -4033,11 +4029,6 @@ static s16b target_pick(int y1, int x1, int dy, int dx) */ static bool_ target_set_accept(int y, int x) { - cave_type *c_ptr; - - s16b this_o_idx, next_o_idx = 0; - - /* Player grid is always interesting */ if ((y == p_ptr->py) && (x == p_ptr->px)) return (TRUE); @@ -4047,7 +4038,7 @@ static bool_ target_set_accept(int y, int x) /* Examine the grid */ - c_ptr = &cave[y][x]; + cave_type *c_ptr = &cave[y][x]; /* Visible monsters */ if (c_ptr->m_idx && c_ptr->m_idx < max_r_idx) @@ -4059,18 +4050,16 @@ static bool_ target_set_accept(int y, int x) } /* Scan all objects in the grid */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) + for (auto const this_o_idx: c_ptr->o_idxs) { - object_type * o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + object_type *o_ptr = &o_list[this_o_idx]; /* Memorized object */ - if (o_ptr->marked) return (TRUE); + if (o_ptr->marked) + { + return (TRUE); + } } /* Interesting memorized features */ @@ -4195,8 +4184,6 @@ static int target_set_aux(int y, int x, int mode, cptr info) { cave_type *c_ptr = &cave[y][x]; - s16b this_o_idx, next_o_idx = 0; - cptr s1, s2, s3; bool_ boring; @@ -4261,14 +4248,15 @@ static int target_set_aux(int y, int x, int mode, cptr info) /* Mimics special treatment -- looks like an object */ if ((r_ptr->flags9 & RF9_MIMIC) && (m_ptr->csleep)) { - object_type *o_ptr; - /* Acquire object */ - o_ptr = &o_list[m_ptr->hold_o_idx]; + object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()]; if (o_ptr->marked) { - if (target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query)) break; + if (target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query)) + { + break; + } } } else @@ -4388,19 +4376,15 @@ static int target_set_aux(int y, int x, int mode, cptr info) s2 = "carrying "; /* Scan all objects being carried */ - for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) + std::size_t i = 0; + for (; i < m_ptr->hold_o_idxs.size(); i++) { - char o_name[80]; - - object_type *o_ptr; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; - - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + auto this_o_idx = m_ptr->hold_o_idxs.at(i); + object_type *o_ptr = &o_list[this_o_idx]; /* Obtain an object description */ + char o_name[80]; object_desc(o_name, o_ptr, TRUE, 3); /* Describe the object */ @@ -4410,17 +4394,26 @@ static int target_set_aux(int y, int x, int mode, cptr info) query = inkey(); /* Always stop at "normal" keys */ - if ((query != '\r') && (query != '\n') && (query != ' ')) break; + if ((query != '\r') && (query != '\n') && (query != ' ')) + { + break; + } /* Sometimes stop at "space" key */ - if ((query == ' ') && !(mode & (TARGET_LOOK))) break; + if ((query == ' ') && !(mode & (TARGET_LOOK))) + { + break; + } /* Change the intro */ s2 = "also carrying "; } - /* Double break */ - if (this_o_idx) break; + /* Double break? */ + if (i != m_ptr->hold_o_idxs.size()) + { + break; + } /* Use a preposition */ s2 = "on "; @@ -4428,29 +4421,29 @@ static int target_set_aux(int y, int x, int mode, cptr info) } } - - /* Scan all objects in the grid */ - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) { - object_type * o_ptr; - - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; + std::size_t i = 0; + for (; i < c_ptr->o_idxs.size(); i++) + { + /* Acquire object */ + auto this_o_idx = c_ptr->o_idxs.at(i); + object_type *o_ptr = &o_list[this_o_idx]; - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + /* Describe it */ + if (o_ptr->marked && target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query)) + { + break; + } + } - /* Describe it */ - if (o_ptr->marked) + /* Double break? */ + if (i != c_ptr->o_idxs.size()) { - if (target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query)) break; + break; } } - /* Double break */ - if (this_o_idx) break; - /* Actual traps */ if ((c_ptr->info & (CAVE_TRDT)) && c_ptr->t_idx) { -- cgit v1.2.3