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:
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user