2 * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
6 static char rcsid
[] = "$NetBSD: hack.pri.c,v 1.4 1995/03/23 08:31:20 cgd Exp $";
11 xchar scrlx
, scrhx
, scrly
, scrhy
; /* corners of new area on screen */
13 extern char *hu_stat
[]; /* in eat.c */
23 fputs("/-\\", stdout
);
29 fputs("\\-/", stdout
);
40 panic(str
,a1
,a2
,a3
,a4
,a5
,a6
)
43 if(panicking
++) exit(1); /* avoid loops - this should never happen*/
45 puts(" Suddenly, the dungeon collapses.");
46 fputs(" ERROR: ", stdout
);
47 printf(str
,a1
,a2
,a3
,a4
,a5
,a6
);
51 abort(); /* generate core dump */
54 more(); /* contains a fflush() */
61 register struct rm
*crm
= &levl
[x
][y
];
63 if(x
<0 || x
>COLNO
-1 || y
<0 || y
>ROWNO
-1){
64 impossible("atl(%d,%d,%c)",x
,y
,ch
);
67 if(crm
->seen
&& crm
->scrsym
== ch
) return;
76 if(x
< scrlx
) scrlx
= x
;
77 if(x
> scrhx
) scrhx
= x
;
78 if(y
< scrly
) scrly
= y
;
79 if(y
> scrhy
) scrhy
= y
;
82 /* call: (x,y) - display
83 (-1,0) - close (leave last symbol)
84 (-1,-1)- close (undo last symbol)
85 (-1,let)-open: initialize symbol
89 tmp_at(x
,y
) schar x
,y
; {
90 static schar prevx
, prevy
;
92 if((int)x
== -2){ /* change let call */
96 if((int)x
== -1 && (int)y
>= 0){ /* open or close call */
101 if(prevx
>= 0 && cansee(prevx
,prevy
)) {
103 prl(prevx
, prevy
); /* in case there was a monster */
104 at(prevx
, prevy
, levl
[prevx
][prevy
].scrsym
);
106 if(x
>= 0){ /* normal call */
107 if(cansee(x
,y
)) at(x
,y
,let
);
110 } else { /* close call */
116 /* like the previous, but the symbols are first erased on completion */
117 Tmp_at(x
,y
) schar x
,y
; {
120 static coord tc
[COLNO
]; /* but watch reflecting beams! */
123 if(y
> 0) { /* open call */
128 /* close call (do not distinguish y==0 and y==-1) */
133 at(xx
, yy
, levl
[xx
][yy
].scrsym
);
135 cnt
= let
= 0; /* superfluous */
138 if((int)x
== -2) { /* change let call */
144 if(cnt
) delay_output();
148 if(++cnt
>= COLNO
) panic("Tmp_at overflow?");
149 levl
[x
][y
].new = 0; /* prevent pline-nscr erasing --- */
154 error("Hack needs a screen of size at least %d by %d.\n",
163 /* if xchar is unsigned, lint will complain about if(x < 0) */
164 if(x
< 0 || x
> COLNO
-1 || y
< 0 || y
> ROWNO
-1) {
165 impossible("At gets 0%o at %d %d.", ch
, x
, y
);
170 impossible("At gets null at %d %d.", x
, y
);
180 if(!Invisible
) at(u
.ux
,u
.uy
,u
.usym
);
192 register struct rm
*room
;
193 register struct monst
*mtmp
;
201 /* Some ridiculous code to get display of @ and monsters (almost) right */
203 levl
[(u
.udisx
= u
.ux
)][(u
.udisy
= u
.uy
)].scrsym
= u
.usym
;
204 levl
[u
.udisx
][u
.udisy
].seen
= 1;
208 seemons(); /* reset old positions */
209 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
211 seemons(); /* force new positions to be shown */
212 /* This nonsense should disappear soon --------------------------------- */
214 for(y
= 0; y
< ROWNO
; y
++)
215 for(x
= 0; x
< COLNO
; x
++)
216 if((room
= &levl
[x
][y
])->new) {
218 at(x
,y
,room
->scrsym
);
219 } else if(room
->seen
)
220 at(x
,y
,room
->scrsym
);
228 docorner(xmin
,ymax
) register xmin
,ymax
; {
230 register struct rm
*room
;
231 register struct monst
*mtmp
;
233 if(u
.uswallow
) { /* Can be done more efficiently */
238 seemons(); /* reset old positions */
239 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
240 if(mtmp
->mx
>= xmin
&& mtmp
->my
< ymax
)
242 seemons(); /* force new positions to be shown */
244 for(y
= 0; y
< ymax
; y
++) {
245 if(y
> ROWNO
&& CD
) break;
249 for(x
= xmin
; x
< COLNO
; x
++) {
250 if((room
= &levl
[x
][y
])->new) {
252 at(x
,y
,room
->scrsym
);
255 at(x
,y
,room
->scrsym
);
261 if(ymax
> ROWNO
+1 && CD
) {
274 if(u
.udispl
&& (Invisible
|| u
.udisx
!= u
.ux
|| u
.udisy
!= u
.uy
))
275 /* if(! levl[u.udisx][u.udisy].new) */
276 if(!vism_at(u
.udisx
, u
.udisy
))
277 newsym(u
.udisx
, u
.udisy
);
282 if(!u
.udispl
|| u
.udisx
!= u
.ux
|| u
.udisy
!= u
.uy
) {
283 atl(u
.ux
, u
.uy
, u
.usym
);
288 levl
[u
.ux
][u
.uy
].seen
= 1;
292 #include "def.wseg.h"
293 extern struct wseg
*m_atseg
;
296 /* print a position that is visible for @ */
299 register struct rm
*room
;
300 register struct monst
*mtmp
;
301 register struct obj
*otmp
;
303 if(x
== u
.ux
&& y
== u
.uy
&& (!Invisible
)) {
307 if(!isok(x
,y
)) return;
310 (IS_ROCK(room
->typ
) && levl
[u
.ux
][u
.uy
].typ
== CORR
))
312 if((mtmp
= m_at(x
,y
)) && !mtmp
->mhide
&&
313 (!mtmp
->minvis
|| See_invisible
)) {
321 else if((otmp
= o_at(x
,y
)) && room
->typ
!= POOL
)
323 else if(mtmp
&& (!mtmp
->minvis
|| See_invisible
)) {
324 /* must be a hiding monster, but not hiding right now */
325 /* assume for the moment that long worms do not hide */
328 else if(g_at(x
,y
) && room
->typ
!= POOL
)
330 else if(!room
->seen
|| room
->scrsym
== ' ') {
331 room
->new = room
->seen
= 1;
342 register struct obj
*otmp
;
343 register struct trap
*ttmp
;
348 if(!room
->seen
) tmp
= ' ';
349 else if(room
->typ
== POOL
) tmp
= POOL_SYM
;
350 else if(!Blind
&& (otmp
= o_at(x
,y
))) tmp
= otmp
->olet
;
351 else if(!Blind
&& g_at(x
,y
)) tmp
= '$';
352 else if(x
== xupstair
&& y
== yupstair
) tmp
= '<';
353 else if(x
== xdnstair
&& y
== ydnstair
) tmp
= '>';
354 else if((ttmp
= t_at(x
,y
)) && ttmp
->tseen
) tmp
= '^';
355 else switch(room
->typ
) {
358 tmp
= room
->scrsym
; /* %% wrong after killing mimic ! */
374 if(room
->lit
|| cansee(x
,y
) || Blind
) tmp
= '.';
394 /* used with wand of digging (or pick-axe): fill scrsym and force display */
395 /* also when a POOL evaporates */
399 register struct rm
*room
;
404 newscrsym
= news0(x
,y
);
405 if(room
->scrsym
!= newscrsym
) {
406 room
->scrsym
= newscrsym
;
415 register struct rm
*room
;
417 if(!isok(x
,y
)) return;
419 if(room
->scrsym
== '.' && !room
->lit
&& !Blind
) {
475 register struct monst
*mtmp
;
477 return((x
== u
.ux
&& y
== u
.uy
&& !Invisible
)
480 ? ((Blind
&& Telepat
) || canseemon(mtmp
)) :
485 pobj(obj
) register struct obj
*obj
; {
486 register int show
= (!obj
->oinvis
|| See_invisible
) &&
487 cansee(obj
->ox
,obj
->oy
);
489 if(obj
->odx
!= obj
->ox
|| obj
->ody
!= obj
->oy
|| !show
)
490 if(!vism_at(obj
->odx
,obj
->ody
)){
491 newsym(obj
->odx
, obj
->ody
);
495 if(show
&& !vism_at(obj
->ox
,obj
->oy
)){
496 atl(obj
->ox
,obj
->oy
,obj
->olet
);
504 unpobj(obj
) register struct obj
*obj
; {
506 if(!vism_at(obj->odx, obj->ody))
507 newsym(obj->odx, obj->ody);
511 if(!vism_at(obj
->ox
,obj
->oy
))
512 newsym(obj
->ox
,obj
->oy
);
516 register struct obj
*obj
, *obj2
;
517 for(obj
= fobj
; obj
; obj
= obj2
) {
519 if(obj
->olet
== FOOD_SYM
&& obj
->otyp
>= CORPSE
520 && obj
->age
+ 250 < moves
)
523 for(obj
= invent
; obj
; obj
= obj2
) {
525 if(obj
->olet
== FOOD_SYM
&& obj
->otyp
>= CORPSE
526 && obj
->age
+ 250 < moves
)
532 register struct monst
*mtmp
;
533 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
){
534 if(mtmp
->data
->mlet
== ';')
535 mtmp
->minvis
= (u
.ustuck
!= mtmp
&&
536 levl
[mtmp
->mx
][mtmp
->my
].typ
== POOL
);
539 if(mtmp
->wormno
) wormsee(mtmp
->wormno
);
544 pmon(mon
) register struct monst
*mon
; {
545 register int show
= (Blind
&& Telepat
) || canseemon(mon
);
547 if(mon
->mdx
!= mon
->mx
|| mon
->mdy
!= mon
->my
|| !show
)
550 if(show
&& !mon
->mdispl
){
553 || u
.uprops
[PROP(RIN_PROTECTION_FROM_SHAPE_CHANGERS
)].p_flgs
554 ) ? mon
->data
->mlet
: mon
->mappearance
);
561 unpmon(mon
) register struct monst
*mon
; {
563 newsym(mon
->mdx
, mon
->mdy
);
571 register struct rm
*room
;
573 if(u
.uswallow
|| u
.ux
== FAR
|| flags
.nscrinh
) return;
575 for(y
= scrly
; y
<= scrhy
; y
++)
576 for(x
= scrlx
; x
<= scrhx
; x
++)
577 if((room
= &levl
[x
][y
])->new) {
579 at(x
,y
,room
->scrsym
);
586 /* 100 suffices for bot(); no relation with COLNO */
587 char oldbot
[100], newbot
[100];
591 if(lth
< sizeof(oldbot
)) {
599 register char *ob
= oldbot
, *nb
= newbot
;
602 if(flags
.botlx
) *ob
= 0;
603 flags
.botl
= flags
.botlx
= 0;
605 (void) sprintf(newbot
,
606 "Level %-2d Gold %-5lu Hp %3d(%d) Ac %-2d Str ",
607 dlevel
, u
.ugold
, u
.uhp
, u
.uhpmax
, u
.uac
);
609 (void) sprintf(newbot
,
610 "Level %-2d Hp %3d(%d) Ac %-2d Str ",
611 dlevel
, u
.uhp
, u
.uhpmax
, u
.uac
);
615 (void) strcat(newbot
,"18/**");
617 (void) sprintf(eos(newbot
), "18/%02d",u
.ustr
-18);
619 (void) sprintf(eos(newbot
), "%-2d ",u
.ustr
);
621 (void) sprintf(eos(newbot
), " Exp %2d/%-5lu ", u
.ulevel
,u
.uexp
);
623 (void) sprintf(eos(newbot
), " Exp %2u ", u
.ulevel
);
625 (void) strcat(newbot
, hu_stat
[u
.uhs
]);
627 (void) sprintf(eos(newbot
), " %ld", moves
);
628 if(strlen(newbot
) >= COLNO
) {
629 register char *bp0
, *bp1
;
632 if(*bp0
!= ' ' || bp0
[1] != ' ' || bp0
[2] != ' ')
636 for(i
= 1; i
<COLNO
; i
++) {
639 (void) putchar(*nb
? *nb
: ' ');
645 (void) strcpy(oldbot
, newbot
);
649 mstatusline(mtmp
) register struct monst
*mtmp
; {
650 pline("Status of %s: ", monnam(mtmp
));
651 pline("Level %-2d Gold %-5lu Hp %3d(%d) Ac %-2d Dam %d",
652 mtmp
->data
->mlevel
, mtmp
->mgold
, mtmp
->mhp
, mtmp
->mhpmax
,
653 mtmp
->data
->ac
, (mtmp
->data
->damn
+ 1) * (mtmp
->data
->damd
+ 1));
658 if(flags
.toplin
== 1)