From 974b110bdeae7084b23c7e7192ad86146bfce586 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Fri, 24 Jun 2022 17:11:06 -0400 Subject: [PATCH 1/4] Expand glyphs, add object materials Create a glyph for each object/material combination. This means that material color is no longer assigned by a somewhat kludgy method that only works for items present on the floor, but the resulting number of glyphs is much larger. There aren't distinct tiles per material; every material glyph for a particular object shares the same base tileidx. This commit covers only normal objects, not corpses or statues. --- include/display.h | 31 ++++++++++++++++++++---------- include/objclass.h | 1 + src/display.c | 31 ++++++++++++++++++++---------- src/pager.c | 5 +++++ win/share/tilemap.c | 46 ++++++++++++++++++++++++--------------------- 5 files changed, 73 insertions(+), 41 deletions(-) diff --git a/include/display.h b/include/display.h index 41f22df0d..285526cc8 100644 --- a/include/display.h +++ b/include/display.h @@ -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() @@ -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), @@ -592,7 +593,7 @@ enum glyph_offsets { GLYPH_STATUE_FEM_OFF = (NUMMONS + GLYPH_STATUE_MALE_OFF), GLYPH_PILETOP_OFF = (NUMMONS + 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), @@ -923,10 +924,11 @@ enum glyph_offsets { (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 @@ -976,12 +978,20 @@ 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) \ @@ -1003,7 +1013,8 @@ enum glyph_offsets { #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 \ @@ -1016,7 +1027,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))) diff --git a/include/objclass.h b/include/objclass.h index 515d40f1e..440af8e24 100644 --- a/include/objclass.h +++ b/include/objclass.h @@ -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 */ diff --git a/src/display.c b/src/display.c index 62a9ab7ad..fe7f24a75 100644 --- a/src/display.c +++ b/src/display.c @@ -2387,16 +2387,15 @@ map_glyphinfo( #ifdef TEXTCOLOR /* isok is used because this is sometimes called with 0,0 */ if (iflags.use_color && isok(x, y)) { + if (On_stairs(x,y)) + glyphinfo->gm.glyphflags |= MG_STAIRS; /* 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)) { + if (glyph_is_statue(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 @@ -2525,6 +2524,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 \ @@ -2547,6 +2547,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) @@ -2630,10 +2631,15 @@ reset_glyphmap(enum glyphmap_change_triggers trigger) 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; @@ -2749,10 +2755,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); diff --git a/src/pager.c b/src/pager.c index 39638522a..9139b1bec 100644 --- a/src/pager.c +++ b/src/pager.c @@ -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) @@ -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 */ diff --git a/win/share/tilemap.c b/win/share/tilemap.c index 55adc2653..ed28af0b0 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -862,36 +862,40 @@ init_tilemap(void) /* start of objects */ file_entry = 0; - for (i = 0; i < NUM_OBJECTS; i++) { - tilemap[GLYPH_OBJ_OFF + i].tilenum = tilenum; - tilemap[GLYPH_OBJ_PILETOP_OFF + i].tilenum = tilenum; + for (k = 0; k < NUM_OBJECTS; k++) { + for (j = 0; j < NUM_MATERIAL_TYPES; j++) { + i = (k * NUM_MATERIAL_TYPES) + j; + /* printf("%d + %d = %d\n", k, j, i); */ + tilemap[GLYPH_OBJ_OFF + i].tilenum = tilenum; + tilemap[GLYPH_OBJ_PILETOP_OFF + i].tilenum = tilenum; #if defined(OBTAIN_TILEMAP) - Snprintf(tilemap[GLYPH_OBJ_OFF + i].name, - sizeof tilemap[GLYPH_OBJ_OFF + i].name, - "%s (onum=%d)", - tilename(OBJ_GLYPH, file_entry, 0), i); - Snprintf(tilemap[GLYPH_OBJ_PILETOP_OFF + i].name, - sizeof tilemap[GLYPH_OBJ_PILETOP_OFF + i].name, - "%s %s (onum=%d)", - "piletop" ,tilename(OBJ_GLYPH, file_entry, 0), i); - add_tileref(tilenum, GLYPH_OBJ_OFF + i, - objects_file, file_entry, - tilemap[GLYPH_OBJ_OFF + i].name, ""); - add_tileref(tilenum, GLYPH_OBJ_PILETOP_OFF + i, - objects_file, file_entry, - tilemap[GLYPH_OBJ_PILETOP_OFF + i].name, ""); + Snprintf(tilemap[GLYPH_OBJ_OFF + i].name, + sizeof tilemap[GLYPH_OBJ_OFF + i].name, + "%s (onum=%d, mat=%d)", + tilename(OBJ_GLYPH, file_entry, 0), k, j); + Snprintf(tilemap[GLYPH_OBJ_PILETOP_OFF + i].name, + sizeof tilemap[GLYPH_OBJ_PILETOP_OFF + i].name, + "%s %s (onum=%d, mat=%d)", + "piletop" ,tilename(OBJ_GLYPH, file_entry, 0), k, j); + add_tileref(tilenum, GLYPH_OBJ_OFF + i, + objects_file, file_entry, + tilemap[GLYPH_OBJ_OFF + i].name, ""); + add_tileref(tilenum, GLYPH_OBJ_PILETOP_OFF + i, + objects_file, file_entry, + tilemap[GLYPH_OBJ_PILETOP_OFF + i].name, ""); #endif + } for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) { if (conditionals[condnum].sequence == OBJ_GLYPH - && conditionals[condnum].predecessor == i) { - tilenum++; + && conditionals[condnum].predecessor == k) { + tilenum++; file_entry++; #if defined(OBTAIN_TILEMAP) Fprintf(tilemap_file, "skipping obj %s (%d)\n", tilename(OBJ_GLYPH, file_entry, 0), file_entry); #endif + } } - } tilenum++; file_entry++; } @@ -1407,7 +1411,7 @@ init_tilemap(void) Fprintf(tilemap_file, "skipping statue of %s (%d)\n", tilename(MON_GLYPH, file_entry, 0), file_entry); #endif - } + } } tilenum++; file_entry++; From 6c5d2f5b9779b2e207c4c94637413acea3536cdf Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Fri, 24 Jun 2022 18:38:40 -0400 Subject: [PATCH 2/4] Use object material glyphs for statues Use the same approach for statues as was used for "normal" objects in the previous commit. Does not include corpses, since they cannot normally be generated in anything but their base material to my knowledge. --- include/display.h | 69 +++++++++++++++++++++---------------- src/display.c | 71 +++++++++++++++++--------------------- src/pager.c | 3 +- win/share/tilemap.c | 84 +++++++++++++++++++++++++-------------------- 4 files changed, 118 insertions(+), 109 deletions(-) diff --git a/include/display.h b/include/display.h index 285526cc8..29d0529e4 100644 --- a/include/display.h +++ b/include/display.h @@ -590,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 * NUM_MATERIAL_TYPES) + 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 }; @@ -908,17 +913,21 @@ 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)) @@ -998,15 +1007,16 @@ enum glyph_offsets { : ((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}. */ @@ -1037,16 +1047,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) \ diff --git a/src/display.c b/src/display.c index fe7f24a75..de993dd72 100644 --- a/src/display.c +++ b/src/display.c @@ -2387,39 +2387,10 @@ map_glyphinfo( #ifdef TEXTCOLOR /* isok is used because this is sometimes called with 0,0 */ if (iflags.use_color && isok(x, y)) { - if (On_stairs(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; - /* object or statue, which might be made of a non-default material or on - * stairs */ - if (glyph_is_statue(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]; - } - /* !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); - */ - } /* iron door * (only check closed door defsym range, not S_ndoor) */ else if (gmap->sym.symidx >= S_vodoor + SYM_OFF_P @@ -2619,12 +2590,22 @@ 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; @@ -2642,12 +2623,22 @@ reset_glyphmap(enum glyphmap_change_triggers trigger) 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 */ diff --git a/src/pager.c b/src/pager.c index 9139b1bec..98d5d90e2 100644 --- a/src/pager.c +++ b/src/pager.c @@ -632,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: diff --git a/win/share/tilemap.c b/win/share/tilemap.c index ed28af0b0..c9aead60d 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -1343,7 +1343,7 @@ init_tilemap(void) #ifdef STATUES_DONT_LOOK_LIKE_MONSTERS /* statue patch: statues still use the same glyph as in 3.4.x */ - for (i = 0; i < NUMMONS; i++) { + for (i = 0; i < (NUMMONS * NUM_MATERIAL_TYPES); i++) { tilemap[GLYPH_STATUE_OFF + i].tilenum = tilemap[GLYPH_OBJ_OFF + STATUE].tilenum; #ifdef OBTAIN_TILEMAP @@ -1360,51 +1360,59 @@ init_tilemap(void) /* STATUES _DO_ LOOK LIKE MONSTERS */ file_entry = 0; /* statue patch: statues look more like the monster */ - for (i = 0; i < NUMMONS; i++) { - precheck(GLYPH_STATUE_MALE_OFF + i, "male statues"); - tilemap[GLYPH_STATUE_MALE_OFF + i].tilenum = tilenum; - precheck(GLYPH_STATUE_MALE_PILETOP_OFF + i, "male statue piletop"); - tilemap[GLYPH_STATUE_MALE_PILETOP_OFF + i].tilenum = tilenum; + for (k = 0; k < NUMMONS; k++) { + for (j = 0; j < NUM_MATERIAL_TYPES; j++) { + i = (k * NUM_MATERIAL_TYPES) + j; + precheck(GLYPH_STATUE_MALE_OFF + i, "male statues"); + tilemap[GLYPH_STATUE_MALE_OFF + i].tilenum = tilenum; + precheck(GLYPH_STATUE_MALE_PILETOP_OFF + i, "male statue piletop"); + tilemap[GLYPH_STATUE_MALE_PILETOP_OFF + i].tilenum = tilenum; #if defined(OBTAIN_TILEMAP) - Snprintf(tilemap[GLYPH_STATUE_MALE_OFF + i].name, - sizeof tilemap[0].name, - "statue of male %s (mnum=%d)", - tilename(MON_GLYPH, file_entry, 0), file_entry); - Snprintf(tilemap[GLYPH_STATUE_MALE_PILETOP_OFF + i].name, - sizeof tilemap[0].name, - "piletop statue of male %s (mnum=%d)", - tilename(MON_GLYPH, file_entry, 0), file_entry); - add_tileref(tilenum, GLYPH_STATUE_MALE_OFF + i, generated, file_entry, - tilemap[GLYPH_STATUE_MALE_OFF + i].name, - ""); - add_tileref(tilenum, GLYPH_STATUE_MALE_PILETOP_OFF + i, generated, - file_entry, - tilemap[GLYPH_STATUE_MALE_PILETOP_OFF + i].name, - ""); + Snprintf(tilemap[GLYPH_STATUE_MALE_OFF + i].name, + sizeof tilemap[0].name, + "statue of male %s (mnum=%d, mat=%d)", + tilename(MON_GLYPH, file_entry, 0), k, j); + Snprintf(tilemap[GLYPH_STATUE_MALE_PILETOP_OFF + i].name, + sizeof tilemap[0].name, + "piletop statue of male %s (mnum=%d, mat=%d)", + tilename(MON_GLYPH, file_entry, 0), k, j); + add_tileref(tilenum, GLYPH_STATUE_MALE_OFF + i, generated, + file_entry, tilemap[GLYPH_STATUE_MALE_OFF + i].name, + ""); + add_tileref(tilenum, GLYPH_STATUE_MALE_PILETOP_OFF + i, generated, + file_entry, + tilemap[GLYPH_STATUE_MALE_PILETOP_OFF + i].name, + ""); #endif + } tilenum++; file_entry++; - precheck(GLYPH_STATUE_FEM_OFF + i, "female statues"); - tilemap[GLYPH_STATUE_FEM_OFF + i].tilenum = tilenum; - precheck(GLYPH_STATUE_FEM_PILETOP_OFF + i, "female statue piletop"); - tilemap[GLYPH_STATUE_FEM_PILETOP_OFF + i].tilenum = tilenum; + for (j = 0; j < NUM_MATERIAL_TYPES; j++) { + i = (k * NUM_MATERIAL_TYPES) + j; + precheck(GLYPH_STATUE_FEM_OFF + i, "female statues"); + tilemap[GLYPH_STATUE_FEM_OFF + i].tilenum = tilenum; + precheck(GLYPH_STATUE_FEM_PILETOP_OFF + i, "female statue piletop"); + tilemap[GLYPH_STATUE_FEM_PILETOP_OFF + i].tilenum = tilenum; #if defined(OBTAIN_TILEMAP) - Snprintf(tilemap[GLYPH_STATUE_FEM_OFF + i].name, - sizeof tilemap[0].name, - "statue of female %s (mnum=%d)", - tilename(MON_GLYPH, file_entry, 0), file_entry); - Sprintf(tilemap[GLYPH_STATUE_FEM_PILETOP_OFF + i].name, - "piletop statue of female %s (mnum=%d)", - tilename(MON_GLYPH, file_entry, 0), file_entry); - add_tileref(tilenum, GLYPH_STATUE_FEM_OFF + i, generated, file_entry, - tilemap[GLYPH_STATUE_FEM_OFF + i].name, ""); - add_tileref(tilenum, GLYPH_STATUE_FEM_PILETOP_OFF + i, generated, - file_entry, - tilemap[GLYPH_STATUE_FEM_PILETOP_OFF + i].name, ""); + Snprintf(tilemap[GLYPH_STATUE_FEM_OFF + i].name, + sizeof tilemap[0].name, + "statue of female %s (mnum=%d, mat=%d)", + tilename(MON_GLYPH, file_entry, 0), k, j); + Snprintf(tilemap[GLYPH_STATUE_FEM_PILETOP_OFF + i].name, + sizeof tilemap[0].name, + "piletop statue of female %s (mnum=%d, mat=%d)", + tilename(MON_GLYPH, file_entry, 0), k, j); + add_tileref(tilenum, GLYPH_STATUE_FEM_OFF + i, generated, + file_entry, tilemap[GLYPH_STATUE_FEM_OFF + i].name, + ""); + add_tileref(tilenum, GLYPH_STATUE_FEM_PILETOP_OFF + i, generated, + file_entry, + tilemap[GLYPH_STATUE_FEM_PILETOP_OFF + i].name, ""); #endif + } for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) { if (conditionals[condnum].sequence == MON_GLYPH - && conditionals[condnum].predecessor == i) { + && conditionals[condnum].predecessor == k) { file_entry += 2; /* skip female tile too */ tilenum += 2; #if defined(OBTAIN_TILEMAP) From 34351f19a98906e2600002d768f910de1da125a1 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Fri, 24 Jun 2022 18:41:32 -0400 Subject: [PATCH 3/4] Remove level-change reset_glyphmap call As far as I know the only reason for calling reset_glyphmap upon every level change is in case the hero is entering or exiting the rogue level and the rogue symset/colors need to be switched with the normal symset/colors. Since xnh has removed the rogue level, this shouldn't be necessary, and removing it will reduce the amount of time spent on iterating through the increased number of glyphs. --- src/do.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/do.c b/src/do.c index 9fde4bd30..85efecf89 100644 --- a/src/do.c +++ b/src/do.c @@ -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); From 6434adb4716b242e3946653bc04c3ef2be78af5e Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Sun, 26 Jun 2022 09:48:55 -0400 Subject: [PATCH 4/4] Update missed obj glyph macro I overlooked objnum_to_glyph in the initial object material glyphs commit, so it was producing the wrong glyphs, turning the gold symbol in the bottom line to a ')'. --- include/display.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/display.h b/include/display.h index 29d0529e4..bc21d3fc7 100644 --- a/include/display.h +++ b/include/display.h @@ -703,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))