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:
@@ -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("");
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
20
src/o_init.c
20
src/o_init.c
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user