1 /* SCCS Id: @(#)display.c 3.4 2003/02/19 */
2 /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */
3 /* and Dave Cohrs, 1990. */
4 /* NetHack may be freely redistributed. See license for details. */
9 * The old display code has been broken up into three parts: vision, display,
10 * and drawing. Vision decides what locations can and cannot be physically
11 * seen by the hero. Display decides _what_ is displayed at a given location.
12 * Drawing decides _how_ to draw a monster, fountain, sword, etc.
14 * The display system uses information from the vision system to decide
15 * what to draw at a given location. The routines for the vision system
16 * can be found in vision.c and vision.h. The routines for display can
17 * be found in this file (display.c) and display.h. The drawing routines
18 * are part of the window port. See doc/window.doc for the drawing
21 * The display system deals with an abstraction called a glyph. Anything
22 * that could possibly be displayed has a unique glyph identifier.
24 * What is seen on the screen is a combination of what the hero remembers
25 * and what the hero currently sees. Objects and dungeon features (walls
26 * doors, etc) are remembered when out of sight. Monsters and temporary
27 * effects are not remembered. Each location on the level has an
28 * associated glyph. This is the hero's _memory_ of what he or she has
33 * If the location is in sight, display in order:
34 * visible (or sensed) monsters
39 * If the location is out of sight, display in order:
40 * sensed monsters (telepathy)
45 * Here is a list of the major routines in this file to be used externally:
49 * Possibly update the screen location (x,y). This is the workhorse routine.
50 * It is always correct --- where correct means following the in-sight/out-
51 * of-sight rules. **Most of the code should use this routine.** This
52 * routine updates the map and displays monsters.
61 * If you absolutely must override the in-sight/out-of-sight rules, there
62 * are two possibilities. First, you can mess with vision to force the
63 * location in sight then use newsym(), or you can use the map_* routines.
64 * The first has not been tried [no need] and the second is used in the
65 * detect routines --- detect object, magic mapping, etc. The map_*
66 * routines *change* what the hero remembers. All changes made by these
67 * routines will be sticky --- they will survive screen redraws. Do *not*
68 * use these for things that only temporarily change the screen. These
69 * routines are also used directly by newsym(). unmap_object is used to
70 * clear a remembered object when/if detection reveals it isn't there.
75 * This is direct (no processing in between) buffered access to the screen.
76 * Temporary screen effects are run through this and its companion,
77 * flush_screen(). There is yet a lower level routine, print_glyph(),
78 * but this is unbuffered and graphic dependent (i.e. it must be surrounded
79 * by graphic set-up and tear-down routines). Do not use print_glyph().
86 * These are only used when something affects all of the monsters or
87 * objects or traps. For objects and traps, the only thing is hallucination.
88 * For monsters, there are hallucination and changing from/to blindness, etc.
93 * This is a useful interface for displaying temporary items on the screen.
94 * Its interface is different than previously, so look at it carefully.
98 * Parts of the rm structure that are used:
100 * typ - What is really there.
101 * glyph - What the hero remembers. This will never be a monster.
102 * Monsters "float" above this.
103 * lit - True if the position is lit. An optimization for
105 * waslit - True if the position was *remembered* as lit.
106 * seenv - A vector of bits representing the directions from which the
107 * hero has seen this position. The vector's primary use is
108 * determining how walls are seen. E.g. a wall sometimes looks
109 * like stone on one side, but is seen as a wall from the other.
110 * Other uses are for unmapping detected objects and felt
111 * locations, where we need to know if the hero has ever
113 * flags - Additional information for the typ field. Different for
115 * horizontal - Indicates whether the wall or door is horizontal or
121 STATIC_DCL
void display_monster(XCHAR_P
,XCHAR_P
,struct monst
*,int,XCHAR_P
);
122 STATIC_DCL
void display_monsterX(XCHAR_P
,XCHAR_P
,struct monst
*,int,XCHAR_P
);
123 STATIC_DCL
int swallow_to_glyph(int, int);
124 STATIC_DCL
void display_warning(struct monst
*);
125 STATIC_DCL
void display_warningX(struct monst
*);
127 STATIC_DCL
int check_pos(int, int, int);
129 STATIC_DCL boolean
more_than_one(int, int, int, int, int);
131 STATIC_DCL
int set_twall(int,int, int,int, int,int, int,int);
132 STATIC_DCL
int set_wall(int, int, int);
133 STATIC_DCL
int set_corn(int,int, int,int, int,int, int,int);
134 STATIC_DCL
int set_crosswall(int, int);
135 STATIC_DCL
void set_seenv(struct rm
*, int, int, int, int);
136 STATIC_DCL
void t_warn(struct rm
*);
137 STATIC_DCL
int wall_angle(struct rm
*);
138 STATIC_DCL
int back_to_cmap(XCHAR_P
, XCHAR_P
);
140 STATIC_VAR boolean transp
; /* cached transparency flag for current tileset */
142 STATIC_DCL
int randomglyph(void);
147 * Returns a pointer to an object if the hero can see an object at the
148 * given location. This takes care of invisible objects. NOTE, this
149 * assumes that the hero is not blind and on top of the object pile.
150 * It does NOT take into account that the location is out of sight, or,
151 * say, one can see blessed, etc.
157 register struct obj
*obj
= level
.objects
[x
][y
];
160 if ((!obj
->oinvis
|| See_invisible
) && !obj
->oinvisreal
) return obj
;
163 return ((struct obj
*) 0);
172 return cmap_to_glyph(rnd(S_grayglyph
));
174 return cmap_to_glyph((S_arrow_trap
+ rn2(S_timerun_trap
+ 1 - S_arrow_trap
)));
176 return (GLYPH_MON_OFF
+ rn2(NUMMONS
));
178 return (GLYPH_OBJ_OFF
+ rn2(NUM_OBJECTS
));
180 return (GLYPH_WARNING_OFF
+ rn2(WARNCOUNT
));
183 return cmap_to_glyph(rnd(S_grayglyph
)); /* "non-void function does not return a value in all control paths" */
187 * magic_map_background()
189 * This function is similar to map_background (see below) except we pay
190 * attention to and correct unexplored, lit ROOM and CORR spots.
193 magic_map_background(x
, y
, show
)
197 int cmap
= back_to_cmap(x
,y
); /* assumes hero can see x,y */
198 struct rm
*lev
= &levl
[x
][y
];
201 * Correct for out of sight lit corridors and rooms that the hero
202 * doesn't remember as lit.
204 if (!cansee(x
,y
) && !lev
->waslit
) {
205 /* Floor spaces are dark if unlit. Corridors are dark if unlit. */
206 if (lev
->typ
== ROOM
&& cmap
== S_room
)
208 else if (lev
->typ
== CORR
&& cmap
== S_litcorr
)
211 if (level
.flags
.hero_memory
)
212 #ifdef DISPLAY_LAYERS
215 lev
->glyph
= cmap_to_glyph(cmap
);
217 if (show
|| transp
) show_glyph(x
,y
, cmap_to_glyph(cmap
));
221 * The routines map_background(), map_object(), and map_trap() could just
224 * map_glyph(x,y,glyph,show)
226 * Which is called with the xx_to_glyph() in the call. Then I can get
227 * rid of 3 routines that don't do very much anyway. And then stop
228 * having to create fake objects and traps. However, I am reluctant to
231 /* FIXME: some of these use xchars for x and y, and some use ints. Make
238 * Make the real background part of our map. This routine assumes that
239 * the hero can physically see the location. Update the screen if directed.
242 map_background(x
, y
, show
)
246 register int cmap
= back_to_cmap(x
,y
);
248 if (level
.flags
.hero_memory
)
249 #ifdef DISPLAY_LAYERS
250 levl
[x
][y
].mem_bg
= cmap
;
252 levl
[x
][y
].glyph
= cmap_to_glyph(cmap
);
254 if (show
|| transp
) show_glyph(x
,y
, cmap_to_glyph(cmap
));
260 * Map the trap and print it out if directed. This routine assumes that the
261 * hero can physically see the location.
265 register struct trap
*trap
;
268 register int x
= trap
->tx
, y
= trap
->ty
;
269 register int cmap
= trap_to_cmap(trap
);
271 if (level
.flags
.hero_memory
)
272 #ifdef DISPLAY_LAYERS
273 levl
[x
][y
].mem_trap
= 1 + cmap
- MAXDCHARS
;
275 levl
[x
][y
].glyph
= cmap_to_glyph(cmap
);
279 if (show
|| transp
) {
281 if (KnowledgeBug
|| u
.uprops
[KNOWLEDGE_BUG
].extrinsic
|| have_trapknowledgestone()) show_glyph(x
, y
, cmap_to_glyph(S_grayglyph
));
282 else show_glyph(x
, y
, cmap_to_glyph(cmap
));
290 * Map the given object. This routine assumes that the hero can physically
291 * see the location of the object. Update the screen if directed.
294 map_object(obj
, show
)
295 register struct obj
*obj
;
298 register int x
= obj
->ox
, y
= obj
->oy
;
299 register int glyph
= obj_to_glyph(obj
);
301 /*pline("object type %d",obj->otyp);*/
303 if (level
.flags
.hero_memory
)
304 #ifdef DISPLAY_LAYERS
305 if ((levl
[x
][y
].mem_corpse
= glyph_is_body(glyph
)))
306 levl
[x
][y
].mem_obj
= 1 + glyph_to_body(glyph
);
308 levl
[x
][y
].mem_obj
= 1 + glyph_to_obj(glyph
);
310 levl
[x
][y
].glyph
= glyph
;
313 if (show
) show_glyph(x
, y
, glyph
);
319 * Make the hero remember that a square contains an invisible monster.
320 * This is a special case in that the square will continue to be displayed
321 * this way even when the hero is close enough to see it. To get rid of
322 * this and display the square's actual contents, use unmap_object() followed
323 * by newsym() if necessary.
329 if (x
!= u
.ux
|| y
!= u
.uy
) { /* don't display I at hero's location */
330 if (level
.flags
.hero_memory
)
331 #ifdef DISPLAY_LAYERS
332 levl
[x
][y
].mem_invis
= 1;
334 levl
[x
][y
].glyph
= GLYPH_INVISIBLE
;
336 if (!(UnderlayerBug
|| u
.uprops
[UNDERLAYER_BUG
].extrinsic
|| have_underlaidstone())) show_glyph(x
, y
, GLYPH_INVISIBLE
);
344 if (x
!= u
.ux
|| y
!= u
.uy
) { /* don't display I at hero's location */
345 if (level
.flags
.hero_memory
)
346 #ifdef DISPLAY_LAYERS
347 levl
[x
][y
].mem_invis
= 1;
349 levl
[x
][y
].glyph
= GLYPH_INVISIBLE
;
351 if (!(UnderlayerBug
|| u
.uprops
[UNDERLAYER_BUG
].extrinsic
|| have_underlaidstone())) show_glyphX(x
, y
, GLYPH_INVISIBLE
);
358 * Remove something from the map when the hero realizes it's not there any
359 * more. Replace it with background or known trap, but not with any other
360 * If this is used for detection, a full screen update is imminent anyway;
361 * if this is used to get rid of an invisible monster notation, we might have
368 #ifndef DISPLAY_LAYERS
369 register struct trap
*trap
;
372 if (!level
.flags
.hero_memory
) return;
374 #ifdef DISPLAY_LAYERS
375 levl
[x
][y
].mem_invis
= levl
[x
][y
].mem_corpse
= levl
[x
][y
].mem_obj
= 0;
377 if ((trap
= t_at(x
,y
)) != 0 && trap
->tseen
&& !covers_traps(x
,y
))
379 else if (levl
[x
][y
].seenv
) {
380 struct rm
*lev
= &levl
[x
][y
];
382 map_background(x
, y
, 0);
384 /* turn remembered dark room squares dark */
385 if (!lev
->waslit
&& lev
->glyph
== cmap_to_glyph(S_room
) &&
387 lev
->glyph
= cmap_to_glyph(S_darkroom
);
389 levl
[x
][y
].glyph
= cmap_to_glyph(S_stone
); /* default val */
394 #define PHYSICALLY_SEEN 1
395 #define is_worm_tail(mon) ((mon) && ((x != (mon)->mx) || (y != (mon)->my)))
400 * Make whatever at this location show up. This is only for non-living
401 * things. This will not handle feeling invisible objects correctly.
403 * Internal to display.c, this is a #define for speed.
405 #ifdef DISPLAY_LAYERS
406 #define _map_location(x,y,show) \
408 register struct obj *obj; \
409 register struct trap *trap; \
412 if (level.flags.hero_memory) { \
413 if ((obj = vobj_at(x, y)) && !covers_objects(x, y)) \
414 map_object(obj, FALSE); \
416 levl[x][y].mem_corpse = levl[x][y].mem_obj = 0; \
417 if ((trap = t_at(x, y)) && trap->tseen && !covers_traps(x, y)) \
418 map_trap(trap, FALSE); \
420 levl[x][y].mem_trap = 0; \
421 map_background(x, y, FALSE); \
422 if (show) show_glyph(x, y, memory_glyph(x, y)); \
423 } else if ((obj = vobj_at(x,y)) && !covers_objects(x,y)) \
424 map_object(obj,show); \
425 else if ((trap = t_at(x,y)) && trap->tseen && !covers_traps(x,y)) \
426 map_trap(trap,show); \
428 map_background(x,y,show); \
429 if (ManlerIsChasing && x == u.manlerx && y == u.manlery) { \
430 show_glyph(x, y, (GLYPH_MON_OFF + rn2(NUMMONS))); \
433 if ((Quaversal || u.uprops[QUAVERSAL].extrinsic || (uimplant && uimplant->oartifact == ART_ND_D___N_NDMNN_ND___NDMN_N) || have_quaversalstone() || autismweaponcheck(ART_OMGHAXERETH) ) && isok(u.ux, u.uy) && !isimportantlocation(x, y) && !(levl[u.ux][u.uy].wall_info & W_QUASAROK)) { \
434 show_glyph(x, y, cmap_to_glyph(S_stone)); \
437 if ((uarmh && itemhasappearance(uarmh, APP_HARDCORE_CLOTH)) && !facingtile(x, y)) { \
438 show_glyph(x, y, cmap_to_glyph(S_stone)); \
441 if (Race_if(PM_SLYER_ALIEN) && !facingtile(x, y)) { \
442 show_glyph(x, y, cmap_to_glyph(S_stone)); \
445 if (!u.seesilverspell && SpellColorSilver && !isimportantlocation(x, y)) { \
446 show_glyph(x, y, cmap_to_glyph(S_stone)); \
449 if ((GrayoutBug || u.uprops[GRAYOUT_BUG].extrinsic || have_grayoutstone() || (uarmc && uarmc->oartifact == ART_DOEDOEDOEDOEDOEDOEDOE_TEST) || autismweaponcheck(ART_PWNHAMMER) ) && grayoutobscuration() ) { \
450 show_glyph(x, y, cmap_to_glyph(S_grayglyph)); \
453 if ((GrayCenterBug || u.uprops[GRAY_CENTER_BUG].extrinsic || have_graycenterstone()) && distu(x, y) < (GrayCenterXtra ? 9 : 4) ) { \
454 show_glyph(x, y, cmap_to_glyph(S_grayglyph)); \
457 if ((CheckerboardBug || u.uprops[CHECKERBOARD_BUG].extrinsic || autismweaponcheck(ART_SAY__CHESS_) || have_checkerboardstone()) && ( ((x + y) % (CheckerboardXtra ? 4 : 2) ) != (moves % (CheckerboardXtra ? 4 : 2) ) ) ) { \
458 show_glyph(x, y, cmap_to_glyph(S_grayglyph)); \
461 if ( (QuasarVision || u.uprops[QUASAR_BUG].extrinsic || have_quasarstone() ) && !isimportantlocation(x, y) && !(levl[x][y].wall_info & W_QUASAROK) ) { \
462 show_glyph(x, y, cmap_to_glyph(S_stone)); \
465 if (Yawming && (distu(x,y) > yawm_distance())) { \
466 show_glyph(x, y, cmap_to_glyph(S_stone)); \
469 if (StupidMojibake && !rn2(MojibakeXtra ? 3 : 10)) { \
470 show_glyph(x, y, randomglyph() ); \
473 if (SpellColorBlue && !rn2(10)) { \
474 show_glyph(x, y, cmap_to_glyph(S_room)); \
477 if (SpellColorOrange && (distu(x,y) > 100)) { \
478 show_glyph(x, y, cmap_to_glyph(S_grayglyph)); \
481 if (SpellColorPlatinum && !rn2(10)) { \
482 show_glyph(x, y, cmap_to_glyph(S_bars)); \
485 if (SpellColorBrightCyan && cyanspellok(x,y)) { \
486 show_glyph(x, y, cmap_to_glyph(S_grayglyph)); \
489 if (FemtrapActiveNicole && nicolesquareok(x,y)) { \
490 show_glyph(x, y, cmap_to_glyph(S_stone)); \
493 if (SpellColorBrown && (distu(x,y) % 3 == 0)) { \
494 show_glyph(x, y, cmap_to_glyph(S_pile_of_shit)); \
498 #else /* DISPLAY_LAYERS */
499 #define _map_location(x,y,show) \
501 register struct obj *obj; \
502 register struct trap *trap; \
504 if ((obj = vobj_at(x,y)) && !covers_objects(x,y)) \
505 map_object(obj,show); \
506 else if ((trap = t_at(x,y)) && trap->tseen && !covers_traps(x,y)) \
507 map_trap(trap,show); \
509 map_background(x,y,show); \
511 #endif /* DISPLAY_LAYERS */
514 map_location(x
,y
,show
)
517 _map_location(x
,y
,show
);
520 int memory_glyph(x
, y
)
523 #ifdef DISPLAY_LAYERS
525 if (ManlerIsChasing
&& x
== u
.manlerx
&& y
== u
.manlery
) {
526 return (GLYPH_MON_OFF
+ rn2(NUMMONS
));
529 if ((Quaversal
|| u
.uprops
[QUAVERSAL
].extrinsic
|| (uimplant
&& uimplant
->oartifact
== ART_ND_D___N_NDMNN_ND___NDMN_N
) || have_quaversalstone() || autismweaponcheck(ART_OMGHAXERETH
) ) && isok(u
.ux
, u
.uy
) && !isimportantlocation(x
, y
) && !(levl
[u
.ux
][u
.uy
].wall_info
& W_QUASAROK
)) {
530 return cmap_to_glyph(S_stone
);
533 if ((uarmh
&& itemhasappearance(uarmh
, APP_HARDCORE_CLOTH
)) && !facingtile(x
, y
)) {
534 return cmap_to_glyph(S_stone
);
537 if (Race_if(PM_SLYER_ALIEN
) && !facingtile(x
, y
)) {
538 return cmap_to_glyph(S_stone
);
541 if (!u
.seesilverspell
&& SpellColorSilver
&& !isimportantlocation(x
, y
)) {
542 return cmap_to_glyph(S_stone
);
545 if ((GrayoutBug
|| u
.uprops
[GRAYOUT_BUG
].extrinsic
|| have_grayoutstone() || (uarmc
&& uarmc
->oartifact
== ART_DOEDOEDOEDOEDOEDOEDOE_TEST
) || autismweaponcheck(ART_PWNHAMMER
) ) && grayoutobscuration() ) {
546 return cmap_to_glyph(S_grayglyph
);
549 if ((GrayCenterBug
|| u
.uprops
[GRAY_CENTER_BUG
].extrinsic
|| have_graycenterstone()) && distu(x
, y
) < (GrayCenterXtra
? 9 : 4)) {
550 return cmap_to_glyph(S_grayglyph
);
553 if ((CheckerboardBug
|| u
.uprops
[CHECKERBOARD_BUG
].extrinsic
|| autismweaponcheck(ART_SAY__CHESS_
) || have_checkerboardstone()) && ( ((x
+ y
) % (CheckerboardXtra
? 4 : 2) ) != (moves
% (CheckerboardXtra
? 4 : 2) ) ) ) {
554 return cmap_to_glyph(S_grayglyph
);
557 if ( (QuasarVision
|| u
.uprops
[QUASAR_BUG
].extrinsic
|| have_quasarstone() ) && !isimportantlocation(x
, y
) && !(levl
[x
][y
].wall_info
& W_QUASAROK
) ) { return cmap_to_glyph(S_stone
); }
559 if (Yawming
&& (distu(x
,y
) > yawm_distance())) { return cmap_to_glyph(S_stone
); }
561 if (StupidMojibake
&& !rn2(MojibakeXtra
? 3 : 10)) {
562 return randomglyph();
565 if (SpellColorBlue
&& !rn2(10)) {
566 return cmap_to_glyph(S_room
);
569 if (SpellColorOrange
&& (distu(x
,y
) > 100)) {
570 return cmap_to_glyph(S_grayglyph
);
573 if (SpellColorPlatinum
&& !rn2(10)) {
574 return cmap_to_glyph(S_bars
);
577 if (SpellColorBrightCyan
&& cyanspellok(x
,y
)) {
578 return cmap_to_glyph(S_grayglyph
);
581 if (FemtrapActiveNicole
&& nicolesquareok(x
,y
)) {
582 return cmap_to_glyph(S_stone
);
585 if (SpellColorBrown
&& (distu(x
,y
) % 3 == 0)) {
586 return cmap_to_glyph(S_pile_of_shit
);
589 if (levl
[x
][y
].mem_invis
&& !(UnderlayerBug
|| u
.uprops
[UNDERLAYER_BUG
].extrinsic
|| have_underlaidstone()) )
590 return GLYPH_INVISIBLE
;
591 else if (levl
[x
][y
].mem_obj
)
592 if (levl
[x
][y
].mem_corpse
)
593 return body_to_glyph(levl
[x
][y
].mem_obj
- 1);
595 return objnum_to_glyph(levl
[x
][y
].mem_obj
- 1);
596 else if (levl
[x
][y
].mem_trap
) {
598 if (KnowledgeBug
|| u
.uprops
[KNOWLEDGE_BUG
].extrinsic
|| have_trapknowledgestone()) {
599 return cmap_to_glyph(S_grayglyph
);
600 } else return cmap_to_glyph(levl
[x
][y
].mem_trap
- 1 + MAXDCHARS
);
603 return cmap_to_glyph(levl
[x
][y
].mem_bg
);
605 return levl
[x
][y
].glyph
;
609 void clear_memory_glyph(x
, y
, to
)
612 #ifdef DISPLAY_LAYERS
613 levl
[x
][y
].mem_bg
= to
;
614 levl
[x
][y
].mem_trap
= 0;
615 levl
[x
][y
].mem_obj
= 0;
616 levl
[x
][y
].mem_corpse
= 0;
617 levl
[x
][y
].mem_invis
= 0;
619 levl
[x
][y
].glyph
= cmap_to_glyph(to
);
626 * Note that this is *not* a map_XXXX() function! Monsters sort of float
629 * Yuck. Display body parts by recognizing that the display position is
630 * not the same as the monster position. Currently the only body part is
635 display_monster(x
, y
, mon
, sightflags
, worm_tail
)
636 register xchar x
, y
; /* display position */
637 register struct monst
*mon
; /* monster to display */
638 int sightflags
; /* 1 if the monster is physically seen */
639 /* 2 if detected using Detect_monsters */
640 register xchar worm_tail
; /* mon is actually a worm tail */
642 register boolean mon_mimic
= (mon
->m_ap_type
!= M_AP_NOTHING
);
643 register int sensed
= mon_mimic
&&
644 ( (Protection_from_shape_changers
&& !permamimic(mon
->data
) && !(mon
->egotype_permamimic
) ) || sensemon(mon
));
646 * We must do the mimic check first. If the mimic is mimicing something,
647 * and the location is in sight, we have to change the hero's memory
648 * so that when the position is out of sight, the hero remembers what
649 * the mimic was mimicing.
652 if (mon_mimic
&& (sightflags
== PHYSICALLY_SEEN
)) {
653 switch (mon
->m_ap_type
) {
655 impossible("display_monster: bad m_ap_type value [ = %d ]",
656 (int) mon
->m_ap_type
);
658 show_glyph(x
, y
, mon_to_glyph(mon
));
661 case M_AP_FURNITURE
: {
663 * This is a poor man's version of map_background(). I can't
664 * use map_background() because we are overriding what is in
665 * the 'typ' field. Maybe have map_background()'s parameters
666 * be (x,y,glyph) instead of just (x,y).
668 * mappearance is currently set to an S_ index value in
671 register int glyph
= cmap_to_glyph(mon
->mappearance
);
672 #ifdef DISPLAY_LAYERS
673 levl
[x
][y
].mem_bg
= mon
->mappearance
;
675 levl
[x
][y
].glyph
= glyph
;
677 if (!sensed
) show_glyph(x
,y
, glyph
);
682 struct obj obj
; /* Make a fake object to send */
683 /* to map_object(). */
686 obj
.otyp
= mon
->mappearance
;
687 obj
.corpsenm
= PM_TENGU
; /* if mimicing a corpse */
688 map_object(&obj
,!sensed
);
693 show_glyph(x
,y
, monnum_to_glyph(what_mon((int)mon
->mappearance
)));
699 /* If the mimic is unsucessfully mimicing something, display the monster */
700 if (!mon_mimic
|| sensed
) {
703 if (StarlitBug
|| u
.uprops
[STARLIT_BUG
].extrinsic
|| have_starlitskystone() || autismweaponcheck(ART_STARRING_INFERNO
) || (uarmf
&& uarmf
->oartifact
== ART_STAR_SOLES
) || (uimplant
&& uimplant
->oartifact
== ART_ARABELLA_S_SEXY_CHARM
) || (uarmg
&& uarmg
->oartifact
== ART_RAAAAAAAARRRRRRGH
) ) {
704 show_glyph(x
,y
,cmap_to_glyph(S_grayglyph
));
708 /* [ALI] Only use detected glyphs when monster wouldn't be
709 * visible by any other means.
711 if (sightflags
== DETECTED
) {
713 num
= detected_monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL
));
715 num
= detected_mon_to_glyph(mon
);
716 } else if (mon
->mtame
&& !Hallucination
) {
718 num
= petnum_to_glyph(PM_LONG_WORM_TAIL
);
720 num
= pet_to_glyph(mon
);
723 num
= monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL
));
725 num
= mon_to_glyph(mon
);
732 display_monsterX(x
, y
, mon
, sightflags
, worm_tail
)
733 register xchar x
, y
; /* display position */
734 register struct monst
*mon
; /* monster to display */
735 int sightflags
; /* 1 if the monster is physically seen */
736 /* 2 if detected using Detect_monsters */
737 register xchar worm_tail
; /* mon is actually a worm tail */
739 register boolean mon_mimic
= (mon
->m_ap_type
!= M_AP_NOTHING
);
740 register int sensed
= mon_mimic
&&
741 ( (Protection_from_shape_changers
&& !permamimic(mon
->data
) && !(mon
->egotype_permamimic
) ) || sensemon(mon
));
743 * We must do the mimic check first. If the mimic is mimicing something,
744 * and the location is in sight, we have to change the hero's memory
745 * so that when the position is out of sight, the hero remembers what
746 * the mimic was mimicing.
749 if (mon_mimic
&& (sightflags
== PHYSICALLY_SEEN
)) {
750 switch (mon
->m_ap_type
) {
752 impossible("display_monster: bad m_ap_type value [ = %d ]",
753 (int) mon
->m_ap_type
);
755 show_glyphX(x
, y
, mon_to_glyph(mon
));
758 case M_AP_FURNITURE
: {
760 * This is a poor man's version of map_background(). I can't
761 * use map_background() because we are overriding what is in
762 * the 'typ' field. Maybe have map_background()'s parameters
763 * be (x,y,glyph) instead of just (x,y).
765 * mappearance is currently set to an S_ index value in
768 register int glyph
= cmap_to_glyph(mon
->mappearance
);
769 #ifdef DISPLAY_LAYERS
770 levl
[x
][y
].mem_bg
= mon
->mappearance
;
772 levl
[x
][y
].glyph
= glyph
;
774 if (!sensed
) show_glyphX(x
,y
, glyph
);
779 struct obj obj
; /* Make a fake object to send */
780 /* to map_object(). */
783 obj
.otyp
= mon
->mappearance
;
784 obj
.corpsenm
= PM_TENGU
; /* if mimicing a corpse */
785 map_object(&obj
,!sensed
);
790 show_glyphX(x
,y
, monnum_to_glyph(what_mon((int)mon
->mappearance
)));
796 /* If the mimic is unsucessfully mimicing something, display the monster */
797 if (!mon_mimic
|| sensed
) {
800 if (StarlitBug
|| u
.uprops
[STARLIT_BUG
].extrinsic
|| have_starlitskystone() || autismweaponcheck(ART_STARRING_INFERNO
) || (uarmf
&& uarmf
->oartifact
== ART_STAR_SOLES
) || (uimplant
&& uimplant
->oartifact
== ART_ARABELLA_S_SEXY_CHARM
) || (uarmg
&& uarmg
->oartifact
== ART_RAAAAAAAARRRRRRGH
) ) {
801 show_glyph(x
,y
,cmap_to_glyph(S_grayglyph
));
805 /* [ALI] Only use detected glyphs when monster wouldn't be
806 * visible by any other means.
808 if (sightflags
== DETECTED
) {
810 num
= detected_monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL
));
812 num
= detected_mon_to_glyph(mon
);
813 } else if (mon
->mtame
&& !Hallucination
) {
815 num
= petnum_to_glyph(PM_LONG_WORM_TAIL
);
817 num
= pet_to_glyph(mon
);
820 num
= monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL
));
822 num
= mon_to_glyph(mon
);
824 show_glyphX(x
,y
,num
);
830 * This is also *not* a map_XXXX() function! Monster warnings float
831 * above everything just like monsters do, but only if the monster
834 * Do not call for worm tails.
838 register struct monst
*mon
;
840 int x
= mon
->mx
, y
= mon
->my
;
841 int wl
= (int) (mon
->m_lev
/ 6);
844 if (mon
&& (mon
->data
->msound
== MS_DEEPSTATE
)) return;
845 if (mon
&& mon
->egotype_deepstatemember
) return;
847 if (mon_warning(mon
)) {
848 if (wl
> WARNCOUNT
- 1) wl
= WARNCOUNT
- 1;
849 /* 3.4.1: this really ought to be rn2(WARNCOUNT), but value "0"
850 isn't handled correctly by the what_is routine so avoid it
851 if (Hallucination) wl = rn1(WARNCOUNT-1,1);*/
852 if (Hallucination
) wl
= rn2(WARNCOUNT
); /* seems the error was a 1 in pager.c where it's supposed to be a 0 --Amy */
853 glyph
= warning_to_glyph(wl
);
854 } else if (MATCH_WARN_OF_MON(mon
)) {
855 glyph
= mon_to_glyph(mon
);
857 impossible("display_warning did not match warning type?");
860 show_glyph(x
, y
, glyph
);
864 display_warningX(mon
)
865 register struct monst
*mon
;
867 int x
= mon
->mx
, y
= mon
->my
;
868 int wl
= (int) (mon
->m_lev
/ 6);
871 if (mon
&& (mon
->data
->msound
== MS_DEEPSTATE
)) return;
872 if (mon
&& mon
->egotype_deepstatemember
) return;
874 if (mon_warning(mon
)) {
875 if (wl
> WARNCOUNT
- 1) wl
= WARNCOUNT
- 1;
876 /* 3.4.1: this really ought to be rn2(WARNCOUNT), but value "0"
877 isn't handled correctly by the what_is routine so avoid it
878 if (Hallucination) wl = rn1(WARNCOUNT-1,1);*/
879 if (Hallucination
) wl
= rn2(WARNCOUNT
); /* seems the error was a 1 in pager.c where it's supposed to be a 0 --Amy */
880 glyph
= warning_to_glyph(wl
);
881 } else if (MATCH_WARN_OF_MON(mon
)) {
882 glyph
= mon_to_glyph(mon
);
884 impossible("display_warning did not match warning type?");
887 show_glyphX(x
, y
, glyph
);
893 * Feel the given location. This assumes that the hero is blind and that
894 * the given position is either the hero's or one of the eight squares
895 * adjacent to the hero (except for a boulder push).
901 struct rm
*lev
= &(levl
[x
][y
]);
903 register struct monst
*mon
;
905 /* If the hero's memory of an invisible monster is accurate, we want to keep
906 * him from detecting the same monster over and over again on each turn.
907 * We must return (so we don't erase the monster). (We must also, in the
908 * search function, be sure to skip over previously detected 'I's.)
910 if (memory_is_invisible(x
,y
) && m_at(x
,y
)) return;
912 /* The hero can't feel non pool locations while under water. */
913 if (Underwater
&& !Swimming
&& !Is_waterlevel(&u
.uz
) && !is_waterypool(x
,y
) && !is_watertunnel(x
,y
) && !is_lava(x
,y
) && !is_shiftingsand(x
,y
) && !is_styxriver(x
,y
) )
916 /* Set the seen vector as if the hero had seen it. It doesn't matter */
917 /* if the hero is levitating or not. */
918 set_seenv(lev
, u
.ux
, u
.uy
, x
, y
);
920 if (Levitation
&& !Is_airlevel(&u
.uz
) && !Is_waterlevel(&u
.uz
)) {
922 * Levitation Rules. It is assumed that the hero can feel the state
923 * of the walls around herself and can tell if she is in a corridor,
924 * room, or doorway. Boulders are felt because they are large enough.
925 * Anything else is unknown because the hero can't reach the ground.
926 * This makes things difficult.
928 * Check (and display) in order:
930 * + Stone, walls, and closed doors.
931 * + Boulders. [see a boulder before a doorway]
933 * + Room/water positions
934 * + Everything else (hallways!)
936 if (IS_ROCK(lev
->typ
) || (IS_DOOR(lev
->typ
) &&
937 (lev
->doormask
& (D_LOCKED
| D_CLOSED
)))) {
938 map_background(x
, y
, 1);
939 } else if ((boulder
= sobj_at(BOULDER
,x
,y
)) != 0) {
940 map_object(boulder
, 1);
941 } else if (IS_DOOR(lev
->typ
)) {
942 map_background(x
, y
, 1);
943 } else if (IS_ROOM(lev
->typ
) || IS_POOL(lev
->typ
)) {
945 * An open room or water location. Normally we wouldn't touch
946 * this, but we have to get rid of remembered boulder symbols.
947 * This will only occur in rare occations when the hero goes
948 * blind and doesn't find a boulder where expected (something
949 * came along and picked it up). We know that there is not a
950 * boulder at this location. Show fountains, pools, etc.
951 * underneath if already seen. Otherwise, show the appropriate
954 * Similarly, if the hero digs a hole in a wall or feels a location
955 * that used to contain an unseen monster. In these cases,
956 * there's no reason to assume anything was underneath, so
957 * just show the appropriate floor symbol. If something was
958 * embedded in the wall, the glyph will probably already
959 * reflect that. Don't change the symbol in this case.
961 * This isn't quite correct. If the boulder was on top of some
962 * other objects they should be seen once the boulder is removed.
963 * However, we have no way of knowing that what is there now
964 * was there then. So we let the hero have a lapse of memory.
965 * We could also just display what is currently on the top of the
966 * object stack (if anything).
968 if (remembered_object(x
, y
) == BOULDER
) {
969 if (lev
->typ
!= ROOM
&& lev
->seenv
) {
970 map_background(x
, y
, 1);
973 #ifdef DISPLAY_LAYERS
974 /*lev->mem_bg = lev->waslit ? S_room : S_stone;*/
975 lev
->mem_bg
= (!lev
->waslit
) ? S_darkroom
: S_room
;
977 lev
->glyph
= (!lev
->waslit
) ? cmap_to_glyph(S_darkroom
) : cmap_to_glyph(S_room
);
978 /*lev->glyph = lev->waslit ? cmap_to_glyph(S_room) :
979 cmap_to_glyph(S_stone);*/
981 show_glyph(x
, y
, memory_glyph(x
, y
));
983 #ifdef DISPLAY_LAYERS
984 } else if ((lev
->mem_bg
>= S_stone
&& lev
->mem_bg
< S_darkroom
) ||
985 memory_is_invisible(x
, y
)) {
986 lev
->mem_bg
= (!lev
->waslit
? S_darkroom
: S_room
);
988 } else if ((lev
->glyph
>= cmap_to_glyph(S_stone
) &&
989 lev
->glyph
< cmap_to_glyph(S_darkroom
)) ||
990 glyph_is_invisible(levl
[x
][y
].glyph
)) {
991 lev
->glyph
= (!cansee(x
,y
) && !lev
->waslit
) ? cmap_to_glyph(S_darkroom
) :
992 cmap_to_glyph(S_room
);
993 /*lev->glyph = lev->waslit ? cmap_to_glyph(S_room) :
994 cmap_to_glyph(S_stone);*/
996 show_glyph(x
, y
, memory_glyph(x
, y
));
999 /* We feel it (I think hallways are the only things left). */
1000 map_background(x
, y
, 1);
1001 /* Corridors are never felt as lit (unless remembered that way) */
1002 /* (lit_corridor only). */
1003 #ifdef DISPLAY_LAYERS
1004 if (lev
->typ
== CORR
&& lev
->mem_bg
== S_litcorr
&& !lev
->waslit
)
1005 show_glyph(x
, y
, cmap_to_glyph(lev
->mem_bg
= S_corr
));
1007 if (lev
->typ
== CORR
&&
1008 lev
->glyph
== cmap_to_glyph(S_litcorr
) && !lev
->waslit
)
1009 show_glyph(x
, y
, lev
->glyph
= cmap_to_glyph(S_corr
));
1013 _map_location(x
, y
, 1);
1017 * A ball or chain is only felt if it is first on the object
1018 * location list. Otherwise, we need to clear the felt bit ---
1019 * something has been dropped on the ball/chain. If the bit is
1020 * not cleared, then when the ball/chain is moved it will drop
1022 * Amy edit: there's the bug that the chain can be removed due to errors, in which case we don't want to try to
1023 * place it. In fact we should probably unpunish the player in that case and print an error message...
1025 if (uchain
&& uchain
->ox
== x
&& uchain
->oy
== y
) {
1026 if (level
.objects
[x
][y
] == uchain
)
1027 u
.bc_felt
|= BC_CHAIN
;
1029 u
.bc_felt
&= ~BC_CHAIN
; /* do not feel the chain */
1031 if (!carried(uball
) && uball
->ox
== x
&& uball
->oy
== y
) {
1032 if (level
.objects
[x
][y
] == uball
)
1033 u
.bc_felt
|= BC_BALL
;
1035 u
.bc_felt
&= ~BC_BALL
; /* do not feel the ball */
1039 /* Floor spaces are dark if unlit. Corridors are dark if unlit. */
1040 #ifdef DISPLAY_LAYERS
1041 if (lev
->typ
== ROOM
&& lev
->mem_bg
== S_room
&& !lev
->waslit
) {
1042 lev
->mem_bg
= S_darkroom
;
1043 show_glyph(x
,y
, memory_glyph(x
, y
));
1044 } else if (lev
->typ
== CORR
&&
1045 lev
->mem_bg
== S_litcorr
&& !lev
->waslit
) {
1046 lev
->mem_bg
= S_corr
;
1047 show_glyph(x
,y
, memory_glyph(x
, y
));
1050 if (lev
->typ
== ROOM
&&
1051 lev
->glyph
== cmap_to_glyph(S_room
) && !lev
->waslit
)
1052 show_glyph(x
,y
, lev
->glyph
= cmap_to_glyph(S_darkroom
));
1053 else if (lev
->typ
== CORR
&&
1054 lev
->glyph
== cmap_to_glyph(S_litcorr
) && !lev
->waslit
)
1055 show_glyph(x
,y
, lev
->glyph
= cmap_to_glyph(S_corr
));
1058 /* draw monster on top if we can sense it */
1059 if ((x
!= u
.ux
|| y
!= u
.uy
) && (mon
= m_at(x
,y
)) && sensemon(mon
))
1060 display_monster(x
, y
, mon
,
1061 (tp_sensemon(mon
) || MATCH_WARN_OF_MON(mon
)) ? PHYSICALLY_SEEN
: DETECTED
,
1068 * Possibly put a new glyph at the given location.
1074 register struct monst
*mon
;
1075 register struct rm
*lev
= &(levl
[x
][y
]);
1076 register int see_it
;
1077 register xchar worm_tail
;
1079 if (in_mklev
) return;
1081 if (program_state
.done_hup
)
1084 if (ManlerIsChasing
&& x
== u
.manlerx
&& y
== u
.manlery
) {
1085 show_glyph(x
, y
, GLYPH_MON_OFF
+ rn2(NUMMONS
));
1089 if ((Quaversal
|| u
.uprops
[QUAVERSAL
].extrinsic
|| (uimplant
&& uimplant
->oartifact
== ART_ND_D___N_NDMNN_ND___NDMN_N
) || have_quaversalstone() || autismweaponcheck(ART_OMGHAXERETH
) ) && isok(u
.ux
, u
.uy
) && !isimportantlocation(x
, y
) && !(levl
[u
.ux
][u
.uy
].wall_info
& W_QUASAROK
)) {
1090 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1094 if ((uarmh
&& itemhasappearance(uarmh
, APP_HARDCORE_CLOTH
)) && !facingtile(x
, y
)) {
1095 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1099 if (Race_if(PM_SLYER_ALIEN
) && !facingtile(x
, y
)) {
1100 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1104 if (!u
.seesilverspell
&& SpellColorSilver
&& !isimportantlocation(x
, y
)) {
1105 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1109 if ((GrayoutBug
|| u
.uprops
[GRAYOUT_BUG
].extrinsic
|| have_grayoutstone() || (uarmc
&& uarmc
->oartifact
== ART_DOEDOEDOEDOEDOEDOEDOE_TEST
) || autismweaponcheck(ART_PWNHAMMER
) ) && grayoutobscuration() ) {
1110 show_glyph(x
, y
, cmap_to_glyph(S_grayglyph
));
1114 if ((GrayCenterBug
|| u
.uprops
[GRAY_CENTER_BUG
].extrinsic
|| have_graycenterstone()) && distu(x
, y
) < (GrayCenterXtra
? 9 : 4)) {
1115 show_glyph(x
, y
, cmap_to_glyph(S_grayglyph
));
1119 if ((CheckerboardBug
|| u
.uprops
[CHECKERBOARD_BUG
].extrinsic
|| autismweaponcheck(ART_SAY__CHESS_
) || have_checkerboardstone()) && ( ((x
+ y
) % (CheckerboardXtra
? 4 : 2) ) != (moves
% (CheckerboardXtra
? 4 : 2) ) ) ) {
1120 show_glyph(x
, y
, cmap_to_glyph(S_grayglyph
));
1124 if ( (QuasarVision
|| u
.uprops
[QUASAR_BUG
].extrinsic
|| have_quasarstone() ) && !isimportantlocation(x
, y
) && !(levl
[x
][y
].wall_info
& W_QUASAROK
) ) {
1125 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1129 if (Yawming
&& (distu(x
,y
) > yawm_distance())) {
1130 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1134 if (StupidMojibake
&& !rn2(MojibakeXtra
? 3 : 10)) {
1135 show_glyph(x
, y
, randomglyph());
1139 if (SpellColorBlue
&& !rn2(10)) {
1140 show_glyph(x
, y
, cmap_to_glyph(S_room
));
1144 if (SpellColorOrange
&& (distu(x
,y
) > 100)) {
1145 show_glyph(x
, y
, cmap_to_glyph(S_grayglyph
));
1149 if (SpellColorPlatinum
&& !rn2(10)) {
1150 show_glyph(x
, y
, cmap_to_glyph(S_bars
));
1154 if (SpellColorBrightCyan
&& cyanspellok(x
,y
)) {
1155 show_glyph(x
, y
, cmap_to_glyph(S_grayglyph
));
1159 if (FemtrapActiveNicole
&& nicolesquareok(x
,y
)) {
1160 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1164 if (SpellColorBrown
&& (distu(x
,y
) % 3 == 0)) {
1165 show_glyph(x
, y
, cmap_to_glyph(S_pile_of_shit
));
1169 if ( (Superscroller
|| (uarm
&& uarm
->oartifact
== ART_VOLUME_ARMAMENT
) || (uarm
&& uarm
->oartifact
== ART_SPLINTER_ARMAMENT
) || (uarm
&& uarm
->oartifact
== ART_TAPE_ARMAMENT
) || (uarmc
&& uarmc
->oartifact
== ART_VEIL_OF_LATONA
) || (uarmc
&& uarmc
->oartifact
== ART_VEIL_OF_MINISTRY
) || u
.uprops
[SUPERSCROLLER_ACTIVE
].extrinsic
|| have_superscrollerstone() ) && !isimportantlocation(x
, y
) && rn2(10) ) { show_glyph(x
, y
, cmap_to_glyph(S_stone
)); return;}
1171 /* only permit updating the hero when swallowed */
1173 if (x
== u
.ux
&& y
== u
.uy
) display_self();
1176 if (Underwater
&& !Swimming
&& !Is_waterlevel(&u
.uz
)) {
1177 /* don't do anything unless (x,y) is an adjacent underwater position */
1179 if (!is_waterypool(x
,y
) && !is_watertunnel(x
,y
) && !is_lava(x
,y
) && !is_shiftingsand(x
,y
) && !is_styxriver(x
,y
)) return;
1180 dx
= x
- u
.ux
; if (dx
< 0) dx
= -dx
;
1181 dy
= y
- u
.uy
; if (dy
< 0) dy
= -dy
;
1182 if (dx
> 1 || dy
> 1) return;
1185 /* Can physically see the location. */
1187 NhRegion
* reg
= visible_region_at(x
,y
);
1189 * Don't use templit here: E.g.
1191 * lev->waslit = !!(lev->lit || templit(x,y));
1193 * Otherwise we have the "light pool" problem, where non-permanently
1194 * lit areas just out of sight stay remembered as lit. They should
1197 * Perhaps ALL areas should revert to their "unlit" look when
1200 lev
->waslit
= (lev
->lit
!=0); /* remember lit condition */
1202 if (reg
!= NULL
&& ACCESSIBLE(lev
->typ
)) {
1203 show_region(reg
,x
,y
);
1206 if (x
== u
.ux
&& y
== u
.uy
) {
1208 _map_location(x
,y
,0); /* map *under* self */
1211 /* we can see what is there */
1212 _map_location(x
,y
,1);
1216 worm_tail
= is_worm_tail(mon
);
1217 see_it
= mon
&& !(uarmh
&& uarmh
->oartifact
== ART_RADAR_NOT_WORKING
&& !mon_visible(mon
) ) && !(isselfhybrid
&& (moves
% 3 == 0) ) && (worm_tail
1218 ? ((!mon
->minvis
|| (See_invisible
&& (StrongSee_invisible
|| mon
->seeinvisble
) ) ) && !mon
->minvisreal
)
1219 : (mon_visible(mon
)) ||
1221 MATCH_WARN_OF_MON(mon
) ||
1222 (Role_if(PM_ACTIVISTOR
) && mon
->data
== &mons
[PM_TOPMODEL
]) ||
1223 (Race_if(PM_PEACEMAKER
) && mon
->data
== &mons
[PM_TOPMODEL
]) ||
1224 (Role_if(PM_ACTIVISTOR
) && type_is_pname(mon
->data
) && uwep
&& is_quest_artifact(uwep
) ) ||
1225 (uamul
&& uamul
->otyp
== AMULET_OF_POISON_WARNING
&& poisonous(mon
->data
) ) ||
1226 (uamul
&& uamul
->otyp
== AMULET_OF_OWN_RACE_WARNING
&& your_race(mon
->data
) ) ||
1227 (Role_if(PM_PALADIN
) && is_demon(mon
->data
) ) ||
1228 (uarms
&& uarms
->oartifact
== ART_SHIELD_OF_THE_PALADIN
&& is_demon(mon
->data
) ) ||
1229 (uarms
&& uarms
->oartifact
== ART_SHIELD_OF_THE_CHEVALIER__W
&& is_demon(mon
->data
) ) ||
1230 (uarmc
&& uarmc
->oartifact
== ART_DEMONIC_UNDEAD_RADAR
&& is_demon(mon
->data
) ) ||
1231 (uwep
&& uwep
->oartifact
== ART_DAEDRA_SEEKER
&& mon
->data
->mlet
== S_DEMON
) ||
1232 (Race_if(PM_VORTEX
) && unsolid(mon
->data
) ) ||
1233 (Race_if(PM_VORTEX
) && nolimbs(mon
->data
) ) ||
1234 (Race_if(PM_CORTEX
) && unsolid(mon
->data
) ) ||
1235 (Race_if(PM_CORTEX
) && nolimbs(mon
->data
) ) ||
1236 (uamul
&& uamul
->otyp
== AMULET_OF_COVETOUS_WARNING
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1237 (uarmh
&& uarmh
->oartifact
== ART_THAT_GIVES_IT_NOT
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1238 (uarmh
&& uarmh
->oartifact
== ART_HEARING_EAR
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1239 (ublindf
&& ublindf
->otyp
== BOSS_VISOR
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1240 (uarmf
&& uarmf
->oartifact
== ART_FINAL_EXAM_TIME
&& (mon
->data
->geno
& G_UNIQ
)) ||
1241 (Stunnopathy
&& Stunned
&& always_hostile(mon
->data
) && mon
->stunnovisible
&& distu(mon
->mx
, mon
->my
) < (StrongStunnopathy
? 401 : 226) ) ||
1242 (uarm
&& uarm
->oartifact
== ART_JEFFERSON_S_LOOKAROUND
&& bigmonst(mon
->data
) && distu(mon
->mx
, mon
->my
) < 101) ||
1243 ( (uarmh
&& itemhasappearance(uarmh
, APP_INTERNET_HELMET
) ) && mon
->internetvisible
) ||
1244 (RngeInternetAccess
&& mon
->internetvisible
) ||
1245 (uarmh
&& uarmh
->oartifact
== ART_WEB_RADIO
&& mon
->internetvisible
) ||
1246 (Numbopathy
&& Numbed
&& (avoid_player(mon
->data
) || mon
->egotype_avoider
) && distu(mon
->mx
, mon
->my
) < (StrongNumbopathy
? 901 : 626) ) ||
1247 (Sickopathy
&& Sick
&& extra_nasty(mon
->data
) && distu(mon
->mx
, mon
->my
) < (StrongSickopathy
? 901 : 401) ) ||
1248 (Freezopathy
&& Frozen
&& mon
->data
->mcolor
== CLR_WHITE
&& distu(mon
->mx
, mon
->my
) < (StrongFreezopathy
? 626 : 401) ) ||
1249 (StrongStunnopathy
&& Stunned
&& dmgtype(mon
->data
, AD_STUN
)) ||
1250 (StrongNumbopathy
&& Numbed
&& (dmgtype(mon
->data
, AD_NUMB
) || dmgtype(mon
->data
, AD_PLYS
) ) ) ||
1251 (StrongDimmopathy
&& Dimmed
&& (dmgtype(mon
->data
, AD_DIMN
) || mon
->data
->msound
== MS_CUSS
) ) ||
1252 (StrongFreezopathy
&& Frozen
&& (dmgtype(mon
->data
, AD_FRZE
) || dmgtype(mon
->data
, AD_ICEB
) ) ) ||
1253 (StrongCorrosivity
&& Slimed
&& acidic(mon
->data
) && distu(mon
->mx
, mon
->my
) < 226 ) ||
1254 (StrongBurnopathy
&& Burned
&& (dmgtype(mon
->data
, AD_BURN
) || dmgtype(mon
->data
, AD_FLAM
) ) ) ||
1255 (uarm
&& uarm
->oartifact
== ART_RNG_CESSATION
&& (dmgtype(mon
->data
, AD_RBRE
) || dmgtype(mon
->data
, AD_RNG
) ) ) ||
1256 (StrongSickopathy
&& Sick
&& (dmgtype(mon
->data
, AD_DISE
) || dmgtype(mon
->data
, AD_PEST
) ) ) ||
1257 (uarmh
&& uarmh
->otyp
== HELM_OF_UNLIVING_ESP
&& mon
->data
->mlet
== S_GOLEM
&& distu(mon
->mx
, mon
->my
) < 626) ||
1258 (uarmh
&& uarmh
->otyp
== HELM_OF_UNLIVING_ESP
&& mindless(mon
->data
) && distu(mon
->mx
, mon
->my
) < 26) ||
1259 (uarmf
&& uarmf
->oartifact
== ART_VERA_S_FREEZER
&& mon
->data
->mcolor
== CLR_WHITE
) ||
1260 (Burnopathy
&& Burned
&& infravision(mon
->data
) && distu(mon
->mx
, mon
->my
) < (StrongBurnopathy
? 170 : 101) ) ||
1261 (Dimmopathy
&& Dimmed
&& mon
->m_lev
> u
.ulevel
&& distu(mon
->mx
, mon
->my
) < (StrongDimmopathy
? 226 : 101) ) ||
1262 (ScentView
&& distu(mon
->mx
, mon
->my
) < 101 && mon
->scentvisible
&& (is_animal(mon
->data
) || mon
->data
->msound
== MS_STENCH
) ) ||
1263 (uwep
&& uwep
->oartifact
== ART_SWISS_AMY_KNIFE
&& mon
->data
->msound
== MS_SHOE
) ||
1264 (uwep
&& uwep
->oartifact
== ART_JENNY_S_PROTECTER
&& uwep
->lamplit
&& mon
->data
->msound
== MS_MOLEST
) ||
1265 (EcholocationActive
&& distu(mon
->mx
, mon
->my
) < 626 && mon
->echolocatevisible
&& (dmgtype(mon
->data
, AD_SOUN
) || mon
->data
->msound
== MS_SOUND
|| mon
->data
->msound
== MS_SHRIEK
|| mon
->data
->msound
== MS_FART_NORMAL
|| mon
->data
->msound
== MS_FART_LOUD
|| mon
->data
->msound
== MS_FART_QUIET
) ) ||
1266 (Race_if(PM_RODNEYAN
) && mon_has_amulet(mon
)) ||
1267 (Race_if(PM_RODNEYAN
) && mon_has_special(mon
)) ||
1268 (Race_if(PM_LEVITATOR
) && (is_flyer(mon
->data
) || mon
->egotype_flying
) ) ||
1269 (isselfhybrid
&& strongmonst(mon
->data
) && is_wanderer(mon
->data
) ) ||
1270 (uarm
&& uarm
->oartifact
== ART_JOKE_S_OVER
&& is_jokemonster(mon
->data
) ) ||
1271 (have_maybrittclick() && is_jokemonster(mon
->data
) ) ||
1272 (uwep
&& uwep
->oartifact
== ART_TIGATOR_S_THORN
&& is_pokemon(mon
->data
) ) ||
1273 (haveartileash(ART_PETCAMERA
) && mon
->mleashed
) ||
1274 (haveartileash(ART_ANNOYING_PET_MONITOR
) && mon
->mtame
) ||
1275 (uarmc
&& uarmc
->oartifact
== ART_SITHE_DED
&& mon
->data
->mlet
== S_MUMMY
) ||
1276 (uarm
&& uarm
->oartifact
== ART_PATROL_S_ORDERS
&& (mon
->data
->mlet
== S_ORC
|| mon
->data
->mlet
== S_OGRE
) ) ||
1277 (uarmh
&& uarmh
->oartifact
== ART_CLIERVOYENS
&& distu(mon
->mx
, mon
->my
) < 9 ) ||
1278 (uarm
&& uarm
->oartifact
== ART_PLAYER_RADAR
&& (is_mplayer(mon
->data
) || is_umplayer(mon
->data
)) ) ||
1279 (uarmf
&& uarmf
->oartifact
== ART_AWAY_YOU_STALKER
&& is_stalker(mon
->data
) ) ||
1280 (uarmf
&& uarmf
->oartifact
== ART_ELENETTES
&& (mon
->mhp
< (mon
->mhpmax
* 9 / 10)) ) ||
1281 (uarmh
&& itemhasappearance(uarmh
, APP_SAGES_HELMET
) && mon
->minvis
&& mon
->sagesvisible
) ||
1282 (ublindf
&& ublindf
->oartifact
== ART_BREATHER_SHOW
&& attacktype(mon
->data
, AT_BREA
)) ||
1283 (uarmc
&& uarmc
->oartifact
== ART_POKEWALKER
&& is_pokemon(mon
->data
) ) ||
1284 (uarmc
&& uarmc
->oartifact
== ART_BUGNOSE
&& (mon
->data
->mlet
== S_ANT
|| mon
->data
->mlet
== S_XAN
) ) ||
1285 (uamul
&& uamul
->otyp
== AMULET_OF_PET_VIEW
&& mon
->mtame
) ||
1286 (uarmu
&& uarmu
->oartifact
== ART_HEEEEELEEEEEN
&& mon
->mtame
) ||
1287 (uarmh
&& itemhasappearance(uarmh
, APP_PETSENSE_HELMET
) && mon
->mtame
) ||
1288 (uarmf
&& uarmf
->oartifact
== ART_SNAILHUNT
&& (mon
->data
->mlet
== S_BLOB
|| mon
->data
->mlet
== S_WORM
) ) ||
1289 (uarmf
&& uarmf
->oartifact
== ART_CAMELIC_SCENT
&& (mon
->data
->mlet
== S_ZOUTHERN
|| mon
->data
->mlet
== S_YETI
) ) ||
1290 (uwep
&& uwep
->oartifact
== ART_EGRID_BUG
&& mon
->data
->mlet
== S_XAN
) ||
1291 (uwep
&& uwep
->oartifact
== ART_FUYER_BREV
&& mon
->data
->mlet
== S_FUNGUS
) ||
1292 (uwep
&& uwep
->oartifact
== ART_SNICKERSNACK
&& mon
->data
->mlet
== S_JABBERWOCK
) ||
1293 (uarm
&& uarm
->oartifact
== ART_FUNGIRADAR
&& mon
->data
->mlet
== S_FUNGUS
) ||
1294 (uarmf
&& uarmf
->oartifact
== ART_BOOTS_OF_THE_MACHINE
&& (mon
->data
->mlet
== S_GOLEM
|| nonliving(mon
->data
) ) ) ||
1295 (uarmf
&& uarmf
->oartifact
== ART_FD_DETH
&& (mon
->data
->mlet
== S_DOG
|| mon
->data
->mlet
== S_FELINE
) ) ||
1296 (uarmh
&& uarmh
->oartifact
== ART_DOGGO_FRIENDSHIP
&& mon
->data
->mlet
== S_DOG
) ||
1297 (uarmg
&& uarmg
->oartifact
== ART_WHAT_S_UP_BITCHES
&& (mon
->data
->mlet
== S_NYMPH
) ) ||
1298 (uwep
&& uwep
->oartifact
== ART_FISHING_GRANDPA
&& mon
->data
->mlet
== S_EEL
) ||
1299 (uarmf
&& uarmf
->oartifact
== ART_PECTORAL_HEEL
&& distu(mon
->mx
, mon
->my
) < 101 && mon
->data
->mlet
== S_EEL
) ||
1300 (uwep
&& uwep
->oartifact
== ART_PEOPLE_EATING_TRIDENT
&& mon
->data
->mlet
== S_HUMAN
) ||
1301 (uwep
&& uwep
->oartifact
== ART_VAMPIREBANE
&& mon
->data
->mlet
== S_VAMPIRE
) ||
1302 (uwep
&& uwep
->oartifact
== ART_GOLEMBANE
&& mon
->data
->mlet
== S_GOLEM
) ||
1303 (uwep
&& uwep
->oartifact
== ART_EELBANE
&& mon
->data
->mlet
== S_EEL
) ||
1304 (uwep
&& uwep
->oartifact
== ART_MAUI_S_FISHHOOK
&& mon
->data
->mlet
== S_EEL
) ||
1305 (uarmf
&& uarmf
->oartifact
== ART_SUCH_A_LOVELY_SHARK
&& mon
->data
->mlet
== S_EEL
&& mon
->mpeaceful
) ||
1306 (uwep
&& uwep
->oartifact
== ART_DEMONSTRANTS_GO_HOME
&& mon
->data
->mlet
== S_HUMAN
) ||
1307 (uarmu
&& uarmu
->oartifact
== ART_PEACE_ADVOCATE
&& mon
->data
->mlet
== S_HUMAN
) ||
1308 (uwep
&& uwep
->oartifact
== ART_DOCTOR_JONES__AID
&& mon
->data
->mlet
== S_SNAKE
) ||
1309 (uarmc
&& uarmc
->oartifact
== ART_KILO_MEGA_GIGA_TERA_PETA_E
&& (mon
->data
->mlet
== S_KOP
|| mon
->data
->msound
== MS_TREESQUAD
) ) ||
1310 (ublindf
&& ublindf
->oartifact
== ART_SEEING_THE_PERSON_ANYWAY
&& mon
->data
->maligntyp
< 0 && distu(mon
->mx
, mon
->my
) < 26) ||
1311 (uarmh
&& uarmh
->otyp
== GOOD_ESP_HELMET
&& mon
->data
->maligntyp
> 0 && distu(mon
->mx
, mon
->my
) < 26) ||
1312 (uwep
&& uwep
->oartifact
== ART_GOODBYE_TROLLS
&& mon
->data
->mlet
== S_TROLL
) ||
1313 (uwep
&& uwep
->oartifact
== ART_ANTINSTANT_DEATH
&& mon
->data
->mlet
== S_ANT
) ||
1314 (uwep
&& uwep
->oartifact
== ART_DRAGONLANCE
&& mon
->data
->mlet
== S_DRAGON
) ||
1315 (uwep
&& uwep
->oartifact
== ART_MINI_PEOPLE_EATER
&& humanoid(mon
->data
)) ||
1316 (uwep
&& uwep
->oartifact
== ART_INDIGENOUS_FUN
&& humanoid(mon
->data
)) ||
1317 (uwep
&& uwep
->oartifact
== ART_ANIMALBANE
&& is_animal(mon
->data
)) ||
1318 (uwep
&& uwep
->oartifact
== ART_SEE_ANIMALS
&& is_animal(mon
->data
)) ||
1319 (isselfhybrid
&& monpolyok(mon
->data
) && !polyok(mon
->data
) && ((mon
->data
->mlevel
< 30) || mon
->selfhybridvisible
) ) );
1321 if (mon
&& (mon
->data
->msound
== MS_DEEPSTATE
) && !mon_visible(mon
) ) see_it
= FALSE
;
1322 if (mon
&& (mon
->data
->msound
== MS_DEEPSTATE
) && mon
->minvis
) see_it
= FALSE
;
1323 if (mon
&& (mon
->egotype_deepstatemember
) && !mon_visible(mon
) ) see_it
= FALSE
;
1324 if (mon
&& (mon
->egotype_deepstatemember
) && mon
->minvis
) see_it
= FALSE
;
1326 if (mon
&& (see_it
|| (!worm_tail
&& Detect_monsters
&& (mon
->data
->msound
!= MS_DEEPSTATE
) && !(mon
->egotype_deepstatemember
) ))) {
1327 if (mon
->mtrapped
) {
1328 struct trap
*trap
= t_at(x
, y
);
1329 int tt
= trap
? trap
->ttyp
: NO_TRAP
;
1331 /* if monster is in a physical trap, you see the trap too */
1332 if (trap
&& (tt
== BEAR_TRAP
|| tt
== PIT
||
1333 tt
== SPIKED_PIT
|| tt
== GIANT_CHASM
|| tt
== SHIT_PIT
|| tt
== MANA_PIT
|| tt
== ANOXIC_PIT
|| tt
== HYPOXIC_PIT
|| tt
== ACID_PIT
|| tt
== WEB
) && (trap
&& !trap
->hiddentrap
)) {
1337 _map_location(x
,y
,0); /* map under the monster */
1338 /* also gets rid of any invisibility glyph */
1339 display_monster(x
, y
, mon
, see_it
? PHYSICALLY_SEEN
: DETECTED
, worm_tail
);
1341 else if (mon
&& mon_warning(mon
) && !is_worm_tail(mon
))
1342 display_warning(mon
);
1343 else if (memory_is_invisible(x
,y
))
1344 map_invisible(x
, y
);
1346 _map_location(x
,y
,1); /* map the location */
1350 /* Can't see the location. */
1352 if (x
== u
.ux
&& y
== u
.uy
) {
1353 feel_location(u
.ux
, u
.uy
); /* forces an update */
1355 if (senseself()) display_self();
1357 else if ((mon
= m_at(x
,y
)) && !(uarmh
&& uarmh
->oartifact
== ART_RADAR_NOT_WORKING
) && !(isselfhybrid
&& (moves
% 3 == 0) )
1358 && ((see_it
= (tp_sensemon(mon
) ||
1359 MATCH_WARN_OF_MON(mon
) ||
1360 (Role_if(PM_ACTIVISTOR
) && mon
->data
== &mons
[PM_TOPMODEL
]) ||
1361 (Race_if(PM_PEACEMAKER
) && mon
->data
== &mons
[PM_TOPMODEL
]) ||
1362 (Role_if(PM_ACTIVISTOR
) && type_is_pname(mon
->data
) && uwep
&& is_quest_artifact(uwep
) ) ||
1363 (uamul
&& uamul
->otyp
== AMULET_OF_POISON_WARNING
&& poisonous(mon
->data
) ) ||
1364 (uamul
&& uamul
->otyp
== AMULET_OF_OWN_RACE_WARNING
&& your_race(mon
->data
) ) ||
1365 (Role_if(PM_PALADIN
) && is_demon(mon
->data
) ) ||
1366 (uarms
&& uarms
->oartifact
== ART_SHIELD_OF_THE_PALADIN
&& is_demon(mon
->data
) ) ||
1367 (uarms
&& uarms
->oartifact
== ART_SHIELD_OF_THE_CHEVALIER__W
&& is_demon(mon
->data
) ) ||
1368 (uarmc
&& uarmc
->oartifact
== ART_DEMONIC_UNDEAD_RADAR
&& is_demon(mon
->data
) ) ||
1369 (uwep
&& uwep
->oartifact
== ART_DAEDRA_SEEKER
&& mon
->data
->mlet
== S_DEMON
) ||
1370 (Race_if(PM_VORTEX
) && unsolid(mon
->data
) ) ||
1371 (Race_if(PM_VORTEX
) && nolimbs(mon
->data
) ) ||
1372 (Race_if(PM_CORTEX
) && unsolid(mon
->data
) ) ||
1373 (Race_if(PM_CORTEX
) && nolimbs(mon
->data
) ) ||
1374 (ublindf
&& ublindf
->otyp
== BOSS_VISOR
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1375 (uarmf
&& uarmf
->oartifact
== ART_FINAL_EXAM_TIME
&& (mon
->data
->geno
& G_UNIQ
)) ||
1376 (uarm
&& uarm
->oartifact
== ART_JEFFERSON_S_LOOKAROUND
&& bigmonst(mon
->data
) && distu(mon
->mx
, mon
->my
) < 101) ||
1377 (uamul
&& uamul
->otyp
== AMULET_OF_COVETOUS_WARNING
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1378 (uarmh
&& uarmh
->oartifact
== ART_THAT_GIVES_IT_NOT
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1379 (uarmh
&& uarmh
->oartifact
== ART_HEARING_EAR
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1380 (Stunnopathy
&& Stunned
&& always_hostile(mon
->data
) && mon
->stunnovisible
&& distu(mon
->mx
, mon
->my
) < (StrongStunnopathy
? 401 : 226)) ||
1381 ( (uarmh
&& itemhasappearance(uarmh
, APP_INTERNET_HELMET
) ) && mon
->internetvisible
) ||
1382 (RngeInternetAccess
&& mon
->internetvisible
) ||
1383 (uarmh
&& uarmh
->oartifact
== ART_WEB_RADIO
&& mon
->internetvisible
) ||
1384 (Numbopathy
&& Numbed
&& (avoid_player(mon
->data
) || mon
->egotype_avoider
) && distu(mon
->mx
, mon
->my
) < (StrongNumbopathy
? 901 : 626) ) ||
1385 (Sickopathy
&& Sick
&& extra_nasty(mon
->data
) && distu(mon
->mx
, mon
->my
) < (StrongSickopathy
? 901 : 401) ) ||
1386 (Freezopathy
&& Frozen
&& mon
->data
->mcolor
== CLR_WHITE
&& distu(mon
->mx
, mon
->my
) < (StrongFreezopathy
? 626 : 401) ) ||
1387 (StrongStunnopathy
&& Stunned
&& dmgtype(mon
->data
, AD_STUN
)) ||
1388 (StrongNumbopathy
&& Numbed
&& (dmgtype(mon
->data
, AD_NUMB
) || dmgtype(mon
->data
, AD_PLYS
) ) ) ||
1389 (StrongDimmopathy
&& Dimmed
&& (dmgtype(mon
->data
, AD_DIMN
) || mon
->data
->msound
== MS_CUSS
) ) ||
1390 (StrongFreezopathy
&& Frozen
&& (dmgtype(mon
->data
, AD_FRZE
) || dmgtype(mon
->data
, AD_ICEB
) ) ) ||
1391 (StrongCorrosivity
&& Slimed
&& acidic(mon
->data
) && distu(mon
->mx
, mon
->my
) < 226 ) ||
1392 (StrongBurnopathy
&& Burned
&& (dmgtype(mon
->data
, AD_BURN
) || dmgtype(mon
->data
, AD_FLAM
) ) ) ||
1393 (uarm
&& uarm
->oartifact
== ART_RNG_CESSATION
&& (dmgtype(mon
->data
, AD_RBRE
) || dmgtype(mon
->data
, AD_RNG
) ) ) ||
1394 (StrongSickopathy
&& Sick
&& (dmgtype(mon
->data
, AD_DISE
) || dmgtype(mon
->data
, AD_PEST
) ) ) ||
1395 (uarmh
&& uarmh
->otyp
== HELM_OF_UNLIVING_ESP
&& mon
->data
->mlet
== S_GOLEM
&& distu(mon
->mx
, mon
->my
) < 626) ||
1396 (uarmh
&& uarmh
->otyp
== HELM_OF_UNLIVING_ESP
&& mindless(mon
->data
) && distu(mon
->mx
, mon
->my
) < 26) ||
1397 (uarmf
&& uarmf
->oartifact
== ART_VERA_S_FREEZER
&& mon
->data
->mcolor
== CLR_WHITE
) ||
1398 (Burnopathy
&& Burned
&& infravision(mon
->data
) && distu(mon
->mx
, mon
->my
) < (StrongBurnopathy
? 170 : 101) ) ||
1399 (Dimmopathy
&& Dimmed
&& mon
->m_lev
> u
.ulevel
&& distu(mon
->mx
, mon
->my
) < (StrongDimmopathy
? 226 : 101) ) ||
1400 (ScentView
&& distu(mon
->mx
, mon
->my
) < 101 && mon
->scentvisible
&& (is_animal(mon
->data
) || mon
->data
->msound
== MS_STENCH
) ) ||
1401 (uwep
&& uwep
->oartifact
== ART_SWISS_AMY_KNIFE
&& mon
->data
->msound
== MS_SHOE
) ||
1402 (uwep
&& uwep
->oartifact
== ART_JENNY_S_PROTECTER
&& uwep
->lamplit
&& mon
->data
->msound
== MS_MOLEST
) ||
1403 (EcholocationActive
&& distu(mon
->mx
, mon
->my
) < 626 && mon
->echolocatevisible
&& (dmgtype(mon
->data
, AD_SOUN
) || mon
->data
->msound
== MS_SOUND
|| mon
->data
->msound
== MS_SHRIEK
|| mon
->data
->msound
== MS_FART_NORMAL
|| mon
->data
->msound
== MS_FART_LOUD
|| mon
->data
->msound
== MS_FART_QUIET
) ) ||
1404 (Race_if(PM_RODNEYAN
) && mon_has_amulet(mon
)) ||
1405 (Race_if(PM_RODNEYAN
) && mon_has_special(mon
)) ||
1406 (Race_if(PM_LEVITATOR
) && (is_flyer(mon
->data
) || mon
->egotype_flying
) ) ||
1407 (isselfhybrid
&& strongmonst(mon
->data
) && is_wanderer(mon
->data
) ) ||
1408 (uarm
&& uarm
->oartifact
== ART_JOKE_S_OVER
&& is_jokemonster(mon
->data
) ) ||
1409 (have_maybrittclick() && is_jokemonster(mon
->data
) ) ||
1410 (uwep
&& uwep
->oartifact
== ART_TIGATOR_S_THORN
&& is_pokemon(mon
->data
) ) ||
1411 (haveartileash(ART_PETCAMERA
) && mon
->mleashed
) ||
1412 (haveartileash(ART_ANNOYING_PET_MONITOR
) && mon
->mtame
) ||
1413 (uarmc
&& uarmc
->oartifact
== ART_SITHE_DED
&& mon
->data
->mlet
== S_MUMMY
) ||
1414 (uarm
&& uarm
->oartifact
== ART_PATROL_S_ORDERS
&& (mon
->data
->mlet
== S_ORC
|| mon
->data
->mlet
== S_OGRE
) ) ||
1415 (uarmh
&& uarmh
->oartifact
== ART_CLIERVOYENS
&& distu(mon
->mx
, mon
->my
) < 9 ) ||
1416 (uarm
&& uarm
->oartifact
== ART_PLAYER_RADAR
&& (is_mplayer(mon
->data
) || is_umplayer(mon
->data
)) ) ||
1417 (uarmf
&& uarmf
->oartifact
== ART_AWAY_YOU_STALKER
&& is_stalker(mon
->data
) ) ||
1418 (uarmf
&& uarmf
->oartifact
== ART_ELENETTES
&& (mon
->mhp
< (mon
->mhpmax
* 9 / 10)) ) ||
1419 (uarmh
&& itemhasappearance(uarmh
, APP_SAGES_HELMET
) && mon
->minvis
&& mon
->sagesvisible
) ||
1420 (ublindf
&& ublindf
->oartifact
== ART_BREATHER_SHOW
&& attacktype(mon
->data
, AT_BREA
)) ||
1421 (uarmc
&& uarmc
->oartifact
== ART_POKEWALKER
&& is_pokemon(mon
->data
) ) ||
1422 (uarmc
&& uarmc
->oartifact
== ART_BUGNOSE
&& (mon
->data
->mlet
== S_ANT
|| mon
->data
->mlet
== S_XAN
) ) ||
1423 (uamul
&& uamul
->otyp
== AMULET_OF_PET_VIEW
&& mon
->mtame
) ||
1424 (uarmu
&& uarmu
->oartifact
== ART_HEEEEELEEEEEN
&& mon
->mtame
) ||
1425 (uarmh
&& itemhasappearance(uarmh
, APP_PETSENSE_HELMET
) && mon
->mtame
) ||
1426 (uarmf
&& uarmf
->oartifact
== ART_SNAILHUNT
&& (mon
->data
->mlet
== S_BLOB
|| mon
->data
->mlet
== S_WORM
) ) ||
1427 (uarmf
&& uarmf
->oartifact
== ART_CAMELIC_SCENT
&& (mon
->data
->mlet
== S_ZOUTHERN
|| mon
->data
->mlet
== S_YETI
) ) ||
1428 (uwep
&& uwep
->oartifact
== ART_EGRID_BUG
&& mon
->data
->mlet
== S_XAN
) ||
1429 (uwep
&& uwep
->oartifact
== ART_FUYER_BREV
&& mon
->data
->mlet
== S_FUNGUS
) ||
1430 (uwep
&& uwep
->oartifact
== ART_SNICKERSNACK
&& mon
->data
->mlet
== S_JABBERWOCK
) ||
1431 (uarm
&& uarm
->oartifact
== ART_FUNGIRADAR
&& mon
->data
->mlet
== S_FUNGUS
) ||
1432 (uarmf
&& uarmf
->oartifact
== ART_BOOTS_OF_THE_MACHINE
&& (mon
->data
->mlet
== S_GOLEM
|| nonliving(mon
->data
) ) ) ||
1433 (uarmf
&& uarmf
->oartifact
== ART_FD_DETH
&& (mon
->data
->mlet
== S_DOG
|| mon
->data
->mlet
== S_FELINE
) ) ||
1434 (uarmh
&& uarmh
->oartifact
== ART_DOGGO_FRIENDSHIP
&& mon
->data
->mlet
== S_DOG
) ||
1435 (uarmg
&& uarmg
->oartifact
== ART_WHAT_S_UP_BITCHES
&& (mon
->data
->mlet
== S_NYMPH
) ) ||
1436 (uwep
&& uwep
->oartifact
== ART_FISHING_GRANDPA
&& mon
->data
->mlet
== S_EEL
) ||
1437 (uarmf
&& uarmf
->oartifact
== ART_PECTORAL_HEEL
&& distu(mon
->mx
, mon
->my
) < 101 && mon
->data
->mlet
== S_EEL
) ||
1438 (uwep
&& uwep
->oartifact
== ART_PEOPLE_EATING_TRIDENT
&& mon
->data
->mlet
== S_HUMAN
) ||
1439 (uwep
&& uwep
->oartifact
== ART_VAMPIREBANE
&& mon
->data
->mlet
== S_VAMPIRE
) ||
1440 (uwep
&& uwep
->oartifact
== ART_GOLEMBANE
&& mon
->data
->mlet
== S_GOLEM
) ||
1441 (uwep
&& uwep
->oartifact
== ART_EELBANE
&& mon
->data
->mlet
== S_EEL
) ||
1442 (uwep
&& uwep
->oartifact
== ART_MAUI_S_FISHHOOK
&& mon
->data
->mlet
== S_EEL
) ||
1443 (uarmf
&& uarmf
->oartifact
== ART_SUCH_A_LOVELY_SHARK
&& mon
->data
->mlet
== S_EEL
&& mon
->mpeaceful
) ||
1444 (uwep
&& uwep
->oartifact
== ART_DEMONSTRANTS_GO_HOME
&& mon
->data
->mlet
== S_HUMAN
) ||
1445 (uarmu
&& uarmu
->oartifact
== ART_PEACE_ADVOCATE
&& mon
->data
->mlet
== S_HUMAN
) ||
1446 (uwep
&& uwep
->oartifact
== ART_DOCTOR_JONES__AID
&& mon
->data
->mlet
== S_SNAKE
) ||
1447 (uarmc
&& uarmc
->oartifact
== ART_KILO_MEGA_GIGA_TERA_PETA_E
&& (mon
->data
->mlet
== S_KOP
|| mon
->data
->msound
== MS_TREESQUAD
) ) ||
1448 (ublindf
&& ublindf
->oartifact
== ART_SEEING_THE_PERSON_ANYWAY
&& mon
->data
->maligntyp
< 0 && distu(mon
->mx
, mon
->my
) < 26) ||
1449 (uarmh
&& uarmh
->otyp
== GOOD_ESP_HELMET
&& mon
->data
->maligntyp
> 0 && distu(mon
->mx
, mon
->my
) < 26) ||
1450 (uwep
&& uwep
->oartifact
== ART_GOODBYE_TROLLS
&& mon
->data
->mlet
== S_TROLL
) ||
1451 (uwep
&& uwep
->oartifact
== ART_ANTINSTANT_DEATH
&& mon
->data
->mlet
== S_ANT
) ||
1452 (uwep
&& uwep
->oartifact
== ART_DRAGONLANCE
&& mon
->data
->mlet
== S_DRAGON
) ||
1453 (uwep
&& uwep
->oartifact
== ART_MINI_PEOPLE_EATER
&& humanoid(mon
->data
)) ||
1454 (uwep
&& uwep
->oartifact
== ART_INDIGENOUS_FUN
&& humanoid(mon
->data
)) ||
1455 (uwep
&& uwep
->oartifact
== ART_ANIMALBANE
&& is_animal(mon
->data
)) ||
1456 (uwep
&& uwep
->oartifact
== ART_SEE_ANIMALS
&& is_animal(mon
->data
)) ||
1457 (isselfhybrid
&& monpolyok(mon
->data
) && !polyok(mon
->data
) && ((mon
->data
->mlevel
< 30) || mon
->selfhybridvisible
) ) ||
1458 (see_with_infrared(mon
) && mon_visible(mon
))))
1460 && !is_worm_tail(mon
)) {
1461 /* Monsters are printed every time. */
1462 /* This also gets rid of any invisibility glyph */
1463 if (mon
->data
->msound
!= MS_DEEPSTATE
&& !(mon
->egotype_deepstatemember
)) display_monster(x
, y
, mon
, see_it
? 0 : DETECTED
, 0);
1465 else if ((mon
= m_at(x
,y
)) && mon_warning(mon
) &&
1466 !is_worm_tail(mon
)) {
1467 display_warning(mon
);
1471 * If the location is remembered as being both dark (waslit is false)
1472 * and lit (glyph is a lit room or lit corridor) then it was either:
1474 * (1) A dark location that the hero could see through night
1477 * (2) Darkened while out of the hero's sight. This can happen
1478 * when cursed scroll of light is read.
1480 * In either case, we have to manually correct the hero's memory to
1481 * match waslit. Deciding when to change waslit is non-trivial.
1483 * Note: If flags.lit_corridor is set, then corridors act like room
1484 * squares. That is, they light up if in night vision range.
1485 * If flags.lit_corridor is not set, then corridors will
1486 * remain dark unless lit by a light spell and may darken
1487 * again, as discussed above.
1489 * These checks and changes must be here and not in back_to_glyph().
1490 * They are dependent on the position being out of sight.
1492 else if (!lev
->waslit
) {
1493 #ifdef DISPLAY_LAYERS
1494 if (lev
->mem_bg
== S_litcorr
&& lev
->typ
== CORR
) {
1495 lev
->mem_bg
= S_corr
;
1496 show_glyph(x
, y
, memory_glyph(x
, y
));
1497 } else if (lev
->mem_bg
== S_room
&& lev
->typ
== ROOM
) {
1498 lev
->mem_bg
= S_darkroom
;
1499 show_glyph(x
, y
, memory_glyph(x
, y
));
1501 #else /* DISPLAY_LAYERS */
1502 if (lev
->glyph
== cmap_to_glyph(S_litcorr
) && lev
->typ
== CORR
)
1503 show_glyph(x
, y
, lev
->glyph
= cmap_to_glyph(S_corr
));
1504 else if (lev
->glyph
== cmap_to_glyph(S_room
) && lev
->typ
== ROOM
)
1505 show_glyph(x
, y
, lev
->glyph
= cmap_to_glyph(S_darkroom
));
1506 #endif /* DISPLAY_LAYERS */
1511 show_glyph(x
, y
, memory_glyph(x
, y
));
1520 register struct monst
*mon
;
1521 register struct rm
*lev
= &(levl
[x
][y
]);
1522 register int see_it
;
1523 register xchar worm_tail
;
1525 if (in_mklev
) return;
1527 if (program_state
.done_hup
)
1530 if (ManlerIsChasing
&& x
== u
.manlerx
&& y
== u
.manlery
) {
1531 show_glyph(x
, y
, GLYPH_MON_OFF
+ rn2(NUMMONS
));
1535 if ((Quaversal
|| u
.uprops
[QUAVERSAL
].extrinsic
|| (uimplant
&& uimplant
->oartifact
== ART_ND_D___N_NDMNN_ND___NDMN_N
) || have_quaversalstone() || autismweaponcheck(ART_OMGHAXERETH
) ) && isok(u
.ux
, u
.uy
) && !isimportantlocation(x
, y
) && !(levl
[u
.ux
][u
.uy
].wall_info
& W_QUASAROK
)) {
1536 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1540 if ((uarmh
&& itemhasappearance(uarmh
, APP_HARDCORE_CLOTH
)) && !facingtile(x
, y
)) {
1541 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1545 if (Race_if(PM_SLYER_ALIEN
) && !facingtile(x
, y
)) {
1546 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1550 if (!u
.seesilverspell
&& SpellColorSilver
&& !isimportantlocation(x
, y
)) {
1551 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1555 if ((GrayoutBug
|| u
.uprops
[GRAYOUT_BUG
].extrinsic
|| have_grayoutstone() || (uarmc
&& uarmc
->oartifact
== ART_DOEDOEDOEDOEDOEDOEDOE_TEST
) || autismweaponcheck(ART_PWNHAMMER
) ) && grayoutobscuration() ) {
1556 show_glyph(x
, y
, cmap_to_glyph(S_grayglyph
));
1560 if ((GrayCenterBug
|| u
.uprops
[GRAY_CENTER_BUG
].extrinsic
|| have_graycenterstone()) && distu(x
, y
) < (GrayCenterXtra
? 9 : 4)) {
1561 show_glyph(x
, y
, cmap_to_glyph(S_grayglyph
));
1565 if ((CheckerboardBug
|| u
.uprops
[CHECKERBOARD_BUG
].extrinsic
|| autismweaponcheck(ART_SAY__CHESS_
) || have_checkerboardstone()) && ( ((x
+ y
) % (CheckerboardXtra
? 4 : 2) ) != (moves
% (CheckerboardXtra
? 4 : 2) ) ) ) {
1566 show_glyph(x
, y
, cmap_to_glyph(S_grayglyph
));
1570 if ( (QuasarVision
|| u
.uprops
[QUASAR_BUG
].extrinsic
|| have_quasarstone() ) && !isimportantlocation(x
, y
) && !(levl
[x
][y
].wall_info
& W_QUASAROK
) ) {
1571 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1575 if (Yawming
&& (distu(x
,y
) > yawm_distance())) {
1576 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1580 if (StupidMojibake
&& !rn2(MojibakeXtra
? 3 : 10)) {
1581 show_glyph(x
, y
, randomglyph());
1585 if (SpellColorBlue
&& !rn2(10)) {
1586 show_glyph(x
, y
, cmap_to_glyph(S_room
));
1590 if (SpellColorOrange
&& (distu(x
,y
) > 100)) {
1591 show_glyph(x
, y
, cmap_to_glyph(S_grayglyph
));
1595 if (SpellColorPlatinum
&& !rn2(10)) {
1596 show_glyph(x
, y
, cmap_to_glyph(S_bars
));
1600 if (SpellColorBrightCyan
&& cyanspellok(x
,y
)) {
1601 show_glyph(x
, y
, cmap_to_glyph(S_grayglyph
));
1605 if (FemtrapActiveNicole
&& nicolesquareok(x
,y
)) {
1606 show_glyph(x
, y
, cmap_to_glyph(S_stone
));
1610 if (SpellColorBrown
&& (distu(x
,y
) % 3 == 0)) {
1611 show_glyph(x
, y
, cmap_to_glyph(S_pile_of_shit
));
1615 if ( (Superscroller
|| (uarm
&& uarm
->oartifact
== ART_VOLUME_ARMAMENT
) || (uarm
&& uarm
->oartifact
== ART_SPLINTER_ARMAMENT
) || (uarm
&& uarm
->oartifact
== ART_TAPE_ARMAMENT
) || (uarmc
&& uarmc
->oartifact
== ART_VEIL_OF_LATONA
) || (uarmc
&& uarmc
->oartifact
== ART_VEIL_OF_MINISTRY
) || u
.uprops
[SUPERSCROLLER_ACTIVE
].extrinsic
|| have_superscrollerstone() ) && !isimportantlocation(x
, y
) && rn2(10) ) { show_glyphX(x
, y
, cmap_to_glyph(S_stone
)); return;}
1617 /* only permit updating the hero when swallowed */
1619 if (x
== u
.ux
&& y
== u
.uy
) display_self();
1622 if (Underwater
&& !Swimming
&& !Is_waterlevel(&u
.uz
)) {
1623 /* don't do anything unless (x,y) is an adjacent underwater position */
1625 if (!is_waterypool(x
,y
) && !is_watertunnel(x
,y
) && !is_lava(x
,y
) && !is_shiftingsand(x
,y
) && !is_styxriver(x
,y
)) return;
1626 dx
= x
- u
.ux
; if (dx
< 0) dx
= -dx
;
1627 dy
= y
- u
.uy
; if (dy
< 0) dy
= -dy
;
1628 if (dx
> 1 || dy
> 1) return;
1631 /* Can physically see the location. */
1633 NhRegion
* reg
= visible_region_at(x
,y
);
1635 * Don't use templit here: E.g.
1637 * lev->waslit = !!(lev->lit || templit(x,y));
1639 * Otherwise we have the "light pool" problem, where non-permanently
1640 * lit areas just out of sight stay remembered as lit. They should
1643 * Perhaps ALL areas should revert to their "unlit" look when
1646 lev
->waslit
= (lev
->lit
!=0); /* remember lit condition */
1648 if (reg
!= NULL
&& ACCESSIBLE(lev
->typ
)) {
1649 show_region(reg
,x
,y
);
1652 if (x
== u
.ux
&& y
== u
.uy
) {
1654 _map_location(x
,y
,0); /* map *under* self */
1657 /* we can see what is there */
1658 _map_location(x
,y
,1);
1662 worm_tail
= is_worm_tail(mon
);
1663 see_it
= mon
&& !(uarmh
&& uarmh
->oartifact
== ART_RADAR_NOT_WORKING
&& !mon_visible(mon
) ) && !(isselfhybrid
&& (moves
% 3 == 0) ) && (worm_tail
1664 ? ((!mon
->minvis
|| (See_invisible
&& (StrongSee_invisible
|| mon
->seeinvisble
) ) ) && !mon
->minvisreal
)
1665 : (mon_visible(mon
)) ||
1667 MATCH_WARN_OF_MON(mon
) ||
1668 (Role_if(PM_ACTIVISTOR
) && mon
->data
== &mons
[PM_TOPMODEL
]) ||
1669 (Race_if(PM_PEACEMAKER
) && mon
->data
== &mons
[PM_TOPMODEL
]) ||
1670 (Role_if(PM_ACTIVISTOR
) && type_is_pname(mon
->data
) && uwep
&& is_quest_artifact(uwep
) ) ||
1671 (uamul
&& uamul
->otyp
== AMULET_OF_POISON_WARNING
&& poisonous(mon
->data
) ) ||
1672 (uamul
&& uamul
->otyp
== AMULET_OF_OWN_RACE_WARNING
&& your_race(mon
->data
) ) ||
1673 (Role_if(PM_PALADIN
) && is_demon(mon
->data
) ) ||
1674 (uarms
&& uarms
->oartifact
== ART_SHIELD_OF_THE_PALADIN
&& is_demon(mon
->data
) ) ||
1675 (uarms
&& uarms
->oartifact
== ART_SHIELD_OF_THE_CHEVALIER__W
&& is_demon(mon
->data
) ) ||
1676 (uarmc
&& uarmc
->oartifact
== ART_DEMONIC_UNDEAD_RADAR
&& is_demon(mon
->data
) ) ||
1677 (uwep
&& uwep
->oartifact
== ART_DAEDRA_SEEKER
&& mon
->data
->mlet
== S_DEMON
) ||
1678 (Race_if(PM_VORTEX
) && unsolid(mon
->data
) ) ||
1679 (Race_if(PM_VORTEX
) && nolimbs(mon
->data
) ) ||
1680 (Race_if(PM_CORTEX
) && unsolid(mon
->data
) ) ||
1681 (Race_if(PM_CORTEX
) && nolimbs(mon
->data
) ) ||
1682 (uamul
&& uamul
->otyp
== AMULET_OF_COVETOUS_WARNING
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1683 (uarmh
&& uarmh
->oartifact
== ART_THAT_GIVES_IT_NOT
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1684 (uarmh
&& uarmh
->oartifact
== ART_HEARING_EAR
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1685 (ublindf
&& ublindf
->otyp
== BOSS_VISOR
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1686 (uarmf
&& uarmf
->oartifact
== ART_FINAL_EXAM_TIME
&& (mon
->data
->geno
& G_UNIQ
)) ||
1687 (uarm
&& uarm
->oartifact
== ART_JEFFERSON_S_LOOKAROUND
&& bigmonst(mon
->data
) && distu(mon
->mx
, mon
->my
) < 101) ||
1688 (Stunnopathy
&& Stunned
&& always_hostile(mon
->data
) && mon
->stunnovisible
&& distu(mon
->mx
, mon
->my
) < (StrongStunnopathy
? 401 : 226)) ||
1689 ( (uarmh
&& itemhasappearance(uarmh
, APP_INTERNET_HELMET
) ) && mon
->internetvisible
) ||
1690 (RngeInternetAccess
&& mon
->internetvisible
) ||
1691 (uarmh
&& uarmh
->oartifact
== ART_WEB_RADIO
&& mon
->internetvisible
) ||
1692 (Numbopathy
&& Numbed
&& (avoid_player(mon
->data
) || mon
->egotype_avoider
) && distu(mon
->mx
, mon
->my
) < (StrongNumbopathy
? 901 : 626) ) ||
1693 (Sickopathy
&& Sick
&& extra_nasty(mon
->data
) && distu(mon
->mx
, mon
->my
) < (StrongSickopathy
? 901 : 401) ) ||
1694 (Freezopathy
&& Frozen
&& mon
->data
->mcolor
== CLR_WHITE
&& distu(mon
->mx
, mon
->my
) < (StrongFreezopathy
? 626 : 401) ) ||
1695 (StrongStunnopathy
&& Stunned
&& dmgtype(mon
->data
, AD_STUN
)) ||
1696 (StrongNumbopathy
&& Numbed
&& (dmgtype(mon
->data
, AD_NUMB
) || dmgtype(mon
->data
, AD_PLYS
) ) ) ||
1697 (StrongDimmopathy
&& Dimmed
&& (dmgtype(mon
->data
, AD_DIMN
) || mon
->data
->msound
== MS_CUSS
) ) ||
1698 (StrongFreezopathy
&& Frozen
&& (dmgtype(mon
->data
, AD_FRZE
) || dmgtype(mon
->data
, AD_ICEB
) ) ) ||
1699 (StrongCorrosivity
&& Slimed
&& acidic(mon
->data
) && distu(mon
->mx
, mon
->my
) < 226 ) ||
1700 (StrongBurnopathy
&& Burned
&& (dmgtype(mon
->data
, AD_BURN
) || dmgtype(mon
->data
, AD_FLAM
) ) ) ||
1701 (uarm
&& uarm
->oartifact
== ART_RNG_CESSATION
&& (dmgtype(mon
->data
, AD_RBRE
) || dmgtype(mon
->data
, AD_RNG
) ) ) ||
1702 (StrongSickopathy
&& Sick
&& (dmgtype(mon
->data
, AD_DISE
) || dmgtype(mon
->data
, AD_PEST
) ) ) ||
1703 (uarmh
&& uarmh
->otyp
== HELM_OF_UNLIVING_ESP
&& mon
->data
->mlet
== S_GOLEM
&& distu(mon
->mx
, mon
->my
) < 626) ||
1704 (uarmh
&& uarmh
->otyp
== HELM_OF_UNLIVING_ESP
&& mindless(mon
->data
) && distu(mon
->mx
, mon
->my
) < 26) ||
1705 (uarmf
&& uarmf
->oartifact
== ART_VERA_S_FREEZER
&& mon
->data
->mcolor
== CLR_WHITE
) ||
1706 (Burnopathy
&& Burned
&& infravision(mon
->data
) && distu(mon
->mx
, mon
->my
) < (StrongBurnopathy
? 170 : 101) ) ||
1707 (Dimmopathy
&& Dimmed
&& mon
->m_lev
> u
.ulevel
&& distu(mon
->mx
, mon
->my
) < (StrongDimmopathy
? 226 : 101) ) ||
1708 (ScentView
&& distu(mon
->mx
, mon
->my
) < 101 && mon
->scentvisible
&& (is_animal(mon
->data
) || mon
->data
->msound
== MS_STENCH
) ) ||
1709 (uwep
&& uwep
->oartifact
== ART_SWISS_AMY_KNIFE
&& mon
->data
->msound
== MS_SHOE
) ||
1710 (uwep
&& uwep
->oartifact
== ART_JENNY_S_PROTECTER
&& uwep
->lamplit
&& mon
->data
->msound
== MS_MOLEST
) ||
1711 (EcholocationActive
&& distu(mon
->mx
, mon
->my
) < 626 && mon
->echolocatevisible
&& (dmgtype(mon
->data
, AD_SOUN
) || mon
->data
->msound
== MS_SOUND
|| mon
->data
->msound
== MS_SHRIEK
|| mon
->data
->msound
== MS_FART_NORMAL
|| mon
->data
->msound
== MS_FART_LOUD
|| mon
->data
->msound
== MS_FART_QUIET
) ) ||
1712 (Race_if(PM_RODNEYAN
) && mon_has_amulet(mon
)) ||
1713 (Race_if(PM_RODNEYAN
) && mon_has_special(mon
)) ||
1714 (Race_if(PM_LEVITATOR
) && (is_flyer(mon
->data
) || mon
->egotype_flying
) ) ||
1715 (isselfhybrid
&& strongmonst(mon
->data
) && is_wanderer(mon
->data
) ) ||
1716 (uarm
&& uarm
->oartifact
== ART_JOKE_S_OVER
&& is_jokemonster(mon
->data
) ) ||
1717 (have_maybrittclick() && is_jokemonster(mon
->data
) ) ||
1718 (uwep
&& uwep
->oartifact
== ART_TIGATOR_S_THORN
&& is_pokemon(mon
->data
) ) ||
1719 (haveartileash(ART_PETCAMERA
) && mon
->mleashed
) ||
1720 (haveartileash(ART_ANNOYING_PET_MONITOR
) && mon
->mtame
) ||
1721 (uarmc
&& uarmc
->oartifact
== ART_SITHE_DED
&& mon
->data
->mlet
== S_MUMMY
) ||
1722 (uarm
&& uarm
->oartifact
== ART_PATROL_S_ORDERS
&& (mon
->data
->mlet
== S_ORC
|| mon
->data
->mlet
== S_OGRE
) ) ||
1723 (uarmh
&& uarmh
->oartifact
== ART_CLIERVOYENS
&& distu(mon
->mx
, mon
->my
) < 9 ) ||
1724 (uarm
&& uarm
->oartifact
== ART_PLAYER_RADAR
&& (is_mplayer(mon
->data
) || is_umplayer(mon
->data
)) ) ||
1725 (uarmf
&& uarmf
->oartifact
== ART_AWAY_YOU_STALKER
&& is_stalker(mon
->data
) ) ||
1726 (uarmf
&& uarmf
->oartifact
== ART_ELENETTES
&& (mon
->mhp
< (mon
->mhpmax
* 9 / 10)) ) ||
1727 (uarmh
&& itemhasappearance(uarmh
, APP_SAGES_HELMET
) && mon
->minvis
&& mon
->sagesvisible
) ||
1728 (ublindf
&& ublindf
->oartifact
== ART_BREATHER_SHOW
&& attacktype(mon
->data
, AT_BREA
)) ||
1729 (uarmc
&& uarmc
->oartifact
== ART_POKEWALKER
&& is_pokemon(mon
->data
) ) ||
1730 (uarmc
&& uarmc
->oartifact
== ART_BUGNOSE
&& (mon
->data
->mlet
== S_ANT
|| mon
->data
->mlet
== S_XAN
) ) ||
1731 (uamul
&& uamul
->otyp
== AMULET_OF_PET_VIEW
&& mon
->mtame
) ||
1732 (uarmu
&& uarmu
->oartifact
== ART_HEEEEELEEEEEN
&& mon
->mtame
) ||
1733 (uarmh
&& itemhasappearance(uarmh
, APP_PETSENSE_HELMET
) && mon
->mtame
) ||
1734 (uarmf
&& uarmf
->oartifact
== ART_SNAILHUNT
&& (mon
->data
->mlet
== S_BLOB
|| mon
->data
->mlet
== S_WORM
) ) ||
1735 (uarmf
&& uarmf
->oartifact
== ART_CAMELIC_SCENT
&& (mon
->data
->mlet
== S_ZOUTHERN
|| mon
->data
->mlet
== S_YETI
) ) ||
1736 (uwep
&& uwep
->oartifact
== ART_EGRID_BUG
&& mon
->data
->mlet
== S_XAN
) ||
1737 (uwep
&& uwep
->oartifact
== ART_FUYER_BREV
&& mon
->data
->mlet
== S_FUNGUS
) ||
1738 (uwep
&& uwep
->oartifact
== ART_SNICKERSNACK
&& mon
->data
->mlet
== S_JABBERWOCK
) ||
1739 (uarm
&& uarm
->oartifact
== ART_FUNGIRADAR
&& mon
->data
->mlet
== S_FUNGUS
) ||
1740 (uarmf
&& uarmf
->oartifact
== ART_BOOTS_OF_THE_MACHINE
&& (mon
->data
->mlet
== S_GOLEM
|| nonliving(mon
->data
) ) ) ||
1741 (uarmf
&& uarmf
->oartifact
== ART_FD_DETH
&& (mon
->data
->mlet
== S_DOG
|| mon
->data
->mlet
== S_FELINE
) ) ||
1742 (uarmh
&& uarmh
->oartifact
== ART_DOGGO_FRIENDSHIP
&& mon
->data
->mlet
== S_DOG
) ||
1743 (uarmg
&& uarmg
->oartifact
== ART_WHAT_S_UP_BITCHES
&& (mon
->data
->mlet
== S_NYMPH
) ) ||
1744 (uwep
&& uwep
->oartifact
== ART_FISHING_GRANDPA
&& mon
->data
->mlet
== S_EEL
) ||
1745 (uarmf
&& uarmf
->oartifact
== ART_PECTORAL_HEEL
&& distu(mon
->mx
, mon
->my
) < 101 && mon
->data
->mlet
== S_EEL
) ||
1746 (uwep
&& uwep
->oartifact
== ART_PEOPLE_EATING_TRIDENT
&& mon
->data
->mlet
== S_HUMAN
) ||
1747 (uwep
&& uwep
->oartifact
== ART_VAMPIREBANE
&& mon
->data
->mlet
== S_VAMPIRE
) ||
1748 (uwep
&& uwep
->oartifact
== ART_GOLEMBANE
&& mon
->data
->mlet
== S_GOLEM
) ||
1749 (uwep
&& uwep
->oartifact
== ART_EELBANE
&& mon
->data
->mlet
== S_EEL
) ||
1750 (uwep
&& uwep
->oartifact
== ART_MAUI_S_FISHHOOK
&& mon
->data
->mlet
== S_EEL
) ||
1751 (uarmf
&& uarmf
->oartifact
== ART_SUCH_A_LOVELY_SHARK
&& mon
->data
->mlet
== S_EEL
&& mon
->mpeaceful
) ||
1752 (uwep
&& uwep
->oartifact
== ART_DEMONSTRANTS_GO_HOME
&& mon
->data
->mlet
== S_HUMAN
) ||
1753 (uarmu
&& uarmu
->oartifact
== ART_PEACE_ADVOCATE
&& mon
->data
->mlet
== S_HUMAN
) ||
1754 (uwep
&& uwep
->oartifact
== ART_DOCTOR_JONES__AID
&& mon
->data
->mlet
== S_SNAKE
) ||
1755 (uarmc
&& uarmc
->oartifact
== ART_KILO_MEGA_GIGA_TERA_PETA_E
&& (mon
->data
->mlet
== S_KOP
|| mon
->data
->msound
== MS_TREESQUAD
) ) ||
1756 (ublindf
&& ublindf
->oartifact
== ART_SEEING_THE_PERSON_ANYWAY
&& mon
->data
->maligntyp
< 0 && distu(mon
->mx
, mon
->my
) < 26) ||
1757 (uarmh
&& uarmh
->otyp
== GOOD_ESP_HELMET
&& mon
->data
->maligntyp
> 0 && distu(mon
->mx
, mon
->my
) < 26) ||
1758 (uwep
&& uwep
->oartifact
== ART_GOODBYE_TROLLS
&& mon
->data
->mlet
== S_TROLL
) ||
1759 (uwep
&& uwep
->oartifact
== ART_ANTINSTANT_DEATH
&& mon
->data
->mlet
== S_ANT
) ||
1760 (uwep
&& uwep
->oartifact
== ART_DRAGONLANCE
&& mon
->data
->mlet
== S_DRAGON
) ||
1761 (uwep
&& uwep
->oartifact
== ART_MINI_PEOPLE_EATER
&& humanoid(mon
->data
)) ||
1762 (uwep
&& uwep
->oartifact
== ART_INDIGENOUS_FUN
&& humanoid(mon
->data
)) ||
1763 (uwep
&& uwep
->oartifact
== ART_ANIMALBANE
&& is_animal(mon
->data
)) ||
1764 (uwep
&& uwep
->oartifact
== ART_SEE_ANIMALS
&& is_animal(mon
->data
)) ||
1765 (isselfhybrid
&& monpolyok(mon
->data
) && !polyok(mon
->data
) && ((mon
->data
->mlevel
< 30) || mon
->selfhybridvisible
) ) );
1767 if (mon
&& (mon
->data
->msound
== MS_DEEPSTATE
) && !mon_visible(mon
) ) see_it
= FALSE
;
1768 if (mon
&& (mon
->data
->msound
== MS_DEEPSTATE
) && mon
->minvis
) see_it
= FALSE
;
1769 if (mon
&& (mon
->egotype_deepstatemember
) && !mon_visible(mon
) ) see_it
= FALSE
;
1770 if (mon
&& (mon
->egotype_deepstatemember
) && mon
->minvis
) see_it
= FALSE
;
1772 if (mon
&& (see_it
|| (!worm_tail
&& Detect_monsters
&& (mon
->data
->msound
!= MS_DEEPSTATE
) && !(mon
->egotype_deepstatemember
) ))) {
1773 if (mon
->mtrapped
) {
1774 struct trap
*trap
= t_at(x
, y
);
1775 int tt
= trap
? trap
->ttyp
: NO_TRAP
;
1777 /* if monster is in a physical trap, you see the trap too */
1778 if (trap
&& (tt
== BEAR_TRAP
|| tt
== PIT
||
1779 tt
== SPIKED_PIT
|| tt
== GIANT_CHASM
|| tt
== SHIT_PIT
|| tt
== MANA_PIT
|| tt
== ANOXIC_PIT
|| tt
== HYPOXIC_PIT
|| tt
== ACID_PIT
|| tt
== WEB
) && (trap
&& !trap
->hiddentrap
)) {
1783 _map_location(x
,y
,0); /* map under the monster */
1784 /* also gets rid of any invisibility glyph */
1785 display_monsterX(x
, y
, mon
, see_it
? PHYSICALLY_SEEN
: DETECTED
, worm_tail
);
1787 else if (mon
&& mon_warning(mon
) && !is_worm_tail(mon
))
1788 display_warningX(mon
);
1789 else if (memory_is_invisible(x
,y
))
1790 map_invisibleX(x
, y
);
1792 _map_location(x
,y
,1); /* map the location */
1796 /* Can't see the location. */
1798 if (x
== u
.ux
&& y
== u
.uy
) {
1799 feel_location(u
.ux
, u
.uy
); /* forces an update */
1801 if (senseself()) display_self();
1803 else if ((mon
= m_at(x
,y
)) && !(uarmh
&& uarmh
->oartifact
== ART_RADAR_NOT_WORKING
) && !(isselfhybrid
&& (moves
% 3 == 0) )
1804 && ((see_it
= (tp_sensemon(mon
) ||
1805 MATCH_WARN_OF_MON(mon
) ||
1806 (Role_if(PM_ACTIVISTOR
) && mon
->data
== &mons
[PM_TOPMODEL
]) ||
1807 (Race_if(PM_PEACEMAKER
) && mon
->data
== &mons
[PM_TOPMODEL
]) ||
1808 (Role_if(PM_ACTIVISTOR
) && type_is_pname(mon
->data
) && uwep
&& is_quest_artifact(uwep
) ) ||
1809 (uamul
&& uamul
->otyp
== AMULET_OF_POISON_WARNING
&& poisonous(mon
->data
) ) ||
1810 (uamul
&& uamul
->otyp
== AMULET_OF_OWN_RACE_WARNING
&& your_race(mon
->data
) ) ||
1811 (Role_if(PM_PALADIN
) && is_demon(mon
->data
) ) ||
1812 (uarms
&& uarms
->oartifact
== ART_SHIELD_OF_THE_PALADIN
&& is_demon(mon
->data
) ) ||
1813 (uarms
&& uarms
->oartifact
== ART_SHIELD_OF_THE_CHEVALIER__W
&& is_demon(mon
->data
) ) ||
1814 (uarmc
&& uarmc
->oartifact
== ART_DEMONIC_UNDEAD_RADAR
&& is_demon(mon
->data
) ) ||
1815 (uwep
&& uwep
->oartifact
== ART_DAEDRA_SEEKER
&& mon
->data
->mlet
== S_DEMON
) ||
1816 (Race_if(PM_VORTEX
) && unsolid(mon
->data
) ) ||
1817 (Race_if(PM_VORTEX
) && nolimbs(mon
->data
) ) ||
1818 (Race_if(PM_CORTEX
) && unsolid(mon
->data
) ) ||
1819 (Race_if(PM_CORTEX
) && nolimbs(mon
->data
) ) ||
1820 (ublindf
&& ublindf
->otyp
== BOSS_VISOR
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1821 (uarmf
&& uarmf
->oartifact
== ART_FINAL_EXAM_TIME
&& (mon
->data
->geno
& G_UNIQ
)) ||
1822 (uarm
&& uarm
->oartifact
== ART_JEFFERSON_S_LOOKAROUND
&& bigmonst(mon
->data
) && distu(mon
->mx
, mon
->my
) < 101) ||
1823 (uamul
&& uamul
->otyp
== AMULET_OF_COVETOUS_WARNING
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1824 (uarmh
&& uarmh
->oartifact
== ART_THAT_GIVES_IT_NOT
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1825 (uarmh
&& uarmh
->oartifact
== ART_HEARING_EAR
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) ||
1826 (Stunnopathy
&& Stunned
&& always_hostile(mon
->data
) && mon
->stunnovisible
&& distu(mon
->mx
, mon
->my
) < (StrongStunnopathy
? 401 : 226)) ||
1827 ( (uarmh
&& itemhasappearance(uarmh
, APP_INTERNET_HELMET
) ) && mon
->internetvisible
) ||
1828 (RngeInternetAccess
&& mon
->internetvisible
) ||
1829 (uarmh
&& uarmh
->oartifact
== ART_WEB_RADIO
&& mon
->internetvisible
) ||
1830 (Numbopathy
&& Numbed
&& (avoid_player(mon
->data
) || mon
->egotype_avoider
) && distu(mon
->mx
, mon
->my
) < (StrongNumbopathy
? 901 : 626) ) ||
1831 (Sickopathy
&& Sick
&& extra_nasty(mon
->data
) && distu(mon
->mx
, mon
->my
) < (StrongSickopathy
? 901 : 401) ) ||
1832 (Freezopathy
&& Frozen
&& mon
->data
->mcolor
== CLR_WHITE
&& distu(mon
->mx
, mon
->my
) < (StrongFreezopathy
? 626 : 401) ) ||
1833 (StrongStunnopathy
&& Stunned
&& dmgtype(mon
->data
, AD_STUN
)) ||
1834 (StrongNumbopathy
&& Numbed
&& (dmgtype(mon
->data
, AD_NUMB
) || dmgtype(mon
->data
, AD_PLYS
) ) ) ||
1835 (StrongDimmopathy
&& Dimmed
&& (dmgtype(mon
->data
, AD_DIMN
) || mon
->data
->msound
== MS_CUSS
) ) ||
1836 (StrongFreezopathy
&& Frozen
&& (dmgtype(mon
->data
, AD_FRZE
) || dmgtype(mon
->data
, AD_ICEB
) ) ) ||
1837 (StrongCorrosivity
&& Slimed
&& acidic(mon
->data
) && distu(mon
->mx
, mon
->my
) < 226 ) ||
1838 (StrongBurnopathy
&& Burned
&& (dmgtype(mon
->data
, AD_BURN
) || dmgtype(mon
->data
, AD_FLAM
) ) ) ||
1839 (uarm
&& uarm
->oartifact
== ART_RNG_CESSATION
&& (dmgtype(mon
->data
, AD_RBRE
) || dmgtype(mon
->data
, AD_RNG
) ) ) ||
1840 (StrongSickopathy
&& Sick
&& (dmgtype(mon
->data
, AD_DISE
) || dmgtype(mon
->data
, AD_PEST
) ) ) ||
1841 (uarmh
&& uarmh
->otyp
== HELM_OF_UNLIVING_ESP
&& mon
->data
->mlet
== S_GOLEM
&& distu(mon
->mx
, mon
->my
) < 626) ||
1842 (uarmh
&& uarmh
->otyp
== HELM_OF_UNLIVING_ESP
&& mindless(mon
->data
) && distu(mon
->mx
, mon
->my
) < 26) ||
1843 (uarmf
&& uarmf
->oartifact
== ART_VERA_S_FREEZER
&& mon
->data
->mcolor
== CLR_WHITE
) ||
1844 (Burnopathy
&& Burned
&& infravision(mon
->data
) && distu(mon
->mx
, mon
->my
) < (StrongBurnopathy
? 170 : 101) ) ||
1845 (Dimmopathy
&& Dimmed
&& mon
->m_lev
> u
.ulevel
&& distu(mon
->mx
, mon
->my
) < (StrongDimmopathy
? 226 : 101) ) ||
1846 (ScentView
&& distu(mon
->mx
, mon
->my
) < 101 && mon
->scentvisible
&& (is_animal(mon
->data
) || mon
->data
->msound
== MS_STENCH
) ) ||
1847 (uwep
&& uwep
->oartifact
== ART_SWISS_AMY_KNIFE
&& mon
->data
->msound
== MS_SHOE
) ||
1848 (uwep
&& uwep
->oartifact
== ART_JENNY_S_PROTECTER
&& uwep
->lamplit
&& mon
->data
->msound
== MS_MOLEST
) ||
1849 (EcholocationActive
&& distu(mon
->mx
, mon
->my
) < 626 && mon
->echolocatevisible
&& (dmgtype(mon
->data
, AD_SOUN
) || mon
->data
->msound
== MS_SOUND
|| mon
->data
->msound
== MS_SHRIEK
|| mon
->data
->msound
== MS_FART_NORMAL
|| mon
->data
->msound
== MS_FART_LOUD
|| mon
->data
->msound
== MS_FART_QUIET
) ) ||
1850 (Race_if(PM_RODNEYAN
) && mon_has_amulet(mon
)) ||
1851 (Race_if(PM_RODNEYAN
) && mon_has_special(mon
)) ||
1852 (Race_if(PM_LEVITATOR
) && (is_flyer(mon
->data
) || mon
->egotype_flying
) ) ||
1853 (isselfhybrid
&& strongmonst(mon
->data
) && is_wanderer(mon
->data
) ) ||
1854 (uarm
&& uarm
->oartifact
== ART_JOKE_S_OVER
&& is_jokemonster(mon
->data
) ) ||
1855 (have_maybrittclick() && is_jokemonster(mon
->data
) ) ||
1856 (uwep
&& uwep
->oartifact
== ART_TIGATOR_S_THORN
&& is_pokemon(mon
->data
) ) ||
1857 (haveartileash(ART_PETCAMERA
) && mon
->mleashed
) ||
1858 (haveartileash(ART_ANNOYING_PET_MONITOR
) && mon
->mtame
) ||
1859 (uarmc
&& uarmc
->oartifact
== ART_SITHE_DED
&& mon
->data
->mlet
== S_MUMMY
) ||
1860 (uarm
&& uarm
->oartifact
== ART_PATROL_S_ORDERS
&& (mon
->data
->mlet
== S_ORC
|| mon
->data
->mlet
== S_OGRE
) ) ||
1861 (uarmh
&& uarmh
->oartifact
== ART_CLIERVOYENS
&& distu(mon
->mx
, mon
->my
) < 9 ) ||
1862 (uarm
&& uarm
->oartifact
== ART_PLAYER_RADAR
&& (is_mplayer(mon
->data
) || is_umplayer(mon
->data
)) ) ||
1863 (uarmf
&& uarmf
->oartifact
== ART_AWAY_YOU_STALKER
&& is_stalker(mon
->data
) ) ||
1864 (uarmf
&& uarmf
->oartifact
== ART_ELENETTES
&& (mon
->mhp
< (mon
->mhpmax
* 9 / 10)) ) ||
1865 (uarmh
&& itemhasappearance(uarmh
, APP_SAGES_HELMET
) && mon
->minvis
&& mon
->sagesvisible
) ||
1866 (ublindf
&& ublindf
->oartifact
== ART_BREATHER_SHOW
&& attacktype(mon
->data
, AT_BREA
)) ||
1867 (uarmc
&& uarmc
->oartifact
== ART_POKEWALKER
&& is_pokemon(mon
->data
) ) ||
1868 (uarmc
&& uarmc
->oartifact
== ART_BUGNOSE
&& (mon
->data
->mlet
== S_ANT
|| mon
->data
->mlet
== S_XAN
) ) ||
1869 (uamul
&& uamul
->otyp
== AMULET_OF_PET_VIEW
&& mon
->mtame
) ||
1870 (uarmu
&& uarmu
->oartifact
== ART_HEEEEELEEEEEN
&& mon
->mtame
) ||
1871 (uarmh
&& itemhasappearance(uarmh
, APP_PETSENSE_HELMET
) && mon
->mtame
) ||
1872 (uarmf
&& uarmf
->oartifact
== ART_SNAILHUNT
&& (mon
->data
->mlet
== S_BLOB
|| mon
->data
->mlet
== S_WORM
) ) ||
1873 (uarmf
&& uarmf
->oartifact
== ART_CAMELIC_SCENT
&& (mon
->data
->mlet
== S_ZOUTHERN
|| mon
->data
->mlet
== S_YETI
) ) ||
1874 (uwep
&& uwep
->oartifact
== ART_EGRID_BUG
&& mon
->data
->mlet
== S_XAN
) ||
1875 (uwep
&& uwep
->oartifact
== ART_FUYER_BREV
&& mon
->data
->mlet
== S_FUNGUS
) ||
1876 (uwep
&& uwep
->oartifact
== ART_SNICKERSNACK
&& mon
->data
->mlet
== S_JABBERWOCK
) ||
1877 (uarm
&& uarm
->oartifact
== ART_FUNGIRADAR
&& mon
->data
->mlet
== S_FUNGUS
) ||
1878 (uarmf
&& uarmf
->oartifact
== ART_BOOTS_OF_THE_MACHINE
&& (mon
->data
->mlet
== S_GOLEM
|| nonliving(mon
->data
) ) ) ||
1879 (uarmf
&& uarmf
->oartifact
== ART_FD_DETH
&& (mon
->data
->mlet
== S_DOG
|| mon
->data
->mlet
== S_FELINE
) ) ||
1880 (uarmh
&& uarmh
->oartifact
== ART_DOGGO_FRIENDSHIP
&& mon
->data
->mlet
== S_DOG
) ||
1881 (uarmg
&& uarmg
->oartifact
== ART_WHAT_S_UP_BITCHES
&& (mon
->data
->mlet
== S_NYMPH
) ) ||
1882 (uwep
&& uwep
->oartifact
== ART_FISHING_GRANDPA
&& mon
->data
->mlet
== S_EEL
) ||
1883 (uarmf
&& uarmf
->oartifact
== ART_PECTORAL_HEEL
&& distu(mon
->mx
, mon
->my
) < 101 && mon
->data
->mlet
== S_EEL
) ||
1884 (uwep
&& uwep
->oartifact
== ART_PEOPLE_EATING_TRIDENT
&& mon
->data
->mlet
== S_HUMAN
) ||
1885 (uwep
&& uwep
->oartifact
== ART_VAMPIREBANE
&& mon
->data
->mlet
== S_VAMPIRE
) ||
1886 (uwep
&& uwep
->oartifact
== ART_GOLEMBANE
&& mon
->data
->mlet
== S_GOLEM
) ||
1887 (uwep
&& uwep
->oartifact
== ART_EELBANE
&& mon
->data
->mlet
== S_EEL
) ||
1888 (uwep
&& uwep
->oartifact
== ART_MAUI_S_FISHHOOK
&& mon
->data
->mlet
== S_EEL
) ||
1889 (uarmf
&& uarmf
->oartifact
== ART_SUCH_A_LOVELY_SHARK
&& mon
->data
->mlet
== S_EEL
&& mon
->mpeaceful
) ||
1890 (uwep
&& uwep
->oartifact
== ART_DEMONSTRANTS_GO_HOME
&& mon
->data
->mlet
== S_HUMAN
) ||
1891 (uarmu
&& uarmu
->oartifact
== ART_PEACE_ADVOCATE
&& mon
->data
->mlet
== S_HUMAN
) ||
1892 (uwep
&& uwep
->oartifact
== ART_DOCTOR_JONES__AID
&& mon
->data
->mlet
== S_SNAKE
) ||
1893 (uarmc
&& uarmc
->oartifact
== ART_KILO_MEGA_GIGA_TERA_PETA_E
&& (mon
->data
->mlet
== S_KOP
|| mon
->data
->msound
== MS_TREESQUAD
) ) ||
1894 (ublindf
&& ublindf
->oartifact
== ART_SEEING_THE_PERSON_ANYWAY
&& mon
->data
->maligntyp
< 0 && distu(mon
->mx
, mon
->my
) < 26) ||
1895 (uarmh
&& uarmh
->otyp
== GOOD_ESP_HELMET
&& mon
->data
->maligntyp
> 0 && distu(mon
->mx
, mon
->my
) < 26) ||
1896 (uwep
&& uwep
->oartifact
== ART_GOODBYE_TROLLS
&& mon
->data
->mlet
== S_TROLL
) ||
1897 (uwep
&& uwep
->oartifact
== ART_ANTINSTANT_DEATH
&& mon
->data
->mlet
== S_ANT
) ||
1898 (uwep
&& uwep
->oartifact
== ART_DRAGONLANCE
&& mon
->data
->mlet
== S_DRAGON
) ||
1899 (uwep
&& uwep
->oartifact
== ART_MINI_PEOPLE_EATER
&& humanoid(mon
->data
)) ||
1900 (uwep
&& uwep
->oartifact
== ART_INDIGENOUS_FUN
&& humanoid(mon
->data
)) ||
1901 (uwep
&& uwep
->oartifact
== ART_ANIMALBANE
&& is_animal(mon
->data
)) ||
1902 (uwep
&& uwep
->oartifact
== ART_SEE_ANIMALS
&& is_animal(mon
->data
)) ||
1903 (isselfhybrid
&& monpolyok(mon
->data
) && !polyok(mon
->data
) && ((mon
->data
->mlevel
< 30) || mon
->selfhybridvisible
) ) ||
1904 (see_with_infrared(mon
) && mon_visible(mon
))))
1906 && !is_worm_tail(mon
)) {
1907 /* Monsters are printed every time. */
1908 /* This also gets rid of any invisibility glyph */
1910 if (mon
->data
->msound
!= MS_DEEPSTATE
&& !(mon
->egotype_deepstatemember
)) display_monsterX(x
, y
, mon
, see_it
? 0 : DETECTED
, 0);
1913 else if ((mon
= m_at(x
,y
)) && mon_warning(mon
) &&
1914 !is_worm_tail(mon
)) {
1915 display_warningX(mon
);
1919 * If the location is remembered as being both dark (waslit is false)
1920 * and lit (glyph is a lit room or lit corridor) then it was either:
1922 * (1) A dark location that the hero could see through night
1925 * (2) Darkened while out of the hero's sight. This can happen
1926 * when cursed scroll of light is read.
1928 * In either case, we have to manually correct the hero's memory to
1929 * match waslit. Deciding when to change waslit is non-trivial.
1931 * Note: If flags.lit_corridor is set, then corridors act like room
1932 * squares. That is, they light up if in night vision range.
1933 * If flags.lit_corridor is not set, then corridors will
1934 * remain dark unless lit by a light spell and may darken
1935 * again, as discussed above.
1937 * These checks and changes must be here and not in back_to_glyph().
1938 * They are dependent on the position being out of sight.
1940 else if (!lev
->waslit
) {
1941 #ifdef DISPLAY_LAYERS
1942 if (lev
->mem_bg
== S_litcorr
&& lev
->typ
== CORR
) {
1943 lev
->mem_bg
= S_corr
;
1944 show_glyphX(x
, y
, memory_glyph(x
, y
));
1945 } else if (lev
->mem_bg
== S_room
&& lev
->typ
== ROOM
) {
1946 lev
->mem_bg
= S_darkroom
;
1947 show_glyphX(x
, y
, memory_glyph(x
, y
));
1949 #else /* DISPLAY_LAYERS */
1950 if (lev
->glyph
== cmap_to_glyph(S_litcorr
) && lev
->typ
== CORR
)
1951 show_glyphX(x
, y
, lev
->glyph
= cmap_to_glyph(S_corr
));
1952 else if (lev
->glyph
== cmap_to_glyph(S_room
) && lev
->typ
== ROOM
)
1953 show_glyphX(x
, y
, lev
->glyph
= cmap_to_glyph(S_darkroom
));
1954 #endif /* DISPLAY_LAYERS */
1959 show_glyphX(x
, y
, memory_glyph(x
, y
));
1969 * Put magic shield pyrotechnics at the given location. This *could* be
1970 * pulled into a platform dependent routine for fancier graphics if desired.
1978 if (!flags
.sparkle
) return;
1979 if (cansee(x
,y
)) { /* Don't see anything if can't see the location */
1981 if (iflags
.usealleg
) {
1983 if(alleg_shield(x
,y
))
1987 for (i
= 0; i
< SHIELD_COUNT
; i
++) {
1988 show_glyph(x
, y
, cmap_to_glyph(shield_static
[i
]));
1989 flush_screen(1); /* make sure the glyph shows up */
1992 newsym(x
,y
); /* restore the old information */
2000 * Temporarily place glyphs on the screen. Do not call delay_output(). It
2001 * is up to the caller to decide if it wants to wait [presently, everyone
2002 * but explode() wants to delay].
2005 * (DISP_BEAM, glyph) open, initialize glyph
2006 * (DISP_BEAM_ALWAYS, glyph) open, initialize glyph
2007 * (DISP_FLASH, glyph) open, initialize glyph
2008 * (DISP_ALWAYS, glyph) open, initialize glyph
2009 * (DISP_CHANGE, glyph) change glyph
2010 * (DISP_END, 0) close & clean up (second argument doesn't
2012 * (DISP_FREEMEM, 0) only used to prevent memory leak during
2014 * (x, y) display the glyph at the location
2016 * DISP_BEAM - Display the given glyph at each location, but do not erase
2017 * any until the close call.
2018 * WAC added beam_always for lightning strikes
2019 * DISP_BEAM_ALWAYS- Like DISP_BEAM, but vision is not taken into account.
2020 * DISP_FLASH - Display the given glyph at each location, but erase the
2021 * previous location's glyph.
2022 * DISP_ALWAYS- Like DISP_FLASH, but vision is not taken into account.
2025 static struct tmp_glyph
{
2026 coord saved
[COLNO
]; /* previously updated positions */
2027 int sidx
; /* index of next unused slot in saved[] */
2028 int style
; /* either DISP_BEAM or DISP_FLASH or DISP_ALWAYS */
2029 int glyph
; /* glyph to use when printing */
2030 struct tmp_glyph
*cont
; /* Used if saved[] is full */
2031 struct tmp_glyph
*prev
;
2033 static struct tmp_glyph
*tglyph
= (struct tmp_glyph
*)0;
2039 struct tmp_glyph
*tmp
, *cont
;
2043 case DISP_BEAM_ALWAYS
:
2048 else /* nested effect; we need dynamic memory */
2049 tmp
= (struct tmp_glyph
*)alloc(sizeof (struct tmp_glyph
));
2055 tglyph
->cont
= (struct tmp_glyph
*)0;
2056 flush_screen(0); /* flush buffered glyphs */
2058 case DISP_FREEMEM
: /* in case game ends with tmp_at() in progress */
2060 cont
= tglyph
->cont
;
2063 if (cont
!= &tgfirst
) free((void *)cont
);
2067 if (tglyph
!= &tgfirst
) free((void *)tglyph
);
2076 if (!tglyph
) panic("tmp_at: tglyph not initialized");
2084 if (tglyph
->style
== DISP_BEAM
|| tglyph
->style
== DISP_BEAM_ALWAYS
) {
2087 /* Erase (reset) from source to end */
2088 for (i
= 0; i
< tglyph
->sidx
; i
++)
2089 newsym(tglyph
->saved
[i
].x
, tglyph
->saved
[i
].y
);
2090 cont
= tglyph
->cont
;
2092 for (i
= 0; i
< cont
->sidx
; i
++)
2093 newsym(cont
->saved
[i
].x
, cont
->saved
[i
].y
);
2095 if (cont
!= &tgfirst
) free((void *)cont
);
2098 /* tglyph->cont = (struct tmp_glyph *)0; */
2099 } else { /* DISP_FLASH or DISP_ALWAYS */
2100 if (tglyph
->sidx
) /* been called at least once */
2101 newsym(tglyph
->saved
[0].x
, tglyph
->saved
[0].y
);
2103 /* tglyph->sidx = 0; -- about to be freed, so not necessary */
2105 if (tglyph
!= &tgfirst
) free((void *)tglyph
);
2109 default: /* do it */
2110 if (tglyph
->style
== DISP_BEAM
|| tglyph
->style
== DISP_BEAM_ALWAYS
) {
2111 if (!cansee(x
,y
) && tglyph
->style
== DISP_BEAM
) break;
2112 /* save pos for later erasing */
2113 if (tglyph
->sidx
>= SIZE(tglyph
->saved
)) {
2114 tmp
= (struct tmp_glyph
*)alloc(sizeof (struct tmp_glyph
));
2116 tglyph
->prev
= (struct tmp_glyph
*)0;
2121 tglyph
->saved
[tglyph
->sidx
].x
= x
;
2122 tglyph
->saved
[tglyph
->sidx
].y
= y
;
2124 } else { /* DISP_FLASH/ALWAYS */
2125 if (tglyph
->sidx
) { /* not first call, so reset previous pos */
2126 newsym(tglyph
->saved
[0].x
, tglyph
->saved
[0].y
);
2127 tglyph
->sidx
= 0; /* display is presently up to date */
2129 if (!cansee(x
,y
) && tglyph
->style
!= DISP_ALWAYS
) break;
2130 tglyph
->saved
[0].x
= x
;
2131 tglyph
->saved
[0].y
= y
;
2135 show_glyph(x
, y
, tglyph
->glyph
); /* show it */
2136 flush_screen(0); /* make sure it shows up */
2141 #ifdef DISPLAY_LAYERS
2143 glyph_is_floating(glyph
)
2146 return glyph_is_monster(glyph
) || glyph_is_explosion(glyph
) ||
2147 glyph_is_zap_beam(glyph
) || glyph_is_swallow(glyph
) ||
2148 glyph_is_warning(glyph
) || tglyph
&& glyph
== tglyph
->glyph
;
2155 * The hero is swallowed. Show a special graphics sequence for this. This
2156 * bypasses all of the display routines and messes with buffered screen
2157 * directly. This method works because both vision and display check for
2164 static xchar lastx
, lasty
; /* last swallowed position */
2165 int swallower
, left_ok
, rght_ok
;
2172 /* Clear old location */
2173 for (y
= lasty
-1; y
<= lasty
+1; y
++)
2174 for (x
= lastx
-1; x
<= lastx
+1; x
++)
2175 if (isok(x
,y
)) show_glyph(x
,y
,cmap_to_glyph(S_stone
));
2179 if(!iflags
.usealleg
|| !alleg_swallowed(u
.ux
,u
.uy
)) {
2181 swallower
= monsndx(u
.ustuck
->data
);
2182 /* assume isok(u.ux,u.uy) */
2183 left_ok
= isok(u
.ux
-1,u
.uy
);
2184 rght_ok
= isok(u
.ux
+1,u
.uy
);
2186 * Display the hero surrounded by the monster's stomach.
2188 if(isok(u
.ux
, u
.uy
-1)) {
2190 show_glyph(u
.ux
-1, u
.uy
-1, swallow_to_glyph(swallower
, S_sw_tl
));
2191 show_glyph(u
.ux
, u
.uy
-1, swallow_to_glyph(swallower
, S_sw_tc
));
2193 show_glyph(u
.ux
+1, u
.uy
-1, swallow_to_glyph(swallower
, S_sw_tr
));
2197 show_glyph(u
.ux
-1, u
.uy
, swallow_to_glyph(swallower
, S_sw_ml
));
2200 show_glyph(u
.ux
+1, u
.uy
, swallow_to_glyph(swallower
, S_sw_mr
));
2202 if(isok(u
.ux
, u
.uy
+1)) {
2204 show_glyph(u
.ux
-1, u
.uy
+1, swallow_to_glyph(swallower
, S_sw_bl
));
2205 show_glyph(u
.ux
, u
.uy
+1, swallow_to_glyph(swallower
, S_sw_bc
));
2207 show_glyph(u
.ux
+1, u
.uy
+1, swallow_to_glyph(swallower
, S_sw_br
));
2213 /* Update the swallowed position. */
2221 * Similar to swallowed() in operation. Shows hero when underwater
2222 * except when in water level. Special routines exist for that.
2228 static xchar lastx
, lasty
;
2229 static boolean dela
;
2232 /* swallowing has a higher precedence than under water */
2233 if (Is_waterlevel(&u
.uz
) || u
.uswallow
) return;
2236 if (mode
== 1 || dela
) {
2240 /* delayed full update */
2241 else if (mode
== 2) {
2245 /* limited update */
2246 else { /* mode == 0 */
2247 for (y
= lasty
-1; y
<= lasty
+1; y
++)
2248 for (x
= lastx
-1; x
<= lastx
+1; x
++)
2250 show_glyph(x
,y
,cmap_to_glyph(S_stone
));
2252 for (x
= u
.ux
-1; x
<= u
.ux
+1; x
++)
2253 for (y
= u
.uy
-1; y
<= u
.uy
+1; y
++)
2255 /* Amy edit: in vanilla, you wouldn't see adjacent lava, and die very unfairly. Here in the land of SLEX,
2256 * we assume that the dungeon can bend physics and have a 'barrier' where the water ends and the lava begins,
2257 * which isn't solid and can be seen through, so when you're underwater, you can see all adjacent types of
2258 * liquid terrain, not just watery ones. */
2260 if (isok(x
,y
) && (is_waterypool(x
,y
) || is_watertunnel(x
,y
) || is_lava(x
,y
) || is_shiftingsand(x
,y
) || is_styxriver(x
,y
) )) {
2261 if (Blind
&& !(x
== u
.ux
&& y
== u
.uy
))
2262 show_glyph(x
,y
,cmap_to_glyph(S_stone
));
2273 * Very restricted display. You can only see yourself.
2279 static boolean dela
;
2281 /* swallowing has a higher precedence than under ground */
2282 if (u
.uswallow
) return;
2285 if (mode
== 1 || dela
) {
2289 /* delayed full update */
2290 else if (mode
== 2) {
2294 /* limited update */
2300 /* ========================================================================= */
2303 * Loop through all of the monsters and update them. Called when:
2304 * + going blind & telepathic
2305 * + regaining sight & telepathic
2306 * + getting and losing infravision
2308 * + doing a full screen redraw
2309 * + see invisible times out or a ring of see invisible is taken off
2310 * + when a potion of see invisible is quaffed or a ring of see
2311 * invisible is put on
2312 * + gaining telepathy when blind [givit() in eat.c, pleased() in pray.c]
2313 * + losing telepathy while blind [xkilled() in mon.c, attrcurse() in
2319 register struct monst
*mon
;
2321 if (defer_see_monsters
) return;
2323 for (mon
= fmon
; mon
; mon
= mon
->nmon
) {
2324 if (DEADMONSTER(mon
)) continue;
2325 newsym(mon
->mx
,mon
->my
);
2326 if (mon
->wormno
) see_wsegs(mon
);
2328 /* when mounted, hero's location gets caught by monster loop */
2336 register struct monst
*mon
;
2338 if (defer_see_monsters
) return;
2340 for (mon
= fmon
; mon
; mon
= mon
->nmon
) {
2341 if (DEADMONSTER(mon
)) continue;
2342 newsymX(mon
->mx
,mon
->my
);
2343 if (mon
->wormno
) see_wsegs(mon
);
2345 /* when mounted, hero's location gets caught by monster loop */
2347 newsymX(u
.ux
, u
.uy
);
2351 * Block/unblock light depending on what a mimic is mimicing and if it's
2352 * invisible or not. Should be called only when the state of See_invisible
2356 set_mimic_blocking()
2358 register struct monst
*mon
;
2360 for (mon
= fmon
; mon
; mon
= mon
->nmon
) {
2361 if (DEADMONSTER(mon
)) continue;
2363 ((mon
->m_ap_type
== M_AP_FURNITURE
&&
2364 (mon
->mappearance
== S_vcdoor
|| mon
->mappearance
== S_hcdoor
)) ||
2365 (mon
->m_ap_type
== M_AP_OBJECT
&& mon
->mappearance
== BOULDER
))) {
2367 block_point(mon
->mx
, mon
->my
);
2369 unblock_point(mon
->mx
, mon
->my
);
2375 * Loop through all of the object *locations* and update them. Called when
2381 register struct obj
*obj
;
2383 for(obj
= fobj
; obj
; obj
= obj
->nobj
)
2384 if (vobj_at(obj
->ox
,obj
->oy
) == obj
) newsym(obj
->ox
, obj
->oy
);
2388 * Update hallucinated traps.
2396 for (trap
= ftrap
; trap
; trap
= trap
->ntrap
) {
2397 glyph
= glyph_at(trap
->tx
, trap
->ty
);
2398 if (glyph_is_trap(glyph
))
2399 newsym(trap
->tx
, trap
->ty
);
2404 * Put the cursor on the hero. Flush all accumulated glyphs before doing it.
2409 flush_screen(1); /* Flush waiting glyphs & put cursor on hero */
2416 if (InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone()) vision_recalc(5);
2418 if (StuckAnnouncement
|| u
.uprops
[STUCK_ANNOUNCEMENT_BUG
].extrinsic
|| have_stuckannouncementstone()) botreal();
2427 register struct rm
*lev
;
2430 if (!u
.ux
) return; /* display isn't ready yet */
2434 for(i
= 0; i
< no_tilesets
; ++i
)
2435 if (!strcmpi(tileset
, tilesets
[i
].name
)) {
2436 transp
= !!(tilesets
[i
].flags
& TILESET_TRANSPARENT
);
2444 if (Underwater
&& !Is_waterlevel(&u
.uz
) && !Swimming
) {
2453 /* shut down vision */
2457 * This routine assumes that cls() does the following:
2458 * + fills the physical screen with the symbol for rock
2459 * + clears the glyph buffer
2463 /* display memory */
2464 for (x
= 1; x
< COLNO
; x
++) {
2466 for (y
= 0; y
< ROWNO
; y
++, lev
++)
2467 if ((glyph
= memory_glyph(x
,y
)) != cmap_to_glyph(S_stone
))
2468 show_glyphX(x
,y
,glyph
);
2471 /* see what is to be seen */
2474 /* overlay with monsters */
2477 flags
.botlx
= 1; /* force a redraw of the bottom line */
2482 /* ========================================================================= */
2483 /* Glyph Buffering (3rd screen) ============================================ */
2486 xchar
new; /* perhaps move this bit into the rm strucure. */
2490 static gbuf_entry gbuf
[ROWNO
][COLNO
];
2491 static char gbuf_start
[ROWNO
];
2492 static char gbuf_stop
[ROWNO
];
2495 /* D: Added to dump screen to output file */
2496 STATIC_PTR uchar
get_glyph_char(glyph
)
2500 register int offset
;
2502 if (glyph
>= NO_GLYPH
)
2506 * Map the glyph back to a character.
2508 * Warning: For speed, this makes an assumption on the order of
2509 * offsets. The order is set in display.h.
2511 if ((offset
= (glyph
- GLYPH_WARNING_OFF
)) >= 0) { /* a warning flash */
2512 ch
= def_warnsyms
[offset
].sym
;
2513 } else if ((offset
= (glyph
- GLYPH_SWALLOW_OFF
)) >= 0) { /* swallow */
2514 /* see swallow_to_glyph() in display.c */
2515 ch
= (uchar
) defsyms
[S_sw_tl
+ (offset
& 0x7)].sym
;
2516 } else if ((offset
= (glyph
- GLYPH_ZAP_OFF
)) >= 0) { /* zap beam */
2517 /* see zapdir_to_glyph() in display.c */
2518 ch
= defsyms
[S_vbeam
+ (offset
& 0x3)].sym
;
2519 } else if ((offset
= (glyph
- GLYPH_CMAP_OFF
)) >= 0) { /* cmap */
2520 ch
= defsyms
[offset
].sym
;
2521 } else if ((offset
= (glyph
- GLYPH_OBJ_OFF
)) >= 0) { /* object */
2522 ch
= def_oc_syms
[(int)objects
[offset
].oc_class
];
2523 } else if ((offset
= (glyph
- GLYPH_RIDDEN_OFF
)) >= 0) { /* mon ridden */
2524 ch
= def_monsyms
[(int)mons
[offset
].mlet
];
2525 } else if ((offset
= (glyph
- GLYPH_BODY_OFF
)) >= 0) { /* a corpse */
2526 ch
= def_oc_syms
[(int)objects
[CORPSE
].oc_class
];
2527 } else if ((offset
= (glyph
- GLYPH_DETECT_OFF
)) >= 0) { /* mon detect */
2528 ch
= def_monsyms
[(int)mons
[offset
].mlet
];
2529 } else if ((offset
= (glyph
- GLYPH_INVIS_OFF
)) >= 0) { /* invisible */
2531 } else if ((offset
= (glyph
- GLYPH_PET_OFF
)) >= 0) { /* a pet */
2532 ch
= def_monsyms
[(int)mons
[offset
].mlet
];
2533 } else { /* a monster */
2534 ch
= monsyms
[(int)mons
[glyph
].mlet
];
2540 extern const char * compress_str(const char *);
2543 compress_str(str
) /* copied from win/tty/wintty.c */
2546 static char cbuf
[BUFSZ
];
2547 /* compress in case line too long */
2548 if((int)strlen(str
) >= 80) {
2549 register const char *bp0
= str
;
2550 register char *bp1
= cbuf
;
2553 if(*bp0
!= ' ' || bp0
[1] != ' ')
2560 #endif /* TTY_GRAPHICS */
2562 /* Take a screen dump */
2567 /* D: botl.c has a closer approximation to the size, but we'll go with
2569 char buf
[300], *ptr
;
2571 for (y
= 0; y
< ROWNO
; y
++) {
2574 for (x
= 1; x
< COLNO
; x
++) {
2575 uchar c
= get_glyph_char(gbuf
[y
][x
].glyph
);
2585 ptr
= (char *) compress_str((const char *) buf
);
2592 #endif /* DUMP_LOG */
2595 * Store the glyph in the 3rd screen for later flushing.
2598 show_glyph(x
,y
,glyph
)
2602 * Check for bad positions and glyphs.
2605 if (InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone()) return;
2611 /* column 0 is invalid, but it's often used as a flag, so ignore it */
2615 * This assumes an ordering of the offsets. See display.h for
2619 if (glyph
>= GLYPH_WARNING_OFF
) { /* a warning */
2620 text
= "warning"; offset
= glyph
- GLYPH_WARNING_OFF
;
2621 } else if (glyph
>= GLYPH_SWALLOW_OFF
) { /* swallow border */
2622 text
= "swallow border"; offset
= glyph
- GLYPH_SWALLOW_OFF
;
2623 } else if (glyph
>= GLYPH_ZAP_OFF
) { /* zap beam */
2624 text
= "zap beam"; offset
= glyph
- GLYPH_ZAP_OFF
;
2625 } else if (glyph
>= GLYPH_EXPLODE_OFF
) { /* explosion */
2626 text
= "explosion"; offset
= glyph
- GLYPH_EXPLODE_OFF
;
2627 } else if (glyph
>= GLYPH_CMAP_OFF
) { /* cmap */
2628 text
= "cmap_index"; offset
= glyph
- GLYPH_CMAP_OFF
;
2629 } else if (glyph
>= GLYPH_OBJ_OFF
) { /* object */
2630 text
= "object"; offset
= glyph
- GLYPH_OBJ_OFF
;
2631 } else if (glyph
>= GLYPH_RIDDEN_OFF
) { /* ridden mon */
2632 text
= "ridden mon"; offset
= glyph
- GLYPH_RIDDEN_OFF
;
2633 } else if (glyph
>= GLYPH_BODY_OFF
) { /* a corpse */
2634 text
= "corpse"; offset
= glyph
- GLYPH_BODY_OFF
;
2635 } else if (glyph
>= GLYPH_DETECT_OFF
) { /* detected mon */
2636 text
= "detected mon"; offset
= glyph
- GLYPH_DETECT_OFF
;
2637 } else if (glyph
>= GLYPH_INVIS_OFF
) { /* invisible mon */
2638 text
= "invisible mon"; offset
= glyph
- GLYPH_INVIS_OFF
;
2639 } else if (glyph
>= GLYPH_PET_OFF
) { /* a pet */
2640 text
= "pet"; offset
= glyph
- GLYPH_PET_OFF
;
2641 } else { /* a monster */
2642 text
= "monster"; offset
= glyph
;
2645 impossible("show_glyph: bad pos %d %d with glyph %d [%s %d].",
2646 x
, y
, glyph
, text
, offset
);
2650 if ( RightMouseButtonDoesNotGo
&& glyph
>= GLYPH_OBJ_OFF
&& !(glyph
>= GLYPH_CMAP_OFF
&& glyph
< (GLYPH_CMAP_OFF
+ 13) ) && !(glyph
>= (GLYPH_CMAP_OFF
+ 24) && glyph
< (GLYPH_CMAP_OFF
+ 28) ) && !isimportantlocation(x
, y
) && !(glyph
== (GLYPH_CMAP_OFF
+ 47) ) )
2651 glyph
= cmap_to_glyph(S_stone
);
2653 if ( (NotSeenBug
|| u
.uprops
[NOT_SEEN_BUG
].extrinsic
|| have_nonseeingstone()) && !isimportantlocation(x
, y
) && ((glyph
>= GLYPH_CMAP_OFF
&& glyph
< (GLYPH_CMAP_OFF
+ 13) ) || (glyph
== (GLYPH_CMAP_OFF
+ 47) ) ) )
2654 glyph
= cmap_to_glyph(S_stone
);
2656 if (!flags
.wallglyph
&& !isimportantlocation(x
, y
) && glyph
== (GLYPH_CMAP_OFF
+ 47)) glyph
= cmap_to_glyph(S_stone
);
2658 if (glyph
>= MAX_GLYPH
) {
2659 impossible("show_glyph: bad glyph %d [max %d] at (%d,%d).",
2660 glyph
, MAX_GLYPH
, x
, y
);
2664 /* [ALI] In transparent mode it is not sufficient just to consider
2665 * the foreground glyph, we also need to consider the background.
2666 * Rather than extend the display module to do this, for the time
2667 * being we just turn off optimization and rely on the windowing port
2668 * to ignore redundant calls to print_glyph().
2670 if (transp
|| gbuf
[y
][x
].glyph
!= glyph
) {
2671 gbuf
[y
][x
].glyph
= glyph
;
2673 if (gbuf_start
[y
] > x
) gbuf_start
[y
] = x
;
2674 if (gbuf_stop
[y
] < x
) gbuf_stop
[y
] = x
;
2678 /* show_glyph function for interface screw trap --Amy */
2680 show_glyphX(x
,y
,glyph
)
2684 * Check for bad positions and glyphs.
2690 /* column 0 is invalid, but it's often used as a flag, so ignore it */
2694 * This assumes an ordering of the offsets. See display.h for
2698 if (glyph
>= GLYPH_WARNING_OFF
) { /* a warning */
2699 text
= "warning"; offset
= glyph
- GLYPH_WARNING_OFF
;
2700 } else if (glyph
>= GLYPH_SWALLOW_OFF
) { /* swallow border */
2701 text
= "swallow border"; offset
= glyph
- GLYPH_SWALLOW_OFF
;
2702 } else if (glyph
>= GLYPH_ZAP_OFF
) { /* zap beam */
2703 text
= "zap beam"; offset
= glyph
- GLYPH_ZAP_OFF
;
2704 } else if (glyph
>= GLYPH_EXPLODE_OFF
) { /* explosion */
2705 text
= "explosion"; offset
= glyph
- GLYPH_EXPLODE_OFF
;
2706 } else if (glyph
>= GLYPH_CMAP_OFF
) { /* cmap */
2707 text
= "cmap_index"; offset
= glyph
- GLYPH_CMAP_OFF
;
2708 } else if (glyph
>= GLYPH_OBJ_OFF
) { /* object */
2709 text
= "object"; offset
= glyph
- GLYPH_OBJ_OFF
;
2710 } else if (glyph
>= GLYPH_RIDDEN_OFF
) { /* ridden mon */
2711 text
= "ridden mon"; offset
= glyph
- GLYPH_RIDDEN_OFF
;
2712 } else if (glyph
>= GLYPH_BODY_OFF
) { /* a corpse */
2713 text
= "corpse"; offset
= glyph
- GLYPH_BODY_OFF
;
2714 } else if (glyph
>= GLYPH_DETECT_OFF
) { /* detected mon */
2715 text
= "detected mon"; offset
= glyph
- GLYPH_DETECT_OFF
;
2716 } else if (glyph
>= GLYPH_INVIS_OFF
) { /* invisible mon */
2717 text
= "invisible mon"; offset
= glyph
- GLYPH_INVIS_OFF
;
2718 } else if (glyph
>= GLYPH_PET_OFF
) { /* a pet */
2719 text
= "pet"; offset
= glyph
- GLYPH_PET_OFF
;
2720 } else { /* a monster */
2721 text
= "monster"; offset
= glyph
;
2724 impossible("show_glyph: bad pos %d %d with glyph %d [%s %d].",
2725 x
, y
, glyph
, text
, offset
);
2729 if ( RightMouseButtonDoesNotGo
&& glyph
>= GLYPH_OBJ_OFF
&& !(glyph
>= GLYPH_CMAP_OFF
&& glyph
< (GLYPH_CMAP_OFF
+ 13) ) && !(glyph
>= (GLYPH_CMAP_OFF
+ 24) && glyph
< (GLYPH_CMAP_OFF
+ 28) ) && !isimportantlocation(x
, y
) && !(glyph
== (GLYPH_CMAP_OFF
+ 47) ) )
2730 glyph
= cmap_to_glyph(S_stone
);
2732 if ( (NotSeenBug
|| u
.uprops
[NOT_SEEN_BUG
].extrinsic
|| have_nonseeingstone()) && !isimportantlocation(x
, y
) && ((glyph
>= GLYPH_CMAP_OFF
&& glyph
< (GLYPH_CMAP_OFF
+ 13) ) || (glyph
== (GLYPH_CMAP_OFF
+ 47) ) ) )
2733 glyph
= cmap_to_glyph(S_stone
);
2735 if (!flags
.wallglyph
&& !isimportantlocation(x
, y
) && glyph
== (GLYPH_CMAP_OFF
+ 47)) glyph
= cmap_to_glyph(S_stone
);
2737 if (glyph
>= MAX_GLYPH
) {
2738 impossible("show_glyph: bad glyph %d [max %d] at (%d,%d).",
2739 glyph
, MAX_GLYPH
, x
, y
);
2743 /* [ALI] In transparent mode it is not sufficient just to consider
2744 * the foreground glyph, we also need to consider the background.
2745 * Rather than extend the display module to do this, for the time
2746 * being we just turn off optimization and rely on the windowing port
2747 * to ignore redundant calls to print_glyph().
2749 if (transp
|| gbuf
[y
][x
].glyph
!= glyph
) {
2750 gbuf
[y
][x
].glyph
= glyph
;
2752 if (gbuf_start
[y
] > x
) gbuf_start
[y
] = x
;
2753 if (gbuf_stop
[y
] < x
) gbuf_stop
[y
] = x
;
2758 * Reset the changed glyph borders so that none of the 3rd screen has
2761 #define reset_glyph_bbox() \
2765 for (i = 0; i < ROWNO; i++) { \
2766 gbuf_start[i] = COLNO-1; \
2772 static gbuf_entry nul_gbuf
= { 0, cmap_to_glyph(S_stone
) };
2774 * Turn the 3rd screen into stone.
2777 clear_glyph_buffer()
2780 register gbuf_entry
*gptr
;
2782 for (y
= 0; y
< ROWNO
; y
++) {
2784 for (x
= COLNO
; x
; x
--) {
2792 * Assumes that the indicated positions are filled with S_stone glyphs.
2795 row_refresh(start
,stop
,y
)
2800 for (x
= start
; x
<= stop
; x
++)
2801 if (gbuf
[y
][x
].glyph
!= cmap_to_glyph(S_stone
))
2802 print_glyph(WIN_MAP
,x
,y
,gbuf
[y
][x
].glyph
);
2809 if (SpellColorYellow
) return;
2811 display_nhwindow(WIN_MESSAGE
, FALSE
); /* flush messages */
2812 flags
.botlx
= 1; /* force update of botl window */
2813 clear_nhwindow(WIN_MAP
); /* clear physical screen */
2814 clear_glyph_buffer(); /* this is sort of an extra effort, but OK */
2818 * Synch the third screen with the display.
2821 flush_screen(cursor_on_u
)
2824 /* Prevent infinite loops on errors:
2825 * flush_screen->print_glyph->impossible->pline->flush_screen
2827 static boolean flushing
= 0;
2828 static boolean delay_flushing
= 0;
2831 if (cursor_on_u
== -1) delay_flushing
= !delay_flushing
;
2832 if (delay_flushing
) return;
2833 if (flushing
) return; /* if already flushing then return */
2836 if (program_state
.done_hup
)
2839 for (y
= 0; y
< ROWNO
; y
++) {
2840 register gbuf_entry
*gptr
= &gbuf
[y
][x
= gbuf_start
[y
]];
2841 for (; x
<= gbuf_stop
[y
]; gptr
++, x
++)
2843 print_glyph(WIN_MAP
,x
,y
,gptr
->glyph
);
2848 if (cursor_on_u
) curs(WIN_MAP
, u
.ux
,u
.uy
); /* move cursor to the hero */
2849 display_nhwindow(WIN_MAP
, FALSE
);
2852 if (iflags
.usealleg
) alleg_vid_refresh();
2855 if(flags
.botl
|| flags
.botlx
) bot();
2858 /* ========================================================================= */
2863 * Use the information in the rm structure at the given position to create
2864 * a glyph of a background.
2866 * I had to add a field in the rm structure (horizontal) so that we knew
2867 * if open doors and secret doors were horizontal or vertical. Previously,
2868 * the screen symbol had the horizontal/vertical information set at
2869 * level generation time.
2871 * I used the 'ladder' field (really doormask) for deciding if stairwells
2872 * were up or down. I didn't want to check the upstairs and dnstairs
2880 struct rm
*ptr
= &(levl
[x
][y
]);
2883 /* KMH -- support arboreal levels */
2886 idx
= level
.flags
.arboreal
? S_tree
: /*S_stone*/S_dungwall
;
2890 if (MapTrapEffect
|| u
.uprops
[MAPBUG
].extrinsic
|| have_mapstone()) idx
= S_stone
;
2892 else idx
= (!cansee(x
,y
) && !ptr
->waslit
) ? S_darkroom
: S_room
;
2896 if (MapTrapEffect
|| u
.uprops
[MAPBUG
].extrinsic
|| have_mapstone()) idx
= S_stone
;
2898 else idx
= (ptr
->waslit
|| flags
.lit_corridor
) ? S_litcorr
: S_corr
;
2912 idx
= ptr
->seenv
? wall_angle(ptr
) : /*S_stone*/S_dungwall
;
2914 case IRONBARS
: idx
= S_bars
; break;
2916 if (ptr
->doormask
) {
2917 if (ptr
->doormask
& D_BROKEN
)
2919 else if (ptr
->doormask
& D_ISOPEN
)
2920 idx
= (ptr
->horizontal
) ? S_hodoor
: S_vodoor
;
2921 else /* else is closed */
2922 idx
= (ptr
->horizontal
) ? S_hcdoor
: S_vcdoor
;
2926 case TREE
: idx
= S_tree
; break;
2928 case MOAT
: idx
= S_pool
; break;
2930 idx
= (ptr
->ladder
& LA_DOWN
) ? S_dnstair
: S_upstair
;
2933 idx
= (ptr
->ladder
& LA_DOWN
) ? S_dnladder
: S_upladder
;
2935 case FOUNTAIN
: idx
= S_fountain
; break;
2936 case SINK
: idx
= S_sink
; break;
2937 case TOILET
: idx
= S_toilet
; break;
2938 case GRAVE
: idx
= S_grave
; break;
2939 case ALTAR
: idx
= S_altar
; break;
2940 case THRONE
: idx
= S_throne
; break;
2941 case LAVAPOOL
: idx
= S_lava
; break;
2942 case ICE
: idx
= S_ice
; break;
2943 case AIR
: idx
= S_air
; break;
2944 case CLOUD
: idx
= S_cloud
; break;
2945 case WATER
: idx
= S_water
; break;
2947 case ROCKWALL
: idx
= S_rockwall
; break;
2948 case GRAVEWALL
: idx
= S_gravewall
; break;
2949 case TUNNELWALL
: idx
= S_tunnelwall
; break;
2950 case FARMLAND
: idx
= S_farmland
; break;
2951 case MOUNTAIN
: idx
= S_mountain
; break;
2952 case WATERTUNNEL
: idx
= S_watertunnel
; break;
2953 case CRYSTALWATER
: idx
= S_crystalwater
; break;
2954 case MOORLAND
: idx
= S_moorland
; break;
2955 case URINELAKE
: idx
= S_urinelake
; break;
2956 case SHIFTINGSAND
: idx
= S_shiftingsand
; break;
2957 case STYXRIVER
: idx
= S_styxriver
; break;
2958 case PENTAGRAM
: idx
= S_pentagram
; break;
2959 case WELL
: idx
= S_well
; break;
2960 case POISONEDWELL
: idx
= S_poisonedwell
; break;
2961 case WAGON
: idx
= S_wagon
; break;
2962 case BURNINGWAGON
: idx
= S_burningwagon
; break;
2963 case WOODENTABLE
: idx
= S_woodentable
; break;
2964 case CARVEDBED
: idx
= S_carvedbed
; break;
2965 case STRAWMATTRESS
: idx
= S_strawmattress
; break;
2966 case SNOW
: idx
= S_snow
; break;
2967 case ASH
: idx
= S_ash
; break;
2968 case SAND
: idx
= S_sand
; break;
2969 case PAVEDFLOOR
: idx
= S_pavedfloor
; break;
2970 case HIGHWAY
: idx
= S_highway
; break;
2971 case GRASSLAND
: idx
= S_grassland
; break;
2972 case NETHERMIST
: idx
= S_nethermist
; break;
2973 case STALACTITE
: idx
= S_stalactite
; break;
2974 case CRYPTFLOOR
: idx
= S_cryptfloor
; break;
2975 case BUBBLES
: idx
= S_bubbles
; break;
2976 case RAINCLOUD
: idx
= S_raincloud
; break;
2979 idx
= (ptr
->horizontal
) ? S_hcdbridge
: S_vcdbridge
;
2982 switch(ptr
->drawbridgemask
& DB_UNDER
) {
2983 case DB_MOAT
: idx
= S_pool
; break;
2984 case DB_LAVA
: idx
= S_lava
; break;
2985 case DB_ICE
: idx
= S_ice
; break;
2986 case DB_FLOOR
: idx
= (!cansee(x
,y
) && !ptr
->waslit
) ? S_darkroom
: S_room
; break;
2988 impossible("Strange db-under: %d",
2989 ptr
->drawbridgemask
& DB_UNDER
);
2990 idx
= (!cansee(x
,y
) && !ptr
->waslit
) ? S_darkroom
: S_room
; /* something is better than nothing */
2994 case DRAWBRIDGE_DOWN
:
2995 idx
= (ptr
->horizontal
) ? S_hodbridge
: S_vodbridge
;
2998 impossible("back_to_glyph: unknown level type [ = %d ]",ptr
->typ
);
2999 idx
= (!cansee(x
,y
) && !ptr
->waslit
) ? S_darkroom
: S_room
;
3009 return cmap_to_glyph(back_to_cmap(x
,y
));
3014 * swallow_to_glyph()
3016 * Convert a monster number and a swallow location into the correct glyph.
3017 * If you don't want a patchwork monster while hallucinating, decide on
3018 * a random monster in swallowed() and don't use what_mon() here.
3021 swallow_to_glyph(mnum
, loc
)
3025 if (loc
< S_sw_tl
|| S_sw_br
< loc
) {
3026 impossible("swallow_to_glyph: bad swallow location");
3029 return ((int) (what_mon(mnum
)<<3) | (loc
- S_sw_tl
)) + GLYPH_SWALLOW_OFF
;
3037 * Change the given zap direction and beam type into a glyph. Each beam
3038 * type has four glyphs, one for each of the symbols below. The order of
3039 * the zap symbols [0-3] as defined in rm.h are:
3041 * | S_vbeam ( 0, 1) or ( 0,-1)
3042 * - S_hbeam ( 1, 0) or (-1, 0)
3043 * \ S_lslant ( 1, 1) or (-1,-1)
3044 * / S_rslant (-1, 1) or ( 1,-1)
3047 zapdir_to_glyph(dx
, dy
, beam_type
)
3048 register int dx
, dy
;
3051 if (beam_type
>= NUM_ZAP
) {
3052 impossible("zapdir_to_glyph: illegal beam type");
3055 dx
= (dx
== dy
) ? 2 : (dx
&& dy
) ? 3 : dx
? 1 : 0;
3057 return ((int) ((beam_type
<< 2) | dx
)) + GLYPH_ZAP_OFF
;
3062 * Utility routine for dowhatis() used to find out the glyph displayed at
3063 * the location. This isn't necessarily the same as the glyph in the levl
3064 * structure, so we must check the "third screen".
3070 if(x
< 0 || y
< 0 || x
>= COLNO
|| y
>= ROWNO
)
3071 return cmap_to_glyph(S_room
); /* XXX */
3072 return gbuf
[y
][x
].glyph
;
3076 /* ------------------------------------------------------------------------- */
3077 /* Wall Angle -------------------------------------------------------------- */
3079 /*#define WA_VERBOSE*/ /* give (x,y) locations for all "bad" spots */
3083 static const char *type_to_name(int);
3084 static void error4(int,int,int,int,int,int);
3086 static int bad_count
[MAX_TYPE
]; /* count of positions flagged as bad */
3087 static const char *type_names
[MAX_TYPE
] = {
3088 "STONE", "VWALL", "HWALL", "TLCORNER",
3089 "TRCORNER", "BLCORNER", "BRCORNER", "CROSSWALL",
3090 "TUWALL", "TDWALL", "TLWALL", "TRWALL",
3091 "DBWALL", "ROCKWALL", "GRAVEWALL", "TUNNELWALL", "SDOOR", "SCORR", "POOL",
3092 "MOAT", "WATER", "WATERTUNNEL", "CRYSTALWATER",
3093 "MOORLAND", "URINELAKE", "DRAWBRIDGE_UP", "SHIFTINGSAND", "LAVAPOOL",
3094 "STYXRIVER", "DOOR", "CORR", "ROOM", "STAIRS",
3095 "LADDER", "FOUNTAIN", "THRONE", "SINK",
3096 "ALTAR", "PENTAGRAM", "WELL", "POISONEDWELL",
3097 "WAGON", "BURNINGWAGON", "WOODENTABLE", "CARVEDBED", "STRAWMATTRESS",
3098 "ICE", "SNOW", "ASH", "SAND", "PAVEDFLOOR",
3099 "HIGHWAY", "GRASSLAND", "NETHERMIST", "STALACTITE", "CRYPTFLOOR",
3100 "DRAWBRIDGE_DOWN", "AIR",
3101 "CLOUD", "BUBBLES", "RAINCLOUD"
3109 return (type
< 0 || type
> MAX_TYPE
) ? "unknown" : type_names
[type
];
3113 error4(x
, y
, a
, b
, c
, dd
)
3114 int x
, y
, a
, b
, c
, dd
;
3116 pline("set_wall_state: %s @ (%d,%d) %s%s%s%s",
3117 type_to_name(levl
[x
][y
].typ
), x
, y
,
3118 a
? "1":"", b
? "2":"", c
? "3":"", dd
? "4":"");
3119 bad_count
[levl
[x
][y
].typ
]++;
3121 #endif /* WA_VERBOSE */
3124 * Return 'which' if position is implies an unfinshed exterior. Return
3125 * zero otherwise. Unfinished implies outer area is rock or a corridor.
3127 * Things that are ambigious: lava
3130 check_pos(x
, y
, which
)
3134 if (!isok(x
,y
)) return which
;
3135 type
= levl
[x
][y
].typ
;
3136 if (IS_ROCK(type
) || type
== CORR
|| type
== SCORR
) return which
;
3140 /* Return TRUE if more than one is non-zero. */
3144 more_than_one(x
, y
, a
, b
, c
)
3147 #if defined(MAC_MPW)
3148 # pragma unused ( x,y )
3150 if ((a
&& (b
|c
)) || (b
&& (a
|c
)) || (c
&& (a
|b
))) {
3151 error4(x
,y
,a
,b
,c
,0);
3157 #define more_than_one(x, y, a, b, c) (((a) && ((b)|(c))) || ((b) && ((a)|(c))) || ((c) && ((a)|(b))))
3160 /* Return the wall mode for a T wall. */
3162 set_twall(x0
,y0
, x1
,y1
, x2
,y2
, x3
,y3
)
3163 int x0
,y0
, x1
,y1
, x2
,y2
, x3
,y3
;
3165 int wmode
, is_1
, is_2
, is_3
;
3167 is_1
= check_pos(x1
, y1
, WM_T_LONG
);
3168 is_2
= check_pos(x2
, y2
, WM_T_BL
);
3169 is_3
= check_pos(x3
, y3
, WM_T_BR
);
3170 if (more_than_one(x0
, y0
, is_1
, is_2
, is_3
)) {
3173 wmode
= is_1
+ is_2
+ is_3
;
3178 /* Return wall mode for a horizontal or vertical wall. */
3180 set_wall(x
, y
, horiz
)
3183 int wmode
, is_1
, is_2
;
3186 is_1
= check_pos(x
,y
-1, WM_W_TOP
);
3187 is_2
= check_pos(x
,y
+1, WM_W_BOTTOM
);
3189 is_1
= check_pos(x
-1,y
, WM_W_LEFT
);
3190 is_2
= check_pos(x
+1,y
, WM_W_RIGHT
);
3192 if (more_than_one(x
, y
, is_1
, is_2
, 0)) {
3195 wmode
= is_1
+ is_2
;
3201 * If an invisible monster has gone away, that will be discovered. If an
3202 * invisible monster has appeared, this will _not_ be discovered since
3203 * searching only finds one monster per turn so we must check that separately.
3205 * Return a wall mode for a corner wall. (x4,y4) is the "inner" position.
3208 set_corn(x1
,y1
, x2
,y2
, x3
,y3
, x4
,y4
)
3209 int x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
3211 int wmode
, is_1
, is_2
, is_3
, is_4
;
3213 is_1
= check_pos(x1
, y1
, 1);
3214 is_2
= check_pos(x2
, y2
, 1);
3215 is_3
= check_pos(x3
, y3
, 1);
3216 is_4
= check_pos(x4
, y4
, 1); /* inner location */
3219 * All 4 should not be true. So if the inner location is rock,
3220 * use it. If all of the outer 3 are true, use outer. We currently
3221 * can't cover the case where only part of the outer is rock, so
3222 * we just say that all the walls are finished (if not overridden
3223 * by the inner section).
3227 } else if (is_1
&& is_2
&& is_3
)
3230 wmode
= 0; /* finished walls on all sides */
3235 /* Return mode for a crosswall. */
3240 int wmode
, is_1
, is_2
, is_3
, is_4
;
3242 is_1
= check_pos(x
-1, y
-1, 1);
3243 is_2
= check_pos(x
+1, y
-1, 1);
3244 is_3
= check_pos(x
+1, y
+1, 1);
3245 is_4
= check_pos(x
-1, y
+1, 1);
3247 wmode
= is_1
+is_2
+is_3
+is_4
;
3249 if (is_1
&& is_3
&& (is_2
+is_4
== 0)) {
3251 } else if (is_2
&& is_4
&& (is_1
+is_3
== 0)) {
3255 error4(x
,y
,is_1
,is_2
,is_3
,is_4
);
3271 /* Called from mklev. Scan the level and set the wall modes. */
3280 for (x
= 0; x
< MAX_TYPE
; x
++) bad_count
[x
] = 0;
3283 for (x
= 0; x
< COLNO
; x
++)
3284 for (lev
= &levl
[x
][0], y
= 0; y
< ROWNO
; y
++, lev
++) {
3287 wmode
= set_wall(x
, y
, (int) lev
->horizontal
);
3290 wmode
= set_wall(x
, y
, 0);
3293 wmode
= set_wall(x
, y
, 1);
3296 wmode
= set_twall(x
,y
, x
,y
-1, x
-1,y
+1, x
+1,y
+1);
3299 wmode
= set_twall(x
,y
, x
,y
+1, x
+1,y
-1, x
-1,y
-1);
3302 wmode
= set_twall(x
,y
, x
+1,y
, x
-1,y
-1, x
-1,y
+1);
3305 wmode
= set_twall(x
,y
, x
-1,y
, x
+1,y
+1, x
+1,y
-1);
3308 wmode
= set_corn(x
-1,y
-1, x
,y
-1, x
-1,y
, x
+1,y
+1);
3311 wmode
= set_corn(x
,y
-1, x
+1,y
-1, x
+1,y
, x
-1,y
+1);
3314 wmode
= set_corn(x
,y
+1, x
-1,y
+1, x
-1,y
, x
+1,y
-1);
3317 wmode
= set_corn(x
+1,y
, x
+1,y
+1, x
,y
+1, x
-1,y
-1);
3320 wmode
= set_crosswall(x
, y
);
3324 wmode
= -1; /* don't set wall info */
3329 lev
->wall_info
= (lev
->wall_info
& ~WM_MASK
) | wmode
;
3333 /* check if any bad positions found */
3334 for (x
= y
= 0; x
< MAX_TYPE
; x
++)
3337 y
= 1; /* only print once */
3338 pline("set_wall_type: wall mode problems with: ");
3340 pline("%s %d;", type_names
[x
], bad_count
[x
]);
3342 #endif /* WA_VERBOSE */
3345 /* ------------------------------------------------------------------------- */
3346 /* This matrix is used here and in vision.c. */
3347 unsigned char seenv_matrix
[3][3] = { {SV2
, SV1
, SV0
},
3351 #define sign(z) ((z) < 0 ? -1 : ((z) > 0 ? 1 : 0))
3353 /* Set the seen vector of lev as if seen from (x0,y0) to (x,y). */
3355 set_seenv(lev
, x0
, y0
, x
, y
)
3357 int x0
, y0
, x
, y
; /* from, to */
3359 int dx
= x
-x0
, dy
= y0
-y
;
3360 lev
->seenv
|= seenv_matrix
[sign(dy
)+1][sign(dx
)+1];
3363 /* ------------------------------------------------------------------------- */
3365 /* T wall types, one for each row in wall_matrix[][]. */
3372 * These are the column names of wall_matrix[][]. They are the "results"
3373 * of a tdwall pattern match. All T walls are rotated so they become
3374 * a tdwall. Then we do a single pattern match, but return the
3375 * correct result for the original wall by using different rows for
3376 * each of the wall types.
3384 static const int wall_matrix
[4][5] = {
3385 { S_stone
, S_tlcorn
, S_trcorn
, S_hwall
, S_tdwall
}, /* tdwall */
3386 { S_stone
, S_trcorn
, S_brcorn
, S_vwall
, S_tlwall
}, /* tlwall */
3387 { S_stone
, S_brcorn
, S_blcorn
, S_hwall
, S_tuwall
}, /* tuwall */
3388 { S_stone
, S_blcorn
, S_tlcorn
, S_vwall
, S_trwall
}, /* trwall */
3392 /* Cross wall types, one for each "solid" quarter. Rows of cross_matrix[][]. */
3399 * These are the column names for cross_matrix[][]. They express results
3400 * in C_br (bottom right) terms. All crosswalls with a single solid
3401 * quarter are rotated so the solid section is at the bottom right.
3402 * We pattern match on that, but return the correct result depending
3403 * on which row we'ere looking at.
3412 static const int cross_matrix
[4][6] = {
3413 { S_brcorn
, S_blcorn
, S_tlcorn
, S_tuwall
, S_trwall
, S_crwall
},
3414 { S_blcorn
, S_tlcorn
, S_trcorn
, S_trwall
, S_tdwall
, S_crwall
},
3415 { S_tlcorn
, S_trcorn
, S_brcorn
, S_tdwall
, S_tlwall
, S_crwall
},
3416 { S_trcorn
, S_brcorn
, S_blcorn
, S_tlwall
, S_tuwall
, S_crwall
},
3419 /* for hardcore cloth etc.: is this tile "behind" you (meaning you cannot see it)? --Amy
3420 * return TRUE if you can "see" the tile, FALSE otherwise */
3425 switch (u
.trontrapdirection
) {
3427 if (u
.ux
> tx
) return FALSE
;
3429 case 2: /* southeast */
3430 if (u
.ux
> tx
&& !(u
.uy
< ty
&& (abs(u
.uy
- ty
) >= abs(u
.ux
- tx
)) ) ) return FALSE
;
3431 if (u
.uy
> ty
&& !(u
.ux
< tx
&& (abs(u
.ux
- tx
) >= abs(u
.uy
- ty
)) ) ) return FALSE
;
3434 if (u
.uy
< ty
) return FALSE
;
3436 case 4: /* northwest */
3437 if (u
.ux
< tx
&& !(u
.uy
> ty
&& (abs(u
.uy
- ty
) >= abs(u
.ux
- tx
)) ) ) return FALSE
;
3438 if (u
.uy
< ty
&& !(u
.ux
> tx
&& (abs(u
.ux
- tx
) >= abs(u
.uy
- ty
)) ) ) return FALSE
;
3441 if (u
.ux
< tx
) return FALSE
;
3443 case 6: /* southwest */
3444 if (u
.ux
< tx
&& !(u
.uy
< ty
&& (abs(u
.uy
- ty
) >= abs(u
.ux
- tx
)) ) ) return FALSE
;
3445 if (u
.uy
> ty
&& !(u
.ux
> tx
&& (abs(u
.ux
- tx
) >= abs(u
.uy
- ty
)) ) ) return FALSE
;
3448 if (u
.uy
> ty
) return FALSE
;
3450 case 8: /* northeast */
3451 if (u
.ux
> tx
&& !(u
.uy
> ty
&& (abs(u
.uy
- ty
) >= abs(u
.ux
- tx
)) ) ) return FALSE
;
3452 if (u
.uy
< ty
&& !(u
.ux
< tx
&& (abs(u
.ux
- tx
) >= abs(u
.uy
- ty
)) ) ) return FALSE
;
3459 /* Print out a T wall warning and all interesting info. */
3464 static const char warn_str
[] = "wall_angle: %s: case %d: seenv = 0x%x";
3467 if (lev
->typ
== TUWALL
) wname
= "tuwall";
3468 else if (lev
->typ
== TLWALL
) wname
= "tlwall";
3469 else if (lev
->typ
== TRWALL
) wname
= "trwall";
3470 else if (lev
->typ
== TDWALL
) wname
= "tdwall";
3471 else wname
= "unknown";
3472 impossible(warn_str
, wname
, lev
->wall_info
& WM_MASK
,
3473 (unsigned int) lev
->seenv
);
3478 * Return the correct graphics character index using wall type, wall mode,
3479 * and the seen vector. It is expected that seenv is non zero.
3481 * All T-wall vectors are rotated to be TDWALL. All single crosswall
3482 * blocks are rotated to bottom right. All double crosswall are rotated
3483 * to W_X_BLTR. All results are converted back.
3485 * The only way to understand this is to take out pen and paper and
3486 * draw diagrams. See rm.h for more details on the wall modes and
3493 register unsigned int seenv
= lev
->seenv
& 0xff;
3497 #define only(sv, bits) (((sv) & (bits)) && ! ((sv) & ~(bits)))
3500 row
= wall_matrix
[T_u
];
3501 seenv
= (seenv
>> 4 | seenv
<< 4) & 0xff;/* rotate to tdwall */
3504 row
= wall_matrix
[T_l
];
3505 seenv
= (seenv
>> 2 | seenv
<< 6) & 0xff;/* rotate to tdwall */
3508 row
= wall_matrix
[T_r
];
3509 seenv
= (seenv
>> 6 | seenv
<< 2) & 0xff;/* rotate to tdwall */
3512 row
= wall_matrix
[T_d
];
3514 switch (lev
->wall_info
& WM_MASK
) {
3518 } else if (seenv
== SV6
) {
3520 } else if (seenv
& (SV3
|SV5
|SV7
) ||
3521 ((seenv
& SV4
) && (seenv
& SV6
))) {
3523 } else if (seenv
& (SV0
|SV1
|SV2
)) {
3524 col
= (seenv
& (SV4
|SV6
) ? T_tdwall
: T_hwall
);
3531 if (seenv
& (SV3
|SV4
) && !(seenv
& (SV5
|SV6
|SV7
))) {
3533 } else if (seenv
&(SV6
|SV7
) && !(seenv
&(SV3
|SV4
|SV5
))) {
3535 } else if ((seenv
& SV5
) ||
3536 ((seenv
& (SV3
|SV4
)) && (seenv
& (SV6
|SV7
)))) {
3539 /* only SV0|SV1|SV2 */
3540 if (! only(seenv
, SV0
|SV1
|SV2
) )
3546 #if 0 /* older method, fixed */
3547 if (only(seenv
, SV4
|SV5
)) {
3549 } else if ((seenv
& (SV0
|SV1
|SV2
)) &&
3550 only(seenv
, SV0
|SV1
|SV2
|SV6
|SV7
)) {
3552 } else if (seenv
& SV3
||
3553 ((seenv
& (SV0
|SV1
|SV2
)) && (seenv
& (SV4
|SV5
)))) {
3561 if (only(seenv
, SV4
|SV5
))
3563 else if ((seenv
& (SV0
|SV1
|SV2
|SV7
)) &&
3564 !(seenv
& (SV3
|SV4
|SV5
)))
3566 else if (only(seenv
, SV6
))
3572 #if 0 /* older method, fixed */
3573 if (only(seenv
, SV5
|SV6
)) {
3575 } else if ((seenv
& (SV0
|SV1
|SV2
)) &&
3576 only(seenv
, SV0
|SV1
|SV2
|SV3
|SV4
)) {
3578 } else if (seenv
& SV7
||
3579 ((seenv
& (SV0
|SV1
|SV2
)) && (seenv
& (SV5
|SV6
)))) {
3587 if (only(seenv
, SV5
|SV6
))
3589 else if ((seenv
& (SV0
|SV1
|SV2
|SV3
)) &&
3590 !(seenv
& (SV5
|SV6
|SV7
)))
3592 else if (only(seenv
, SV4
))
3599 if (wizard
) impossible("wall_angle: unknown T wall mode %d",
3600 lev
->wall_info
& WM_MASK
);
3608 if (lev
->horizontal
) goto horiz
;
3611 switch (lev
->wall_info
& WM_MASK
) {
3612 case 0: idx
= seenv
? S_vwall
: /*S_stone*/S_dungwall
; break;
3613 case 1: idx
= seenv
& (SV1
|SV2
|SV3
|SV4
|SV5
) ? S_vwall
:
3614 /*S_stone*/S_dungwall
;
3616 case 2: idx
= seenv
& (SV0
|SV1
|SV5
|SV6
|SV7
) ? S_vwall
:
3617 /*S_stone*/S_dungwall
;
3620 if (wizard
) impossible("wall_angle: unknown vwall mode %d",
3621 lev
->wall_info
& WM_MASK
);
3622 idx
= /*S_stone*/S_dungwall
;
3629 switch (lev
->wall_info
& WM_MASK
) {
3630 case 0: idx
= seenv
? S_hwall
: /*S_stone*/S_dungwall
; break;
3631 case 1: idx
= seenv
& (SV3
|SV4
|SV5
|SV6
|SV7
) ? S_hwall
:
3632 /*S_stone*/S_dungwall
;
3634 case 2: idx
= seenv
& (SV0
|SV1
|SV2
|SV3
|SV7
) ? S_hwall
:
3635 /*S_stone*/S_dungwall
;
3638 if (wizard
) impossible("wall_angle: unknown hwall mode %d",
3639 lev
->wall_info
& WM_MASK
);
3640 idx
= /*S_stone*/S_dungwall
;
3645 #define set_corner(idx, lev, which, outer, inner, name) \
3646 switch ((lev)->wall_info & WM_MASK) { \
3647 case 0: idx = which; break; \
3648 case WM_C_OUTER: idx = seenv & (outer) ? which : /*S_stone*/S_dungwall; break; \
3649 case WM_C_INNER: idx = seenv & ~(inner) ? which : /*S_stone*/S_dungwall; break; \
3651 if (wizard) impossible("wall_angle: unknown %s mode %d", name, \
3652 (lev)->wall_info & WM_MASK); \
3653 idx = /*S_stone*/S_dungwall; \
3658 set_corner(idx
, lev
, S_tlcorn
, (SV3
|SV4
|SV5
), SV4
, "tlcorn");
3661 set_corner(idx
, lev
, S_trcorn
, (SV5
|SV6
|SV7
), SV6
, "trcorn");
3664 set_corner(idx
, lev
, S_blcorn
, (SV1
|SV2
|SV3
), SV2
, "blcorn");
3667 set_corner(idx
, lev
, S_brcorn
, (SV7
|SV0
|SV1
), SV0
, "brcorn");
3672 switch (lev
->wall_info
& WM_MASK
) {
3676 else if (seenv
== SV2
)
3678 else if (seenv
== SV4
)
3680 else if (seenv
== SV6
)
3682 else if (!(seenv
& ~(SV0
|SV1
|SV2
)) &&
3683 (seenv
& SV1
|| seenv
== (SV0
|SV2
)))
3685 else if (!(seenv
& ~(SV2
|SV3
|SV4
)) &&
3686 (seenv
& SV3
|| seenv
== (SV2
|SV4
)))
3688 else if (!(seenv
& ~(SV4
|SV5
|SV6
)) &&
3689 (seenv
& SV5
|| seenv
== (SV4
|SV6
)))
3691 else if (!(seenv
& ~(SV0
|SV6
|SV7
)) &&
3692 (seenv
& SV7
|| seenv
== (SV0
|SV6
)))
3699 row
= cross_matrix
[C_tl
];
3700 seenv
= (seenv
>> 4 | seenv
<< 4) & 0xff;
3703 row
= cross_matrix
[C_tr
];
3704 seenv
= (seenv
>> 6 | seenv
<< 2) & 0xff;
3707 row
= cross_matrix
[C_bl
];
3708 seenv
= (seenv
>> 2 | seenv
<< 6) & 0xff;
3711 row
= cross_matrix
[C_br
];
3714 idx
= /*S_stone*/S_dungwall
;
3716 seenv
= seenv
& ~SV4
; /* strip SV4 */
3719 } else if (seenv
& (SV2
|SV3
)) {
3720 if (seenv
& (SV5
|SV6
|SV7
))
3722 else if (seenv
& (SV0
|SV1
))
3726 } else if (seenv
& (SV5
|SV6
)) {
3727 if (seenv
& (SV1
|SV2
|SV3
))
3729 else if (seenv
& (SV0
|SV7
))
3733 } else if (seenv
& SV1
) {
3734 col
= seenv
& SV7
? C_crwall
: C_tuwall
;
3735 } else if (seenv
& SV7
) {
3736 col
= seenv
& SV1
? C_crwall
: C_tlwall
;
3738 if (wizard
) impossible(
3739 "wall_angle: bottom of crwall check");
3748 if ( only(seenv
, SV1
|SV2
|SV3
) )
3750 else if ( only(seenv
, SV5
|SV6
|SV7
) )
3752 else if ( only(seenv
, SV0
|SV4
) )
3753 idx
= /*S_stone*/S_dungwall
;
3759 if ( only(seenv
, SV0
|SV1
|SV7
) )
3761 else if ( only(seenv
, SV3
|SV4
|SV5
) )
3763 else if ( only(seenv
, SV2
|SV6
) )
3764 idx
= /*S_stone*/S_dungwall
;
3770 if (wizard
) impossible("wall_angle: unknown crosswall mode");
3771 idx
= /*S_stone*/S_dungwall
;
3777 if (wizard
) impossible("wall_angle: unexpected wall type %d", lev
->typ
);
3778 idx
= /*S_stone*/S_dungwall
;
3787 if (mon
->data
->msound
== MS_DEEPSTATE
) return FALSE
;
3788 if (mon
->egotype_deepstatemember
) return FALSE
;
3789 if (uarmh
&& uarmh
->oartifact
== ART_RADAR_NOT_WORKING
) return FALSE
;
3790 if (isselfhybrid
&& (moves
% 3 == 0) ) return FALSE
;
3792 if (tp_sensemon(mon
)) return TRUE
;
3793 if (Detect_monsters
) return TRUE
;
3794 if (MATCH_WARN_OF_MON(mon
)) return TRUE
;
3795 if (Role_if(PM_ACTIVISTOR
) && mon
->data
== &mons
[PM_TOPMODEL
]) return TRUE
;
3796 if (Race_if(PM_PEACEMAKER
) && mon
->data
== &mons
[PM_TOPMODEL
]) return TRUE
;
3797 if (Role_if(PM_ACTIVISTOR
) && type_is_pname(mon
->data
) && uwep
&& is_quest_artifact(uwep
) ) return TRUE
;
3798 if (uamul
&& uamul
->otyp
== AMULET_OF_POISON_WARNING
&& poisonous(mon
->data
) ) return TRUE
;
3799 if (Role_if(PM_PALADIN
) && is_demon(mon
->data
) ) return TRUE
;
3800 if (uarms
&& uarms
->oartifact
== ART_SHIELD_OF_THE_PALADIN
&& is_demon(mon
->data
) ) return TRUE
;
3801 if (uarms
&& uarms
->oartifact
== ART_SHIELD_OF_THE_CHEVALIER__W
&& is_demon(mon
->data
) ) return TRUE
;
3802 if (uarmc
&& uarmc
->oartifact
== ART_DEMONIC_UNDEAD_RADAR
&& is_demon(mon
->data
) ) return TRUE
;
3803 if (uwep
&& uwep
->oartifact
== ART_DAEDRA_SEEKER
&& mon
->data
->mlet
== S_DEMON
) return TRUE
;
3804 if (Race_if(PM_VORTEX
) && unsolid(mon
->data
) ) return TRUE
;
3805 if (Race_if(PM_VORTEX
) && nolimbs(mon
->data
) ) return TRUE
;
3806 if (Race_if(PM_CORTEX
) && unsolid(mon
->data
) ) return TRUE
;
3807 if (Race_if(PM_CORTEX
) && nolimbs(mon
->data
) ) return TRUE
;
3808 if (uamul
&& uamul
->otyp
== AMULET_OF_OWN_RACE_WARNING
&& your_race(mon
->data
) ) return TRUE
;
3809 if (uamul
&& uamul
->otyp
== AMULET_OF_COVETOUS_WARNING
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) return TRUE
;
3810 if (uarmh
&& uarmh
->oartifact
== ART_THAT_GIVES_IT_NOT
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) return TRUE
;
3811 if (uarmh
&& uarmh
->oartifact
== ART_HEARING_EAR
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) return TRUE
;
3812 if (ublindf
&& ublindf
->otyp
== BOSS_VISOR
&& (is_covetous(mon
->data
) || mon
->egotype_covetous
) ) return TRUE
;
3813 if (uarmf
&& uarmf
->oartifact
== ART_FINAL_EXAM_TIME
&& (mon
->data
->geno
& G_UNIQ
)) return TRUE
;
3814 if (uarm
&& uarm
->oartifact
== ART_JEFFERSON_S_LOOKAROUND
&& bigmonst(mon
->data
) && distu(mon
->mx
, mon
->my
) < 101) return TRUE
;
3815 if ((uarmh
&& itemhasappearance(uarmh
, APP_INTERNET_HELMET
) ) && mon
->internetvisible
) return TRUE
;
3816 if (RngeInternetAccess
&& mon
->internetvisible
) return TRUE
;
3817 if (uarmh
&& uarmh
->oartifact
== ART_WEB_RADIO
&& mon
->internetvisible
) return TRUE
;
3818 if (Stunnopathy
&& Stunned
&& always_hostile(mon
->data
) && mon
->stunnovisible
&& distu(mon
->mx
, mon
->my
) < (StrongStunnopathy
? 401 : 226)) return TRUE
;
3819 if (Numbopathy
&& Numbed
&& (avoid_player(mon
->data
) || mon
->egotype_avoider
) && distu(mon
->mx
, mon
->my
) < (StrongNumbopathy
? 901 : 626) ) return TRUE
;
3820 if (Sickopathy
&& Sick
&& extra_nasty(mon
->data
) && distu(mon
->mx
, mon
->my
) < (StrongSickopathy
? 901 : 401) ) return TRUE
;
3821 if (Freezopathy
&& Frozen
&& mon
->data
->mcolor
== CLR_WHITE
&& distu(mon
->mx
, mon
->my
) < (StrongFreezopathy
? 626 : 401) ) return TRUE
;
3822 if (StrongStunnopathy
&& Stunned
&& dmgtype(mon
->data
, AD_STUN
)) return TRUE
;
3823 if (StrongNumbopathy
&& Numbed
&& (dmgtype(mon
->data
, AD_NUMB
) || dmgtype(mon
->data
, AD_PLYS
) ) ) return TRUE
;
3824 if (StrongDimmopathy
&& Dimmed
&& (dmgtype(mon
->data
, AD_DIMN
) || mon
->data
->msound
== MS_CUSS
) ) return TRUE
;
3825 if (StrongFreezopathy
&& Frozen
&& (dmgtype(mon
->data
, AD_FRZE
) || dmgtype(mon
->data
, AD_ICEB
) ) ) return TRUE
;
3826 if (StrongCorrosivity
&& Slimed
&& acidic(mon
->data
) && distu(mon
->mx
, mon
->my
) < 226 ) return TRUE
;
3827 if (StrongBurnopathy
&& Burned
&& (dmgtype(mon
->data
, AD_BURN
) || dmgtype(mon
->data
, AD_FLAM
) ) ) return TRUE
;
3828 if (uarm
&& uarm
->oartifact
== ART_RNG_CESSATION
&& (dmgtype(mon
->data
, AD_RBRE
) || dmgtype(mon
->data
, AD_RNG
) ) ) return TRUE
;
3829 if (StrongSickopathy
&& Sick
&& (dmgtype(mon
->data
, AD_DISE
) || dmgtype(mon
->data
, AD_PEST
) ) ) return TRUE
;
3830 if (ScentView
&& distu(mon
->mx
, mon
->my
) < 101 && mon
->scentvisible
&& (is_animal(mon
->data
) || mon
->data
->msound
== MS_STENCH
) ) return TRUE
;
3831 if (uwep
&& uwep
->oartifact
== ART_SWISS_AMY_KNIFE
&& mon
->data
->msound
== MS_SHOE
) return TRUE
;
3832 if (uwep
&& uwep
->oartifact
== ART_JENNY_S_PROTECTER
&& uwep
->lamplit
&& mon
->data
->msound
== MS_MOLEST
) return TRUE
;
3833 if (EcholocationActive
&& distu(mon
->mx
, mon
->my
) < 626 && mon
->echolocatevisible
&& (dmgtype(mon
->data
, AD_SOUN
) || mon
->data
->msound
== MS_SOUND
|| mon
->data
->msound
== MS_SHRIEK
|| mon
->data
->msound
== MS_FART_NORMAL
|| mon
->data
->msound
== MS_FART_LOUD
|| mon
->data
->msound
== MS_FART_QUIET
) ) return TRUE
;
3834 if (uarmh
&& uarmh
->otyp
== HELM_OF_UNLIVING_ESP
&& mon
->data
->mlet
== S_GOLEM
&& distu(mon
->mx
, mon
->my
) < 626) return TRUE
;
3835 if (uarmh
&& uarmh
->otyp
== HELM_OF_UNLIVING_ESP
&& mindless(mon
->data
) && distu(mon
->mx
, mon
->my
) < 26) return TRUE
;
3836 if (uarmf
&& uarmf
->oartifact
== ART_VERA_S_FREEZER
&& mon
->data
->mcolor
== CLR_WHITE
) return TRUE
;
3837 if (Burnopathy
&& Burned
&& infravision(mon
->data
) && distu(mon
->mx
, mon
->my
) < (StrongBurnopathy
? 170 : 101) ) return TRUE
;
3838 if (Dimmopathy
&& Dimmed
&& mon
->m_lev
> u
.ulevel
&& distu(mon
->mx
, mon
->my
) < (StrongDimmopathy
? 226 : 101) ) return TRUE
;
3839 if (Race_if(PM_RODNEYAN
) && mon_has_amulet(mon
)) return TRUE
;
3840 if (Race_if(PM_RODNEYAN
) && mon_has_special(mon
)) return TRUE
;
3841 if (Race_if(PM_LEVITATOR
) && (is_flyer(mon
->data
) || mon
->egotype_flying
) ) return TRUE
;
3842 if (uarmf
&& uarmf
->oartifact
== ART_ELENETTES
&& (mon
->mhp
< (mon
->mhpmax
* 9 / 10)) ) return TRUE
;
3843 if (isselfhybrid
&& strongmonst(mon
->data
) && is_wanderer(mon
->data
) ) return TRUE
;
3844 if (uarm
&& uarm
->oartifact
== ART_JOKE_S_OVER
&& is_jokemonster(mon
->data
) ) return TRUE
;
3845 if (have_maybrittclick() && is_jokemonster(mon
->data
) ) return TRUE
;
3846 if (uwep
&& uwep
->oartifact
== ART_TIGATOR_S_THORN
&& is_pokemon(mon
->data
) ) return TRUE
;
3847 if (haveartileash(ART_PETCAMERA
) && mon
->mleashed
) return TRUE
;
3848 if (haveartileash(ART_ANNOYING_PET_MONITOR
) && mon
->mtame
) return TRUE
;
3849 if (uarmc
&& uarmc
->oartifact
== ART_SITHE_DED
&& mon
->data
->mlet
== S_MUMMY
) return TRUE
;
3850 if (uarm
&& uarm
->oartifact
== ART_PATROL_S_ORDERS
&& (mon
->data
->mlet
== S_ORC
|| mon
->data
->mlet
== S_OGRE
) ) return TRUE
;
3851 if (uarmh
&& uarmh
->oartifact
== ART_CLIERVOYENS
&& distu(mon
->mx
, mon
->my
) < 9 ) return TRUE
;
3852 if (uarm
&& uarm
->oartifact
== ART_PLAYER_RADAR
&& (is_mplayer(mon
->data
) || is_umplayer(mon
->data
)) ) return TRUE
;
3853 if (uarmf
&& uarmf
->oartifact
== ART_AWAY_YOU_STALKER
&& is_stalker(mon
->data
) ) return TRUE
;
3854 if (uarmh
&& itemhasappearance(uarmh
, APP_SAGES_HELMET
) && mon
->minvis
&& mon
->sagesvisible
) return TRUE
;
3855 if (ublindf
&& ublindf
->oartifact
== ART_BREATHER_SHOW
&& attacktype(mon
->data
, AT_BREA
)) return TRUE
;
3856 if (uarmc
&& uarmc
->oartifact
== ART_POKEWALKER
&& is_pokemon(mon
->data
) ) return TRUE
;
3857 if (uwep
&& uwep
->oartifact
== ART_EGRID_BUG
&& mon
->data
->mlet
== S_XAN
) return TRUE
;
3858 if (uarmc
&& uarmc
->oartifact
== ART_BUGNOSE
&& (mon
->data
->mlet
== S_ANT
|| mon
->data
->mlet
== S_XAN
) ) return TRUE
;
3859 if (uamul
&& uamul
->otyp
== AMULET_OF_PET_VIEW
&& mon
->mtame
) return TRUE
;
3860 if (uarmu
&& uarmu
->oartifact
== ART_HEEEEELEEEEEN
&& mon
->mtame
) return TRUE
;
3861 if (uarmh
&& itemhasappearance(uarmh
, APP_PETSENSE_HELMET
) && mon
->mtame
) return TRUE
;
3862 if (uarmf
&& uarmf
->oartifact
== ART_SNAILHUNT
&& (mon
->data
->mlet
== S_BLOB
|| mon
->data
->mlet
== S_WORM
) ) return TRUE
;
3863 if (uarmf
&& uarmf
->oartifact
== ART_CAMELIC_SCENT
&& (mon
->data
->mlet
== S_ZOUTHERN
|| mon
->data
->mlet
== S_YETI
) ) return TRUE
;
3864 if (uwep
&& uwep
->oartifact
== ART_FUYER_BREV
&& mon
->data
->mlet
== S_FUNGUS
) return TRUE
;
3865 if (uwep
&& uwep
->oartifact
== ART_SNICKERSNACK
&& mon
->data
->mlet
== S_JABBERWOCK
) return TRUE
;
3866 if (uarm
&& uarm
->oartifact
== ART_FUNGIRADAR
&& mon
->data
->mlet
== S_FUNGUS
) return TRUE
;
3867 if (uarmf
&& uarmf
->oartifact
== ART_BOOTS_OF_THE_MACHINE
&& (mon
->data
->mlet
== S_GOLEM
|| nonliving(mon
->data
) ) ) return TRUE
;
3868 if (uarmf
&& uarmf
->oartifact
== ART_FD_DETH
&& (mon
->data
->mlet
== S_DOG
|| mon
->data
->mlet
== S_FELINE
) ) return TRUE
;
3869 if (uarmh
&& uarmh
->oartifact
== ART_DOGGO_FRIENDSHIP
&& mon
->data
->mlet
== S_DOG
) return TRUE
;
3870 if (uarmg
&& uarmg
->oartifact
== ART_WHAT_S_UP_BITCHES
&& (mon
->data
->mlet
== S_NYMPH
) ) return TRUE
;
3871 if (uwep
&& uwep
->oartifact
== ART_FISHING_GRANDPA
&& mon
->data
->mlet
== S_EEL
) return TRUE
;
3872 if (uarmf
&& uarmf
->oartifact
== ART_PECTORAL_HEEL
&& distu(mon
->mx
, mon
->my
) < 101 && mon
->data
->mlet
== S_EEL
) return TRUE
;
3873 if (uwep
&& uwep
->oartifact
== ART_PEOPLE_EATING_TRIDENT
&& mon
->data
->mlet
== S_HUMAN
) return TRUE
;
3874 if (uwep
&& uwep
->oartifact
== ART_VAMPIREBANE
&& mon
->data
->mlet
== S_VAMPIRE
) return TRUE
;
3875 if (uwep
&& uwep
->oartifact
== ART_GOLEMBANE
&& mon
->data
->mlet
== S_GOLEM
) return TRUE
;
3876 if (uwep
&& uwep
->oartifact
== ART_EELBANE
&& mon
->data
->mlet
== S_EEL
) return TRUE
;
3877 if (uwep
&& uwep
->oartifact
== ART_MAUI_S_FISHHOOK
&& mon
->data
->mlet
== S_EEL
) return TRUE
;
3878 if (uarmf
&& uarmf
->oartifact
== ART_SUCH_A_LOVELY_SHARK
&& mon
->data
->mlet
== S_EEL
&& mon
->mpeaceful
) return TRUE
;
3879 if (uwep
&& uwep
->oartifact
== ART_DEMONSTRANTS_GO_HOME
&& mon
->data
->mlet
== S_HUMAN
) return TRUE
;
3880 if (uarmu
&& uarmu
->oartifact
== ART_PEACE_ADVOCATE
&& mon
->data
->mlet
== S_HUMAN
) return TRUE
;
3881 if (uwep
&& uwep
->oartifact
== ART_DOCTOR_JONES__AID
&& mon
->data
->mlet
== S_SNAKE
) return TRUE
;
3882 if (uarmc
&& uarmc
->oartifact
== ART_KILO_MEGA_GIGA_TERA_PETA_E
&& (mon
->data
->mlet
== S_KOP
|| mon
->data
->msound
== MS_TREESQUAD
) ) return TRUE
;
3883 if (ublindf
&& ublindf
->oartifact
== ART_SEEING_THE_PERSON_ANYWAY
&& mon
->data
->maligntyp
< 0 && distu(mon
->mx
, mon
->my
) < 26) return TRUE
;
3884 if (uarmh
&& uarmh
->otyp
== GOOD_ESP_HELMET
&& mon
->data
->maligntyp
> 0 && distu(mon
->mx
, mon
->my
) < 26) return TRUE
;
3885 if (uwep
&& uwep
->oartifact
== ART_GOODBYE_TROLLS
&& mon
->data
->mlet
== S_TROLL
) return TRUE
;
3886 if (uwep
&& uwep
->oartifact
== ART_ANTINSTANT_DEATH
&& mon
->data
->mlet
== S_ANT
) return TRUE
;
3887 if (uwep
&& uwep
->oartifact
== ART_DRAGONLANCE
&& mon
->data
->mlet
== S_DRAGON
) return TRUE
;
3888 if (uwep
&& uwep
->oartifact
== ART_MINI_PEOPLE_EATER
&& humanoid(mon
->data
)) return TRUE
;
3889 if (uwep
&& uwep
->oartifact
== ART_INDIGENOUS_FUN
&& humanoid(mon
->data
)) return TRUE
;
3890 if (uwep
&& uwep
->oartifact
== ART_ANIMALBANE
&& is_animal(mon
->data
)) return TRUE
;
3891 if (uwep
&& uwep
->oartifact
== ART_SEE_ANIMALS
&& is_animal(mon
->data
)) return TRUE
;
3892 if (isselfhybrid
&& monpolyok(mon
->data
) && !polyok(mon
->data
) && ((mon
->data
->mlevel
< 30) || mon
->selfhybridvisible
) ) return TRUE
;
3894 return FALSE
; /* catchall */