diff --git a/include/align.h b/include/align.h index bd7b70cc1..bb00f2c6e 100644 --- a/include/align.h +++ b/include/align.h @@ -24,20 +24,21 @@ typedef struct align { /* alignment & record */ #define A_COALIGNED 1 #define A_OPALIGNED (-1) -#define AM_NONE 0 -#define AM_CHAOTIC 1 -#define AM_NEUTRAL 2 -#define AM_LAWFUL 4 +/* align masks */ +#define AM_NONE 0x00 +#define AM_CHAOTIC 0x01 +#define AM_NEUTRAL 0x02 +#define AM_LAWFUL 0x04 +#define AM_MASK 0x07 /* mask for "normal" alignment values */ -#define AM_MASK 7 -/* Some altars are considered as shrines, so we need a flag for that +/* Some altars are considered shrines, add a flag for that for the altarmask field of struct rm. */ -#define AM_SHRINE 8 +#define AM_SHRINE 0x08 /* special level flags, gone by the time the level has been loaded */ -#define AM_SPLEV_CO 3 /* co-aligned: force alignment to match hero's */ -#define AM_SPLEV_NONCO 7 /* non-co-aligned: force alignment to not match */ -#define AM_SPLEV_RANDOM 8 +#define AM_SPLEV_CO 0x10 /* co-aligned: force alignment to match hero's */ +#define AM_SPLEV_NONCO 0x20 /* non-co-aligned: force alignment to not match */ +#define AM_SPLEV_RANDOM 0x40 #define Amask2align(x) \ ((aligntyp) ((((x) & AM_MASK) == 0) ? A_NONE \ diff --git a/include/extern.h b/include/extern.h index 25bebb26a..a6302da2c 100644 --- a/include/extern.h +++ b/include/extern.h @@ -621,7 +621,7 @@ extern void find_hell(d_level *); extern void goto_hell(boolean, boolean); extern void assign_level(d_level *, d_level *); extern void assign_rnd_level(d_level *, d_level *, int); -extern int induced_align(int); +extern unsigned int induced_align(int); extern boolean Invocation_lev(d_level *); extern xchar level_difficulty(void); extern schar lev_by_name(const char *); diff --git a/include/sp_lev.h b/include/sp_lev.h index ed3e20381..cdead3bd5 100644 --- a/include/sp_lev.h +++ b/include/sp_lev.h @@ -132,7 +132,7 @@ typedef struct { typedef struct { Str_or_Len name, appear_as; short id; - aligntyp align; + unsigned int sp_amask; /* splev amask */ packed_coord coord; xchar x, y, class, appear; schar peaceful, asleep; @@ -159,7 +159,7 @@ typedef struct { typedef struct { packed_coord coord; xchar x, y; - aligntyp align; + unsigned int sp_amask; /* splev amask */ xchar shrine; } altar; diff --git a/src/dungeon.c b/src/dungeon.c index 872330d4a..f70dcf6bf 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1869,7 +1869,8 @@ assign_rnd_level(d_level *dest, d_level *src, int range) dest->dlevel = 1; } -int +/* return an alignment mask */ +unsigned int induced_align(int pct) { s_level *lev = Is_special(&u.uz); diff --git a/src/sp_lev.c b/src/sp_lev.c index a80b4234e..4b4e78411 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -49,6 +49,7 @@ static void create_trap(spltrap *, struct mkroom *); static int noncoalignment(aligntyp); static boolean m_bad_boulder_spot(int, int); static int pm_to_humidity(struct permonst *); +static unsigned int sp_amask_to_amask(unsigned int sp_amask); static void create_monster(monster *, struct mkroom *); static void create_object(object *, struct mkroom *); static void create_altar(altar *, struct mkroom *); @@ -1758,13 +1759,36 @@ pm_to_humidity(struct permonst* pm) return loc; } +/* + * Convert a special level alignment mask (an alignment mask with possible + * extra values/flags) to a "normal" alignment mask (no extra flags). + * + * When random: there is an 80% chance that the altar will be co-aligned. + */ +static unsigned int +sp_amask_to_amask(unsigned int sp_amask) +{ + unsigned int amask; + + if (sp_amask == AM_SPLEV_CO) + amask = Align2amask(u.ualignbase[A_ORIGINAL]); + else if (sp_amask == AM_SPLEV_NONCO) + amask = Align2amask(noncoalignment(u.ualignbase[A_ORIGINAL])); + else if (sp_amask == AM_SPLEV_RANDOM) + amask = induced_align(80); + else + amask = sp_amask & AM_MASK; + + return amask; +} + static void create_monster(monster* m, struct mkroom* croom) { struct monst *mtmp; xchar x, y; char class; - aligntyp amask; + unsigned int amask; coord cc; struct permonst *pm; unsigned g_mvflags; @@ -1777,13 +1801,7 @@ create_monster(monster* m, struct mkroom* croom) if (class == MAXMCLASSES) panic("create_monster: unknown monster class '%c'", m->class); - amask = (m->align == AM_SPLEV_CO) - ? Align2amask(u.ualignbase[A_ORIGINAL]) - : (m->align == AM_SPLEV_NONCO) - ? Align2amask(noncoalignment(u.ualignbase[A_ORIGINAL])) - : (m->align == AM_SPLEV_RANDOM) - ? induced_align(80) - : m->align; + amask = sp_amask_to_amask(m->sp_amask); if (!class) pm = (struct permonst *) 0; @@ -1823,7 +1841,7 @@ create_monster(monster* m, struct mkroom* croom) if (croom && !inside_room(croom, x, y)) return; - if (m->align != AM_SPLEV_RANDOM) + if (m->sp_amask != AM_SPLEV_RANDOM) mtmp = mk_roamer(pm, Amask2align(amask), x, y, m->peaceful); else if (PM_ARCHEOLOGIST <= m->id && m->id <= PM_WIZARD) mtmp = mk_mplayer(pm, x, y, FALSE); @@ -2261,7 +2279,7 @@ create_altar(altar* a, struct mkroom* croom) { schar sproom; xchar x = -1, y = -1; - aligntyp amask; + unsigned int amask; boolean croom_is_temple = TRUE; int oldtyp; @@ -2282,20 +2300,7 @@ create_altar(altar* a, struct mkroom* croom) if (oldtyp == STAIRS || oldtyp == LADDER) return; - /* Is the alignment random ? - * If so, it's an 80% chance that the altar will be co-aligned. - * - * The alignment is encoded as amask values instead of alignment - * values to avoid conflicting with the rest of the encoding, - * shared by many other parts of the special level code. - */ - amask = (a->align == AM_SPLEV_CO) - ? Align2amask(u.ualignbase[A_ORIGINAL]) - : (a->align == AM_SPLEV_NONCO) - ? Align2amask(noncoalignment(u.ualignbase[A_ORIGINAL])) - : (a->align == AM_SPLEV_RANDOM) - ? induced_align(80) - : a->align; + amask = sp_amask_to_amask(a->sp_amask); levl[x][y].typ = ALTAR; levl[x][y].altarmask = amask; @@ -3008,7 +3013,7 @@ lspo_monster(lua_State* L) tmpmons.name.str = NULL; tmpmons.appear = 0; tmpmons.appear_as.str = (char *) 0; - tmpmons.align = AM_SPLEV_RANDOM; + tmpmons.sp_amask = AM_SPLEV_RANDOM; tmpmons.female = 0; tmpmons.invis = 0; tmpmons.cancelled = 0; @@ -3073,7 +3078,7 @@ lspo_monster(lua_State* L) tmpmons.name.str = get_table_str_opt(L, "name", NULL); tmpmons.appear = 0; tmpmons.appear_as.str = (char *) 0; - tmpmons.align = get_table_align(L); + tmpmons.sp_amask = get_table_align(L); tmpmons.female = get_table_int_opt(L, "female", 0); tmpmons.invis = get_table_int_opt(L, "invisible", 0); tmpmons.cancelled = get_table_int_opt(L, "cancelled", 0); @@ -3907,7 +3912,7 @@ lspo_altar(lua_State* L) acoord = SP_COORD_PACK(x, y); tmpaltar.coord = acoord; - tmpaltar.align = al; + tmpaltar.sp_amask = al; tmpaltar.shrine = shrine; create_altar(&tmpaltar, g.coder->croom);