Snapshotting something that builds but is certainly flaky
authorMartin Read <mpread@chiark.greenend.org.uk>
Sat, 8 Mar 2014 18:59:27 +0000 (18:59 +0000)
committerMartin Read <mpread@chiark.greenend.org.uk>
Sat, 8 Mar 2014 18:59:27 +0000 (18:59 +0000)
23 files changed:
cave.cc
combat.cc
combat.hh
coord.hh
core.hh
display-nc.cc
display.hh
log.cc
main.cc
map.cc
map.hh
mapgen.hh
mon2.cc
monsters.cc
monsters.hh
notify-local-tty.cc
notify.hh
objects.cc
objects.hh
player.hh
shrine.cc
sorcery.cc
u.cc

diff --git a/cave.cc b/cave.cc
index 42b83a8..e5d8c5d 100644 (file)
--- a/cave.cc
+++ b/cave.cc
 #include "monsters.hh"
 #include "mapgen.hh"
 
-void place_cave_stairs(void)
+void place_cave_stairs(Level *l)
 {
     Coord c;
     Coord d;
     int stair_tries = 0;
     do
     {
-        c = lvl.random_point(1);
-    } while (!(terrain_props[lvl.terrain_at(c)].flags & TFLAG_floor) ||
-             (lvl.flags_at(c) & MAPFLAG_HARDWALL));
-    lvl.add_stairs_at(c, STAIRS_DOWN, lvl.self.naive_next());
+        c = l->random_point(1);
+    } while (!(terrain_props[l->terrain_at(c)].flags & TFLAG_floor) ||
+             (l->flags_at(c) & MAPFLAG_HARDWALL));
+    l->add_stairs_at(c, STAIRS_DOWN, l->self.naive_next());
     do
     {
-        d = lvl.random_point(1);
+        d = l->random_point(1);
         ++stair_tries;
-    } while (!(terrain_props[lvl.terrain_at(d)].flags & TFLAG_floor) ||
-             (lvl.flags_at(d) & MAPFLAG_HARDWALL) ||
+    } while (!(terrain_props[l->terrain_at(d)].flags & TFLAG_floor) ||
+             (l->flags_at(d) & MAPFLAG_HARDWALL) ||
              (d.dist_cheb(c) < (10 - (stair_tries / 40))));
-    lvl.add_stairs_at(d, STAIRS_UP, lvl.self.naive_prev());
+    l->add_stairs_at(d, STAIRS_UP, l->self.naive_prev());
 }
 
 /*! \brief Excavate a cave level.
  *
  *  This algorithm runs two random walks on the map.
  */
-void build_level_cave(void)
+void build_level_cave(Level *l)
 {
     Coord c = { GUIDE_EDGE_SIZE / 2, GUIDE_EDGE_SIZE / 2 };
     int num_pools;
     int walk_data[4] = { 1, FLOOR, WALL, FLOOR };
 
-    initialize_chunks(&lvl, GUIDE_EDGE_CHUNKS, GUIDE_EDGE_CHUNKS, true);
-    run_random_walk_unbounded(c, excavation_write, walk_data, LEVGEN_WALK_CELLS);
+    initialize_chunks(l, GUIDE_EDGE_CHUNKS, GUIDE_EDGE_CHUNKS, true);
+    run_random_walk_unbounded(l, c, excavation_write, walk_data, LEVGEN_WALK_CELLS);
     //run_random_walk_unbounded(c, excavation_write, walk_data, LEVGEN_WALK_CELLS);
-    if ((lvl.theme != THEME_UNDEAD) && (depth > 20) && !zero_die(4))
+    if ((l->theme != THEME_UNDEAD) && (depth > 20) && !zero_die(4))
     {
         num_pools = inc_flat(1, 4);
         walk_data[0] = 2;
@@ -85,29 +85,29 @@ void build_level_cave(void)
     {
         int pool_size = inc_flat(9, 36);
         do {
-            c = lvl.random_point(2);
-        } while (lvl.terrain_at(c) != FLOOR);
-        run_random_walk(c, excavation_write, walk_data, pool_size);
+            c = l->random_point(2);
+        } while (l->terrain_at(c) != FLOOR);
+        run_random_walk(l, c, excavation_write, walk_data, pool_size);
         --num_pools;
     }
-    place_cave_stairs();
+    place_cave_stairs(l);
 }
 
 /*! \brief Excavate a cave level with intrusions */
-void build_level_intrusions(void)
+void build_level_intrusions(Level *l)
 {
     Coord c = { GUIDE_EDGE_SIZE / 2, GUIDE_EDGE_SIZE / 2 };
     int i;
     int walk_data[4] = { 1, FLOOR, WALL, FLOOR };
 
-    initialize_chunks(&lvl, GUIDE_EDGE_CHUNKS, GUIDE_EDGE_CHUNKS, true);
+    initialize_chunks(l, GUIDE_EDGE_CHUNKS, GUIDE_EDGE_CHUNKS, true);
     for (i = 0; i < 6; ++i)
     {
-        place_random_intrusion(WALL);
+        place_random_intrusion(l, WALL);
     }
-    run_random_walk_unbounded(c, excavation_write, walk_data, LEVGEN_WALK_CELLS);
+    run_random_walk_unbounded(l, c, excavation_write, walk_data, LEVGEN_WALK_CELLS);
     /* and now the stairs */
-    place_cave_stairs();
+    place_cave_stairs(l);
 }
 
 /* cave.cc */
index 8a14113..fe9664c 100644 (file)
--- a/combat.cc
+++ b/combat.cc
@@ -42,7 +42,7 @@ int player_melee_base(void)
     int damage;
     if (u.weapon != NO_OBJ)
     {
-        dmgbase = permobjs[objects[u.weapon].obj_id].power + (u.body / 10);
+        dmgbase = permobjs[objects[u.weapon].po_ref].power + (u.body / 10);
         damage = dmgbase / 3 + one_die(dmgbase - dmgbase / 3);
     }
     else
@@ -54,10 +54,10 @@ int player_melee_base(void)
 
 /*! \brief Calculate the effect of the player's  damage amplifier ring
  */
-bool ring_effectiveness(int mon, int ring_pobj, int damage, int *bonus_damage, int *vamp_healing)
+bool ring_effectiveness(Mon_handle mon, int ring_pobj, int damage, int *bonus_damage, int *vamp_healing)
 {
     bool rv = false;
-    int pm = monsters[mon].mon_id;
+    int pm = monsters[mon].pm_ref;
     *vamp_healing = 0;
     switch (ring_pobj)
     {
@@ -94,17 +94,17 @@ bool ring_effectiveness(int mon, int ring_pobj, int damage, int *bonus_damage, i
  * \param mon Monster hit
  * \param damage Rolled damage before rings are applied
  */
-void resolve_player_melee(int mon, int damage)
+void resolve_player_melee(Mon_handle mon, int damage)
 {
     bool ring_eff;
     int ring_bonus;
     int healing = 0;
     if (u.ring != NO_OBJ)
     {
-        ring_eff = ring_effectiveness(mon, objects[u.ring].obj_id, damage, &ring_bonus, &healing);
+        ring_eff = ring_effectiveness(mon, objects[u.ring].po_ref, damage, &ring_bonus, &healing);
         if (ring_eff)
         {
-            notify_ring_boost(mon, objects[u.ring].obj_id);
+            notify_ring_boost(mon, objects[u.ring].po_ref);
             damage += ring_bonus;
         }
     }
@@ -128,7 +128,7 @@ Action_cost player_power_attack(Offset delta)
 {
     Coord c = u.pos + delta;
     int damage;
-    int mon = lvl.mon_at(c);
+    Mon_handle mon = lvl.mon_at(c);
     /* Power Attack: Always hit, do +75% damage. */
     notify_player_combo_powatk(mon);
     damage = (player_melee_base() * 7) / 4;
@@ -155,13 +155,13 @@ Action_cost player_attack(Offset delta)
     return Cost_std;
 }
 
-int uhitm(int mon)
+int uhitm(Mon_handle mon)
 {
     Mon *mp;
     int tohit;
     int damage;
     int hitbase = u.agility + u.level;
-    mp = monsters + mon;
+    mp = mon_snapv(mon);
     tohit = hitbase / 3 + zero_die(hitbase - hitbase / 3);
     if (tohit < mp->defence)
     {
@@ -182,13 +182,13 @@ int ushootm(Offset step)
     int range;
     Coord c = u.pos + step;
     bool done = false;
-    int mon;
+    Mon_handle mon;
     Mon *mptr;
     Obj *wep;
     Permobj *pwep;
     int damage;
-    wep = objects + u.weapon;
-    pwep = permobjs + wep->obj_id;
+    wep = obj_snapv(u.weapon);
+    pwep = permobjs + wep->po_ref;
     damage = one_die(pwep->power);
     for (range = 1; !done; ++range, (c += step))
     {
@@ -196,7 +196,7 @@ int ushootm(Offset step)
         if (mon != NO_MON)
         {
             done = true;
-            mptr = monsters + mon;
+            mptr = mon_snapv(mon);
             tohit = zero_die(u.agility + u.level - range);
             if (range == 1)
             {
@@ -212,7 +212,7 @@ int ushootm(Offset step)
                     notify_player_hurt_mon(mon, damage);
                 }
                 damage_mon(mon, damage, true);
-                if ((mptr->used) && (wep->obj_id == PO_THUNDERBOW))
+                if ((mptr->flags & MF_ALIVE) && (wep->po_ref == PO_THUNDERBOW))
                 {
                     int kb = knockback_mon(mon, step, true, true);
                     switch (kb)
@@ -243,12 +243,12 @@ int ushootm(Offset step)
     return 0;
 }
 
-int mhitu(int mon, Damtyp dtype)
+int mhitu(Mon_handle mon, Damtyp dtype)
 {
     int tohit;
     int damage;
     int unaffected;
-    Mon *mptr = monsters + mon;
+    Mon *mptr = mon_snapv(mon);
     tohit = zero_die(mptr->mtohit + 5);
     if (tohit < u.defence)
     {
@@ -307,19 +307,19 @@ test_unaffected:
     else
     {
         notify_player_touch_effect(dtype);
-        if ((mptr->mon_id == PM_VAMPIRE) && !u.resists(DT_NECRO))
+        if ((mptr->pm_ref == PM_VAMPIRE) && !u.resists(DT_NECRO))
         {
             heal_mon(mon, damage * 2 / 5, 1);
-        } else if ((tohit - u.defence >= 5) && (mptr->mon_id == PM_SNAKE))
+        } else if ((tohit - u.defence >= 5) && (mptr->pm_ref == PM_SNAKE))
         {
             drain_body(1, "snake venom", 0);
         }
-        damage_u(damage, DEATH_KILLED_MON, permons[mptr->mon_id].name);
+        damage_u(damage, DEATH_KILLED_MON, permons[mptr->pm_ref].name);
     }
     return 1;
 }
 
-int mshootu(int mon)
+int mshootu(Mon_handle mon)
 {
     Mon *mptr;
     Mon *bystander;
@@ -333,14 +333,14 @@ int mshootu(int mon)
     int evasion;
     int defence;
     Damtyp dtype;
-    mptr = monsters + mon;
+    mptr = mon_snapv(mon);
     c = mptr->pos;
     /* dy, dx == trajectory of missile */
     delta = u.pos.delta(c);
     step = mysign(delta);
     /* Don't get the bonus that applies to melee attacks. */
     tohit = zero_die(mptr->rtohit);
-    dtype = permons[mptr->mon_id].rdtyp;
+    dtype = permons[mptr->pm_ref].rdtyp;
     notify_mon_ranged_attack(mon);
     if ((dtype == DT_NECRO) || (dtype == DT_ELEC))
     {
@@ -360,7 +360,7 @@ int mshootu(int mon)
     /* Move projectile one square before looking for targets. */
     for ((done = 0), (c = mptr->pos + step); !done; c += step)
     {
-        int victim;
+        Mon_handle victim;
         if ((lvl.terrain_at(c) == WALL) || (lvl.terrain_at(c) == DOOR))
         {
             done = 1;
@@ -376,7 +376,7 @@ int mshootu(int mon)
                 if (!unaffected)
                 {
                     damage = one_die(mptr->rdam);
-                    damage_u(damage, DEATH_KILLED_MON, permons[mptr->mon_id].name);
+                    damage_u(damage, DEATH_KILLED_MON, permons[mptr->pm_ref].name);
                 }
                 return 1;
             }
@@ -388,11 +388,11 @@ int mshootu(int mon)
         else if (victim != NO_MON)
         {
             done = 1;
-            bystander = monsters + victim;
+            bystander = mon_snapv(victim);
             switch (dtype)
             {
             case DT_COLD:
-                if (pmon_resists_cold(bystander->mon_id))
+                if (pmon_resists_cold(bystander->pm_ref))
                 {
                     unaffected = 1;
                 }
@@ -402,7 +402,7 @@ int mshootu(int mon)
                 }
                 break;
             case DT_FIRE:
-                if (pmon_resists_fire(bystander->mon_id))
+                if (pmon_resists_fire(bystander->pm_ref))
                 {
                     unaffected = 1;
                 }
@@ -412,7 +412,7 @@ int mshootu(int mon)
                 }
                 break;
             case DT_NECRO:
-                if (pmon_is_undead(bystander->mon_id))
+                if (pmon_is_undead(bystander->pm_ref))
                 {
                     unaffected = 1;
                 }
index a65c4f8..c2be288 100644 (file)
--- a/combat.hh
+++ b/combat.hh
 
 #define agility_modifier() (u.withering ? (u.agility / 10) : (u.agility / 5))
 /* XXX combat.c data and funcs */
-extern Action_cost throw_flask(int obj, Offset step);
 extern Action_cost player_attack(Offset step);
 extern Action_cost player_power_attack(Offset step);
-extern void resolve_player_melee(int mon, int damage);
-extern int mhitu(int mon, Damtyp dtyp);
-extern int uhitm(int mon);
-extern int mshootu(int mon);
+extern void resolve_player_melee(Mon_handle mon, int damage);
+extern int mhitu(Mon_handle mon, Damtyp dtyp);
+extern int uhitm(Mon_handle mon);
+extern int mshootu(Mon_handle mon);
 extern int ushootm(Offset step);
 
 class Combo_spec
index 1a2016a..c69dda2 100644 (file)
--- a/coord.hh
+++ b/coord.hh
@@ -30,6 +30,7 @@
 #define COORD_HH
 
 #include <algorithm>
+#include <stdint.h>
 
 template <typename T> T myabs(T val);
 template <typename T> T mysign(T val);
@@ -48,8 +49,8 @@ template <typename T> inline T mysign(T val) { return (val < 0) ? -1 : ((val > 0
 class Offset
 {
 public:
-    int y;
-    int x;
+    int32_t y;
+    int32_t x;
     bool ecardinal(void) const { return ((y && !x) || (x && !y)); }
     bool rcardinal(void) const { return ecardinal() || (myabs(y) == myabs(x)); }
     int len_cheb(void) const { return std::max(myabs(y), myabs(x)); }
@@ -69,7 +70,7 @@ public:
     bool operator <=(Offset const& right) const { return (y < right.y) || ((y == right.y) && (x <= right.x)); }
     bool operator >(Offset const& right) const { return (y > right.y) || ((y == right.y) && (x > right.x)); }
     bool operator >=(Offset const& right) const { return (y > right.y) || ((y == right.y) && (x >= right.x)); }
-    void clamp(int ymin, int xmin, int ymax, int xmax)
+    void clamp(int32_t ymin, int32_t xmin, int32_t ymax, int32_t xmax)
     {
         y = std::min(ymax, std::max(ymin, y));
         x = std::min(xmax, std::max(xmin, x));
@@ -88,8 +89,8 @@ public:
 class Coord
 {
 public:
-    int y;
-    int x;
+    int32_t y;
+    int32_t x;
     int dist_cheb(Coord const& right) const { return std::max(myabs(y - right.y), myabs(x - right.x)); }
     int dist_taxi(Coord const& right) const { return myabs(y - right.y) + myabs(x - right.x); }
     int distsq_eucl(Coord const& right) const { return (y - right.y) * (y - right.y) + (x - right.x) * (x - right.x); }
@@ -104,7 +105,7 @@ public:
     bool operator <=(Coord const& right) const { return (y < right.y) || ((y == right.y) && (x <= right.x)); }
     bool operator >(Coord const& right) const { return (y > right.y) || ((y == right.y) && (x > right.x)); }
     bool operator >=(Coord const& right) const { return (y > right.y) || ((y == right.y) && (x >= right.x)); }
-    void clamp(int ymin, int xmin, int ymax, int xmax)
+    void clamp(int32_t ymin, int32_t xmin, int32_t ymax, int32_t xmax)
     {
         y = std::min(ymax, std::max(ymin, y));
         x = std::min(xmax, std::max(xmin, x));
diff --git a/core.hh b/core.hh
index de1c387..3f47981 100644 (file)
--- a/core.hh
+++ b/core.hh
@@ -163,12 +163,14 @@ class Level_key;
 class Permobj;
 class Permon;
 class Obj;
+typedef uint32_t Obj_handle;
 class Mon;
+typedef uint32_t Mon_handle;
 
 #define NO_POBJ (-1)
 #define NO_PMON (-1)
-#define NO_OBJ (-1)
-#define NO_MON (-1)
+extern const Obj_handle NO_OBJ;
+extern const Mon_handle NO_MON;
 #define NO_REGION 0xffffffffu
 
 #endif
index e3ce020..cef82a2 100644 (file)
@@ -45,8 +45,8 @@
 #define DISP_NC_SIDE (DISP_NC_RADIUS * 2 + 1)
 
 /* Prototypes for static funcs */
-static cchar_t const *object_char(int object_id);
-static cchar_t const *monster_char(int monster_id);
+static cchar_t const *object_char(int po_ref);
+static cchar_t const *monster_char(int pm_ref);
 static cchar_t const *terrain_char(Terrain terrain_type);
 static void draw_status_line(void);
 static void draw_world(void);
@@ -220,22 +220,22 @@ static cchar_t const *terrain_char(Terrain terrain_type)
 
 /*! \brief Get pointer to cchar_t object for specified permon
  *
- * \param monster_id Specified permon
+ * \param pm_ref Specified permon
  * \return pointer to the specified permon's tile
  */
-static cchar_t const *monster_char(int monster_id)
+static cchar_t const *monster_char(int pm_ref)
 {
-    return permon_tiles + monster_id;
+    return permon_tiles + pm_ref;
 }
 
 /*! \brief Get pointer to cchar_t object for specified permobj
  *
- * \param object_id Specified permobj
+ * \param po_ref Specified permobj
  * \return pointer to the specified permobj's tile
  */
-static cchar_t const *object_char(int object_id)
+static cchar_t const *object_char(int po_ref)
 {
-    return permobj_tiles + object_id;
+    return permobj_tiles + po_ref;
 }
 
 /*! \brief Repopulate the back buffer and set the hard redraw flag */
@@ -278,8 +278,8 @@ void newsym(Coord c)
     }
     else
     {
-        int obj = lvl.obj_at(c);
-        int mon = lvl.mon_at(c);
+        Obj_handle obj = lvl.obj_at(c);
+        Mon_handle mon = lvl.mon_at(c);
         Terrain terr = lvl.terrain_at(c);
         uint32_t flags = lvl.flags_at(c);
         if (c == u.pos)
@@ -288,13 +288,13 @@ void newsym(Coord c)
         }
         else if ((!show_terrain) && (mon != NO_MON) && occupant_visible(c))
         {
-            back_buffer[camoff.y][camoff.x] = monster_char(monsters[mon].mon_id);
+            back_buffer[camoff.y][camoff.x] = monster_char(monsters[mon].pm_ref);
         }
         else if (flags & MAPFLAG_EXPLORED)
         {
             if ((!show_terrain) && (obj != NO_OBJ))
             {
-                back_buffer[camoff.y][camoff.x] = object_char(objects[obj].obj_id);
+                back_buffer[camoff.y][camoff.x] = object_char(objects[obj].po_ref);
             }
             else
             {
@@ -760,7 +760,7 @@ static void update_inv(enum poclass_num filter)
         else
         {
             if ((filter == POCLASS_NONE) ||
-                 (permobjs[objects[u.inventory[i]].obj_id].poclass == filter))
+                 (permobjs[objects[u.inventory[i]].po_ref].poclass == filter))
             {
                 wattr_set(inventory_window, colour_data[Gcol_l_grey].attr, colour_data[Gcol_l_grey].cpair, nullptr);
             }
@@ -800,7 +800,7 @@ static int inv_select(enum poclass_num filter, char const *action, int accept_bl
 
     for (i = 0; i < 19; i++)
     {
-        if ((u.inventory[i] != NO_OBJ) && ((filter == POCLASS_NONE) || (permobjs[objects[u.inventory[i]].obj_id].poclass == filter)))
+        if ((u.inventory[i] != NO_OBJ) && ((filter == POCLASS_NONE) || (permobjs[objects[u.inventory[i]].po_ref].poclass == filter)))
         {
             items++;
         }
@@ -859,7 +859,7 @@ tryagain:
          * a strict superset of ASCII. IF we're not, the following code may
          * break. */
         selection = ch - 'a';
-        if ((u.inventory[selection] != NO_OBJ) && ((filter == POCLASS_NONE) || (permobjs[objects[u.inventory[selection]].obj_id].poclass == filter)))
+        if ((u.inventory[selection] != NO_OBJ) && ((filter == POCLASS_NONE) || (permobjs[objects[u.inventory[selection]].po_ref].poclass == filter)))
         {
             hide_inv();
             return selection;
@@ -1608,8 +1608,8 @@ static void examine_square(Offset o)
 {
     Coord c = u.pos + o;
     uint32_t flags;
-    int mon;
-    int obj;
+    Mon_handle mon;
+    Obj_handle obj;
     Terrain terr;
     if ((c.y < 0) || (c.x < 0) || (c.y >= (lvl.chunks_high << CHUNK_SHIFT)) ||
         (c.x >= (lvl.chunks_wide << CHUNK_SHIFT)))
@@ -1629,11 +1629,11 @@ static void examine_square(Offset o)
     print_msg("%s\n", terrain_props[terr]);
     if ((mon != NO_MON) && mon_visible(mon))
     {
-        print_msg("%s\n%s\n", permons[monsters[mon].mon_id].name, permons[monsters[mon].mon_id].description);
+        print_msg("%s\n%s\n", permons[monsters[mon].pm_ref].name, permons[monsters[mon].pm_ref].description);
     }
     if (obj != NO_OBJ)
     {
-        print_msg("%s\n%s\n", permobjs[objects[obj].obj_id].name, permobjs[objects[obj].obj_id].description);
+        print_msg("%s\n%s\n", permobjs[objects[obj].po_ref].name, permobjs[objects[obj].po_ref].description);
     }
 }
 
@@ -1690,27 +1690,23 @@ void welcome(void)
     print_msg("Press '?' for help.\n");
 }
 
-void describe_object(int obj)
+void describe_object(Obj_handle obj)
 {
-    Obj *optr;
-    Permobj *poptr;
+    Obj const *optr = obj_snap(obj);
+    Permobj const *poptr = permobjs + optr->po_ref;
     print_obj_name(obj);
-    optr = objects + obj;
-    poptr = permobjs + optr->obj_id;
     print_msg("\n%s\n", poptr->description);
 }
 
-void print_obj_name(int obj)
+void print_obj_name(Obj_handle obj)
 {
-    Obj *optr;
-    Permobj *poptr;
-    optr = objects + obj;
-    poptr = permobjs + optr->obj_id;
+    Obj const *optr = obj_snap(obj);
+    Permobj const *poptr = permobjs + optr->po_ref;
     if (optr->quan > 1)
     {
         print_msg("%d %s", optr->quan, poptr->plural);
     }
-    else if (po_is_stackable(optr->obj_id))
+    else if (po_is_stackable(optr->po_ref))
     {
         print_msg("1 %s", poptr->name);
     }
@@ -1725,26 +1721,26 @@ void print_obj_name(int obj)
     }
 }
 
-void print_mon_name(int mon, int article)
+void print_mon_name(Mon_handle mon, int article)
 {
-    if (permons[monsters[mon].mon_id].name[0] == '\0')
+    if (permons[monsters[mon].pm_ref].name[0] == '\0')
     {
-        print_msg("GROB THE VOID (%d)", monsters[mon].mon_id);
+        print_msg("GROB THE VOID (%d)", monsters[mon].pm_ref);
         return;
     }
     switch (article)
     {
     case 0:     /* a */
-        print_msg("a%s %s", is_vowel(permons[monsters[mon].mon_id].name[0]) ? "n" : "", permons[monsters[mon].mon_id].name);
+        print_msg("a%s %s", is_vowel(permons[monsters[mon].pm_ref].name[0]) ? "n" : "", permons[monsters[mon].pm_ref].name);
         break;
     case 1: /* the */
-        print_msg("the %s", permons[monsters[mon].mon_id].name);
+        print_msg("the %s", permons[monsters[mon].pm_ref].name);
         break;
     case 2: /* A */
-        print_msg("A%s %s", is_vowel(permons[monsters[mon].mon_id].name[0]) ? "n" : "", permons[monsters[mon].mon_id].name);
+        print_msg("A%s %s", is_vowel(permons[monsters[mon].pm_ref].name[0]) ? "n" : "", permons[monsters[mon].pm_ref].name);
         break;
     case 3: /* The */
-        print_msg("The %s", permons[monsters[mon].mon_id].name);
+        print_msg("The %s", permons[monsters[mon].pm_ref].name);
         break;
     }
 }
index 0a92378..b524572 100644 (file)
@@ -56,6 +56,7 @@ extern void pressanykey(void);
 extern void show_discoveries(void);
 extern void touch_one_screen(Coord c);
 extern void welcome(void);
+extern void print_obj_name(Obj_handle obj);
 
 /* "I've changed things that need to be redisplayed" flags. */
 extern bool hard_redraw;
diff --git a/log.cc b/log.cc
index b2bc2c0..6aa7b0f 100644 (file)
--- a/log.cc
+++ b/log.cc
@@ -154,6 +154,136 @@ void wrapped_fread(void *buf, size_t size, size_t nmemb, FILE *fp)
     }
 }
 
+static inline void deserialize_uint32(FILE *fp, uint32_t *i)
+{
+    wrapped_fread(&i, 1, sizeof i, fp);
+    *i = ntohl(*i);
+}
+
+static inline void deserialize_int32(FILE *fp, int32_t *i)
+{
+    int32_t tmp;
+    wrapped_fread(&tmp, 1, sizeof tmp, fp);
+    *i = (int32_t) ntohl(tmp);
+}
+
+static inline void deserialize_int(FILE *fp, int *i)
+{
+    int32_t tmp;
+    wrapped_fread(&tmp, 1, sizeof tmp, fp);
+    *i = (int32_t) ntohl(tmp);
+}
+
+static inline void deserialize_coord(FILE *fp, Coord * c)
+{
+    deserialize_int32(fp, &(c->y));
+    deserialize_int32(fp, &(c->x));
+}
+
+static inline void serialize_uint32(FILE *fp, uint32_t i)
+{
+    i = htonl(i);
+    fwrite(&i, 1, sizeof i, fp);
+}
+
+static inline void serialize_int32(FILE *fp, int32_t i)
+{
+    int32_t tmp = htonl(i);
+    fwrite(&tmp, 1, sizeof tmp, fp);
+}
+
+static inline void serialize_int(FILE *fp, int i)
+{
+    int32_t tmp = htonl(i);
+    fwrite(&tmp, 1, sizeof tmp, fp);
+}
+
+static inline void serialize_coord(FILE *fp, Coord const& c)
+{
+    serialize_int32(fp, c.y);
+    serialize_int32(fp, c.x);
+}
+
+static inline void serialize_monhandle(FILE *fp, Mon_handle m)
+{
+    uint32_t tmp = htonl(m);
+    fwrite(&tmp, 1, sizeof tmp, fp);
+}
+
+static void serialize_monster(FILE *fp, Mon const& mon)
+{
+    serialize_monhandle(fp, mon.self);
+    serialize_int(fp, mon.pm_ref);
+    serialize_uint32(fp, mon.flags);
+    serialize_coord(fp, mon.pos);
+    serialize_coord(fp, mon.ai_lastpos);
+    serialize_int(fp, mon.hpmax);
+    serialize_int(fp, mon.hpcur);
+    serialize_int(fp, mon.mtohit);
+    serialize_int(fp, mon.rtohit);
+    serialize_int(fp, mon.defence);
+    serialize_int(fp, mon.mdam);
+    serialize_int(fp, mon.rdam);
+    serialize_int(fp, mon.next_summon);
+}
+
+static inline void serialize_objhandle(FILE *fp, Obj_handle o)
+{
+    uint32_t tmp = htonl(o);
+    fwrite(&tmp, 1, sizeof tmp, fp);
+}
+
+static inline void serialize_object(FILE *fp, Obj const& obj)
+{
+    serialize_objhandle(fp, obj.self);
+    serialize_int(fp, obj.po_ref);
+    serialize_uint32(fp, obj.flags);
+    serialize_coord(fp, obj.pos);
+    serialize_int(fp, obj.quan);
+    serialize_int(fp, obj.durability);
+}
+
+static inline void deserialize_monhandle(FILE *fp, Mon_handle *m)
+{
+    uint32_t tmp;
+    wrapped_fread(&tmp, 1, sizeof tmp, fp);
+    *m = htonl(tmp);
+}
+
+static inline void deserialize_objhandle(FILE *fp, Obj_handle *o)
+{
+    uint32_t tmp;
+    wrapped_fread(&tmp, 1, sizeof tmp, fp);
+    *o = htonl(tmp);
+}
+
+static inline void deserialize_object(FILE *fp, Obj *obj)
+{
+    deserialize_objhandle(fp, &(obj->self));
+    deserialize_int(fp, &(obj->po_ref));
+    deserialize_uint32(fp, &(obj->flags));
+    deserialize_coord(fp, &(obj->pos));
+    deserialize_int(fp, &(obj->quan));
+    deserialize_int(fp, &(obj->durability));
+}
+
+static void deserialize_monster(FILE *fp, Mon * mon)
+{
+    deserialize_monhandle(fp, &(mon->self));
+    deserialize_int(fp, &(mon->pm_ref));
+    deserialize_uint32(fp, &(mon->flags));
+    deserialize_coord(fp, &(mon->pos));
+    deserialize_coord(fp, &(mon->ai_lastpos));
+    deserialize_int(fp, &(mon->hpmax));
+    deserialize_int(fp, &(mon->hpcur));
+    deserialize_int(fp, &(mon->mtohit));
+    deserialize_int(fp, &(mon->rtohit));
+    deserialize_int(fp, &(mon->defence));
+    deserialize_int(fp, &(mon->mdam));
+    deserialize_int(fp, &(mon->rdam));
+    deserialize_int(fp, &(mon->next_summon));
+}
+
 void save_game(void)
 {
     FILE *fp;
@@ -177,8 +307,18 @@ void save_game(void)
     tmp = htonl(game_tick);
     fwrite(&tmp, 1, sizeof tmp, fp);
     serialize_level(fp, &lvl);
-    fwrite(monsters, sizeof (Mon), MONSTERS_IN_PLAY, fp);
-    fwrite(objects, sizeof (Obj), OBJECTS_IN_PLAY, fp);
+    for (auto iter = monsters.begin(); iter != monsters.end(); ++iter)
+    {
+        serialize_monhandle(fp, iter->second.self);
+        serialize_monster(fp, iter->second);
+    }
+    serialize_monhandle(fp, NO_MON);
+    for (auto iter = objects.begin(); iter != objects.end(); ++iter)
+    {
+        serialize_objhandle(fp, iter->second.self);
+        serialize_object(fp, iter->second);
+    }
+    serialize_objhandle(fp, NO_OBJ);
     /* Clean up */
     fflush(fp);
     fsync(fd);
@@ -191,12 +331,11 @@ void save_game(void)
  */
 static void rebuild_mapmons(void)
 {
-    int i;
-    for (i = 0; i < 100; i++)
+    for (auto iter = monsters.begin(); iter != monsters.end(); ++iter)
     {
-        if (monsters[i].used)
+        if (iter->second.flags & MF_USED)
         {
-            lvl.set_mon_at(monsters[i].pos, i);
+            lvl.set_mon_at(iter->second.pos, iter->first);
         }
     }
 }
@@ -205,12 +344,11 @@ static void rebuild_mapmons(void)
  */
 static void rebuild_mapobjs(void)
 {
-    int i;
-    for (i = 0; i < 100; i++)
+    for (auto iter = objects.begin(); iter != objects.end(); ++iter)
     {
-        if (objects[i].used && !objects[i].with_you)
+        if (iter->second.flags & OF_USED)
         {
-            lvl.set_obj_at(objects[i].pos, i);
+            lvl.set_obj_at(iter->second.pos, iter->first);
         }
     }
 }
@@ -235,8 +373,36 @@ int load_game(void)
     wrapped_fread(&game_tick, 1, sizeof game_tick, fp);
     game_tick = ntohl(game_tick);
     deserialize_level(fp, &lvl);
-    wrapped_fread(monsters, sizeof (Mon), MONSTERS_IN_PLAY, fp);
-    wrapped_fread(objects, sizeof (Obj), OBJECTS_IN_PLAY, fp);
+    while (1)
+    {
+        Mon_handle mon;
+        deserialize_monhandle(fp, &mon);
+        if (mon != NO_MON)
+        {
+            Mon m;
+            deserialize_monster(fp, &m);
+            monsters[mon] = m;
+        }
+        else
+        {
+            break;
+        }
+    }
+    while (1)
+    {
+        Obj_handle obj;
+        deserialize_objhandle(fp, &obj);
+        if (obj != NO_OBJ)
+        {
+            Obj o;
+            deserialize_object(fp, &o);
+            objects[obj] = o;
+        }
+        else
+        {
+            break;
+        }
+    }
     rebuild_mapobjs();
     rebuild_mapmons();
     fclose(fp);
diff --git a/main.cc b/main.cc
index 411c02d..25d305d 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -66,7 +66,6 @@ void new_game(char const *name)
 
 void main_loop(void)
 {
-    int i;
     int action_speed = 0;
     welcome();
     while (!game_finished)
@@ -99,18 +98,17 @@ void main_loop(void)
                 }
             } while (cost == Cost_none);
         }
-        for (i = 0; i < 100; i++)
+        for (auto iter = monsters.begin(); iter != monsters.end(); ++iter)
         {
-            if (!monsters[i].used)
+            if (!(iter->second.flags & MF_USED))
             {
-                /* Unused monster */
                 continue;
             }
             /* Update the monster's status. */
-            update_mon(i);
-            if (action_speed <= permons[monsters[i].mon_id].speed)
+            update_mon(iter->first);
+            if (action_speed <= permons[iter->second.pm_ref].speed)
             {
-                mon_acts(i);
+                mon_acts(iter->first);
             }
             if (game_finished)
             {
diff --git a/map.cc b/map.cc
index ab8069d..764fa10 100644 (file)
--- a/map.cc
+++ b/map.cc
@@ -255,7 +255,7 @@ int Level::find_stairs(Terrain t, std::vector<Stair_detail> *dest) const
 int Level::find_stairs(Level_key from, std::vector<Stair_detail> *dest) const
 {
     int count = 0;
-    for (auto iter = lvl.stairs.begin(); iter != lvl.stairs.end(); ++iter)
+    for (auto iter = stairs.begin(); iter != stairs.end(); ++iter)
     {
         if (iter->destination == from)
         {
@@ -268,16 +268,22 @@ int Level::find_stairs(Level_key from, std::vector<Stair_detail> *dest) const
 
 void leave_level(void)
 {
-    int i;
-    for (i = 0; i < 100; i++)
+    for (auto iter = monsters.begin(); iter != monsters.end(); )
     {
-        /* Throw away each monster */
-        monsters[i].used = false;
-        /* and each object not carried by the player */
-        if (!objects[i].with_you)
+        auto iter2 = iter;
+        ++iter2;
+        monsters.erase(iter);
+        iter = iter2;
+    }
+    for (auto iter = objects.begin(); iter != objects.end(); )
+    {
+        auto iter2 = iter;
+        ++iter2;
+        if (!(iter->second.flags & OF_WITH_YOU))
         {
-            objects[i].used = false;
+            objects.erase(iter);
         }
+        iter = iter2;
     }
     depth++;
 }
@@ -286,7 +292,7 @@ void make_new_level(void)
 {
     build_level();
     populate_level();
-    inject_player(lvl.self.naive_prev());
+    inject_player(&lvl, lvl.self.naive_prev());
     look_around_you();
     notify_change_of_depth();
 }
@@ -296,28 +302,28 @@ void make_new_level(void)
  * This version of run_random_walk will extend the level boundaries instead
  * of rejecting out-of-bounds coordinates.
  */
-Coord run_random_walk(Coord oc, rwalk_mod_funcptr func,
+Coord run_random_walk(Level *l, Coord oc, rwalk_mod_funcptr func,
                       void const *priv_ptr, int cells)
 {
     int i;
     Coord c = oc;
     int bailout = 10000;
 
-    func(c, priv_ptr);
+    func(l, c, priv_ptr);
     for (i = 0; (i < cells) && (bailout > 0); --bailout)
     {
         oc = c;
         if (zero_die(2))
         {
             c.y += (zero_die(2) ? -1 : 1);
-            c.y = std::min(lvl.max_y() - 2, std::max(c.y, lvl.min_y() + 2));
+            c.y = std::min(l->max_y() - 2, std::max(c.y, l->min_y() + 2));
         }
         else
         {
             c.x += (zero_die(2) ? -1 : 1);
-            c.x = std::min(lvl.max_x() - 2, std::max(c.x, lvl.min_x() + 2));
+            c.x = std::min(l->max_x() - 2, std::max(c.x, l->min_x() + 2));
         }
-        switch (func(c, priv_ptr))
+        switch (func(l, c, priv_ptr))
         {
         case 0:
             /* nothing changed */
@@ -344,14 +350,14 @@ Coord run_random_walk(Coord oc, rwalk_mod_funcptr func,
  * This version of run_random_walk will extend the level boundaries instead
  * of rejecting out-of-bounds coordinates.
  */
-Coord run_random_walk_unbounded(Coord oc, rwalk_mod_funcptr func,
+Coord run_random_walk_unbounded(Level *l, Coord oc, rwalk_mod_funcptr func,
                                 void const *priv_ptr, int cells)
 {
     int i;
     Coord c = oc;
     int bailout = 10000;
 
-    func(c, priv_ptr);
+    func(l, c, priv_ptr);
     for (i = 0; (i < cells) && (bailout > 0); --bailout)
     {
         oc = c;
@@ -363,23 +369,23 @@ Coord run_random_walk_unbounded(Coord oc, rwalk_mod_funcptr func,
         {
             c.x += (zero_die(2) ? -1 : 1);
         }
-        if (c.y <= lvl.min_y())
+        if (c.y <= l->min_y())
         {
-            lvl.grow(North, true);
+            l->grow(North, true);
         }
-        if (c.y >= lvl.max_y())
+        if (c.y >= l->max_y())
         {
-            lvl.grow(South, true);
+            l->grow(South, true);
         }
-        if (c.x <= lvl.min_x())
+        if (c.x <= l->min_x())
         {
-            lvl.grow(West, true);
+            l->grow(West, true);
         }
-        if (c.x >= lvl.max_x())
+        if (c.x >= l->max_x())
         {
-            lvl.grow(East, true);
+            l->grow(East, true);
         }
-        switch (func(c, priv_ptr))
+        switch (func(l, c, priv_ptr))
         {
         case 0:
             /* nothing changed */
@@ -444,22 +450,22 @@ void build_level(void)
     switch (lvl.layout)
     {
     case LAYOUT_CAVE_SHRINE:
-        build_level_shrine();
+        build_level_shrine(&lvl);
         break;
     case LAYOUT_CAVE_INTRUSIONS:
-        build_level_intrusions();
+        build_level_intrusions(&lvl);
         break;
     case LAYOUT_DUNGEONBASH:
-        build_level_dungeonbash();
+        build_level_dungeonbash(&lvl);
         break;
     case LAYOUT_CLASSIC_CAVE:
-        build_level_cave();
+        build_level_cave(&lvl);
         break;
     }
 }
 
 /*! \brief Build a dungeonbash-style rooms-and-corridors level */
-void build_level_dungeonbash()
+void build_level_dungeonbash(Level *l)
 {
     int chy;
     int chx;
@@ -467,9 +473,9 @@ void build_level_dungeonbash()
      * immediately. */
     initialize_chunks(&lvl, GUIDE_EDGE_CHUNKS, GUIDE_EDGE_CHUNKS, true);
     /* One room per chunk. */
-    for (chy = 0; chy < lvl.chunks_high; ++chy)
+    for (chy = 0; chy < l->chunks_high; ++chy)
     {
-        for (chx = 0; chx < lvl.chunks_wide; ++ chx)
+        for (chx = 0; chx < l->chunks_wide; ++ chx)
         {
             /* Smallest allowed room has a 2x2 interior. */
             Offset room_size = { MIN_ROOM_EDGE + zero_die(5), MIN_ROOM_EDGE + zero_die(5) };
@@ -487,13 +493,13 @@ void build_level_dungeonbash()
 }
 
 /*! \brief Excavation function for use with random walks */
-int excavation_write(Coord c, void const *data)
+int excavation_write(Level *l, Coord c, void const *data)
 {
     int const *data_as_ints = (int const *) data;
     int const *overwrite = data_as_ints + 2;
     int newterr = data_as_ints[1];
     int j;
-    if (lvl.flags_at(c) & MAPFLAG_HARDWALL)
+    if (l->flags_at(c) & MAPFLAG_HARDWALL)
     {
         /* Don't bite into hardened walls, but don't waste a step on
          * them either. */
@@ -501,9 +507,9 @@ int excavation_write(Coord c, void const *data)
     }
     for (j = 0; j < data_as_ints[0]; ++j)
     {
-        if (lvl.terrain_at(c) == overwrite[j])
+        if (l->terrain_at(c) == overwrite[j])
         {
-            lvl.set_terrain_at(c, (Terrain) newterr);
+            l->set_terrain_at(c, (Terrain) newterr);
             return 1;
         }
     }
@@ -511,10 +517,10 @@ int excavation_write(Coord c, void const *data)
 }
 
 /*! \brief "Intrusion" function for use with random walks */
-int intrusion_write(Coord c, void const *data)
+int intrusion_write(Level *l, Coord c, void const *data)
 {
     Terrain const *tptr = (Terrain const *) data;
-    if ((lvl.terrain_at(c) != WALL) || (lvl.flags_at(c) & MAPFLAG_HARDWALL))
+    if ((l->terrain_at(c) != WALL) || (l->flags_at(c) & MAPFLAG_HARDWALL))
     {
         return 0;
     }
@@ -529,14 +535,14 @@ int intrusion_write(Coord c, void const *data)
     }
     if (tptr)
     {
-        lvl.set_terrain_at(c, *tptr);
+        l->set_terrain_at(c, *tptr);
     }
-    lvl.set_flags_at(c, MAPFLAG_HARDWALL);
+    l->set_flags_at(c, MAPFLAG_HARDWALL);
     return 1;
 }
 
 /*! \brief Do a random walk laying down an exclusion area */
-void place_random_intrusion(Terrain new_wall)
+void place_random_intrusion(Level *l, Terrain new_wall)
 {
     Coord c;
     int intrusion_size = inc_flat(27, 54);
@@ -544,19 +550,19 @@ void place_random_intrusion(Terrain new_wall)
     {
         c.x = zero_die(2) ? inc_flat(1, GUIDE_EDGE_SIZE / 3) : inc_flat((2 * GUIDE_EDGE_SIZE) / 3, GUIDE_EDGE_SIZE - 2);
         c.y = zero_die(2) ? inc_flat(1, GUIDE_EDGE_SIZE / 3) : inc_flat((2 * GUIDE_EDGE_SIZE) / 3, GUIDE_EDGE_SIZE - 2);
-    } while (lvl.flags_at(c) & MAPFLAG_HARDWALL);
-    run_random_walk(c, intrusion_write, &new_wall, intrusion_size);
+    } while (l->flags_at(c) & MAPFLAG_HARDWALL);
+    run_random_walk(l, c, intrusion_write, &new_wall, intrusion_size);
 }
 
 /*! \brief Get a valid square to generate a monster on */
-Pass_fail get_levgen_mon_floor(Coord *c)
+Pass_fail get_levgen_mon_floor(Level *l, Coord *c)
 {
     int cell_try;
     Coord t;
     for (cell_try = 0; cell_try < 200; cell_try++)
     {
-        t = lvl.random_point(1);
-        if ((lvl.terrain_at(t) != FLOOR) || (lvl.mon_at(t) != NO_MON))
+        t = l->random_point(1);
+        if ((l->terrain_at(t) != FLOOR) || (l->mon_at(t) != NO_MON))
         {
             t = Nowhere;
             continue;
@@ -581,7 +587,7 @@ void populate_level(void)
     /* Generate some random monsters */
     for (i = 0; i < 10; i++)
     {
-        pf = get_levgen_mon_floor(&c);
+        pf = get_levgen_mon_floor(&lvl, &c);
         if (pf == You_fail)
         {
             continue;
@@ -597,7 +603,7 @@ void populate_level(void)
     /* Generate some random treasure */
     for (i = 0; i < ic; i++)
     {
-        pf = get_levgen_mon_floor(&c);
+        pf = get_levgen_mon_floor(&lvl, &c);
         if (pf == You_fail)
         {
             continue;
@@ -607,12 +613,12 @@ void populate_level(void)
 }
 
 /*! \brief Inject the player into the level based on where they arrived from */
-void inject_player(Level_key from)
+void inject_player(Level *l, Level_key from)
 {
     /* For now we are allowing only one linkage between levels */ 
     Coord c;
     std::vector<Stair_detail> stair_list;
-    int i = lvl.find_stairs(from, &stair_list);
+    int i = l->find_stairs(from, &stair_list);
     if (i != 0)
     {
         c = stair_list[0].pos;
@@ -818,16 +824,8 @@ uint32_t rotate_connection_mask(uint32_t val, int clockwise_steps)
 
 void level_cleanup(void)
 {
-    int i;
-    for (i = 0; i < MONSTERS_IN_PLAY; ++i)
-    {
-        monsters[i].used = false;
-    }
-    for (i = 0; i < OBJECTS_IN_PLAY; ++i)
-    {
-        objects[i].used = false;
-        objects[i].with_you = false;
-    }
+    monsters.clear();
+    objects.clear();
     drop_all_chunks(&lvl);
 }
 
diff --git a/map.hh b/map.hh
index 3f5bbcf..532bb03 100644 (file)
--- a/map.hh
+++ b/map.hh
@@ -105,8 +105,8 @@ extern Terrain_props terrain_props[NUM_TERRAINS];
 class Chunk
 {
 public:
-    int objs[CHUNK_EDGE][CHUNK_EDGE];
-    int mons[CHUNK_EDGE][CHUNK_EDGE];
+    Obj_handle objs[CHUNK_EDGE][CHUNK_EDGE];
+    Mon_handle mons[CHUNK_EDGE][CHUNK_EDGE];
     Terrain terrain[CHUNK_EDGE][CHUNK_EDGE];
     uint32_t flags[CHUNK_EDGE][CHUNK_EDGE];
     uint32_t region_number[CHUNK_EDGE][CHUNK_EDGE];
@@ -217,14 +217,14 @@ public:
             ch->clear_flags_at(c2, to_clear);
         }
     }
-    int mon_at(Coord c) const
+    Mon_handle mon_at(Coord c) const
     {
         Coord rc = c + origin_off;
         Coord c2 = { rc.y & CHUNK_MASK, rc.x & CHUNK_MASK };
         Chunk const *ch = chunks[rc.y >> CHUNK_SHIFT][rc.x >> CHUNK_SHIFT];
         return ch ? ch->mon_at(c2) : NO_MON;
     }
-    void set_mon_at(Coord c, int mon)
+    void set_mon_at(Coord c, Mon_handle mon)
     {
         Coord rc = c + origin_off;
         Coord c2 = { rc.y & CHUNK_MASK, rc.x & CHUNK_MASK };
@@ -234,14 +234,14 @@ public:
             ch->set_mon_at(c2, mon);
         }
     }
-    int obj_at(Coord c) const
+    Obj_handle obj_at(Coord c) const
     {
         Coord rc = c + origin_off;
         Coord c2 = { rc.y & CHUNK_MASK, rc.x & CHUNK_MASK };
         Chunk const *ch = chunks[rc.y >> CHUNK_SHIFT][rc.x >> CHUNK_SHIFT];
         return ch ? ch->obj_at(c2) : NO_OBJ;
     }
-    void set_obj_at(Coord c, int obj)
+    void set_obj_at(Coord c, Obj_handle obj)
     {
         Coord rc = c + origin_off;
         Coord c2 = { rc.y & CHUNK_MASK, rc.x & CHUNK_MASK };
@@ -293,7 +293,7 @@ void leave_level(void);
 void make_new_level(void);
 void build_level(void);
 void populate_level(void);
-void inject_player(Level_key from);
+void inject_player(Level *l, Level_key from);
 void look_around_you(void);
 bool terrain_is_opaque(Terrain terr);
 bool terrain_blocks_beings(Terrain terr);
index 4936e8e..4f16841 100644 (file)
--- a/mapgen.hh
+++ b/mapgen.hh
@@ -42,18 +42,18 @@ extern int depth;
 extern enum level_theme current_theme;
 extern enum level_layout current_layout;
 
-void build_level_shrine(void);
-void build_level_intrusions(void);
-void build_level_cave(void);
-void build_level_dungeonbash(void);
-Pass_fail get_levgen_mon_floor(Coord *c);
-int excavation_write(Coord c, void const *data);
-int intrusion_write(Coord c, void const *data);
+void build_level_shrine(Level *l);
+void build_level_intrusions(Level *l);
+void build_level_cave(Level *l);
+void build_level_dungeonbash(Level *l);
+Pass_fail get_levgen_mon_floor(Level *l, Coord *c);
+int excavation_write(Level *l, Coord c, void const *data);
+int intrusion_write(Level *l, Coord c, void const *data);
 void initialize_chunks(Level *l, int height, int width, bool dense);
 void drop_all_chunks(Level *l);
-void place_shrine(Coord topleft, shrine const *sh, uint32_t accept_conns = 0, Terrain shwall = MASONRY_WALL, Terrain shfloor = FLOOR, bool margin_is_wall = false);
-void place_random_intrusion(Terrain new_wall = WALL);
-void place_cave_stairs(void);
+void place_shrine(Level *l, Coord topleft, shrine const *sh, uint32_t accept_conns = 0, Terrain shwall = MASONRY_WALL, Terrain shfloor = FLOOR, bool margin_is_wall = false);
+void place_random_intrusion(Level *l, Terrain new_wall = WALL);
+void place_cave_stairs(Level *l);
 
 #define ROOMCONN_NORTH 0x00000001u
 #define ROOMCONN_EAST 0x00000002u
@@ -61,10 +61,10 @@ void place_cave_stairs(void);
 #define ROOMCONN_WEST 0x00000008u
 uint32_t rotate_connection_mask(uint32_t val, int clockwise_steps);
 
-typedef int (*rwalk_mod_funcptr)(Coord c, void const *data);
-Coord run_random_walk(Coord oc, rwalk_mod_funcptr func,
+typedef int (*rwalk_mod_funcptr)(Level *l, Coord c, void const *data);
+Coord run_random_walk(Level *l, Coord oc, rwalk_mod_funcptr func,
                       void const *priv_ptr, int cells);
-Coord run_random_walk_unbounded(Coord oc, rwalk_mod_funcptr func,
+Coord run_random_walk_unbounded(Level *l, Coord oc, rwalk_mod_funcptr func,
                                 void const *priv_ptr, int cells);
 
 #endif
diff --git a/mon2.cc b/mon2.cc
index 9f216bf..7c6c716 100644 (file)
--- a/mon2.cc
+++ b/mon2.cc
@@ -48,7 +48,7 @@ static void get_drunk_prefs(Coord loc, Offset delta, Coord *pref_pos);
 static void build_ai_cells(struct ai_cell *cells, Coord loc);
 static Comparison ai_cell_compare(struct ai_cell *cell, Offset delta);
 static void get_dodger_prefs(Coord loc, Offset delta, Coord *pref_pos);
-static void get_chase_prefs(int mon, Coord *pref_pos);
+static void get_chase_prefs(Mon_handle mon, Coord *pref_pos);
 
 /* get_drunk_prefs()
  *
@@ -105,9 +105,9 @@ static void get_drunk_prefs(Coord loc, Offset delta, Coord *pref_pos)
  * details.
  */
 
-static void get_chase_prefs(int mon, Coord *pref_pos)
+static void get_chase_prefs(Mon_handle mon, Coord *pref_pos)
 {
-    Mon const *mptr = monsters + mon;
+    Mon const *mptr = mon_snapv(mon);
     Offset delta = mptr->ai_lastpos.delta(mptr->pos);
     Offset step = mysign(delta);
     Offset absdelta = myabs(delta);
@@ -192,7 +192,7 @@ static void get_seeking_prefs(Coord loc, Offset delta, Coord *pref_pos)
     int i;
     int highest_score = AI_REALLY_HATE;
     int tryct;
-    Mon *mptr = monsters + lvl.mon_at(loc);
+    Mon *mptr = mon_snapv(lvl.mon_at(loc));
     *pref_pos = loc;
     build_ai_cells(ai_cells, loc);
     for (i = 0; i < 8; i++)
@@ -367,7 +367,7 @@ static void get_dodger_prefs(Coord loc, Offset delta, Coord *pref_pos)
     Offset absdelta = myabs(delta);
     int highest_score = AI_REALLY_HATE;
     int tryct;
-    Mon *mptr = monsters + lvl.mon_at(loc);
+    Mon *mptr = mon_snapv(lvl.mon_at(loc));
     *pref_pos = loc;
     build_ai_cells(ai_cells, loc);
     /* Build the local dx/dy arrays. */
@@ -444,7 +444,7 @@ void select_space(Coord *pc, Offset delta, int selection_mode)
     Offset absdelta = myabs(delta);
     Coord c;
     Offset step = mysign(delta);
-    Mon *mptr = monsters + lvl.mon_at(*pc);
+    Mon *mptr = mon_snapv(lvl.mon_at(*pc));
     switch (selection_mode)
     {
     case AI_charger:
@@ -566,14 +566,14 @@ void select_space(Coord *pc, Offset delta, int selection_mode)
         break;
     case AI_chaser:
         /* "chase" AI i.e. pursue your last known position. */
-        get_chase_prefs(mptr - monsters, ai_pos);
+        get_chase_prefs(mptr->self, ai_pos);
         c = ai_pos[0];
         break;
     }
     *pc = c;
 }
 
-void mon_acts(int mon)
+void mon_acts(Mon_handle mon)
 {
     Mon *mptr;
     Offset delta;
@@ -582,7 +582,7 @@ void mon_acts(int mon)
     bool meleerange;
     bool oncardinal;
     bool special_used = false;
-    mptr = monsters + mon;
+    mptr = mon_snapv(mon);
     /* dy,dx == direction monster must go to reach you. */
     c = mptr->pos;
     delta = u.pos.delta(c);
@@ -592,17 +592,17 @@ void mon_acts(int mon)
     if (delta.len_cheb() == 0)
     {
         debug_misplaced_monster();
-        mptr->used = false;
+        mptr->flags &= ~MF_USED;
         lvl.set_mon_at(c, NO_MON);
         return;
     }
     if (lvl.mon_at(c) != mon)
     {
         debug_misplaced_monster();
-        mptr->used = false;
+        mptr->flags &= ~MF_USED;
         if (lvl.mon_at(c) != NO_MON)
         {
-            monsters[lvl.mon_at(c)].used = false;
+            monsters[lvl.mon_at(c)].flags &= ~MF_USED;
             lvl.set_mon_at(c, NO_MON);
         }
         return;
@@ -620,14 +620,14 @@ void mon_acts(int mon)
         /* Adjacent! Attack you.  Demons have a 1 in 10 chance of attempting to
          * summon another demon instead of attacking you, if that individual
          * demon has not summoned in the last 100 ticks. */
-        if ((mptr->mon_id == PM_DEMON) && (mptr->next_summon < game_tick) &&
+        if ((mptr->pm_ref == PM_DEMON) && (mptr->next_summon < game_tick) &&
             !zero_die(10))
         {
             summon_demon_near(c);
             mptr->next_summon = game_tick + 100;
             special_used = true;
         }
-        else if (pmon_is_magician(mptr->mon_id))
+        else if (pmon_is_magician(mptr->pm_ref))
         {
             special_used = mon_use_sorcery(mon);
         }
@@ -639,7 +639,7 @@ void mon_acts(int mon)
     else if (mon_visible(mon))
     {
         /* In sight. */
-        if (pmon_is_magician(mptr->mon_id))
+        if (pmon_is_magician(mptr->pm_ref))
         {
             /* Two-thirds of the time, try to use sorcery. */
             if (zero_die(6) < 4)
@@ -654,7 +654,7 @@ void mon_acts(int mon)
              * as if an archer. */
             select_space(&c, delta, AI_archer);
         }
-        else if (pmon_is_archer(mptr->mon_id))
+        else if (pmon_is_archer(mptr->pm_ref))
         {
             if (oncardinal && (zero_die(6) < 3))
             {
@@ -667,7 +667,7 @@ void mon_acts(int mon)
             }
             select_space(&c, delta, AI_archer);
         }
-        else if (pmon_is_smart(mptr->mon_id))
+        else if (pmon_is_smart(mptr->pm_ref))
         {
             select_space(&c, delta, AI_dodger);
         }
@@ -685,7 +685,7 @@ void mon_acts(int mon)
     {
         /* Out of LOS, but awake. Stupid monsters move "drunkenly"; smart
          * monsters (may) seek you out. */
-        if (pmon_is_magician(mptr->mon_id))
+        if (pmon_is_magician(mptr->pm_ref))
         {
             /* Magicians may have spells that are used when
              * you are out of sight.  For example, some magicians
@@ -696,11 +696,11 @@ void mon_acts(int mon)
         {
             return;
         }
-        if (pmon_is_smart(mptr->mon_id))
+        if (pmon_is_smart(mptr->pm_ref))
         {
             select_space(&c, delta, AI_seeker);
         }
-        else if (pmon_is_stupid(mptr->mon_id) || (mptr->ai_lastpos == Nowhere))
+        else if (pmon_is_stupid(mptr->pm_ref) || (mptr->ai_lastpos == Nowhere))
         {
             select_space(&c, delta, AI_drunk);
         }
index a3d8ed4..55fee7c 100644 (file)
 #include "monsters.hh"
 #include "objects.hh"
 
-Mon monsters[100];
-static int reject_mon(int pm);
+const Mon_handle NO_MON = 0u;
+
+std::map<Mon_handle, Mon> monsters;
+static bool reject_mon(int pm);
 
 /*! \brief Summon some monsters
  *
@@ -45,7 +47,7 @@ int summoning(Coord c, int how_many)
     Offset delta;
     Coord testpos;
     int tryct;
-    int mon;
+    Mon_handle mon;
     int created = 0;
     int pmon;
     for (i = 0; i < how_many; i++)
@@ -98,9 +100,19 @@ int get_random_pmon(void)
     return pm;
 }
 
-int create_mon(int pm_idx, Coord c)
+Mon_handle first_free_mon_handle = 1u;
+static Mon_handle get_first_free_mon(void)
 {
-    int mon;
+    if (first_free_mon_handle == NO_MON)
+    {
+       return NO_MON;
+    }
+    return first_free_mon_handle++;
+}
+
+Mon_handle create_mon(int pm_idx, Coord c)
+{
+    Mon_handle mon;
     if (lvl.mon_at(c) != NO_MON)
     {
         debug_create_mon_occupied(c);
@@ -115,45 +127,44 @@ int create_mon(int pm_idx, Coord c)
             return NO_MON;
         }
     }
-    for (mon = 0; mon < 100; mon++)
-    {
-        if (!monsters[mon].used)
-        {
-            monsters[mon].mon_id = pm_idx;
-            monsters[mon].used = true;
-            monsters[mon].pos = c;
-            monsters[mon].ai_lastpos = Nowhere;
-            monsters[mon].hpmax = permons[pm_idx].hp + ood(permons[pm_idx].power, 1);
-            monsters[mon].hpcur = monsters[mon].hpmax;
-            monsters[mon].mtohit = permons[pm_idx].mtohit + ood(permons[pm_idx].power, 3);
-            monsters[mon].defence = permons[pm_idx].defence + ood(permons[pm_idx].power, 3);
-            monsters[mon].mdam = permons[pm_idx].mdam + ood(permons[pm_idx].power, 5);
-            if (permons[pm_idx].rdam != NO_ATK)
-            {
-                monsters[mon].rtohit = permons[pm_idx].rtohit + ood(permons[pm_idx].power, 3);
-                monsters[mon].rdam = permons[pm_idx].rdam + ood(permons[pm_idx].power, 5);
-            }
-            else
-            {
-                monsters[mon].rtohit = NO_ATK;
-                monsters[mon].rdam = NO_ATK;
-            }
-            monsters[mon].awake = false;
-            lvl.set_mon_at(c, mon);
-            if (mon_visible(mon))
-            {
-                notify_new_mon_at(c, mon);
-            }
-            return mon;
-        }
+    mon = get_first_free_mon();
+    if (mon != NO_MON)
+    {
+       Mon m;
+       m.pm_ref = pm_idx;
+       m.flags = MF_USED | MF_ALIVE;
+       m.pos = c;
+       m.ai_lastpos = Nowhere;
+       m.hpmax = permons[pm_idx].hp + ood(permons[pm_idx].power, 1);
+       m.hpcur = m.hpmax;
+       m.mtohit = permons[pm_idx].mtohit + ood(permons[pm_idx].power, 3);
+       m.defence = permons[pm_idx].defence + ood(permons[pm_idx].power, 3);
+       m.mdam = permons[pm_idx].mdam + ood(permons[pm_idx].power, 5);
+       if (permons[pm_idx].rdam != NO_ATK)
+       {
+           m.rtohit = permons[pm_idx].rtohit + ood(permons[pm_idx].power, 3);
+           m.rdam = permons[pm_idx].rdam + ood(permons[pm_idx].power, 5);
+       }
+       else
+       {
+           m.rtohit = NO_ATK;
+           m.rdam = NO_ATK;
+       }
+       monsters[mon] = m;
+       lvl.set_mon_at(c, mon);
+       if (mon_visible(mon))
+       {
+           notify_new_mon_at(c, mon);
+       }
+       return mon;
     }
     return NO_MON;
 }
 
-void death_drop(int mon)
+void death_drop(Mon_handle mon)
 {
-    Mon *mptr = monsters + mon;
-    int pm = mptr->mon_id;
+    Mon *mptr = mon_snapv(mon);
+    int pm = mptr->pm_ref;
     Coord c = mptr->pos;
     Offset delta;
     int tryct = 0;
@@ -279,7 +290,7 @@ bool Mon::can_pass(Coord c) const
     return true;
 }
 
-void heal_mon(int mon, int amount, int cansee)
+void heal_mon(Mon_handle mon, int amount, int cansee)
 {
     if (amount > (monsters[mon].hpmax - monsters[mon].hpcur))
     {
@@ -295,17 +306,17 @@ void heal_mon(int mon, int amount, int cansee)
     }
 }
 
-void unplace_mon(int mon)
+void unplace_mon(Mon_handle mon)
 {
     lvl.set_mon_at(monsters[mon].pos, NO_MON);
-    monsters[mon].used = false;
+    monsters[mon].flags &= ~MF_USED;
 }
 
 /*! \brief Handle the death of a monster
  *
  * \todo Support special effects on monster death
  */
-void kill_mon(int mon, bool by_you)
+void kill_mon(Mon_handle mon, bool by_you)
 {
     death_drop(mon); // phat lewt!
     monsters[mon].hpcur = -1; // Set HP to -1 so nothing will think it's alive
@@ -313,7 +324,7 @@ void kill_mon(int mon, bool by_you)
     if (by_you)
     {
         notify_player_killed_mon(mon);
-        gain_experience(permons[monsters[mon].mon_id].exp);
+        gain_experience(permons[monsters[mon].pm_ref].exp);
     }
     else if (mon_visible(mon))
     {
@@ -321,10 +332,10 @@ void kill_mon(int mon, bool by_you)
     }
 }
 
-void damage_mon(int mon, int amount, bool by_you)
+void damage_mon(Mon_handle mon, int amount, bool by_you)
 {
     Mon *mptr;
-    mptr = monsters + mon;
+    mptr = mon_snapv(mon);
     if (amount >= mptr->hpcur)
     {
         kill_mon(mon, by_you);
@@ -335,22 +346,22 @@ void damage_mon(int mon, int amount, bool by_you)
     }
 }
 
-int reject_mon(int pm)
+bool reject_mon(int pm)
 {
     if ((permons[pm].power > depth) || (zero_die(100) < permons[pm].rarity))
     {
-        return 1;
+        return true;
     }
-    return 0;
+    return false;
 }
 
-Pass_fail teleport_mon_to_you(int mon)
+Pass_fail teleport_mon_to_you(Mon_handle mon)
 {
     int tryct;
     Offset delta;
     Coord c;
     int success = 0;
-    Mon *mptr = monsters + mon;
+    Mon *mptr = mon_snapv(mon);
     Coord oldpos = mptr->pos;
     for (tryct = 0; tryct < 40; tryct++)
     {
@@ -371,7 +382,7 @@ Pass_fail teleport_mon_to_you(int mon)
     return You_fail;
 }
 
-Pass_fail teleport_mon(int mon)
+Pass_fail teleport_mon(Mon_handle mon)
 {
     Pass_fail rval = You_fail;
     int cell_try;
@@ -389,10 +400,10 @@ Pass_fail teleport_mon(int mon)
     return rval;
 }
 
-int knockback_mon(int mon, Offset step, bool cansee, bool by_you)
+int knockback_mon(Mon_handle mon, Offset step, bool cansee, bool by_you)
 {
     /* 0 = blocked, 1 = knocked, 2 = killed */
-    Mon *mptr = monsters + mon;
+    Mon *mptr = mon_snapv(mon);
     Coord c = mptr->pos + step;
     Coord savedpos = mptr->pos;
     Terrain terr = lvl.terrain_at(c);
@@ -472,9 +483,9 @@ int knockback_mon(int mon, Offset step, bool cansee, bool by_you)
     return 1;
 }
 
-void reloc_mon(int mon, Coord newpos)
+void reloc_mon(Mon_handle mon, Coord newpos)
 {
-    Mon *mptr = monsters + mon;
+    Mon *mptr = mon_snapv(mon);
     lvl.set_mon_at(mptr->pos, NO_MON);
     notify_new_mon_at(mptr->pos, NO_MON);
     mptr->pos = newpos;
@@ -482,10 +493,10 @@ void reloc_mon(int mon, Coord newpos)
     notify_new_mon_at(mptr->pos, mon);
 }
 
-void move_mon(int mon, Coord c)
+void move_mon(Mon_handle mon, Coord c)
 {
     Mon *mptr;
-    mptr = monsters + mon;
+    mptr = mon_snapv(mon);
     if (!mptr->can_pass(c))
     {
         debug_mon_invalid_move(mon, c);
@@ -502,7 +513,7 @@ void move_mon(int mon, Coord c)
 void summon_demon_near(Coord c)
 {
     Coord c2 = c + random_step();
-    int mon;
+    Mon_handle mon;
     if ((lvl.terrain_at(c2) == FLOOR) && (lvl.mon_at(c2) == NO_MON) &&
         (c2 != u.pos))
     {
@@ -511,14 +522,15 @@ void summon_demon_near(Coord c)
     }
 }
 
-bool mon_visible(int mon)
+bool mon_visible(Mon_handle mon)
 {
     Offset delta;
-    if (monsters[mon].used == 0)
+    Mon const *mptr = mon_snap(mon);
+    if (!(mptr->flags & MF_USED))
     {
         return false;
     }
-    delta = monsters[mon].pos.delta(u.pos);
+    delta = mptr->pos.delta(u.pos);
     if (delta.len_cheb() <= MAX_FOV_RADIUS)
     {
         return (player_fov.affected[MAX_FOV_RADIUS + delta.y][MAX_FOV_RADIUS + delta.x]) & Visflag_central;
@@ -529,14 +541,15 @@ bool mon_visible(int mon)
     }
 }
 
-void update_mon(int mon)
+void update_mon(Mon_handle mon)
 {
     int cansee;
-    if (monsters[mon].hpcur < monsters[mon].hpmax)
+    Mon *mptr = mon_snapv(mon);
+    if (mptr->hpcur < mptr->hpmax)
     {
         cansee = mon_visible(mon);
-        // TODO modify regen handling to use flags/fields instead of switching on mon_id
-        switch (monsters[mon].mon_id)
+        // TODO modify regen handling to use flags/fields instead of switching on pm_ref
+        switch (mptr->pm_ref)
         {
         case PM_TROLL:
             if (!(game_tick % 10))
@@ -568,19 +581,19 @@ bool Mon::resists(Damtyp dt) const
     switch (dt)
     {
     case DT_COLD:
-        return pmon_resists_cold(mon_id);
+        return pmon_resists_cold(pm_ref);
     case DT_FIRE:
-        return pmon_resists_fire(mon_id);
+        return pmon_resists_fire(pm_ref);
     case DT_POISON:
-        return pmon_resists_poison(mon_id);
+        return pmon_resists_poison(pm_ref);
     case DT_NECRO:
-        return pmon_resists_necro(mon_id);
+        return pmon_resists_necro(pm_ref);
     case DT_ELEC:
-        return pmon_resists_elec(mon_id);
+        return pmon_resists_elec(pm_ref);
     case DT_KNOCKBACK:
-        return pmon_resists_knockback(mon_id);
+        return pmon_resists_knockback(pm_ref);
     case DT_DROWNING:
-        return pmon_resists_drowning(mon_id);
+        return pmon_resists_drowning(pm_ref);
     default:
         return false;
     }
@@ -588,12 +601,12 @@ bool Mon::resists(Damtyp dt) const
 
 bool Mon::is_ethereal(void) const
 {
-    return pmon_is_ethereal(mon_id);
+    return pmon_is_ethereal(pm_ref);
 }
 
 bool Mon::can_fly(void) const
 {
-    return pmon_can_fly(mon_id);
+    return pmon_can_fly(pm_ref);
 }
 
 /* monsters.c */
index fc8fd38..a845ca0 100644 (file)
 #endif
 
 /* XXX struct mon */
-#define MONSTERS_IN_PLAY 100
+
+#define MF_AWAKE    0x00000001u // gets turns
+#define MF_ALIVE    0x00000002u // gets displayed
+#define MF_USED     0x00000004u // legacy cruft
+
 class Mon {
 public:
-    int mon_id;
+    Mon_handle self;
+    int pm_ref;
     Coord pos;
     Coord ai_lastpos;
-    bool used;
+    uint32_t flags;
     int hpmax;  /* Improved by OOD rating at 1:1. */
     int hpcur;  /* <= 0 is dead. */
     int mtohit; /* Improved by OOD rating at 1:3. */
@@ -54,39 +59,52 @@ public:
     int rdam;   /* Improved by OOD rating at 1:5. */
     bool awake;
     int next_summon;
+    /* member functions only past this point please */
     bool resists(Damtyp dt) const;
     bool can_pass(Coord c) const;
     bool can_fly(void) const;
     bool is_ethereal(void) const;
 };
-extern Mon monsters[MONSTERS_IN_PLAY];
+#include <map>
+extern std::map<Mon_handle, Mon> monsters;
+
+inline Mon *mon_snapv(Mon_handle mon)
+{
+    auto iter = monsters.find(mon);
+    return ((iter == monsters.end()) ? &(iter->second) : nullptr);
+}
+
+inline Mon const *mon_snap(Mon_handle mon)
+{
+    auto iter = monsters.find(mon);
+    return ((iter == monsters.end()) ? &(iter->second) : nullptr);
+}
 
-#define NO_MON (-1)
 #define PLAYER_MON (-2)
 
 /* XXX monsters.c data and funcs */
-extern void update_mon(int mon);
-extern void mon_acts(int mon);
-extern void death_drop(int mon);
-extern void print_mon_name(int mon, int article);
-extern void summon_demon_near(Coord  c);
-extern int create_mon(int pm_idx, Coord c);
-extern int summoning(Coord c, int how_many);
-extern int ood(int power, int ratio);
-extern int get_random_pmon(void);
-extern void damage_mon(int mon, int amount, bool by_you);
-extern bool mon_visible(int mon);
-extern int knockback_mon(int mon, Offset step, bool cansee, bool by_you);
-extern void move_mon(int mon, Coord c);
-extern void reloc_mon(int mon, Coord c);
-extern Pass_fail teleport_mon(int mon);       /* Randomly relocate monster. */
-extern Pass_fail teleport_mon_to_you(int mon);        /* Relocate monster to your vicinity. */
-extern void heal_mon(int mon, int amount, int cansee);
-extern void kill_mon(int mon, bool by_you);
-extern void unplace_mon(int mon);
+void update_mon(Mon_handle mon);
+void mon_acts(Mon_handle mon);
+void death_drop(Mon_handle mon);
+void print_mon_name(Mon_handle mon, int article);
+void summon_demon_near(Coord  c);
+Mon_handle create_mon(int pm_idx, Coord c);
+int summoning(Coord c, int how_many);
+int ood(int power, int ratio);
+int get_random_pmon(void);
+void damage_mon(Mon_handle mon, int amount, bool by_you);
+bool mon_visible(Mon_handle mon);
+int knockback_mon(Mon_handle mon, Offset step, bool cansee, bool by_you);
+void move_mon(Mon_handle mon, Coord c);
+void reloc_mon(Mon_handle mon, Coord c);
+Pass_fail teleport_mon(Mon_handle mon);       /* Randomly relocate monster. */
+Pass_fail teleport_mon_to_you(Mon_handle mon);        /* Relocate monster to your vicinity. */
+void heal_mon(Mon_handle mon, int amount, int cansee);
+void kill_mon(Mon_handle mon, bool by_you);
+void unplace_mon(Mon_handle mon);
 
 /* XXX mon2.c data and funcs */
-extern void select_space(int *py, int *px, int dy, int dx, int selection_mode);
+void select_space(Coord *pc, Offset delta, int selection_mode);
 
 #endif
 
index 0497681..c976ca3 100644 (file)
@@ -274,7 +274,7 @@ void notify_wasted_gain(void)
     print_msg("You feel disappointed.\n");
 }
 
-void notify_summon_help(int mon, bool success)
+void notify_summon_help(Mon_handle mon, bool success)
 {
     /* Do the summoning... */
     print_mon_name(mon, 3);
@@ -289,7 +289,7 @@ void notify_summon_help(int mon, bool success)
     }
 }
 
-void notify_summon_demon(int mon)
+void notify_summon_demon(Mon_handle mon)
 {
     if (mon != NO_MON)
     {
@@ -301,7 +301,7 @@ void notify_summon_demon(int mon)
     }
 }
 
-void notify_mon_disappear(int mon)
+void notify_mon_disappear(Mon_handle mon)
 {
     print_mon_name(mon, 3);
     print_msg(" vanishes in a puff of smoke.\n");
@@ -345,7 +345,7 @@ void notify_hellfire_hit(bool resisted)
     print_msg("The fires of hell %s\n", resisted ? "lightly singe you." : "burn you!");
 }
 
-void notify_monster_cursing(int mon)
+void notify_monster_cursing(Mon_handle mon)
 {
     print_mon_name(mon, 3);
     print_msg(" points at you and curses horribly.\n");
@@ -361,21 +361,21 @@ void notify_knockback_mon_pass(void)
     print_msg("Your foe is knocked backwards by the force of the shot.\n");
 }
 
-void notify_player_miss(int mon)
+void notify_player_miss(Mon_handle mon)
 {
     print_msg("You miss ");
     print_mon_name(mon, 1);
     print_msg(".\n");
 }
 
-void notify_player_hit_mon(int mon)
+void notify_player_hit_mon(Mon_handle mon)
 {
     print_msg("You hit ");
     print_mon_name(mon, 1);
     print_msg(".\n");
 }
 
-void notify_player_combo_powatk(int mon)
+void notify_player_combo_powatk(Mon_handle mon)
 {
     print_msg("You deal a powerful blow to ");
     print_mon_name(mon, 1);
@@ -387,12 +387,12 @@ void notify_point_blank_warning(void)
     print_msg(Msg_prio::Alert, "Using a bow at such close quarters is awkward, and you are unlikely to hit your target.\n");
 }
 
-void notify_player_shot_terrain(int obj, Coord c)
+void notify_player_shot_terrain(Obj_handle obj, Coord c)
 {
-    print_msg("Your %s hits the %s.\n", (objects[obj].obj_id == PO_CROSSBOW) ? "bolt" : "arrow", terrain_props[lvl.terrain_at(c)].name);
+    print_msg("Your %s hits the %s.\n", (objects[obj].po_ref == PO_CROSSBOW) ? "bolt" : "arrow", terrain_props[lvl.terrain_at(c)].name);
 }
 
-void notify_ring_boost(int mon, int pobj)
+void notify_ring_boost(Mon_handle mon, int pobj)
 {
     switch (pobj)
     {
@@ -414,12 +414,12 @@ void notify_ring_boost(int mon, int pobj)
     }
 }
 
-void notify_player_hurt_mon(int mon, int damage)
+void notify_player_hurt_mon(Mon_handle mon, int damage)
 {
     print_msg("You do %d damage.\n", damage);
 }
 
-void notify_player_killed_mon(int mon)
+void notify_player_killed_mon(Mon_handle mon)
 {
     newsym(monsters[mon].pos);
     print_msg("You kill ");
@@ -434,7 +434,7 @@ void notify_player_killed_mon(int mon)
     print_msg("!\n");
 }
 
-void notify_mon_dies(int mon)
+void notify_mon_dies(Mon_handle mon)
 {
     newsym(monsters[mon].pos);
     if (occupant_visible(monsters[mon].pos))
@@ -444,37 +444,37 @@ void notify_mon_dies(int mon)
     }
 }
 
-void notify_knockback_mon_resisted(int mon)
+void notify_knockback_mon_resisted(Mon_handle mon)
 {
     print_mon_name(mon, 3);
     print_msg(" wobbles slightly.\n");
 }
 
-void notify_knockback_mon_blocked(int mon)
+void notify_knockback_mon_blocked(Mon_handle mon)
 {
     print_mon_name(mon, 3);
     print_msg(" is slammed against the wall.\n");
 }
 
-void notify_knockback_mon_hover_lava(int mon)
+void notify_knockback_mon_hover_lava(Mon_handle mon)
 {
     print_mon_name(mon, 3);
     print_msg(" is hurled out over the lava.\n");
 }
 
-void notify_knockback_mon_hover_water(int mon)
+void notify_knockback_mon_hover_water(Mon_handle mon)
 {
     print_mon_name(mon, 3);
     print_msg(" is hurled out over the water.\n");
 }
 
-void notify_knockback_mon_immersed_lava(int mon)
+void notify_knockback_mon_immersed_lava(Mon_handle mon)
 {
     print_mon_name(mon, 3);
     print_msg(" tumbles into a pool of molten rock.\n");
 }
 
-void notify_knockback_mon_immersed_water(int mon)
+void notify_knockback_mon_immersed_water(Mon_handle mon)
 {
     print_mon_name(mon, 3);
     print_msg(" tumbles into the water.\n");
@@ -490,38 +490,38 @@ void notify_knockback_mon_water_offscreen(void)
     print_msg("Splash!\n");
 }
 
-void notify_mon_disappears(int mon, Coord oldpos)
+void notify_mon_disappears(Mon_handle mon, Coord oldpos)
 {
 }
 
-void notify_mon_appears(int mon)
+void notify_mon_appears(Mon_handle mon)
 {
     print_mon_name(mon, 2);
     print_msg(" appears in a puff of smoke.\n");
 }
 
-void notify_mon_hit_armour(int mon)
+void notify_mon_hit_armour(Mon_handle mon)
 {
     print_msg("Your armour deflects ");
     print_mon_name(mon, 1);
     print_msg("'s blow.\n");
 }
 
-void notify_mon_missed_player(int mon)
+void notify_mon_missed_player(Mon_handle mon)
 {
     print_mon_name(mon, 3);
     print_msg(" misses you.\n");
 }
 
-void notify_mon_hit_player(int mon)
+void notify_mon_hit_player(Mon_handle mon)
 {
     print_mon_name(mon, 3);
     print_msg(" hits you.\n");
 }
 
-void notify_mon_ranged_attack(int mon)
+void notify_mon_ranged_attack(Mon_handle mon)
 {
-    int pm = monsters[mon].mon_id;
+    int pm = monsters[mon].pm_ref;
     Damtyp dt = permons[pm].rdtyp;
     print_mon_name(mon, 3);
     if (dt == DT_PHYS)
@@ -540,12 +540,12 @@ void notify_mon_ranged_hit_mon(int er, int ee)
     print_msg("It hits a bystander.\n");
 }
 
-void notify_mon_ranged_missed_player(int mon)
+void notify_mon_ranged_missed_player(Mon_handle mon)
 {
     print_msg("It misses you.\n");
 }
 
-void notify_mon_ranged_hit_player(int mon)
+void notify_mon_ranged_hit_player(Mon_handle mon)
 {
     print_msg("It hits you!\n");
 }
@@ -586,12 +586,12 @@ void notify_zap_powerless_weapon(void)
     print_msg("Your current weapon seems to have no magic powers to activate.\n");
 }
 
-void notify_armour_equip(int obj)
+void notify_armour_equip(Obj_handle obj)
 {
-    Permobj *pobj = permobjs + objects[obj].obj_id;
+    Permobj *pobj = permobjs + objects[obj].po_ref;
     if (pobj->flags[0] & POF_NOTIFY_EQUIP)
     {
-        switch (objects[u.armour].obj_id)
+        switch (objects[u.armour].po_ref)
         {
         case PO_FOETID_VESTMENTS:
             if (u.rotten())
@@ -622,13 +622,13 @@ void notify_armour_equip(int obj)
     }
 }
 
-void notify_armour_unequip(int obj)
+void notify_armour_unequip(Obj_handle obj)
 {
-    Permobj *pobj = permobjs + objects[obj].obj_id;
+    Permobj *pobj = permobjs + objects[obj].po_ref;
     // TODO add unequip messages for NOTIFY_EQUIP armours.
     if (pobj->flags[0] & POF_NOTIFY_EQUIP)
     {
-        switch (objects[obj].obj_id)
+        switch (objects[obj].po_ref)
         {
         case PO_LICHS_ROBE:
             print_msg("The supernatural chill of the robes lingers in your bones even after you put them aside.\n");
@@ -657,14 +657,14 @@ void notify_armour_unequip(int obj)
     }
 }
 
-void notify_ring_equip(int obj)
+void notify_ring_equip(Obj_handle obj)
 {
     print_msg("You put on ");
     print_obj_name(obj);
     print_msg(".\n");
 }
 
-void notify_ring_unequip(int obj)
+void notify_ring_unequip(Obj_handle obj)
 {
     print_msg("You remove your ring.\n");
 }
@@ -735,9 +735,9 @@ void notify_player_ignore_damage(Damtyp dt)
     }
 }
 
-void notify_item_explodes_flames(int obj)
+void notify_item_explodes_flames(Obj_handle obj)
 {
-    print_msg("The %s explodes in flames!\n", permobjs[objects[obj].obj_id].name);
+    print_msg("The %s explodes in flames!\n", permobjs[objects[obj].po_ref].name);
 }
 
 void notify_read_scroll_protection(void)
@@ -789,7 +789,7 @@ void notify_firestaff_activation(int specific)
     }
 }
 
-void notify_fireitem_hit(int mon)
+void notify_fireitem_hit(Mon_handle mon)
 {
     print_mon_name(mon, 3);
     print_msg(" is engulfed in roaring flames.\n");
@@ -866,19 +866,19 @@ void notify_nothing_to_get(void)
     print_msg("Nothing to get.\n");
 }
 
-void notify_mon_healed(int mon)
+void notify_mon_healed(Mon_handle mon)
 {
     print_mon_name(mon, 3);
     print_msg(" looks healthier.\n");
 }
 
-void notify_mon_regenerates(int mon)
+void notify_mon_regenerates(Mon_handle mon)
 {
     // TODO allow things that aren't trolls to be regenerators
     print_msg("The troll regenerates.\n");
 }
 
-void notify_unwield(int obj, Noisiness noisy)
+void notify_unwield(Obj_handle obj, Noisiness noisy)
 {
     if (noisy == Noise_std)
     {
@@ -886,24 +886,24 @@ void notify_unwield(int obj, Noisiness noisy)
     }
 }
 
-void notify_wield_weapon(int obj)
+void notify_wield_weapon(Obj_handle obj)
 {
     print_msg("Wielding ");
     print_obj_name(obj);
     print_msg(".\n");
 }
 
-void notify_weapon_broke(int obj)
+void notify_weapon_broke(Obj_handle obj)
 {
     print_msg(Msg_prio::Warn, "Your weapon breaks!\n");
 }
 
-void notify_armour_broke(int obj)
+void notify_armour_broke(Obj_handle obj)
 {
     print_msg(Msg_prio::Warn, "Your armour is ruined!\n");
 }
 
-void notify_drop_item(int obj)
+void notify_drop_item(Obj_handle obj)
 {
     print_msg("You drop ");
     print_obj_name(obj);
@@ -915,7 +915,7 @@ void notify_drop_blocked(void)
     print_msg(Msg_prio::Alert, "There is no room to drop that here.\n");
 }
 
-void notify_get_item(int from, int slot)
+void notify_get_item(Obj_handle from, int slot)
 {
     if (from != NO_OBJ)
     {
@@ -948,7 +948,7 @@ void notify_pack_full(void)
  * \param c Affected location
  * \param mon Monster at that location.
  */
-void notify_new_mon_at(Coord c, int mon)
+void notify_new_mon_at(Coord c, Mon_handle mon)
 {
     newsym(c);
     display_update();
@@ -1052,9 +1052,9 @@ void debug_read_non_scroll(void)
     print_msg(Msg_prio::Bug, "BUG: reading non-scroll\n");
 }
 
-void debug_eat_non_food(int obj)
+void debug_eat_non_food(Obj_handle obj)
 {
-    print_msg(Msg_prio::Bug, "BUG: attempt to eat non-food (%d)!\n", objects[obj].obj_id);
+    print_msg(Msg_prio::Bug, "BUG: attempt to eat non-food (%d)!\n", objects[obj].po_ref);
 }
 
 void debug_quaff_non_potion(void)
@@ -1137,7 +1137,7 @@ void debug_unimplemented_break_reaction(int po)
     print_msg(Msg_prio::Bug, "BUG: permobj %d should react to hitting durability 0 but has no break reaction handler.\n");
 }
 
-void debug_mon_invalid_move(int mon, Coord c)
+void debug_mon_invalid_move(Mon_handle mon, Coord c)
 {
     print_msg(Msg_prio::Bug, "BUG: monster %d attempted move to impassable location y=%d x=%d\n", mon, c.y, c.x);
 }
index c6778f5..a90d738 100644 (file)
--- a/notify.hh
+++ b/notify.hh
@@ -64,10 +64,10 @@ void notify_cant_go(void);
 // Unsorted notifications
 void notify_obj_at(Coord c);
 void notify_dress_shredded(void);
-void notify_mon_healed(int mon);
-void notify_mon_regenerates(int mon);
-void notify_mon_disappears(int mon, Coord oldpos);
-void notify_mon_appears(int mon);
+void notify_mon_healed(Mon_handle mon);
+void notify_mon_regenerates(Mon_handle mon);
+void notify_mon_disappears(Mon_handle mon, Coord oldpos);
+void notify_mon_appears(Mon_handle mon);
 
 // Item manipulation notifications
 void notify_magic_no_ring(void);
@@ -76,20 +76,20 @@ void notify_zap_no_weapon(void);
 void notify_magic_powerless_ring(void);
 void notify_emanate_powerless_armour(void);
 void notify_zap_powerless_weapon(void);
-void notify_ring_equip(int obj);
-void notify_ring_unequip(int obj);
-void notify_armour_equip(int obj);
-void notify_armour_unequip(int obj);
+void notify_ring_equip(Obj_handle obj);
+void notify_ring_unequip(Obj_handle obj);
+void notify_armour_equip(Obj_handle obj);
+void notify_armour_unequip(Obj_handle obj);
 void notify_lava_blocks_unequip(void);
 void notify_water_blocks_unequip(void);
 void notify_nothing_to_get(void);
-void notify_unwield(int obj, Noisiness noisy);
-void notify_wield_weapon(int obj);
-void notify_weapon_broke(int obj);
-void notify_armour_broke(int obj);
-void notify_drop_item(int obj);
+void notify_unwield(Obj_handle obj, Noisiness noisy);
+void notify_wield_weapon(Obj_handle obj);
+void notify_weapon_broke(Obj_handle obj);
+void notify_armour_broke(Obj_handle obj);
+void notify_drop_item(Obj_handle obj);
 void notify_drop_blocked(void);
-void notify_get_item(int from, int slot);
+void notify_get_item(Obj_handle from, int slot);
 void notify_pack_full(void);
 
 // Magic item use releated notifications
@@ -100,10 +100,10 @@ void notify_quaff_potion_restoration(void);
 void notify_ribbon_activation(int specific);
 void notify_lash_activation(int specific);
 void notify_firestaff_activation(int specific);
-void notify_fireitem_hit(int mon);
+void notify_fireitem_hit(Mon_handle mon);
 void notify_telering_activation(int specific);
 
-void notify_item_explodes_flames(int obj);
+void notify_item_explodes_flames(Obj_handle obj);
 void notify_eat_food(bool ravenous);
 void notify_ingest_spleen(void);
 
@@ -111,43 +111,43 @@ void notify_ingest_spleen(void);
 void notify_swing_bow(void);
 void notify_no_attackee(void);
 void notify_no_flask_target(void);
-void notify_player_miss(int mon);
-void notify_ring_boost(int mon, int pobj);
-void notify_player_hit_mon(int mon);
-void notify_player_hurt_mon(int mon, int damage);
-void notify_player_killed_mon(int mon);
-void notify_player_combo_powatk(int mon);
-void notify_knockback_mon_resisted(int mon);
-void notify_knockback_mon_blocked(int mon);
-void notify_knockback_mon_hover_lava(int mon);
-void notify_knockback_mon_hover_water(int mon);
-void notify_knockback_mon_immersed_lava(int mon);
-void notify_knockback_mon_immersed_water(int mon);
+void notify_player_miss(Mon_handle mon);
+void notify_ring_boost(Mon_handle mon, int pobj);
+void notify_player_hit_mon(Mon_handle mon);
+void notify_player_hurt_mon(Mon_handle mon, int damage);
+void notify_player_killed_mon(Mon_handle mon);
+void notify_player_combo_powatk(Mon_handle mon);
+void notify_knockback_mon_resisted(Mon_handle mon);
+void notify_knockback_mon_blocked(Mon_handle mon);
+void notify_knockback_mon_hover_lava(Mon_handle mon);
+void notify_knockback_mon_hover_water(Mon_handle mon);
+void notify_knockback_mon_immersed_lava(Mon_handle mon);
+void notify_knockback_mon_immersed_water(Mon_handle mon);
 void notify_knockback_mon_water_offscreen(void);
 void notify_knockback_mon_lava_offscreen(void);
 
 void notify_point_blank_warning(void);
-void notify_player_shot_terrain(int obj, Coord c);
-
-void notify_mon_hit_armour(int mon);
-void notify_mon_missed_player(int mon);
-void notify_mon_hit_player(int mon);
-void notify_mon_ranged_attack(int mon);
-void notify_mon_ranged_hit_player(int mon);
-void notify_mon_ranged_missed_player(int mon);
+void notify_player_shot_terrain(Obj_handle obj, Coord c);
+
+void notify_mon_hit_armour(Mon_handle mon);
+void notify_mon_missed_player(Mon_handle mon);
+void notify_mon_hit_player(Mon_handle mon);
+void notify_mon_ranged_attack(Mon_handle mon);
+void notify_mon_ranged_hit_player(Mon_handle mon);
+void notify_mon_ranged_missed_player(Mon_handle mon);
 void notify_mon_ranged_hit_mon(int er, int ee);
-void notify_mon_dies(int mon);
-void notify_new_mon_at(Coord c, int mon);
+void notify_mon_dies(Mon_handle mon);
+void notify_new_mon_at(Coord c, Mon_handle mon);
 
 void notify_player_damage_taken(int amount);
 void notify_player_touch_effect(Damtyp dt);
 void notify_player_ignore_damage(Damtyp dt);
 
 // Sorcery notifications
-void notify_summon_help(int mon, bool success);
-void notify_summon_demon(int mon);
-void notify_monster_cursing(int mon);
-void notify_mon_disappear(int mon);
+void notify_summon_help(Mon_handle mon, bool success);
+void notify_summon_demon(Mon_handle mon);
+void notify_monster_cursing(Mon_handle mon);
+void notify_mon_disappear(Mon_handle mon);
 void notify_moncurse_fail(void);
 void notify_start_armourmelt(void);
 void notify_start_withering(void);
@@ -178,7 +178,7 @@ void debug_take_off_no_armour(void);
 void debug_remove_no_ring(void);
 void debug_put_on_second_ring(void);
 void debug_put_on_uncarried_ring(void);
-void debug_eat_non_food(int obj);
+void debug_eat_non_food(Obj_handle obj);
 void debug_read_non_scroll(void);
 void debug_quaff_non_potion(void);
 void debug_ascend_non_stairs(void);
@@ -190,7 +190,7 @@ void debug_pobj_select_failed(void);
 void debug_misplaced_monster(void);
 void debug_create_mon_occupied(Coord c);
 void debug_monster_pool_exhausted(void);
-void debug_mon_invalid_move(int mon, Coord c);
+void debug_mon_invalid_move(Mon_handle mon, Coord c);
 void debug_pmon_select_failed(void);
 void debug_dump_write_failed(void);
 void debug_unimplemented_activation(int po);
@@ -210,7 +210,7 @@ bool query_wizmode_death(void);
 class Notify_uattkm
 {
 public:
-    int mon;
+    Mon_handle mon;
     bool hit;
     int dmg;
     bool ringflag;
index 46788d3..bd1c47e 100644 (file)
@@ -31,7 +31,9 @@
 #include "objects.hh"
 #include "monsters.hh"
 
-Obj objects[100];
+std::map<Obj_handle, Obj> objects;
+const Obj_handle NO_OBJ = 0u;
+
 int get_random_pobj(void);
 
 char const ring_colours[20][16] = {
@@ -55,11 +57,10 @@ char const potion_colours[20][16] = {
     "navy blue", "bottle green", "amber", "lilac", "ivory"
 };
 
-Action_cost read_scroll(int obj)
+Action_cost read_scroll(Obj_handle obj)
 {
-    Obj *optr = objects + obj;
-    int i;
-    switch (optr->obj_id)
+    Obj *optr = obj_snapv(obj);
+    switch (optr->po_ref)
     {
     case PO_TELEPORT_SCROLL:
         teleport_u();
@@ -74,17 +75,20 @@ Action_cost read_scroll(int obj)
         {
             damage_u(dice(4, 10), DEATH_KILLED, "searing flames");
         }
+#if 0
+       // TODO iterate over visible monsters
         for (i = 0; i < MONSTERS_IN_PLAY; ++i)
         {
             if (mon_visible(i))
             {
-                if (!pmon_resists_fire(monsters[i].mon_id))
+                if (!pmon_resists_fire(monsters[i].pm_ref))
                 {
                     notify_fireitem_hit(i);
                     damage_mon(i, dice(4, 10), true);
                 }
             }
         }
+#endif
         break;
     case PO_PROTECTION_SCROLL:
         notify_read_scroll_protection();
@@ -119,14 +123,15 @@ Action_cost read_scroll(int obj)
     return Cost_std;
 }
 
-bool consume_obj(int obj)
+bool consume_obj(Obj_handle obj)
 {
     int i;
-    objects[obj].quan--;
-    if (objects[obj].quan == 0)
+    Obj *optr = obj_snapv(obj);
+    optr->quan--;
+    if (optr->quan == 0)
     {
-        objects[obj].used = false;
-        if (objects[obj].with_you)
+        optr->flags &= ~OF_USED;
+        if (optr->flags & OF_WITH_YOU)
         {
             if (obj == u.armour)
             {
@@ -145,34 +150,31 @@ bool consume_obj(int obj)
                 u.ring = NO_OBJ;
                 recalc_defence();
             }
-            if (!objects[obj].used)
-            {
-                for (i = 0; i < 19; i++)
-                {
-                    if (u.inventory[i] == obj)
-                    {
-                        u.inventory[i] = NO_OBJ;
-                        break;
-                    }
-                }
-            }
+           for (i = 0; i < 19; i++)
+           {
+               if (u.inventory[i] == obj)
+               {
+                   u.inventory[i] = NO_OBJ;
+                   break;
+               }
+           }
         }
         return true;
     }
     return false;
 }
 
-Action_cost eat_food(int obj)
+Action_cost eat_food(Obj_handle obj)
 {
-    Obj *optr = objects + obj;
+    Obj *optr = obj_snapv(obj);
     bool ravenous = (u.food < 0);
     u.food += 1500;
-    if (permobjs[optr->obj_id].poclass != POCLASS_FOOD)
+    if (permobjs[optr->po_ref].poclass != POCLASS_FOOD)
     {
         debug_eat_non_food(obj);
         return Cost_none;
     }
-    if (optr->obj_id == PO_DEVIL_SPLEEN)
+    if (optr->po_ref == PO_DEVIL_SPLEEN)
     {
         notify_ingest_spleen();
         if (zero_die(2))
@@ -194,10 +196,10 @@ Action_cost eat_food(int obj)
     return Cost_std;
 }
 
-Action_cost quaff_potion(int obj)
+Action_cost quaff_potion(Obj_handle obj)
 {
-    Obj *optr = objects + obj;
-    switch (optr->obj_id)
+    Obj *optr = obj_snapv(obj);
+    switch (optr->po_ref)
     {
     case PO_BODY_POTION:
         gain_body(1);
@@ -307,29 +309,21 @@ void flavours_init(void)
     permobjs[PO_RESTORATION_POTION].power = colour_choices[3];
 }
 
-int get_first_free_obj(void)
+Obj_handle first_free_obj_handle = 1u;
+
+Obj_handle get_first_free_obj(void)
 {
-    int obj;
-    for (obj = 0; obj < 100; obj++)
+    if (first_free_obj_handle == 0u)
     {
-        if (!objects[obj].used)
-        {
-            break;
-        }
+       return NO_OBJ;
     }
-    return (obj == 100) ? NO_OBJ : obj;
+    return first_free_obj_handle++;
 }
 
-int create_obj_class(enum poclass_num po_class, int quantity, bool with_you, Coord c)
+Obj_handle create_obj_class(enum poclass_num po_class, int quantity, bool with_you, Coord c)
 {
     int po_idx;
     int tryct;
-    int obj = get_first_free_obj();
-    if (obj == 100)
-    {
-        debug_object_pool_exhausted();
-        return NO_OBJ;
-    }
     for (tryct = 0; tryct < 200; tryct++)
     {
         switch (po_class)
@@ -353,9 +347,7 @@ int create_obj_class(enum poclass_num po_class, int quantity, bool with_you, Coo
         }
         break;
     }
-    objects[obj].obj_id = po_idx;
-    objects[obj].quan = quantity;
-    return obj;
+    return create_obj(po_idx, quantity, with_you, c);
 }
 
 int get_random_pobj(void)
@@ -370,9 +362,6 @@ int get_random_pobj(void)
             po_idx = NO_POBJ;
             continue;
         }
-        /* v1.3: Do not permit generation of particularly powerful
-         * items (runeswords, mage armour, etc.) at shallow depths.
-         * (game balance fix) */
         if (depth < permobjs[po_idx].depth)
         {
             po_idx = NO_POBJ;
@@ -383,10 +372,10 @@ int get_random_pobj(void)
     return po_idx;
 }
 
-int create_obj(int po_idx, int quantity, bool with_you, Coord c)
+Obj_handle create_obj(int po_idx, int quantity, bool with_you, Coord c)
 {
-    int obj = get_first_free_obj();
-    if (obj == 100)
+    Obj_handle obj = get_first_free_obj();
+    if (obj == NO_OBJ)
     {
         debug_object_pool_exhausted();
         return NO_OBJ;
@@ -400,11 +389,11 @@ int create_obj(int po_idx, int quantity, bool with_you, Coord c)
             return NO_OBJ;
         }
     }
-    objects[obj].obj_id = po_idx;
-    objects[obj].with_you = with_you;
-    objects[obj].used = true;
-    objects[obj].pos = c;
-    objects[obj].quan = quantity;
+    Obj o;
+    o.po_ref = po_idx;
+    o.flags = OF_USED | (with_you ? OF_WITH_YOU : 0);
+    o.pos = c;
+    o.quan = quantity;
     switch (permobjs[po_idx].poclass)
     {
     case POCLASS_WEAPON:
@@ -412,29 +401,29 @@ int create_obj(int po_idx, int quantity, bool with_you, Coord c)
         /* Set durability of weapons and armour to a suitable value.
          * 100 has been chosen for the moment, but this may need
          * tuning. */
-        objects[obj].durability = OBJ_MAX_DUR;
+        o.durability = OBJ_MAX_DUR;
         break;
     default:
         break;
     }
-    if (!objects[obj].with_you)
+    if (!(o.flags & OF_WITH_YOU))
     {
         lvl.set_obj_at(c, obj);
     }
     return obj;
 }
 
-void sprint_obj_name(char *buf, int obj, int len)
+void sprint_obj_name(char *buf, Obj_handle obj, int len)
 {
     Obj *optr;
     Permobj *poptr;
-    optr = objects + obj;
-    poptr = permobjs + optr->obj_id;
+    optr = obj_snapv(obj);
+    poptr = permobjs + optr->po_ref;
     if (optr->quan > 1)
     {
         snprintf(buf, len, "%d %s", optr->quan, poptr->plural);
     }
-    else if (po_is_stackable(optr->obj_id))
+    else if (po_is_stackable(optr->po_ref))
     {
         snprintf(buf, len, "1 %s", poptr->name);
     }
@@ -449,17 +438,17 @@ void sprint_obj_name(char *buf, int obj, int len)
     }
 }
 
-void fprint_obj_name(FILE *fp, int obj)
+void fprint_obj_name(FILE *fp, Obj_handle obj)
 {
     Obj *optr;
     Permobj *poptr;
-    optr = objects + obj;
-    poptr = permobjs + optr->obj_id;
+    optr = obj_snapv(obj);
+    poptr = permobjs + optr->po_ref;
     if (optr->quan > 1)
     {
         fprintf(fp, "%d %s", optr->quan, poptr->plural);
     }
-    else if (po_is_stackable(optr->obj_id))
+    else if (po_is_stackable(optr->po_ref))
     {
         fprintf(fp, "1 %s", poptr->name);
     }
@@ -477,7 +466,7 @@ void fprint_obj_name(FILE *fp, int obj)
 Action_cost drop_obj(int inv_idx)
 {
     Obj *optr;
-    optr = objects + u.inventory[inv_idx];
+    optr = obj_snapv(u.inventory[inv_idx]);
     if (lvl.obj_at(u.pos) == NO_OBJ)
     {
         optr->pos = u.pos;
@@ -487,7 +476,7 @@ Action_cost drop_obj(int inv_idx)
             u.weapon = NO_OBJ;
         }
         u.inventory[inv_idx] = NO_OBJ;
-        optr->with_you = false;
+        optr->flags &= ~OF_WITH_YOU;
         notify_drop_item(lvl.obj_at(u.pos));
         return Cost_std;
     }
@@ -515,16 +504,16 @@ void attempt_pickup(void)
 {
     int i;
     int stackable;
-    stackable = po_is_stackable(objects[lvl.obj_at(u.pos)].obj_id);
+    stackable = po_is_stackable(objects[lvl.obj_at(u.pos)].po_ref);
     if (stackable)
     {
         for (i = 0; i < 19; i++)
         {
-            if ((objects[u.inventory[i]].obj_id == objects[lvl.obj_at(u.pos)].obj_id))
+            if ((objects[u.inventory[i]].po_ref == objects[lvl.obj_at(u.pos)].po_ref))
             {
                 int stale_obj = lvl.obj_at(u.pos);
                 objects[u.inventory[i]].quan += objects[lvl.obj_at(u.pos)].quan;
-                objects[stale_obj].used = false;
+                objects[stale_obj].flags &= ~OF_USED;
                 lvl.set_obj_at(u.pos, NO_OBJ);
                 notify_get_item(stale_obj, i);
                 return;
@@ -545,14 +534,14 @@ void attempt_pickup(void)
     }
     u.inventory[i] = lvl.obj_at(u.pos);
     lvl.set_obj_at(u.pos, NO_OBJ);
-    objects[u.inventory[i]].with_you = true;
+    objects[u.inventory[i]].flags |= OF_WITH_YOU;
     objects[u.inventory[i]].pos = Nowhere;
     notify_get_item(NO_OBJ, i);
 }
 
-void break_reaction(int obj)
+void break_reaction(Obj_handle obj)
 {
-    switch (objects[obj].obj_id)
+    switch (objects[obj].po_ref)
     {
     case PO_TORMENTORS_LASH:
         if (u.food < 500)
@@ -572,22 +561,22 @@ void break_reaction(int obj)
         break;
 
     default:
-        if (permobjs[objects[obj].obj_id].flags[0] & POF_DRESS)
+        if (permobjs[objects[obj].po_ref].flags[0] & POF_DRESS)
         {
             objects[obj].durability = 50 + zero_die(51);
-            objects[obj].obj_id = PO_RAGGED_SHIFT;
+            objects[obj].po_ref = PO_RAGGED_SHIFT;
             notify_dress_shredded();
             recalc_defence();
         }
         else
         {
-            debug_unimplemented_break_reaction(objects[obj].obj_id);
+            debug_unimplemented_break_reaction(objects[obj].po_ref);
         }
         break;
     }
 }
 
-void damage_obj(int obj)
+void damage_obj(Obj_handle obj)
 {
     /* Only weapons and armour have non-zero durability. */
     if (objects[obj].durability == 0)
@@ -598,26 +587,26 @@ void damage_obj(int obj)
     else
     {
         objects[obj].durability--;
-        if ((objects[obj].durability == 0) && (permobjs[objects[obj].obj_id].flags[0] & POF_BREAK_REACT))
+        if ((objects[obj].durability == 0) && (permobjs[objects[obj].po_ref].flags[0] & POF_BREAK_REACT))
         {
             break_reaction(obj);
         }
     }
 } 
 
-int evasion_penalty(int obj)
+int evasion_penalty(Obj_handle obj)
 {
-    if (permobjs[objects[obj].obj_id].poclass == POCLASS_ARMOUR)
+    if (permobjs[objects[obj].po_ref].poclass == POCLASS_ARMOUR)
     {
-        return permobjs[objects[obj].obj_id].power2;
+        return permobjs[objects[obj].po_ref].power2;
     }
     return 100;
 }
 
 Action_cost magic_ring(void)
 {
-    Obj *optr = objects + u.ring;
-    switch (optr->obj_id)
+    Obj *optr = obj_snapv(u.ring);
+    switch (optr->po_ref)
     {
     case PO_TELEPORT_RING:
         if (u.food >= 50)
@@ -633,9 +622,9 @@ Action_cost magic_ring(void)
         }
         return Cost_none;
     default:
-        if (permobjs[optr->obj_id].flags[0] & POF_ACTIVATABLE)
+        if (permobjs[optr->po_ref].flags[0] & POF_ACTIVATABLE)
         {
-            debug_unimplemented_activation(optr->obj_id);
+            debug_unimplemented_activation(optr->po_ref);
         }
         else
         {
@@ -647,13 +636,13 @@ Action_cost magic_ring(void)
 
 Action_cost emanate_armour(void)
 {
-    Obj *optr = objects + u.armour;
-    switch (optr->obj_id)
+    Obj *optr = obj_snapv(u.armour);
+    switch (optr->po_ref)
     {
     default:
-        if (permobjs[optr->obj_id].flags[0] & POF_ACTIVATABLE)
+        if (permobjs[optr->po_ref].flags[0] & POF_ACTIVATABLE)
         {
-            debug_unimplemented_activation(optr->obj_id);
+            debug_unimplemented_activation(optr->po_ref);
         }
         else
         {
@@ -666,8 +655,8 @@ Action_cost emanate_armour(void)
 
 Action_cost zap_weapon(void)
 {
-    Obj *optr = objects + u.weapon;
-    switch (optr->obj_id)
+    Obj *optr = obj_snapv(u.weapon);
+    switch (optr->po_ref)
     {
     case PO_STAFF_OF_FIRE:
         if (u.food > 150)
@@ -683,7 +672,7 @@ Action_cost zap_weapon(void)
                 }
                 for (c.x = u.pos.x - 1; c.x <= u.pos.x + 1; ++c.x)
                 {
-                    int mon;
+                    Mon_handle mon;
                     if ((c.x < lvl.min_x()) || (c.x >= lvl.max_x()))
                     {
                         continue;
@@ -691,8 +680,8 @@ Action_cost zap_weapon(void)
                     mon = lvl.mon_at(c);
                     if (mon != NO_MON)
                     {
-                        Mon *mptr = monsters + mon;
-                        if (!pmon_resists_fire(mptr->mon_id))
+                        Mon *mptr = mon_snapv(mon);
+                        if (!pmon_resists_fire(mptr->pm_ref))
                         {
                             notify_fireitem_hit(mon);
                             damage_mon(mon, dice(4, 10), true);
@@ -709,9 +698,9 @@ Action_cost zap_weapon(void)
         }
         return Cost_std;
     default:
-        if (permobjs[optr->obj_id].flags[0] & POF_ACTIVATABLE)
+        if (permobjs[optr->po_ref].flags[0] & POF_ACTIVATABLE)
         {
-            debug_unimplemented_activation(optr->obj_id);
+            debug_unimplemented_activation(optr->po_ref);
         }
         else
         {
@@ -740,28 +729,26 @@ Action_cost player_unwield(Noisiness noisy)
     return Cost_std;
 }
 
-Action_cost player_wield(int slot, Noisiness noisy)
+Action_cost player_wield(Obj_handle obj, Noisiness noisy)
 {
     if (u.weapon != NO_OBJ)
     {
         player_unwield(Noise_low);
     }
-    u.weapon = u.inventory[slot];
+    u.weapon = obj;
     notify_wield_weapon(u.weapon);
     recalc_defence();
     return Cost_std;
 }
 
-Action_cost wear_armour(int slot)
+Action_cost wear_armour(Obj_handle obj)
 {
-    int obj;
     if (u.armour != NO_OBJ)
     {
         debug_wear_while_wearing();
         return Cost_none;
     }
-    obj = u.inventory[slot];
-    if (!objects[obj].with_you)
+    if (!(objects[obj].flags & OF_WITH_YOU))
     {
         debug_wear_uncarried_armour();
         return Cost_none;
@@ -772,14 +759,14 @@ Action_cost wear_armour(int slot)
     return Cost_std;
 }
 
-Action_cost put_on_ring(int obj)
+Action_cost put_on_ring(Obj_handle obj)
 {
     if (u.ring != NO_OBJ)
     {
         debug_put_on_second_ring();
         return Cost_none;
     }
-    if (!objects[obj].with_you)
+    if (!(objects[obj].flags & OF_WITH_YOU))
     {
         debug_put_on_uncarried_ring();
         return Cost_none;
@@ -814,7 +801,7 @@ Pass_fail ring_removal_unsafe(Noisiness noisy)
         }
         return You_fail;
     }
-    else if ((objects[u.ring].obj_id == PO_FROST_RING) && (lvl.terrain_at(u.pos) == WATER))
+    else if ((objects[u.ring].po_ref == PO_FROST_RING) && (lvl.terrain_at(u.pos) == WATER))
     {
         if (noisy != Noise_silent)
         {
index 719c9e1..689a992 100644 (file)
 #include "permobj.hh"
 #endif
 
+#include <map>
 /* XXX Obj */
 #define OBJ_MAX_DUR 100
 #define OBJECTS_IN_PLAY 100
+#define OF_USED            0x00000001u
+#define OF_WITH_YOU 0x00000002u
 class Obj {
 public:
-    int obj_id;
-    bool used;   /* Entry is occupied. */
-    bool with_you;       /* Preserved when item DB is reaped on level change. */
+    Obj_handle self;
+    int po_ref;
+    uint32_t flags;
     int quan;
     Coord pos;
     int durability;     /* Weapons and armour degrade with use. */
 };
-extern Obj objects[OBJECTS_IN_PLAY];
+extern std::map<Obj_handle, Obj> objects;
 
-#define NO_OBJ (-1)
+/* XXX objects.cc data and funcs */
+void sprint_obj_name(char *s, Obj_handle obj, int len);
+void fprint_obj_name(FILE *fp, Obj_handle obj);
+void describe_object(Obj_handle obj);
+Obj_handle create_obj(int po_idx, int quantity, bool with_you, Coord c);
+bool consume_obj(Obj_handle obj);
+Obj_handle create_obj_class(enum poclass_num pocl, int quantity, bool with_you, Coord c);
+void damage_obj(Obj_handle obj);
+int evasion_penalty(Obj_handle obj);
 
-/* XXX objects.c data and funcs */
-extern void flavours_init(void);
-extern void sprint_obj_name(char *s, int obj, int len);
-extern void fprint_obj_name(FILE *fp, int obj);
-extern void print_obj_name(int obj);
-extern void describe_object(int obj);
-extern int create_obj(int po_idx, int quantity, bool with_you, Coord c);
-extern bool consume_obj(int obj);
-extern int create_obj_class(enum poclass_num pocl, int quantity, bool with_you, Coord c);
-extern void damage_obj(int obj);
-extern int evasion_penalty(int obj);
+inline Obj *obj_snapv(Obj_handle obj)
+{
+    auto iter = objects.find(obj);
+    return ((iter == objects.end()) ? &(iter->second) : nullptr);
+}
 
-extern Action_cost drop_obj(int inv_idx);
-extern Action_cost put_on_ring(int obj);
-extern Action_cost remove_ring(void);
-extern Action_cost wear_armour(int obj);
-extern Action_cost take_off_armour(void);
-extern Action_cost read_scroll(int obj);
-extern Action_cost quaff_potion(int obj);
-extern Action_cost eat_food(int obj);
-extern Action_cost magic_ring(void);
-extern Action_cost emanate_armour(void);
-extern Action_cost zap_weapon(void);
-extern Action_cost player_unwield(Noisiness noisy = Noise_std);
-extern Action_cost player_wield(int slot, Noisiness noisy = Noise_std);
-extern void attempt_pickup(void);
+inline Obj const *obj_snap(Obj_handle obj)
+{
+    auto iter = objects.find(obj);
+    return ((iter == objects.end()) ? &(iter->second) : nullptr);
+}
 
-extern Pass_fail ring_removal_unsafe(Noisiness noisy = Noise_std);
-extern Pass_fail armour_removal_unsafe(Noisiness noisy = Noise_std);
+Action_cost drop_obj(int inv_idx);
+Action_cost put_on_ring(Obj_handle obj);
+Action_cost remove_ring(void);
+Action_cost wear_armour(Obj_handle obj);
+Action_cost take_off_armour(void);
+Action_cost read_scroll(Obj_handle obj);
+Action_cost quaff_potion(Obj_handle obj);
+Action_cost eat_food(Obj_handle obj);
+Action_cost magic_ring(void);
+Action_cost emanate_armour(void);
+Action_cost zap_weapon(void);
+Action_cost player_unwield(Noisiness noisy = Noise_std);
+Action_cost player_wield(Obj_handle obj, Noisiness noisy = Noise_std);
+void attempt_pickup(void);
+
+Pass_fail ring_removal_unsafe(Noisiness noisy = Noise_std);
+Pass_fail armour_removal_unsafe(Noisiness noisy = Noise_std);
 
 #endif
 
index 6913afe..b7fb924 100644 (file)
--- a/player.hh
+++ b/player.hh
@@ -53,10 +53,10 @@ public:
     int speed;      //!< Controls how often you act.
     uint32_t resistances[DT_COUNT]; //!< Resistance masks per damage type
     int level;      //!< Current experience level.
-    int inventory[19];  //!< Object handles of currently carried items.
-    int weapon;     //!< Object handle of currently equipped weapon.
-    int armour;     //!< Object handle of currently equipped armour.
-    int ring;       //!< Object handle of currently equipped ring.
+    Obj_handle inventory[19];  //!< currently carried items.
+    Obj_handle weapon;     //!< currently equipped weapon.
+    Obj_handle armour;     //!< currently equipped armour.
+    Obj_handle ring;       //!< currently equipped ring.
     int sympathy[TOTAL_FELL_POWERS]; //!< Level of alignment with fell powers
     /* Methods only after here plzkthx */
     bool resists(Damtyp dtype) const; //!< Does player resist this Damtyp?
index 1f00063..573ed0a 100644 (file)
--- a/shrine.cc
+++ b/shrine.cc
@@ -106,7 +106,7 @@ struct shrine shrines[4] =
 };
 
 /*! \brief Construction helper for shrines */
-void place_shrine(Coord topleft, shrine const *sh, uint32_t accept_conns, Terrain shwall, Terrain shfloor, bool margin_is_wall)
+void place_shrine(Level *l, Coord topleft, shrine const *sh, uint32_t accept_conns, Terrain shwall, Terrain shfloor, bool margin_is_wall)
 {
     Coord c;
     Coord start;
@@ -165,38 +165,38 @@ void place_shrine(Coord topleft, shrine const *sh, uint32_t accept_conns, Terrai
             switch (sh->grid[shy][shx])
             {
             case '0':
-                lvl.set_terrain_at(c, shfloor);
+                l->set_terrain_at(c, shfloor);
                 /* We want to be able to slap this down as a room, which means
                  * that at least one square on the connectable edges must not
                  * be HARDWALL. Those squares are marked '0'. */
                 break;
             case '1':
-                lvl.set_terrain_at(c, margin_is_wall ? shwall : shfloor);
-                lvl.set_flags_at(c, MAPFLAG_HARDWALL);
+                l->set_terrain_at(c, margin_is_wall ? shwall : shfloor);
+                l->set_flags_at(c, MAPFLAG_HARDWALL);
                 break;
             case '.':
-                lvl.set_terrain_at(c, shfloor);
-                lvl.set_flags_at(c, MAPFLAG_HARDWALL);
+                l->set_terrain_at(c, shfloor);
+                l->set_flags_at(c, MAPFLAG_HARDWALL);
                 break;
             case '#':
-                lvl.set_terrain_at(c, shwall);
-                lvl.set_flags_at(c, MAPFLAG_HARDWALL);
+                l->set_terrain_at(c, shwall);
+                l->set_flags_at(c, MAPFLAG_HARDWALL);
                 break;
             case '+':
-                lvl.set_terrain_at(c, DOOR);
-                lvl.set_flags_at(c, MAPFLAG_HARDWALL);
+                l->set_terrain_at(c, DOOR);
+                l->set_flags_at(c, MAPFLAG_HARDWALL);
                 break;
             case '_':
-                lvl.set_terrain_at(c, ALTAR);
-                lvl.set_flags_at(c, MAPFLAG_HARDWALL);
+                l->set_terrain_at(c, ALTAR);
+                l->set_flags_at(c, MAPFLAG_HARDWALL);
                 break;
             case 'L':
-                lvl.set_terrain_at(c, LAVA);
-                lvl.set_flags_at(c, MAPFLAG_HARDWALL);
+                l->set_terrain_at(c, LAVA);
+                l->set_flags_at(c, MAPFLAG_HARDWALL);
                 break;
             case 'W':
-                lvl.set_terrain_at(c, WATER);
-                lvl.set_flags_at(c, MAPFLAG_HARDWALL);
+                l->set_terrain_at(c, WATER);
+                l->set_flags_at(c, MAPFLAG_HARDWALL);
                 break;
             }
         }
@@ -205,7 +205,7 @@ void place_shrine(Coord topleft, shrine const *sh, uint32_t accept_conns, Terrai
 }
 
 /*! \brief Excavate a cave-with-shrine level. */
-void build_level_shrine(void)
+void build_level_shrine(Level *l)
 {
     Coord shrinepos = { inc_flat(GUIDE_EDGE_SIZE / 4, GUIDE_EDGE_SIZE / 2), inc_flat(GUIDE_EDGE_SIZE / 4, GUIDE_EDGE_SIZE / 2) };
     Coord c;
@@ -217,11 +217,11 @@ void build_level_shrine(void)
     int intrusions;
     int i;
 
-    initialize_chunks(&lvl, GUIDE_EDGE_CHUNKS, GUIDE_EDGE_CHUNKS, true);
+    initialize_chunks(l, GUIDE_EDGE_CHUNKS, GUIDE_EDGE_CHUNKS, true);
     intrusions = dice(2, 4) - 1;
     for (i = 0; i < 6; ++i)
     {
-        place_random_intrusion(WALL);
+        place_random_intrusion(l, WALL);
     }
     switch (zero_die(4))
     {
@@ -253,12 +253,12 @@ void build_level_shrine(void)
         c3 = c + North;
         mask = ROOMCONN_EAST;
     }
-    place_shrine(shrinepos, shrines + shrine_num, mask);
-    lvl.set_terrain_at(c, FLOOR);
-    lvl.set_terrain_at(c2, FLOOR);
-    lvl.set_terrain_at(c3, FLOOR);
-    run_random_walk_unbounded(c, excavation_write, walk_data, LEVGEN_WALK_CELLS);
-    place_cave_stairs();
+    place_shrine(l, shrinepos, shrines + shrine_num, mask);
+    l->set_terrain_at(c, FLOOR);
+    l->set_terrain_at(c2, FLOOR);
+    l->set_terrain_at(c3, FLOOR);
+    run_random_walk_unbounded(l, c, excavation_write, walk_data, LEVGEN_WALK_CELLS);
+    place_cave_stairs(l);
 }
 
 /* shrine.cc */
index e6b03b3..021be67 100644 (file)
@@ -68,7 +68,7 @@ int mon_use_sorcery(int mon)
 {
     /* Returns zero for no spell selected, -1 for unsupported spell
      * selected, 1 for supported spell selected. */
-    Mon *mptr = monsters + mon;
+    Mon *mptr = mon_snapv(mon);
     Offset delta = u.pos.delta(mptr->pos);
     Offset step = mysign(delta);
     enum monspell to_cast = MS_REJECT;
@@ -81,7 +81,7 @@ int mon_use_sorcery(int mon)
     bool cansee = mon_visible(mon);
     int i;
 
-    switch (monsters[mon].mon_id)
+    switch (monsters[mon].pm_ref)
     {
     case PM_ARCHMAGE:
         if (cansee)
@@ -434,7 +434,7 @@ int mon_use_sorcery(int mon)
         }
         else
         {
-            damage_u(dice(1, 20), DEATH_KILLED_MON, permons[monsters[mon].mon_id].name);
+            damage_u(dice(1, 20), DEATH_KILLED_MON, permons[monsters[mon].pm_ref].name);
         }
         break;
 
@@ -443,11 +443,11 @@ int mon_use_sorcery(int mon)
         notify_hellfire_hit(u.resists(DT_FIRE));
         if (u.resists(DT_FIRE))
         {
-            damage_u(dice(1, 5), DEATH_KILLED_MON, permons[monsters[mon].mon_id].name);
+            damage_u(dice(1, 5), DEATH_KILLED_MON, permons[monsters[mon].pm_ref].name);
         }
         else
         {
-            damage_u(dice(1, 20), DEATH_KILLED_MON, permons[monsters[mon].mon_id].name);
+            damage_u(dice(1, 20), DEATH_KILLED_MON, permons[monsters[mon].pm_ref].name);
         }
         break;
     }
diff --git a/u.cc b/u.cc
index ce957bf..e0bce27 100644 (file)
--- a/u.cc
+++ b/u.cc
@@ -40,12 +40,12 @@ struct Player u;
 
 bool wielding_ranged_weapon(void)
 {
-    return permobjs[objects[u.weapon].obj_id].flags[0] & POF_RANGED_WEAPON;
+    return permobjs[objects[u.weapon].po_ref].flags[0] & POF_RANGED_WEAPON;
 }
 
 bool wielding_melee_weapon(void)
 {
-    return permobjs[objects[u.weapon].obj_id].flags[0] & POF_MELEE_WEAPON;
+    return permobjs[objects[u.weapon].po_ref].flags[0] & POF_MELEE_WEAPON;
 }
 
 void recalc_defence(void)
@@ -58,9 +58,9 @@ void recalc_defence(void)
     u.speed = (u.leadfoot ? 0 : 1);
     if (u.armour != NO_OBJ)
     {
-        u.defence = u.armourmelt ? 0 : permobjs[objects[u.armour].obj_id].power;
+        u.defence = u.armourmelt ? 0 : permobjs[objects[u.armour].po_ref].power;
         u.defence += u.withering ? (u.agility / 10) : (u.agility / 5);
-        switch (objects[u.armour].obj_id)
+        switch (objects[u.armour].po_ref)
         {
         case PO_DRAGONHIDE_ARMOUR:
         case PO_METEORIC_PLATE_ARMOUR:
@@ -79,7 +79,7 @@ void recalc_defence(void)
     }
     if (u.ring != NO_OBJ)
     {
-        switch (objects[u.ring].obj_id)
+        switch (objects[u.ring].po_ref)
         {
         case PO_FIRE_RING:
             u.resistances[DT_FIRE] |= RESIST_RING;
@@ -107,9 +107,9 @@ Action_cost move_player(Offset delta)
     {
         if (u.weapon != NO_OBJ)
         {
-            if ((objects[u.weapon].obj_id == PO_BOW) ||
-                (objects[u.weapon].obj_id == PO_CROSSBOW) ||
-                (objects[u.weapon].obj_id == PO_THUNDERBOW))
+            if ((objects[u.weapon].po_ref == PO_BOW) ||
+                (objects[u.weapon].po_ref == PO_CROSSBOW) ||
+                (objects[u.weapon].po_ref == PO_THUNDERBOW))
             {
                 notify_swing_bow();
                 return Cost_none;
@@ -154,7 +154,7 @@ Action_cost move_player(Offset delta)
             return Cost_none;
         }
     case WATER:
-        if ((u.ring != NO_OBJ) && (objects[u.ring].obj_id == PO_FROST_RING))
+        if ((u.ring != NO_OBJ) && (objects[u.ring].po_ref == PO_FROST_RING))
         {
             if (lvl.terrain_at(u.pos) != WATER)
             {
@@ -447,7 +447,7 @@ void update_player(void)
      * working, and like normal regen, it won't raise you above 75% HP if
      * your food counter is negative. */
     if (((game_tick % 10) == 5) &&
-        (objects[u.ring].obj_id == PO_REGENERATION_RING) &&
+        (objects[u.ring].po_ref == PO_REGENERATION_RING) &&
         (u.hpcur < ((u.food >= 0) ? u.hpmax : ((u.hpmax * 3) / 4))) &&
         (u.food > MIN_FOOD))
     {
@@ -460,7 +460,7 @@ void update_player(void)
     {
         int food_use = 1;
         int squeal = 0;
-        if ((objects[u.ring].obj_id == PO_REGENERATION_RING) && !(game_tick % 2) && (u.food > MIN_FOOD))
+        if ((objects[u.ring].po_ref == PO_REGENERATION_RING) && !(game_tick % 2) && (u.food > MIN_FOOD))
         {
             /* If you are still less hungry than MIN_FOOD nutrition,
              * use one more food every second tick if you are
@@ -547,7 +547,7 @@ enum Combo_phase
 bool action_rewrite(Action const *act, Action *revised_act)
 {
     Coord c = u.pos;
-    int mon = NO_MON;
+    Mon_handle mon = NO_MON;
     Offset o;
     Action tmp_act = *act;
     Combo_phase p;