summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cave.cc111
-rw-r--r--src/cave_type.hpp37
-rw-r--r--src/cmd1.cc72
-rw-r--r--src/cmd2.cc166
-rw-r--r--src/cmd2.hpp3
-rw-r--r--src/cmd4.cc20
-rw-r--r--src/cmd5.cc42
-rw-r--r--src/dungeon.cc2
-rw-r--r--src/gen_evol.cc4
-rw-r--r--src/generate.cc253
-rw-r--r--src/help.cc2
-rw-r--r--src/init2.cc8
-rw-r--r--src/loadsave.cc14
-rw-r--r--src/melee1.cc5
-rw-r--r--src/melee2.cc19
-rw-r--r--src/monster2.cc87
-rw-r--r--src/monster3.cc44
-rw-r--r--src/monster_type.hpp84
-rw-r--r--src/object1.cc287
-rw-r--r--src/object2.cc291
-rw-r--r--src/object_type.hpp2
-rw-r--r--src/q_troll.cc7
-rw-r--r--src/q_wight.cc4
-rw-r--r--src/spells1.cc14
-rw-r--r--src/spells3.cc2
-rw-r--r--src/squeltch.cc11
-rw-r--r--src/traps.cc31
-rw-r--r--src/xtra1.cc4
-rw-r--r--src/xtra2.cc109
29 files changed, 676 insertions, 1059 deletions
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 <cassert>
+#include <vector>
+
/**
* 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<s16b> 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<s16b> 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<s16b> 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<s16b> 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<s16b> 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<s16b> 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<std::size_t>(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 <vector>
-extern byte show_monster_inven(int m_idx, int *monst_list);
+extern std::vector<s16b> 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<std::size_t>(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<std::size_t>(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<object_type>(max_o_idx);
/* Allocate and Wipe the monster list */
- m_list = make_array<monster_type>(max_m_idx);
+ m_list = new monster_type[max_m_idx];
/* Allocate and Wipe the to keep monster list */
- km_list = make_array<monster_type>(max_m_idx);
+ km_list = new monster_type[max_m_idx];
/* Allocate and Wipe the max dungeon level */
max_dlv = make_array<s16b>(max_d_idx);
@@ -843,11 +843,11 @@ static errr init_other(void)
}
/* Allocate and wipe each line of the cave */
- cave = make_array<cave_type *>(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<cave_type>(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 <cassert>
+#include <vector>
+
/**
* 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<s16b> 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<int> scan_floor(int y, int x, object_filter_t const &filter)
{
- int this_o_idx, next_o_idx;
std::vector<int> items;
/* Sanity */
@@ -5039,14 +5038,11 @@ static std::vector<int> 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<int> 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<int> 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 <algorithm>
#include <cassert>
#include <type_traits>
#include <vector>
@@ -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<s16b> *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)
{