displaying generic objects

Add 17 fake objects to objects[], one for each object class.  All
specific color as gray.  They're grouped at the start--actually near
the start since "strange object" is still objects[0]--rather than
being among the objects for each class.  init_object() knows to start
at [MAXOCLASSES] instead of [0]; other code that loops through every
object might need adjusting.

For potions, non-stone gems, and non-novel/non-Book_of_the_Dead
spellbooks that don't have obj->dknown set, display the corresponding
generic object rather the object itself.  Fixes the longstanding bug
of seeing color for not-yet-seen objects whose primary distinguishing
characteristic is their color.  Walking next to a generic object
while able to see its spot will set dknown and redraw as specific.
It's slightly disconcerting to have objects change as you reach them;
I hope it's just a matter of becoming used to that.  (If there is any
code still changing the hero's location manually instead of using
u_on_newpos(), it should be changed to use that routine.)

Most of the new tiles are just a big rendering of punctuation
characters.  The potion, gem, and spellbook ones could be cloned from
a specific object in their class and then have the color removed.  I
started out that way but wasn't happy with the result.  I'm not
artisticly inclined; hopefully someone else will do better.  Each of
them is preceded by a comment beginning with "#_"; the underscore
isn't required, just being used to make the comments stand out a bit.

Invalidates existing save and bones files.
This commit is contained in:
PatR
2023-01-10 14:33:21 -08:00
parent 3f3c581f65
commit 85c908cb03
13 changed files with 994 additions and 529 deletions

View File

@@ -1058,6 +1058,9 @@ dump_enums(void)
static const struct enum_dump omdump[] = {
dump_om(FIRST_AMULET),
dump_om(LAST_AMULET),
dump_om(FIRST_POTION),
dump_om(LAST_POTION),
dump_om(NUM_POTIONS),
dump_om(FIRST_SPELL),
dump_om(LAST_SPELL),
dump_om(MAXSPELL),
@@ -1065,7 +1068,9 @@ dump_enums(void)
dump_om(LAST_REAL_GEM),
dump_om(FIRST_GLASS_GEM),
dump_om(LAST_GLASS_GEM),
dump_om(NUM_REAL_GEMS),
dump_om(NUM_GLASS_GEMS),
dump_om(MAX_GLYPH),
};
#undef dump_om
static const struct enum_dump *const ed[NUM_ENUM_DUMPS] = {
@@ -1075,16 +1080,16 @@ dump_enums(void)
static int szd[NUM_ENUM_DUMPS] = {
SIZE(monsdump), SIZE(objdump), SIZE(omdump)
};
int i, j;
const char *nmprefix;
int i, j, nmwidth;
for (i = 0; i < NUM_ENUM_DUMPS; ++ i) {
raw_printf("enum %s = {", titles[i]);
for (j = 0; j < szd[i]; ++j) {
raw_printf(" %s%s = %i%s",
(j == szd[i] - 1) ? "" : pfx[i],
ed[i][j].nm,
ed[i][j].val,
(j == szd[i] - 1) ? "" : ",");
nmprefix = (j == szd[i] - 1) ? "" : pfx[i]; /* "" or "PM_" */
nmwidth = 27 - (int) strlen(nmprefix); /* 27 or 24 */
raw_printf(" %s%*s = %3d,",
nmprefix, -nmwidth, ed[i][j].nm, ed[i][j].val);
}
raw_print("};");
raw_print("");

View File

@@ -588,6 +588,7 @@ const struct instance_globals_o g_init_o = {
UNDEFINED_PTR, /* occupation */
0, /* occtime */
UNDEFINED_VALUE, /* otg_temp */
NULL, /* otg_otmp */
NULL, /* occtxt */
/* symbols.c */
DUMMY, /* ov_primary_syms */

View File

@@ -309,13 +309,23 @@ map_trap(register struct trap *trap, register int show)
*
* Map the given object. This routine assumes that the hero can physically
* see the location of the object. Update the screen if directed.
* [Note: feel_location() -> map_location() -> map_object() contradicts
* the claim here that the hero can see obj's <ox,oy>.]
*/
void
map_object(register struct obj *obj, register int show)
map_object(register struct obj *obj, int show)
{
register coordxy x = obj->ox, y = obj->oy;
register int glyph = obj_to_glyph(obj, newsym_rn2);
/* if this object is already displayed as a generic object, it might
become a specific one now */
if (glyph_is_generic_object(glyph) && cansee(x, y) && next2u(x, y)
&& !Hallucination) {
obj->dknown = 1;
glyph = obj_to_glyph(obj, newsym_rn2);
}
if (gl.level.flags.hero_memory) {
/* MRKR: While hallucinating, statues are seen as random monsters */
/* but remembered as random objects. */
@@ -1425,6 +1435,29 @@ see_objects(void)
update_inventory();
}
/* mark the top object of each adjacent stack as having been seen, and
if it was being displayed as generic, redisplay it as specific */
void
see_nearby_objects(void)
{
struct obj *obj;
int glyph;
coordxy ix, iy, x = u.ux, y = u.uy;
for (iy = y - 1; iy <= y + 1; ++iy)
for (ix = x - 1; ix <= x + 1; ++ix) {
if (!isok(ix, iy) || !cansee(ix, iy))
continue;
if ((obj = vobj_at(ix, iy)) != 0) {
obj->dknown = 1; /* adjacent, so close enough to see it */
/* operate on remembered glyph rather than current one */
glyph = levl[ix][iy].glyph;
if (glyph_is_generic_object(glyph))
newsym_force(ix, iy);
}
}
}
/*
* Update hallucinated traps.
*/
@@ -1697,8 +1730,10 @@ show_glyph(coordxy x, coordxy y, int glyph)
text = "statue of a male monster at top of a pile";
} else if ((offset = (glyph - GLYPH_BODY_PILETOP_OFF)) >= 0) {
text = "body at top of a pile";
} else if ((offset = (glyph - GLYPH_OBJ_PILETOP_OFF))) {
text = "object at top of a pile";
} else if ((offset = (glyph - GLYPH_OBJ_PILETOP_OFF)) >= 0) {
text = (glyph_is_piletop_generic_obj(glyph)
? "generic object at top of a pile"
: "object at top of a pile");
} else if ((offset = (glyph - GLYPH_STATUE_FEM_OFF)) >= 0) {
text = "statue of female monster";
} else if ((offset = (glyph - GLYPH_STATUE_MALE_OFF)) >= 0) {
@@ -1745,7 +1780,9 @@ show_glyph(coordxy x, coordxy y, int glyph)
} else if ((offset = (glyph - GLYPH_CMAP_STONE_OFF)) >= 0) {
text = "stone";
} else if ((offset = (glyph - GLYPH_OBJ_OFF)) >= 0) {
text = "object";
text = (glyph_is_normal_generic_obj(glyph)
? "generic object"
: "object");
} else if ((offset = (glyph - GLYPH_RIDDEN_FEM_OFF)) >= 0) {
text = "ridden female monster";
} else if ((offset = (glyph - GLYPH_RIDDEN_MALE_OFF)) >= 0) {

View File

@@ -1426,7 +1426,7 @@ void
u_on_newpos(coordxy x, coordxy y)
{
if (!isok(x, y)) { /* validate location */
void (*func)(const char *, ...);
void (*func)(const char *, ...) PRINTF_F_PTR(1, 2);
func = (x < 0 || y < 0 || x > COLNO - 1 || y > ROWNO - 1) ? panic
: impossible;
@@ -1445,6 +1445,10 @@ u_on_newpos(coordxy x, coordxy y)
stale values from previous level */
if (!on_level(&u.uz, &u.uz0))
u.ux0 = u.ux, u.uy0 = u.uy;
else if (!Blind && !Hallucination)
/* still on same level; might have come close enough to
generic object(s) to redisplay them as specific objects */
see_nearby_objects();
}
/* place you on a random location when arriving on a level */

View File

@@ -31,8 +31,10 @@ shuffle_tiles(void)
short tmp_tilemap[2][NUM_OBJECTS];
for (i = 0; i < NUM_OBJECTS; i++) {
tmp_tilemap[0][i] = glyphmap[objects[i].oc_descr_idx + GLYPH_OBJ_OFF].tileidx;
tmp_tilemap[1][i] = glyphmap[objects[i].oc_descr_idx + GLYPH_OBJ_PILETOP_OFF].tileidx;
tmp_tilemap[0][i] = glyphmap[objects[i].oc_descr_idx
+ GLYPH_OBJ_OFF].tileidx;
tmp_tilemap[1][i] = glyphmap[objects[i].oc_descr_idx
+ GLYPH_OBJ_PILETOP_OFF].tileidx;
}
for (i = 0; i < NUM_OBJECTS; i++) {
glyphmap[i + GLYPH_OBJ_OFF].tileidx = tmp_tilemap[0][i];
@@ -122,17 +124,19 @@ init_objects(void)
#define COPY_OBJ_DESCR(o_dst, o_src) o_dst.oc_descr_idx = o_src.oc_descr_idx
#endif
/* bug fix to prevent "initialization error" abort on Intel Xenix.
* reported by mikew@semike
*/
for (i = 0; i <= MAXOCLASSES; i++)
for (i = 0; i <= MAXOCLASSES; i++) {
gb.bases[i] = 0;
if (i > 0 && i < MAXOCLASSES && objects[i].oc_class != i)
panic(
"init_objects: class for generic object #%d doesn't match (%d)",
i, objects[i].oc_class);
}
/* initialize object descriptions */
for (i = 0; i < NUM_OBJECTS; i++)
objects[i].oc_name_idx = objects[i].oc_descr_idx = i;
/* init base; if probs given check that they add up to 1000,
otherwise compute probs */
first = 0;
first = MAXOCLASSES;
prevoclass = -1;
while (first < NUM_OBJECTS) {
oclass = objects[first].oc_class;
@@ -188,7 +192,7 @@ init_objects(void)
gb.bases[last] = gb.bases[last + 1];
/* check objects[].oc_name_known */
for (i = 0; i < NUM_OBJECTS; ++i) {
for (i = MAXOCLASSES; i < NUM_OBJECTS; ++i) {
int nmkn = objects[i].oc_name_known != 0;
if (!OBJ_DESCR(objects[i]) ^ nmkn) {