int len_cheb(void) const { return std::max(myabs(y), myabs(x)); }
int len_taxi(void) const { return myabs(y) + myabs(x); }
int lensq_eucl(void) const { return y * y + x * x; }
- const Offset& operator +=(const Offset& right) { y += right.y; x += right.x; return *this; }
- const Offset& operator -=(const Offset& right) { y -= right.y; x -= right.x; return *this; }
- bool operator !=(const Offset& right) const { return (y != right.y) || (x != right.x); }
- bool operator ==(const Offset& right) const { return (y == right.y) && (x == right.x); }
+ Offset const& operator +=(Offset const& right) { y += right.y; x += right.x; return *this; }
+ Offset const& operator -=(Offset const& right) { y -= right.y; x -= right.x; return *this; }
+ bool operator !=(Offset const& right) const { return (y != right.y) || (x != right.x); }
+ bool operator ==(Offset const& right) const { return (y == right.y) && (x == right.x); }
};
struct Coord
{
int y;
int x;
- int dist_cheb(const Coord& right) const { return std::max(myabs(y - right.y), myabs(x - right.x)); }
- int dist_taxi(const Coord& right) const { return myabs(y - right.y) + myabs(x - right.x); }
- int distsq_eucl(const Coord& right) const { return (y - right.y) * (y - right.y) + (x - right.x) * (x - right.x); }
- Offset delta(const Coord& right) const { Offset d = { y - right.y, x - right.x }; return d; }
- Coord operator +(const Offset& right) const { Coord c = { y + right.y, x + right.x}; return c; }
- Coord operator -(const Offset& right) const { Coord c = { y - right.y, x - right.x}; return c; }
- const Coord& operator +=(const Offset& right) { y += right.y; x += right.x; return *this;}
- const Coord& operator -=(const Offset& right) { y -= right.y; x -= right.x; return *this;}
- bool operator !=(const Coord& right) const { return (y != right.y) || (x != right.x); }
- bool operator ==(const Coord& right) const { return (y == right.y) && (x == right.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); }
+ Offset delta(Coord const& right) const { Offset d = { y - right.y, x - right.x }; return d; }
+ Coord operator +(Offset const& right) const { Coord c = { y + right.y, x + right.x}; return c; }
+ Coord operator -(Offset const& right) const { Coord c = { y - right.y, x - right.x}; return c; }
+ Coord const& operator +=(Offset const& right) { y += right.y; x += right.x; return *this;}
+ Coord const& operator -=(Offset const& right) { y -= right.y; x -= right.x; return *this;}
+ bool operator !=(Coord const& right) const { return (y != right.y) || (x != right.x); }
+ bool operator ==(Coord const& right) const { return (y == right.y) && (x == right.x); }
};
-extern const Coord Nowhere;
-extern const Offset North, Northeast, East, Southeast, South, Southwest, West, Northwest, Stationary;
+extern Coord const Nowhere;
+extern Offset const North, Northeast, East, Southeast, South, Southwest, West, Northwest, Stationary;
template<> inline Coord myabs<Coord>(Coord val) { Coord c = { myabs(val.y), myabs(val.x) }; return c; }
template<> inline Offset myabs<Offset>(Offset val) { Offset o = { myabs(val.y), myabs(val.x) }; return o; }
#define DISP_NC_RADIUS (10)
#define DISP_NC_SIDE (DISP_NC_RADIUS * 2 + 1)
-void set_inventory_message(const char *s, bool allow_nil);
+void set_inventory_message(char const *s, bool allow_nil);
void reset_inventory_message(void);
void hide_inv(void);
void show_inv(void);
cchar_t blank_tile;
cchar_t player_tile;
-const cchar_t *back_buffer[DUN_HEIGHT][DUN_WIDTH];
-const cchar_t *front_buffer[DISP_HEIGHT][DISP_WIDTH];
+cchar_t const *back_buffer[DUN_HEIGHT][DUN_WIDTH];
+cchar_t const *front_buffer[DISP_HEIGHT][DISP_WIDTH];
/* Prototypes for static funcs */
-static const cchar_t *object_char(int object_id);
-static const cchar_t *monster_char(int monster_id);
-static const cchar_t *terrain_char(Terrain terrain_type);
+static cchar_t const *object_char(int object_id);
+static cchar_t const *monster_char(int monster_id);
+static cchar_t const *terrain_char(Terrain terrain_type);
static void draw_status_line(void);
static void draw_world(void);
/*! \brief Get pointer to cchar_t object for specified terrain
*/
-static const cchar_t *terrain_char(Terrain terrain_type)
+static cchar_t const *terrain_char(Terrain terrain_type)
{
return terrain_tiles + terrain_type;
}
/*! \brief Get pointer to cchar_t object for specified monster
*/
-static const cchar_t *monster_char(int monster_id)
+static cchar_t const *monster_char(int monster_id)
{
return permon_tiles + monster_id;
}
/*! \brief Get pointer to cchar_t object for specified object
*/
-static const cchar_t *object_char(int object_id)
+static cchar_t const *object_char(int object_id)
{
return permobj_tiles + object_id;
}
*/
void newsym(Coord c)
{
- const cchar_t *ch;
+ cchar_t const *ch;
int obj = lvl.obj_at(c);
int mon = lvl.mon_at(c);
Terrain terr = lvl.terrain_at(c);
int i;
int j;
Coord c;
+ Coord d;
for (i = 0; i < DISP_NC_SIDE; i++)
{
for (j = 0; j < DISP_NC_SIDE; j++)
{
c.x = u.pos.x + j - DISP_NC_RADIUS;
+ d.y = i - DISP_NC_RADIUS + MAX_FOV_RADIUS;
+ d.x = j - DISP_NC_RADIUS + MAX_FOV_RADIUS;
if ((c.y < 0) || (c.x < 0) ||
(c.y >= DUN_HEIGHT) || (c.x >= DUN_WIDTH))
{
else if (hard_redraw || (front_buffer[i][j] != back_buffer[c.y][c.x]))
{
mvwadd_wch(world_window, i, j, back_buffer[c.y][c.x]);
- if (!player_fov.test(i - DISP_NC_RADIUS + MAX_FOV_RADIUS, j - DISP_NC_RADIUS + MAX_FOV_RADIUS))
+ if (!player_fov.test(d))
{
mvwchgat(world_window, i, j, 1, A_BOLD, Gcol_d_grey, NULL);
}
int display_init(void)
{
int i;
- const char *foo;
+ char const *foo;
foo = getenv("LANG");
if (foo)
{
*
* \todo Handle the message window getting resized
*/
-void print_msg(const char *fmt, ...)
+void print_msg(char const *fmt, ...)
{
va_list ap;
/* For now, assume (1) that the player will never be so inundated
/*! \brief Set a message and whether 'nothing' should be listed in inventory
*/
-void set_inventory_message(const char *s, bool allow_nil)
+void set_inventory_message(char const *s, bool allow_nil)
{
mvwprintw(inventory_window, 0, 0, "%-57s\n", s);
if (!allow_nil)
*
* \todo Take function pointer and private arg for smarter filtering
*/
-int inv_select(enum poclass_num filter, const char *action, int accept_blank)
+int inv_select(enum poclass_num filter, char const *action, int accept_blank)
{
int selection;
int ch;
/*! \brief Prompt the player for a relatively paranoid 'Y'
*/
-int getYN(const char *msg)
+int getYN(char const *msg)
{
int ch;
print_msg("%s", msg);
/*! \brief Get a yes/no response from the player
*/
-int getyn(const char *msg)
+int getyn(char const *msg)
{
int ch;
print_msg("%s", msg);
#ifndef DISPLAY_HH
#define DISPLAY_HH
-extern void print_msg(const char *fmt, ...);
+extern void print_msg(char const *fmt, ...);
extern int read_input(char *buffer, int length);
extern void print_help(void);
extern int display_init(void);
extern int display_shutdown(void);
extern void newsym(Coord c);
extern void touch_back_buffer(void);
-extern int inv_select(enum poclass_num filter, const char *action, int accept_blank);
+extern int inv_select(enum poclass_num filter, char const *action, int accept_blank);
extern enum game_cmd get_command(void);
extern Pass_fail select_dir(Offset *pstep);
-extern int getYN(const char *msg);
-extern int getyn(const char *msg);
+extern int getYN(char const *msg);
+extern int getyn(char const *msg);
extern void press_enter(void);
extern void pressanykey(void);
extern void show_discoveries(void);
/*! \file fov.cc
* \brief field-of-view computation (recursive shadowcasting)
*
- * A recursive shadowcasting implementation using diamond (rather than whole-
- * cell) occlusion rules.
+ * A recursive shadowcasting implementation using diamond (rather than
+ * whole-cell) occlusion rules.
*/
/* Copyright 2013 Martin Read
* This function returns true if the specified coordinates are out of bounds
* or the terrain at the specified position is opaque.
*/
-static bool dflt_blk(int y, int x)
+static bool dflt_blk(Coord c)
{
- return ((y <= 0) || (x <= 0) || (y >= DUN_HEIGHT - 1) || (x >= DUN_WIDTH - 1) || (terrain_is_opaque(lvl.terrain[y][x])));
+ return ((c.y <= 0) || (c.x <= 0) || (c.y >= DUN_HEIGHT - 1) || (c.x >= DUN_WIDTH - 1) || (terrain_is_opaque(lvl.terrain_at(c))));
}
/*! \brief Function for marking affected cells as explored
* This function marks the specified tile as explored, triggers a symbol
* update, and returns true.
*/
-static bool mark_explored(int y, int x, void *pvt)
+static bool mark_explored(Coord c, void *pvt)
{
- Coord c = { y, x };
lvl.set_flags_at(c, MAPFLAG_EXPLORED);
newsym(c);
return true;
static void compute_row(Radiance *rad, int octant, int radius, double inmost_slope, double outmost_slope)
{
int trn;
- int dy;
- int dx;
+ Offset delta;
+ Coord tst;
bool block_flag = false;
int outer_idx;
int inner_idx;
* the potentially affected area - are calculated using the rdl_* and trn_*
* arrays.
*/
- dx = radius * rdl_dx[octant] + outer_idx * trn_dx[octant];
- dy = radius * rdl_dy[octant] + outer_idx * trn_dy[octant];
+ delta.x = radius * rdl_dx[octant] + outer_idx * trn_dx[octant];
+ delta.y = radius * rdl_dy[octant] + outer_idx * trn_dy[octant];
/*
* Iterate over the range of transverse deflections from outer_idx to
* inner_idx.
isl = inner_slope(radius, trn);
csl = centre_slope(radius, trn);
/* Mark the tile being examined as affected. */
- rad->affected[MAX_FOV_RADIUS + dy][MAX_FOV_RADIUS + dx] |= Visflag_partial;
+ rad->affected[MAX_FOV_RADIUS + delta.y][MAX_FOV_RADIUS + delta.x] |= Visflag_partial;
+ tst = rad->centre + delta;
if ((csl >= inmost_slope) && (csl <= outmost_slope))
{
- rad->affected[MAX_FOV_RADIUS + dy][MAX_FOV_RADIUS + dx] |= Visflag_central;
+ rad->affected[MAX_FOV_RADIUS + delta.y][MAX_FOV_RADIUS + delta.x] |= Visflag_central;
}
if (block_flag)
{
/* If the previous tile was opaque... */
- if (rad->opaque_fun(dy + rad->centre_y, dx + rad->centre_x))
+ if (rad->opaque_fun(tst))
{
/* ... then if this one is too, update the slope */
if (outmost_slope > isl)
else
{
/* Otherwise... */
- if (rad->opaque_fun(dy + rad->centre_y, dx + rad->centre_x))
+ if (rad->opaque_fun(tst))
{
/* ... if the current tile is opaque, set the blocking flag. */
block_flag = true;
* Advance whichever of dx or dy is the transverse coordinate for this
* octant.
*/
- dx -= trn_dx[octant];
- dy -= trn_dy[octant];
+ delta.x -= trn_dx[octant];
+ delta.y -= trn_dy[octant];
}
if ((radius < rad->radius) && !block_flag)
{
void resolve_radiance(Radiance *rad)
{
- int y;
- int x;
+ Coord c;
int i;
int j;
int k;
switch (rad->order)
{
case Reo_ascending:
- for ((i = MAX_FOV_RADIUS - rad->radius), (y = rad->centre_y - rad->radius); y <= rad->centre_y + rad->radius; ++y, ++i)
+ for ((i = MAX_FOV_RADIUS - rad->radius), (c.y = rad->centre.y - rad->radius); c.y <= rad->centre.y + rad->radius; ++c.y, ++i)
{
- for ((j = MAX_FOV_RADIUS - rad->radius), (x = rad->centre_x - rad->radius); x <= rad->centre_x + rad->radius; ++x, ++j)
+ for ((j = MAX_FOV_RADIUS - rad->radius), (c.x = rad->centre.x - rad->radius); c.x <= rad->centre.x + rad->radius; ++c.x, ++j)
{
if (rad->affected[i][j])
{
- rad->effect_fun(y, x, rad->pvt);
+ rad->effect_fun(c, rad->pvt);
}
}
}
case Reo_spiral_out:
for (i = 0, j = 0, k = 0; i >= -(rad->radius); )
{
+ c.y = rad->centre.y + i;
+ c.x = rad->centre.x + j;
if (rad->affected[MAX_FOV_RADIUS + i][MAX_FOV_RADIUS + j])
{
- rad->effect_fun(rad->centre_y + i, rad->centre_x + j, rad->pvt);
+ rad->effect_fun(c, rad->pvt);
}
if ((i == 0) && (j == 0))
{
case Reo_spiral_in:
for (i = -(rad->radius), j = -(rad->radius), k = rad->radius; k >= 0; )
{
+ c.y = rad->centre.y + i;
+ c.x = rad->centre.x + j;
if (rad->affected[MAX_FOV_RADIUS + i][MAX_FOV_RADIUS + j])
{
- rad->effect_fun(rad->centre_y + i, rad->centre_x + j, rad->pvt);
+ rad->effect_fun(c, rad->pvt);
}
if ((i == 0) && (j == 0))
{
void compute_fov(void)
{
clear_radiance(&player_fov);
- player_fov.centre_y = u.pos.y;
- player_fov.centre_x = u.pos.x;
+ player_fov.centre = u.pos;
player_fov.radius = MAX_FOV_RADIUS;
player_fov.order = Reo_ascending;
player_fov.exclude_centre = false;
struct radiance_data
{
Vision_flags affected[FOV_SIDE][FOV_SIDE];
- int centre_y;
- int centre_x;
+ Coord centre;
int radius;
Rad_eval_order order; /*!< What order to iterate through affected squares */
bool exclude_centre; /*!< Exclude the centre from being affected. */
void *pvt;
- bool (*opaque_fun)(int y, int x);
- bool (*effect_fun)(int y, int x, void *pvt);
- bool test(int y, int x) const {
- if ((y >= 0) && (x >= 0) && (y < FOV_SIDE) && (x < FOV_SIDE))
+ bool (*opaque_fun)(Coord c);
+ bool (*effect_fun)(Coord c, void *pvt);
+ bool test(Coord c) const {
+ if ((c.y >= 0) && (c.x >= 0) && (c.y < FOV_SIDE) && (c.x < FOV_SIDE))
{
- return affected[y][x];
+ return affected[c.y][c.x];
}
return false;
}
#include <limits.h>
/* Coord/Offset constants */
-const Coord Nowhere = { INT_MIN, INT_MIN };
-const Offset North = { -1, 0 };
-const Offset Northeast = { -1, 1 };
-const Offset East = { 0, 1 };
-const Offset Southeast = { 1, 1 };
-const Offset South = { 1, 0 };
-const Offset Southwest = { 1, -1 };
-const Offset West = { 0, -1 };
-const Offset Northwest = { -1, -1 };
-const Offset Stationary = { 0, 0 };
+Coord const Nowhere = { INT_MIN, INT_MIN };
+Offset const North = { -1, 0 };
+Offset const Northeast = { -1, 1 };
+Offset const East = { 0, 1 };
+Offset const Southeast = { 1, 1 };
+Offset const South = { 1, 0 };
+Offset const Southwest = { 1, -1 };
+Offset const West = { 0, -1 };
+Offset const Northwest = { -1, -1 };
+Offset const Stationary = { 0, 0 };
void save_game(void);
static void load_game(void);
static int excavation_write(Coord c, void *data);
static int intrusion_write(Coord c, void *data);
+/*! \brief Find a random point on the level
+ *
+ * \param margin Width of the "dead" space along each edge in which the point cannot appear
+ */
Coord Level::random_point(int margin) const
{
Coord tl = { margin, margin };
static int excavation_write(Coord c, void *data)
{
- const int *data_as_ints = (const int *) data;
- const int *overwrite = data_as_ints + 2;
+ 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)
#define SHRINE_HEIGHT 11
#define SHRINE_WIDTH 11
+//! Layout data for "shrines"
struct shrine
{
bool used;
- const char *grid[SHRINE_HEIGHT];
+ char const *grid[SHRINE_HEIGHT];
};
+//! Property structure for terrain types
struct Terrain_props
{
- const char *name; // UTF-8 English
- char ascii;
- const char * unicode; // UTF-8
- Gamecolour colour;
- uint32_t flags;
+ char const *name; //!< UTF-8 encoded English name
+ char ascii; //!< ASCII symbol
+ char const * unicode; //!< UTF-8 encoded Unicode symbol
+ Gamecolour colour; //!< colour to use in terminal-like environments
+ uint32_t flags; //!< Bitmask composed using TFLAG_* macros.
};
+//! Array of terrain properties
extern Terrain_props terrain_props[NUM_TERRAINS];
#define TFLAG_opaque 0x00000001u
#define TFLAG_drown_hazard 0x00040000u
#define TFLAG_flammable 0x10000000u
-/* XXX map.c data and funcs*/
+#define CHUNK_EDGE 16
+#define CHUNK_AREA (CHUNK_EDGE * CHUNK_EDGE)
+
+//! The fundamental object-like unit of cartography
+struct Chunk
+{
+ int objs[CHUNK_EDGE][CHUNK_EDGE];
+ int mons[CHUNK_EDGE][CHUNK_EDGE];
+ Terrain terrain[CHUNK_EDGE][CHUNK_EDGE];
+ uint32_t flags[CHUNK_EDGE][CHUNK_EDGE];
+ Terrain terrain_at(Coord c) const { return terrain[c.y][c.x]; }
+ Chunk() = default;
+ Chunk(Terrain t); // initialize the chunk to a specified terrain type.
+};
+
+//! The top-tier object for describing everything about a level
struct Level
{
int objs[DUN_HEIGHT][DUN_WIDTH];
int mons[DUN_HEIGHT][DUN_WIDTH];
Terrain terrain[DUN_HEIGHT][DUN_WIDTH];
uint32_t flags[DUN_HEIGHT][DUN_WIDTH];
+ Terrain dead_space;
level_theme theme;
level_layout layout;
Terrain terrain_at(Coord c) const { return terrain[c.y][c.x]; }
#include "victrix-abyssi.hh"
-const char *damtype_names[DT_COUNT] = {
+char const *damtype_names[DT_COUNT] = {
"physical damage",
"fire",
"cold",
static void get_chase_prefs(int mon, Coord *pref_pos)
{
- const Mon *mptr = monsters + mon;
+ Mon const *mptr = monsters + mon;
Offset delta = mptr->ai_lastpos.delta(mptr->pos);
Offset step = mysign(delta);
Offset absdelta = myabs(delta);
#define PMF_FLYING 0x00800000
struct permon {
- const char name[48];
- const char plural[48];
+ char const name[48];
+ char const plural[48];
char sym;
int colour;
int rarity; /* Chance in 100 of being thrown back and regen'd. */
int mdam; /* Improved by OOD rating at 1:5. */
int rdam; /* Improved by OOD rating at 1:5. */
Damtyp rdtyp; /* type of damage used by ranged attack. */
- const char shootverb[48]; /* shooting verb e.g. "fires an arrow", "breathes". */
+ char const shootverb[48]; /* shooting verb e.g. "fires an arrow", "breathes". */
int defence; /* Improved by OOD rating at 1:3. */
int exp; /* Unaffected by OOD rating. */
int speed; /* 0 = slow; 1 = normal; 2 = quick */
Obj objects[100];
int get_random_pobj(void);
-const char ring_colours[20][16] = {
+char const ring_colours[20][16] = {
"gold", "ruby", "sapphire", "ivory", "coral",
"amethyst", "silver", "iron", "copper", "jade",
"haematite", "bone", "crystal", "platinum", "lead",
"diamond", "topaz", "emerald", "electrum", "smoky quartz"
};
-const char scroll_titles[20][16] = {
+char const scroll_titles[20][16] = {
"grem pho", "terra terrax", "phong", "ateh malkuth", "xixaxa",
"aku ryo tai san", "qoph shin tau", "ythek shri", "ia ia", "cthulhu fhtagn",
"arifech malex", "DOOM", "leme athem", "hail smkznrf", "rorrim foo",
"ad aerarium", "ligemrom", "asher ehiyeh", "YELLOW SIGN", "ELDER SIGN"
};
-const char potion_colours[20][16] = {
+char const potion_colours[20][16] = {
"purple", "red", "blue", "green", "yellow",
"orange", "white", "black", "brown", "fizzy",
"grey", "silver", "gold", "shimmering", "glowing",
/* XXX struct permobj */
struct permobj {
- const char name[48];
- const char plural[48];
- const char *description;
+ char const name[48];
+ char const plural[48];
+ char const *description;
enum poclass_num poclass;
int rarity; /* Chance in 100 of being thrown away and regen'd. */
char sym; /* ASCII */
- const char *unicode; /* UTF-8 */
+ char const *unicode; /* UTF-8 */
Gamecolour colour;
int power; /* AC for armour; damage for weapons; colour/title for
* scrolls and potions and rings and such. */
}
}
-int drain_body(int amount, const char *what, int permanent)
+int drain_body(int amount, char const *what, int permanent)
{
print_msg("You feel weaker!\n");
if (permanent)
}
}
-int drain_agility(int amount, const char *what, int permanent)
+int drain_agility(int amount, char const *what, int permanent)
{
print_msg("You feel clumsy!\n");
if (permanent)
return 0;
}
-int damage_u(int amount, enum death d, const char *what)
+int damage_u(int amount, enum death d, char const *what)
{
u.hpcur -= amount;
status_updated = 1;
return;
}
-int do_death(enum death d, const char *what)
+int do_death(enum death d, char const *what)
{
FILE *fp;
int really = 0;
extern int wizard_mode;
/* XXX misc.c data and funcs */
-extern const char *damtype_names[DT_COUNT];
+extern char const *damtype_names[DT_COUNT];
extern void attempt_pickup(void);
extern bool po_is_stackable(int po);
/* XXX u.c data and funcs */
extern void u_init(void);
extern void write_char_dump(void);
-extern int do_death(enum death d, const char *what);
+extern int do_death(enum death d, char const *what);
extern void heal_u(int amount, int boost, int loud);
-extern int damage_u(int amount, enum death d, const char *what);
+extern int damage_u(int amount, enum death d, char const *what);
extern int gain_body(int amount, int loud);
extern int gain_agility(int amount, int loud);
-extern int drain_body(int amount, const char *what, int permanent);
-extern int drain_agility(int amount, const char *what, int permanent);
+extern int drain_body(int amount, char const *what, int permanent);
+extern int drain_agility(int amount, char const *what, int permanent);
extern void gain_experience(int amount);
extern int lev_threshold(int level);
extern Action_cost move_player(Offset delta);