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

@@ -1082,6 +1082,8 @@ when identifying items via menu and more than one pass is needed (so when
identifying 3 items and player only picks 1, for instance), issue
--More-- because the next menu might cover up the ID message(s)
slightly more interesting Gehennom filler levels
don't reveal color of potions, gems, or spellbooks that haven't been seen up
close (seeing faraway monster operate on an object counts as up close)
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository

View File

@@ -1259,6 +1259,7 @@ struct instance_globals_o {
int (*occupation)(void);
int occtime;
int otg_temp; /* used by object_to_glyph() [otg] */
struct obj *otg_otmp; /* used by obj_is_piletop() */
const char *occtxt; /* defined when occupation != NULL */
/* symbols.c */

View File

@@ -388,7 +388,15 @@ enum glyphmap_change_triggers { gm_nochange, gm_newgame, gm_levelchange,
* ridden (female) Represents all female monsters being ridden.
* Count: NUMMONS
*
* object One for each object.
* object One for each type of object. The first entry is
* 'strange object', the next 1..MAXOCLASSES-1 entries
* are generic (one for each class, including one for
* strange object's 'illobj class'), the rest are
* regular objects. Some members of the generic
* subset are used to prevent color of potions, gems,
* and spellbooks from being revealed when obj->dknown
* hasn't been set, avoiding a bug which had been
* present since day one of color support.
* Count: NUM_OBJECTS
*
* Stone Stone
@@ -451,7 +459,8 @@ enum glyphmap_change_triggers { gm_nochange, gm_newgame, gm_levelchange,
* frosty explosions A set of nine.
* Count: MAXEXPCHAR
*
* warning A set of six representing the different warning levels.
* warning A set of six representing the different warning
* levels.
* Count: 6
*
* statues (male) One for each male monster.
@@ -749,7 +758,8 @@ enum glyph_offsets {
#define glyph_is_normal_female_monster(glyph) \
((glyph) >= GLYPH_MON_FEM_OFF && (glyph) < (GLYPH_MON_FEM_OFF + NUMMONS))
#define glyph_is_normal_monster(glyph) \
(glyph_is_normal_male_monster(glyph) || glyph_is_normal_female_monster(glyph))
(glyph_is_normal_male_monster(glyph) \
|| glyph_is_normal_female_monster(glyph))
#define glyph_is_female_pet(glyph) \
((glyph) >= GLYPH_PET_FEM_OFF && (glyph) < (GLYPH_PET_FEM_OFF + NUMMONS))
#define glyph_is_male_pet(glyph) \
@@ -799,10 +809,23 @@ enum glyph_offsets {
? ((glyph) - GLYPH_RIDDEN_MALE_OFF) \
: NUMMONS)
/* boulder hides pile except when on top of another boulder;
the otg_otmp assignment might occur multiple times in the same
expression but there will always be sequence points in between */
#define obj_is_piletop(obj) \
((obj)->where == OBJ_FLOOR \
/*&& gl.level.objects[(obj)->ox][(obj)->oy]*/ \
&& gl.level.objects[(obj)->ox][(obj)->oy]->nexthere)
&& (go.otg_otmp = gl.level.objects[(obj)->ox][(obj)->oy]->nexthere) != 0 \
&& ((obj)->otyp != BOULDER || go.otg_otmp->otyp == BOULDER))
/* used to hide info such as potion and gem color when not seen yet;
stones and rock are excluded for gem class; LAST_SPELL includes blank
spellbook but excludes novel and the Book of the Dead */
#define obj_is_generic(obj) \
(!(obj)->dknown \
&& ((obj)->oclass == POTION_CLASS \
|| ((obj)->otyp >= FIRST_REAL_GEM \
&& ((obj)->otyp <= LAST_GLASS_GEM)) \
|| ((obj)->otyp >= FIRST_SPELL \
&& ((obj)->otyp <= LAST_SPELL))))
#define glyph_is_body_piletop(glyph) \
(((glyph) >= GLYPH_BODY_PILETOP_OFF) \
@@ -827,17 +850,31 @@ enum glyph_offsets {
|| glyph_is_male_statue_piletop(glyph))
#define glyph_is_statue(glyph) \
(glyph_is_male_statue(glyph) || glyph_is_fem_statue(glyph))
/* note: 'strange object' gets [mis?]classified as generic here but that
shouldn't impact anything; to do it properly, glyph_is_normal_generic_obj()
and glyph_is_piletop_generic_obj() should use '>' rather than '>=', and
glyph_is_normal_object() and glyph_is_normal_piletop_obj() should include
(glyph == {GLYPH_OBJ_OFF,GLYPH_OBJ_PILETOP_OFF}) to test for object #0 */
#define glyph_is_normal_generic_obj(glyph) \
((glyph) >= GLYPH_OBJ_OFF && (glyph) < GLYPH_OBJ_OFF + MAXOCLASSES)
#define glyph_is_piletop_generic_obj(glyph) \
((glyph) >= GLYPH_OBJ_PILETOP_OFF \
&& (glyph) < GLYPH_OBJ_PILETOP_OFF + MAXOCLASSES)
#define glyph_is_generic_object(glyph) \
(glyph_is_normal_generic_obj(glyph) \
|| glyph_is_piletop_generic_obj(glyph))
#define glyph_is_normal_piletop_obj(glyph) \
(((glyph) >= GLYPH_OBJ_PILETOP_OFF) \
(((glyph) >= GLYPH_OBJ_PILETOP_OFF + MAXOCLASSES) \
&& ((glyph) < (GLYPH_OBJ_PILETOP_OFF + NUM_OBJECTS)))
#define glyph_is_normal_object(glyph) \
((((glyph) >= GLYPH_OBJ_OFF) \
((((glyph) >= GLYPH_OBJ_OFF + MAXOCLASSES) \
&& ((glyph) < (GLYPH_OBJ_OFF + NUM_OBJECTS))) \
|| glyph_is_normal_piletop_obj(glyph))
#if 0
#if 0 /* [note: out of date] */
#define glyph_is_object(glyph) \
((((glyph) >= GLYPH_OBJ_OFF) && ((glyph) < (GLYPH_OBJ_OFF + NUM_OBJECTS))) \
( (((glyph) >= GLYPH_OBJ_OFF) \
&& ((glyph) < (GLYPH_OBJ_OFF + NUM_OBJECTS))) \
|| (((glyph) >= GLYPH_OBJ_PILETOP_OFF) \
&& ((glyph) < (GLYPH_OBJ_PILETOP_OFF + NUM_OBJECTS))) \
|| (((glyph) >= GLYPH_STATUE_MALE_OFF) \
@@ -851,15 +888,16 @@ enum glyph_offsets {
|| (((glyph) >= GLYPH_BODY_OFF) \
&& ((glyph) < (GLYPH_BODY_OFF + NUMMONS))) \
|| (((glyph) >= GLYPH_BODY_PILETOP_OFF) \
&& ((glyph) < (GLYPH_BODY_PILETOP_OFF + NUMMONS))))
&& ((glyph) < (GLYPH_BODY_PILETOP_OFF + NUMMONS))) \
)
#endif
#define glyph_is_object(glyph) \
(glyph_is_normal_object(glyph) || glyph_is_statue(glyph) \
|| glyph_is_body(glyph))
(glyph_is_normal_object(glyph) || glyph_is_generic_object(glyph) \
|| glyph_is_statue(glyph) || glyph_is_body(glyph))
/* briefly used for Qt's "paper doll" inventory which shows map tiles for
equipped objects; those vary like floor items during hallucination now
so this isn't used anywhere */
so this isn't used anywhere [note: out of date since generic objs added] */
#define obj_to_true_glyph(obj) \
(((obj)->otyp == STATUE) \
? ((int) (obj)->corpsenm \
@@ -881,10 +919,14 @@ enum glyph_offsets {
#define glyph_to_obj(glyph) \
(glyph_is_body(glyph) ? CORPSE \
: glyph_is_statue(glyph) ? STATUE \
: glyph_is_normal_object(glyph) \
: glyph_is_generic_object(glyph) \
? ((glyph) - (glyph_is_piletop_generic_obj(glyph) \
? GLYPH_OBJ_PILETOP_OFF \
: GLYPH_OBJ_OFF)) \
: glyph_is_normal_object(glyph) \
? ((glyph) - (glyph_is_normal_piletop_obj(glyph) \
? GLYPH_OBJ_PILETOP_OFF \
: GLYPH_OBJ_OFF)) \
? GLYPH_OBJ_PILETOP_OFF \
: GLYPH_OBJ_OFF)) \
: NUM_OBJECTS)
#define glyph_to_body_corpsenm(glyph) \
@@ -903,27 +945,21 @@ enum glyph_offsets {
? ((glyph) - GLYPH_STATUE_MALE_OFF) \
: NO_GLYPH)
/* These have the unfortunate side effect of needing a global variable */
/* to store a result. 'otg_temp' is defined and declared in decl.{ch}. */
/* This has 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) \
((go.otg_temp = random_object(rng)) == CORPSE \
(((go.otg_temp = random_object(rng)) == CORPSE) \
? (random_monster(rng) + GLYPH_BODY_OFF) \
: (go.otg_temp + GLYPH_OBJ_OFF))
#define corpse_to_glyph(obj) \
((int) ((obj)->corpsenm + (obj_is_piletop(obj) \
? GLYPH_BODY_PILETOP_OFF \
: GLYPH_BODY_OFF)))
/* Paraphrased rationale from the original commit for the boulder
exception: If a boulder is the topmost item on a pile, then it is
not mapped to a piletop glyph; mainly because boulders are "solid";
boulders dropped by monsters are nearly always over other objects;
also done so that special levels such a Sokoban can "hide" items
under the boulders. */
((int) ((obj)->corpsenm \
+ (obj_is_piletop(obj) ? GLYPH_BODY_PILETOP_OFF : GLYPH_BODY_OFF)))
#define generic_obj_to_glyph(obj) \
((int) ((obj)->oclass \
+ (obj_is_piletop(obj) ? GLYPH_OBJ_PILETOP_OFF : GLYPH_OBJ_OFF)))
#define normal_obj_to_glyph(obj) \
((int) ((obj)->otyp + ((obj_is_piletop(obj) && ((obj)->otyp != BOULDER)) \
? GLYPH_OBJ_PILETOP_OFF \
: GLYPH_OBJ_OFF)))
((int) ((obj)->otyp \
+ (obj_is_piletop(obj) ? GLYPH_OBJ_PILETOP_OFF : GLYPH_OBJ_OFF)))
/* MRKR: Statues now have glyphs corresponding to the monster they */
/* represent and look like monsters when you are hallucinating. */
@@ -942,13 +978,11 @@ enum glyph_offsets {
: GLYPH_STATUE_MALE_OFF))))
#define obj_to_glyph(obj, rng) \
(((obj)->otyp == STATUE) \
? statue_to_glyph(obj, rng) \
: ((Hallucination) \
? random_obj_to_glyph(rng) \
: (((obj)->otyp == CORPSE) \
? corpse_to_glyph(obj) \
: normal_obj_to_glyph(obj))))
(((obj)->otyp == STATUE) ? statue_to_glyph(obj, rng) \
: (Hallucination) ? random_obj_to_glyph(rng) \
: ((obj)->otyp == CORPSE) ? corpse_to_glyph(obj) \
: obj_is_generic(obj) ? generic_obj_to_glyph(obj) \
: normal_obj_to_glyph(obj))
#define GLYPH_TRAP_OFF \
(GLYPH_CMAP_B_OFF + (S_arrow_trap - S_grave))
@@ -963,8 +997,10 @@ enum glyph_offsets {
#if 0
#define glyph_is_piletop(glyph) \
(glyph_is_body_piletop(glyph) || glyph_is_statue_piletop(glyph) \
|| glyph_is_obj_piletop(glyph))
(glyph_is_body_piletop(glyph) \
|| glyph_is_statue_piletop(glyph) \
|| glyph_is_piletop_generic_obj(glyph) \
|| glyph_is_obj_piletop(glyph))
#endif
/* mgflags for altering map_glyphinfo() internal behavior */

View File

@@ -430,6 +430,7 @@ extern void under_water(int);
extern void see_monsters(void);
extern void set_mimic_blocking(void);
extern void see_objects(void);
extern void see_nearby_objects(void);
extern void see_traps(void);
extern void curs_on_u(void);
extern int doredraw(void);

View File

@@ -171,11 +171,12 @@ enum objects_nums {
};
enum misc_object_nums {
NUM_POTIONS = (LAST_POTION - FIRST_POTION + 1),
NUM_REAL_GEMS = (LAST_REAL_GEM - FIRST_REAL_GEM + 1),
NUM_GLASS_GEMS = (LAST_GLASS_GEM - FIRST_GLASS_GEM + 1),
/* 1st +1: last-first subtraction; 2nd +1: extra empty spl_book[] slot;
currently LAST_SPELL includes blank, novel, and DeadBook so this
overallocates when used to define spl_book[] array */
MAXSPELL = (LAST_SPELL + 1 - FIRST_SPELL + 1),
/* LAST_SPELL is SPE_BLANK_PAPER, guaranteeing that spl_book[] will
have at least one unused slot at end to be used as a terminator */
MAXSPELL = (LAST_SPELL - FIRST_SPELL + 1),
};
extern NEARDATA struct objclass objects[NUM_OBJECTS + 1];

View File

@@ -66,10 +66,38 @@
#error Unproductive inclusion of objects.h
#endif /* OBJECTS_DESCR_INIT || OBJECTS_INIT || OBJECTS_ENUM */
#define GENERIC(desc, class, gen_enum) \
OBJECT(OBJ(NoDes, desc), \
BITS(0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, P_NONE, 0), \
0, class, 0, 0, 0, 0, 0, 0, 0, 0, 0, CLR_GRAY, gen_enum)
/* dummy object[0] -- description [2nd arg] *must* be NULL */
OBJECT(OBJ("strange object", NoDes),
BITS(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, P_NONE, 0),
0, ILLOBJ_CLASS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, STRANGE_OBJECT),
/* slots [1] through [MAXOCLASSES-1] are indexed by class; some are
used for display purposes, most aren't used; none are actual objects;
note that 'real' strange object is in slot [0] but ILLOBJ_CLASS is 1
so we add a dummy for it in slot [1] to simplify accessing the rest;
there isn't any entry for RANDOM_CLASS (0) */
GENERIC("strange", ILLOBJ_CLASS, GENERIC_ILLOBJ), /* [1] */
GENERIC("weapon", WEAPON_CLASS, GENERIC_WEAPON), /* [2] */
GENERIC("armor", ARMOR_CLASS, GENERIC_ARMOR), /* [3] */
GENERIC("ring", RING_CLASS, GENERIC_RING), /* [4] */
GENERIC("amulet", AMULET_CLASS, GENERIC_AMULET), /* [5] */
GENERIC("tool", TOOL_CLASS, GENERIC_TOOL), /* [6] */
GENERIC("food", FOOD_CLASS, GENERIC_FOOD), /* [7] */
GENERIC("potion", POTION_CLASS, GENERIC_POTION), /* [8] */
GENERIC("scroll", SCROLL_CLASS, GENERIC_SCROLL), /* [9] */
GENERIC("spellbook", SPBOOK_CLASS, GENERIC_SPBOOK), /* [10] */
GENERIC("wand", WAND_CLASS, GENERIC_WAND), /* [11] */
GENERIC("coin", COIN_CLASS, GENERIC_COIN), /* [12] */
GENERIC("gem", GEM_CLASS, GENERIC_GEM), /* [13] */
GENERIC("large rock", ROCK_CLASS, GENERIC_ROCK), /* [14] bldr+statue */
GENERIC("iron ball", BALL_CLASS, GENERIC_BALL), /* [15] */
GENERIC("iron chain", CHAIN_CLASS, GENERIC_CHAIN), /* [16] */
GENERIC("venom", VENOM_CLASS, GENERIC_VENOM), /* [17] */
#undef GENERIC
/* weapons ... */
#define WEAPON(name,desc,kn,mg,bi,prob,wt, \
@@ -1045,6 +1073,7 @@ FOOD("tin", 75, 0, 10, 1, METAL, 0, HI_METAL, TIN),
power, POTION_CLASS, prob, 0, 20, cost, 0, 0, 0, 0, 10, color, sn)
POTION("gain ability", "ruby", 1, 0, 42, 300, CLR_RED,
POT_GAIN_ABILITY),
MARKER(FIRST_POTION, POT_GAIN_ABILITY)
POTION("restore ability", "pink", 1, 0, 40, 100, CLR_BRIGHT_MAGENTA,
POT_RESTORE_ABILITY),
POTION("confusion", "orange", 1, CONFUSION, 42, 100, CLR_ORANGE,
@@ -1097,6 +1126,7 @@ POTION("oil", "murky", 0, 0, 30, 250, CLR_BROWN,
*/
POTION("water", "clear", 0, 0, 92, 100, CLR_CYAN,
POT_WATER),
MARKER(LAST_POTION, POT_WATER)
#undef POTION
/* scrolls ... */
@@ -1338,6 +1368,11 @@ SPELL("freeze sphere", "hardcover",
*/
SPELL("blank paper", "plain", P_NONE, 18, 0, 0, 0, 0, HI_PAPER,
SPE_BLANK_PAPER),
/* LAST_SPELL is used to calculate MAXSPELL, allocation size of spl_book[];
by including blank paper, which has no actual spell, we ensure that
even if hero learns every spell, spl_book[] will have at least one
unused slot at end; an unused slot is needed for use as terminator */
MARKER(LAST_SPELL, SPE_BLANK_PAPER)
/* tribute book for 3.6 */
OBJECT(OBJ("novel", "paperback"),
BITS(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, P_NONE, PAPER),
@@ -1348,10 +1383,6 @@ OBJECT(OBJ("Book of the Dead", "papyrus"),
BITS(0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, P_NONE, PAPER),
0, SPBOOK_CLASS, 0, 0, 20, 10000, 0, 0, 0, 7, 20, HI_PAPER,
SPE_BOOK_OF_THE_DEAD),
/* LAST_SPELL is used to compute MAXSPELL and should probably be
SPE_BLANK_PAPER-1 since there's no need for spl_book[] slots for
blank, novel, and Book of the Dead */
MARKER(LAST_SPELL, SPE_BOOK_OF_THE_DEAD)
#undef SPELL
/* wands ... */
@@ -1488,7 +1519,7 @@ GEM("worthless piece of blue glass", "blue",
GEM("worthless piece of red glass", "red",
77, 1, 0, 6, 5, GLASS, CLR_RED, WORTHLESS_RED_GLASS),
GEM("worthless piece of yellowish brown glass", "yellowish brown",
77, 1, 0, 6, 5, GLASS, CLR_BROWN, WORTHLESS_YELLOWISH_BROWN_GLASS),
77, 1, 0, 6, 5, GLASS, CLR_BROWN, WORTHLESS_YELLOWBROWN_GLASS),
GEM("worthless piece of orange glass", "orange",
76, 1, 0, 6, 5, GLASS, CLR_ORANGE, WORTHLESS_ORANGE_GLASS),
GEM("worthless piece of yellow glass", "yellow",

View File

@@ -17,7 +17,7 @@
* Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files.
*/
#define EDITLEVEL 67
#define EDITLEVEL 68
/*
* Development status possibilities.

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) {

File diff suppressed because it is too large Load Diff