Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorporate object materials into glyphmap #82

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 62 additions & 39 deletions include/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@
*/
#define random_monster(rng) rng(NUMMONS)
#define random_object(rng) (rng(NUM_OBJECTS - 1) + 1)
#define random_material(rng) (rng(NUM_MATERIAL_TYPES - 1) + 1)

/*
* what_obj()
Expand Down Expand Up @@ -562,7 +563,7 @@ enum glyph_offsets {
GLYPH_RIDDEN_MALE_OFF = (GLYPH_RIDDEN_OFF),
GLYPH_RIDDEN_FEM_OFF = (NUMMONS + GLYPH_RIDDEN_MALE_OFF),
GLYPH_OBJ_OFF = (NUMMONS + GLYPH_RIDDEN_FEM_OFF),
GLYPH_CMAP_OFF = (NUM_OBJECTS + GLYPH_OBJ_OFF),
GLYPH_CMAP_OFF = ((NUM_OBJECTS * NUM_MATERIAL_TYPES) + GLYPH_OBJ_OFF),
GLYPH_CMAP_STONE_OFF = (GLYPH_CMAP_OFF),
GLYPH_CMAP_MAIN_OFF = (1 + GLYPH_CMAP_STONE_OFF),
GLYPH_CMAP_MINES_OFF = (((S_trwall - S_vwall) + 1) + GLYPH_CMAP_MAIN_OFF),
Expand All @@ -589,13 +590,18 @@ enum glyph_offsets {
GLYPH_WARNING_OFF = (MAXEXPCHARS + GLYPH_EXPLODE_FROSTY_OFF),
GLYPH_STATUE_OFF = (WARNCOUNT + GLYPH_WARNING_OFF),
GLYPH_STATUE_MALE_OFF = (GLYPH_STATUE_OFF),
GLYPH_STATUE_FEM_OFF = (NUMMONS + GLYPH_STATUE_MALE_OFF),
GLYPH_PILETOP_OFF = (NUMMONS + GLYPH_STATUE_FEM_OFF),
GLYPH_STATUE_FEM_OFF = ((NUMMONS * NUM_MATERIAL_TYPES)
+ GLYPH_STATUE_MALE_OFF),
GLYPH_PILETOP_OFF = ((NUMMONS * NUM_MATERIAL_TYPES)
+ GLYPH_STATUE_FEM_OFF),
GLYPH_OBJ_PILETOP_OFF = (GLYPH_PILETOP_OFF),
GLYPH_BODY_PILETOP_OFF = (NUM_OBJECTS + GLYPH_OBJ_PILETOP_OFF),
GLYPH_BODY_PILETOP_OFF = ((NUM_OBJECTS * NUM_MATERIAL_TYPES)
+ GLYPH_OBJ_PILETOP_OFF),
GLYPH_STATUE_MALE_PILETOP_OFF = (NUMMONS + GLYPH_BODY_PILETOP_OFF),
GLYPH_STATUE_FEM_PILETOP_OFF = (NUMMONS + GLYPH_STATUE_MALE_PILETOP_OFF),
GLYPH_UNEXPLORED_OFF = (NUMMONS + GLYPH_STATUE_FEM_PILETOP_OFF),
GLYPH_STATUE_FEM_PILETOP_OFF = ((NUMMONS * NUM_MATERIAL_TYPES)
+ GLYPH_STATUE_MALE_PILETOP_OFF),
GLYPH_UNEXPLORED_OFF = ((NUMMONS * NUM_MATERIAL_TYPES)
+ GLYPH_STATUE_FEM_PILETOP_OFF),
GLYPH_NOTHING_OFF = (GLYPH_UNEXPLORED_OFF + 1),
MAX_GLYPH
};
Expand Down Expand Up @@ -697,7 +703,8 @@ enum glyph_offsets {

/* Not affected by hallucination. Gives a generic body for CORPSE */
/* MRKR: ...and the generic statue */
#define objnum_to_glyph(onum) ((int) (onum) + GLYPH_OBJ_OFF)
#define objnum_to_glyph(onum) \
(((int) (onum) * NUM_MATERIAL_TYPES) + GLYPH_OBJ_OFF)
#define monnum_to_glyph(mnum,gnd) \
((int) (mnum) + (((gnd) == MALE) ? GLYPH_MON_MALE_OFF \
: GLYPH_MON_FEM_OFF))
Expand Down Expand Up @@ -907,26 +914,31 @@ enum glyph_offsets {

#define glyph_is_fem_statue_piletop(glyph) \
(((glyph) >= GLYPH_STATUE_FEM_PILETOP_OFF) \
&& ((glyph) < (GLYPH_STATUE_FEM_PILETOP_OFF + NUMMONS)))
&& ((glyph) < (GLYPH_STATUE_FEM_PILETOP_OFF \
+ (NUMMONS * NUM_MATERIAL_TYPES))))
#define glyph_is_male_statue_piletop(glyph) \
(((glyph) >= GLYPH_STATUE_MALE_PILETOP_OFF) \
&& ((glyph) < (GLYPH_STATUE_MALE_PILETOP_OFF + NUMMONS)))
&& ((glyph) < (GLYPH_STATUE_MALE_PILETOP_OFF \
+ (NUMMONS * NUM_MATERIAL_TYPES))))
#define glyph_is_fem_statue(glyph) \
((((glyph) >= GLYPH_STATUE_FEM_OFF) && \
((glyph) < (GLYPH_STATUE_FEM_OFF + NUMMONS))) \
((glyph) < (GLYPH_STATUE_FEM_OFF \
+ (NUMMONS * NUM_MATERIAL_TYPES)))) \
|| glyph_is_fem_statue_piletop(glyph))
#define glyph_is_male_statue(glyph) \
((((glyph) >= GLYPH_STATUE_MALE_OFF) && \
((glyph) < (GLYPH_STATUE_MALE_OFF + NUMMONS))) \
((((glyph) >= GLYPH_STATUE_MALE_OFF) && \
((glyph) < (GLYPH_STATUE_MALE_OFF \
+ (NUMMONS * NUM_MATERIAL_TYPES)))) \
|| glyph_is_male_statue_piletop(glyph))
#define glyph_is_statue(glyph) \
(glyph_is_male_statue(glyph) || glyph_is_fem_statue(glyph))
#define glyph_is_normal_piletop_obj(glyph) \
(((glyph) >= GLYPH_OBJ_PILETOP_OFF) && \
((glyph) < (GLYPH_OBJ_PILETOP_OFF + NUM_OBJECTS)))
((glyph) < (GLYPH_OBJ_PILETOP_OFF \
+ (NUM_OBJECTS * NUM_MATERIAL_TYPES))))
#define glyph_is_normal_object(glyph) \
((((glyph) >= GLYPH_OBJ_OFF) && \
((glyph) < (GLYPH_OBJ_OFF + NUM_OBJECTS))) \
((glyph) < (GLYPH_OBJ_OFF + (NUM_OBJECTS * NUM_MATERIAL_TYPES)))) \
|| glyph_is_normal_piletop_obj(glyph))

#if 0
Expand Down Expand Up @@ -976,34 +988,44 @@ enum glyph_offsets {
: glyph_is_statue(glyph) \
? STATUE \
: glyph_is_normal_object(glyph) \
? ((glyph) - \
(glyph_is_normal_piletop_obj(glyph) \
? GLYPH_OBJ_PILETOP_OFF \
: GLYPH_OBJ_OFF)) \
? (((glyph) - \
(glyph_is_normal_piletop_obj(glyph) \
? GLYPH_OBJ_PILETOP_OFF \
: GLYPH_OBJ_OFF)) \
/ NUM_MATERIAL_TYPES) \
: NO_GLYPH)

#define glyph_to_obj_material(glyph) \
(glyph_is_normal_object(glyph) \
? (((glyph) - (glyph_is_normal_piletop_obj(glyph) \
? GLYPH_OBJ_PILETOP_OFF \
: GLYPH_OBJ_OFF)) % NUM_MATERIAL_TYPES) \
: NO_MATERIAL)

#define glyph_to_body_corpsenm(glyph) \
(glyph_is_body_piletop(glyph) \
? ((glyph) - GLYPH_BODY_PILETOP_OFF) \
: ((glyph) - GLYPH_BODY_OFF))

#define glyph_to_statue_corpsenm(glyph) \
(glyph_is_fem_statue_piletop(glyph) \
? ((glyph) - GLYPH_STATUE_FEM_PILETOP_OFF) \
: glyph_is_male_statue_piletop(glyph) \
? ((glyph) - GLYPH_STATUE_MALE_PILETOP_OFF) \
: glyph_is_fem_statue(glyph) \
? ((glyph) - GLYPH_STATUE_FEM_OFF) \
: glyph_is_male_statue(glyph) \
? ((glyph) - GLYPH_STATUE_MALE_OFF) \
: NO_GLYPH)
(!glyph_is_statue(glyph) \
? NO_GLYPH \
: ((glyph_is_fem_statue_piletop(glyph) \
? ((glyph) - GLYPH_STATUE_FEM_PILETOP_OFF) \
: glyph_is_male_statue_piletop(glyph) \
? ((glyph) - GLYPH_STATUE_MALE_PILETOP_OFF) \
: glyph_is_fem_statue(glyph) \
? ((glyph) - GLYPH_STATUE_FEM_OFF) \
: ((glyph) - GLYPH_STATUE_MALE_OFF)) \
/ NUM_MATERIAL_TYPES))

/* These have the unfortunate side effect of needing a global variable */
/* to store a result. 'otg_temp' is defined and declared in decl.{ch}. */
#define random_obj_to_glyph(rng) \
((g.otg_temp = random_object(rng)) == CORPSE \
? (random_monster(rng) + GLYPH_BODY_OFF) \
: (g.otg_temp + GLYPH_OBJ_OFF))
: ((g.otg_temp * NUM_MATERIAL_TYPES) + random_material(rng) \
+ GLYPH_OBJ_OFF))
#define corpse_to_glyph(obj) \
((int) ((obj)->corpsenm + (obj_is_piletop(obj) \
? GLYPH_BODY_PILETOP_OFF \
Expand All @@ -1016,7 +1038,7 @@ enum glyph_offsets {
also done so that special levels such a Sokoban can "hide" items
under the boulders. */
#define normal_obj_to_glyph(obj) \
((int) ((obj)->otyp + \
((int) (((obj)->otyp * NUM_MATERIAL_TYPES) + (obj)->material + \
((obj_is_piletop(obj) && ((obj)->otyp != BOULDER)) \
? GLYPH_OBJ_PILETOP_OFF \
: GLYPH_OBJ_OFF)))
Expand All @@ -1026,16 +1048,17 @@ enum glyph_offsets {

#define statue_to_glyph(obj, rng) \
((Hallucination) \
? ((random_monster(rng)) + \
((!(rng)(2)) ? GLYPH_MON_MALE_OFF : GLYPH_MON_FEM_OFF)) \
: ((int) (obj)->corpsenm + \
((((obj)->spe & CORPSTAT_GENDER) == CORPSTAT_FEMALE) \
? (obj_is_piletop(obj) \
? GLYPH_STATUE_FEM_PILETOP_OFF \
: GLYPH_STATUE_FEM_OFF) \
: (obj_is_piletop(obj) \
? GLYPH_STATUE_MALE_PILETOP_OFF \
: GLYPH_STATUE_MALE_OFF))))
? ((random_monster(rng)) \
+ ((!(rng)(2)) ? GLYPH_MON_MALE_OFF : GLYPH_MON_FEM_OFF)) \
: (((int) (obj)->corpsenm * NUM_MATERIAL_TYPES) \
+ (obj)->material \
+ ((((obj)->spe & CORPSTAT_GENDER) == CORPSTAT_FEMALE) \
? (obj_is_piletop(obj) \
? GLYPH_STATUE_FEM_PILETOP_OFF \
: GLYPH_STATUE_FEM_OFF) \
: (obj_is_piletop(obj) \
? GLYPH_STATUE_MALE_PILETOP_OFF \
: GLYPH_STATUE_MALE_OFF))))

#define obj_to_glyph(obj, rng) \
(((obj)->otyp == STATUE) \
Expand Down
1 change: 1 addition & 0 deletions include/objclass.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
(liquid potion inside glass bottle, metal arrowhead on wooden shaft)
and object definitions only specify one type on a best-fit basis */
enum obj_material_types {
NO_MATERIAL = 0,
LIQUID = 1, /* currently only for venom */
WAX = 2,
VEGGY = 3, /* foodstuffs */
Expand Down
98 changes: 50 additions & 48 deletions src/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -2387,40 +2387,10 @@ map_glyphinfo(
#ifdef TEXTCOLOR
/* isok is used because this is sometimes called with 0,0 */
if (iflags.use_color && isok(x, y)) {
/* object or statue, which might be made of a non-default material or on
* stairs */
if (glyph_is_statue(glyph) || glyph_is_normal_object(glyph)
|| glyph_is_body(glyph)) {
struct obj *otmp = vobj_at(x, y);
if (otmp) {
if (otmp && otmp->material != objects[otmp->otyp].oc_material)
glyphinfo->gm.sym.color = materialclr[otmp->material];
if (On_stairs(x,y))
glyphinfo->gm.glyphflags |= MG_STAIRS;
}
/* !otmp is not actually impossible, because this is called from
* tmp_at(), in which an object is flying through the air above
* ground where there's usually no object.
* There is no single unified way to get the object that happens to
* be flying through the air. g.thrownobj and g.kickedobj are only
* set in a small number of cases involving flying objects, and it's
* possible that by comprehensively tracking them in all cases,
* !otmp would actually be an impossible case.
* This causes the following bugs (both of which were present before
* commit 1f6c1d0):
* 1. Flying objects' materials don't normally render. The object
* is shown as the base glyph no matter its material.
* 2. If a flying object passes over an object of a material
* that's not its base, it will briefly render as that material
* (since we have only x, y, and glyph here and vobj_at() can't
* tell that it's actually a flying object being mapped.)
* Another reason !otmp is not actually impossible is that the
* object could have been moved while out of sight.
else
impossible("no visible object at (%d, %d)?",
x, y);
*/
}
/* object or statue, which might be made of a non-default material or
* on stairs */
if (glyph_is_object(glyph) && On_stairs(x,y))
glyphinfo->gm.glyphflags |= MG_STAIRS;
/* iron door
* (only check closed door defsym range, not S_ndoor) */
else if (gmap->sym.symidx >= S_vodoor + SYM_OFF_P
Expand Down Expand Up @@ -2525,6 +2495,7 @@ int wallcolors[sokoban_walls + 1] = {
#define zap_color(n) color = iflags.use_color ? zapcolors[n] : NO_COLOR
#define cmap_color(n) color = iflags.use_color ? defsyms[n].color : NO_COLOR
#define obj_color(n) color = iflags.use_color ? objects[n].oc_color : NO_COLOR
#define material_color(n) color = iflags.use_color ? materialclr[n]: NO_COLOR
#define mon_color(n) \
color = iflags.use_color \
? g.monstercolors[n] != MONSTERCOLOR_DEFAULT \
Expand All @@ -2547,6 +2518,7 @@ int wallcolors[sokoban_walls + 1] = {
#define zap_color(n)
#define cmap_color(n)
#define obj_color(n)
#define material_color(n)
#define mon_color(n)
#define invis_color(n)
#define pet_color(c)
Expand Down Expand Up @@ -2618,30 +2590,55 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
color = NO_COLOR;
gmap->glyphflags |= MG_UNEXPL;
} else if ((offset = (glyph - GLYPH_STATUE_FEM_PILETOP_OFF)) >= 0) {
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
obj_color(STATUE);
int mat = (offset % NUM_MATERIAL_TYPES),
mid = (offset / NUM_MATERIAL_TYPES);
gmap->sym.symidx = mons[mid].mlet + SYM_OFF_M;
if (mat == objects[STATUE].oc_material || mat == NO_MATERIAL)
obj_color(STATUE);
else
material_color(mat);
gmap->glyphflags |= (MG_STATUE | MG_FEMALE | MG_OBJPILE);
} else if ((offset = (glyph - GLYPH_STATUE_MALE_PILETOP_OFF)) >= 0) {
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
obj_color(STATUE);
int mat = (offset % NUM_MATERIAL_TYPES),
mid = (offset / NUM_MATERIAL_TYPES);
gmap->sym.symidx = mons[mid].mlet + SYM_OFF_M;
if (mat == objects[STATUE].oc_material || mat == NO_MATERIAL)
obj_color(STATUE);
else
material_color(mat);
gmap->glyphflags |= (MG_STATUE | MG_MALE | MG_OBJPILE);
} else if ((offset = (glyph - GLYPH_BODY_PILETOP_OFF)) >= 0) {
gmap->sym.symidx = objects[CORPSE].oc_class + SYM_OFF_O;
mon_color(offset);
gmap->glyphflags |= (MG_CORPSE | MG_OBJPILE);
} else if ((offset = (glyph - GLYPH_OBJ_PILETOP_OFF)) >= 0) {
gmap->sym.symidx = objects[offset].oc_class + SYM_OFF_O;
if (offset == BOULDER)
int mat = (offset % NUM_MATERIAL_TYPES),
oid = (offset / NUM_MATERIAL_TYPES);
gmap->sym.symidx = objects[oid].oc_class + SYM_OFF_O;
if (oid == BOULDER)
gmap->sym.symidx = SYM_BOULDER + SYM_OFF_X;
obj_color(offset);
if (mat == objects[oid].oc_material || mat == NO_MATERIAL)
obj_color(oid);
else
material_color(mat);
gmap->glyphflags |= MG_OBJPILE;
} else if ((offset = (glyph - GLYPH_STATUE_FEM_OFF)) >= 0) {
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
obj_color(STATUE);
int mat = (offset % NUM_MATERIAL_TYPES),
mid = (offset / NUM_MATERIAL_TYPES);
gmap->sym.symidx = mons[mid].mlet + SYM_OFF_M;
if (mat == objects[STATUE].oc_material || mat == NO_MATERIAL)
obj_color(STATUE);
else
material_color(mat);
gmap->glyphflags |= (MG_STATUE | MG_FEMALE);
} else if ((offset = (glyph - GLYPH_STATUE_MALE_OFF)) >= 0) {
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
obj_color(STATUE);
int mat = (offset % NUM_MATERIAL_TYPES),
mid = (offset / NUM_MATERIAL_TYPES);
gmap->sym.symidx = mons[mid].mlet + SYM_OFF_M;
if (mat == objects[STATUE].oc_material || mat == NO_MATERIAL)
obj_color(STATUE);
else
material_color(mat);
gmap->glyphflags |= (MG_STATUE | MG_MALE);
} else if ((offset = (glyph - GLYPH_WARNING_OFF))
>= 0) { /* warn flash */
Expand Down Expand Up @@ -2749,10 +2746,15 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
gmap->sym.symidx = SYM_OFF_P;
cmap_color(S_stone);
} else if ((offset = (glyph - GLYPH_OBJ_OFF)) >= 0) {
gmap->sym.symidx = objects[offset].oc_class + SYM_OFF_O;
if (offset == BOULDER)
int mat = (offset % NUM_MATERIAL_TYPES),
oid = (offset / NUM_MATERIAL_TYPES);
gmap->sym.symidx = objects[oid].oc_class + SYM_OFF_O;
if (oid == BOULDER)
gmap->sym.symidx = SYM_BOULDER + SYM_OFF_X;
obj_color(offset);
if (mat == objects[oid].oc_material || mat == NO_MATERIAL)
obj_color(oid);
else
material_color(mat);
} else if ((offset = (glyph - GLYPH_RIDDEN_FEM_OFF)) >= 0) {
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
mon_color(offset);
Expand Down
4 changes: 3 additions & 1 deletion src/do.c
Original file line number Diff line number Diff line change
Expand Up @@ -1647,7 +1647,9 @@ goto_level(

/* Reset the screen. */
vision_reset(); /* reset the blockages */
reset_glyphmap(gm_levelchange);
/* reset_glyphmap call shouldn't be necessary unless different levels
require different glyphmap handling/trigger glyphmap change */
/* reset_glyphmap(gm_levelchange); */
docrt(); /* does a full vision recalc */
flush_screen(-1);

Expand Down
8 changes: 6 additions & 2 deletions src/pager.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ object_from_map(int glyph, int x, int y, struct obj **obj_p)
mtmp = 0;

if (!otmp || otmp->otyp != glyphotyp) {
int mat;
/* this used to exclude STRANGE_OBJECT; now caller deals with it */
otmp = mksobj(glyphotyp, FALSE, FALSE);
if (!otmp)
Expand All @@ -272,6 +273,10 @@ object_from_map(int glyph, int x, int y, struct obj **obj_p)
} else if (otmp->otyp == STATUE && glyph_is_statue(glyph)) {
otmp->corpsenm = glyph_to_statue_corpsenm(glyph);
}
mat = glyph_to_obj_material(glyph);
if (mat == NO_MATERIAL)
mat = objects[glyphotyp].oc_material;
otmp->material = mat;
if (otmp->otyp == LEASH)
otmp->leashmon = 0;
/* extra fields needed for shop price with doname() formatting */
Expand Down Expand Up @@ -627,9 +632,8 @@ lookat(int x, int y, char *buf, char *monbuf)
} else if (!glyph_is_cmap(glyph)) {
Strcpy(buf, "unexplored area");
} else {
int amsk;
int amsk, symidx = glyph_to_cmap(glyph);
aligntyp algn;
short symidx = glyph_to_cmap(glyph);

switch (symidx) {
case S_altar:
Expand Down
Loading