1 /* $NetBSD: hack.pri.c,v 1.11 2009/06/07 20:13:18 dholland Exp $ */
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * - Neither the name of the Stichting Centrum voor Wiskunde en
20 * Informatica, nor the names of its contributors may be used to endorse or
21 * promote products derived from this software without specific prior
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 #include <sys/cdefs.h>
66 __RCSID("$NetBSD: hack.pri.c,v 1.11 2009/06/07 20:13:18 dholland Exp $");
72 static xchar scrlx
, scrhx
, scrly
, scrhy
; /* corners of new area on
75 static void cornbot(int);
84 curs(u
.ux
- 1, u
.uy
+ 1);
85 fputs("/-\\", stdout
);
87 curs(u
.ux
- 1, u
.uy
+ 2);
90 curs(u
.ux
- 1, u
.uy
+ 3);
91 fputs("\\-/", stdout
);
100 static boolean panicking
;
103 panic(const char *fmt
, ...)
109 exit(1); /* avoid loops - this should never happen */
111 puts(" Suddenly, the dungeon collapses.");
112 fputs(" ERROR: ", stdout
);
118 abort(); /* generate core dump */
121 more(); /* contains a fflush() */
126 atl(int x
, int y
, int ch
)
128 struct rm
*crm
= &levl
[x
][y
];
130 if (x
< 0 || x
> COLNO
- 1 || y
< 0 || y
> ROWNO
- 1) {
131 impossible("atl(%d,%d,%c)", x
, y
, ch
);
134 if (crm
->seen
&& crm
->scrsym
== ch
)
155 * call: (x,y) - display (-1,0) - close (leave last symbol) (-1,-1)- close
156 * (undo last symbol) (-1,let)-open: initialize symbol (-2,let)-change let
160 tmp_at(schar x
, schar y
)
162 static schar prevx
, prevy
;
164 if ((int) x
== -2) { /* change let call */
168 if ((int) x
== -1 && (int) y
>= 0) { /* open or close call */
173 if (prevx
>= 0 && cansee(prevx
, prevy
)) {
175 prl(prevx
, prevy
); /* in case there was a monster */
176 at(prevx
, prevy
, levl
[prevx
][prevy
].scrsym
);
178 if (x
>= 0) { /* normal call */
183 } else { /* close call */
189 /* like the previous, but the symbols are first erased on completion */
191 Tmp_at(schar x
, schar y
)
195 static coord tc
[COLNO
]; /* but watch reflecting beams! */
198 if (y
> 0) { /* open call */
203 /* close call (do not distinguish y==0 and y==-1) */
208 at(xx
, yy
, levl
[xx
][yy
].scrsym
);
210 cnt
= let
= 0; /* superfluous */
213 if ((int) x
== -2) { /* change let call */
225 panic("Tmp_at overflow?");
226 levl
[x
][y
].new = 0; /* prevent pline-nscr erasing --- */
233 error("Hack needs a screen of size at least %d by %d.\n",
238 at(xchar x
, xchar y
, int ch
)
241 /* if xchar is unsigned, lint will complain about if(x < 0) */
242 if (x
< 0 || x
> COLNO
- 1 || y
< 0 || y
> ROWNO
- 1) {
243 impossible("At gets 0%o at %d %d.", ch
, x
, y
);
248 impossible("At gets null at %d %d.", x
, y
);
261 at(u
.ux
, u
.uy
, u
.usym
);
285 * Some ridiculous code to get display of @ and monsters (almost)
289 levl
[(u
.udisx
= u
.ux
)][(u
.udisy
= u
.uy
)].scrsym
= u
.usym
;
290 levl
[u
.udisx
][u
.udisy
].seen
= 1;
295 seemons(); /* reset old positions */
296 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
298 seemons(); /* force new positions to be shown */
300 * This nonsense should disappear soon
301 * ---------------------------------
304 for (y
= 0; y
< ROWNO
; y
++)
305 for (x
= 0; x
< COLNO
; x
++)
306 if ((room
= &levl
[x
][y
])->new) {
308 at(x
, y
, room
->scrsym
);
309 } else if (room
->seen
)
310 at(x
, y
, room
->scrsym
);
319 docorner(int xmin
, int ymax
)
325 if (u
.uswallow
) { /* Can be done more efficiently */
329 seemons(); /* reset old positions */
330 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
331 if (mtmp
->mx
>= xmin
&& mtmp
->my
< ymax
)
333 seemons(); /* force new positions to be shown */
335 for (y
= 0; y
< ymax
; y
++) {
341 for (x
= xmin
; x
< COLNO
; x
++) {
342 if ((room
= &levl
[x
][y
])->new) {
344 at(x
, y
, room
->scrsym
);
345 } else if (room
->seen
)
346 at(x
, y
, room
->scrsym
);
352 if (ymax
> ROWNO
+ 1 && CD
) {
362 curs(u
.ux
, u
.uy
+ 2);
368 if (u
.udispl
&& (Invisible
|| u
.udisx
!= u
.ux
|| u
.udisy
!= u
.uy
))
369 /* if(! levl[u.udisx][u.udisy].new) */
370 if (!vism_at(u
.udisx
, u
.udisy
))
371 newsym(u
.udisx
, u
.udisy
);
375 } else if (!u
.udispl
|| u
.udisx
!= u
.ux
|| u
.udisy
!= u
.uy
) {
376 atl(u
.ux
, u
.uy
, u
.usym
);
381 levl
[u
.ux
][u
.uy
].seen
= 1;
385 #include "def.wseg.h"
388 /* print a position that is visible for @ */
396 if (x
== u
.ux
&& y
== u
.uy
&& (!Invisible
)) {
404 (IS_ROCK(room
->typ
) && levl
[u
.ux
][u
.uy
].typ
== CORR
))
406 if ((mtmp
= m_at(x
, y
)) && !mtmp
->mhide
&&
407 (!mtmp
->minvis
|| See_invisible
)) {
414 } else if ((otmp
= o_at(x
, y
)) && room
->typ
!= POOL
)
415 atl(x
, y
, otmp
->olet
);
416 else if (mtmp
&& (!mtmp
->minvis
|| See_invisible
)) {
417 /* must be a hiding monster, but not hiding right now */
418 /* assume for the moment that long worms do not hide */
420 } else if (g_at(x
, y
) && room
->typ
!= POOL
)
422 else if (!room
->seen
|| room
->scrsym
== ' ') {
423 room
->new = room
->seen
= 1;
431 news0(xchar x
, xchar y
)
441 else if (room
->typ
== POOL
)
443 else if (!Blind
&& (otmp
= o_at(x
, y
)))
445 else if (!Blind
&& g_at(x
, y
))
447 else if (x
== xupstair
&& y
== yupstair
)
449 else if (x
== xdnstair
&& y
== ydnstair
)
451 else if ((ttmp
= t_at(x
, y
)) && ttmp
->tseen
)
457 tmp
= room
->scrsym
; /* %% wrong after killing
474 if (room
->lit
|| cansee(x
, y
) || Blind
)
493 atl(x
, y
, news0(x
, y
));
496 /* used with wand of digging (or pick-axe): fill scrsym and force display */
497 /* also when a POOL evaporates */
499 mnewsym(int x
, int y
)
504 if (!vism_at(x
, y
)) {
506 newscrsym
= news0(x
, y
);
507 if (room
->scrsym
!= newscrsym
) {
508 room
->scrsym
= newscrsym
;
522 if (room
->scrsym
== '.' && !room
->lit
&& !Blind
) {
535 prl(x
- (2 * u
.dx
), y
);
539 prl(x
, y
- (2 * u
.dy
));
558 nosee(x
, u
.uy
- u
.dy
);
560 nosee(u
.ux
- u
.dx
, y
);
576 vism_at(int x
, int y
)
580 return ((x
== u
.ux
&& y
== u
.uy
&& !Invisible
)
583 ? ((Blind
&& Telepat
) || canseemon(mtmp
)) :
589 pobj(struct obj
*obj
)
591 int show
= (!obj
->oinvis
|| See_invisible
) &&
592 cansee(obj
->ox
, obj
->oy
);
594 if (obj
->odx
!= obj
->ox
|| obj
->ody
!= obj
->oy
|| !show
)
595 if (!vism_at(obj
->odx
, obj
->ody
)) {
596 newsym(obj
->odx
, obj
->ody
);
600 if (show
&& !vism_at(obj
->ox
, obj
->oy
)) {
601 atl(obj
->ox
, obj
->oy
, obj
->olet
);
610 unpobj(struct obj
*obj
)
613 * if(obj->odispl){ if(!vism_at(obj->odx, obj->ody)) newsym(obj->odx,
614 * obj->ody); obj->odispl = 0; }
616 if (!vism_at(obj
->ox
, obj
->oy
))
617 newsym(obj
->ox
, obj
->oy
);
623 struct obj
*obj
, *obj2
;
624 for (obj
= fobj
; obj
; obj
= obj2
) {
626 if (obj
->olet
== FOOD_SYM
&& obj
->otyp
>= CORPSE
627 && obj
->age
+ 250 < moves
)
630 for (obj
= invent
; obj
; obj
= obj2
) {
632 if (obj
->olet
== FOOD_SYM
&& obj
->otyp
>= CORPSE
633 && obj
->age
+ 250 < moves
)
642 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
643 if (mtmp
->data
->mlet
== ';')
644 mtmp
->minvis
= (u
.ustuck
!= mtmp
&&
645 levl
[mtmp
->mx
][mtmp
->my
].typ
== POOL
);
649 wormsee(mtmp
->wormno
);
655 pmon(struct monst
*mon
)
657 int show
= (Blind
&& Telepat
) || canseemon(mon
);
659 if (mon
->mdx
!= mon
->mx
|| mon
->mdy
!= mon
->my
|| !show
)
662 if (show
&& !mon
->mdispl
) {
663 atl(mon
->mx
, mon
->my
,
665 || u
.uprops
[PROP(RIN_PROTECTION_FROM_SHAPE_CHANGERS
)].p_flgs
666 ) ? mon
->data
->mlet
: mon
->mappearance
);
674 unpmon(struct monst
*mon
)
677 newsym(mon
->mdx
, mon
->mdy
);
688 if (u
.uswallow
|| u
.ux
== FAR
|| flags
.nscrinh
)
691 for (y
= scrly
; y
<= scrhy
; y
++)
692 for (x
= scrlx
; x
<= scrhx
; x
++)
693 if ((room
= &levl
[x
][y
])->new) {
695 at(x
, y
, room
->scrsym
);
702 /* 100 suffices for bot(); no relation with COLNO */
703 static char oldbot
[100], newbot
[100];
707 if ((unsigned)lth
< sizeof(oldbot
)) {
716 char *ob
= oldbot
, *nb
= newbot
;
722 flags
.botl
= flags
.botlx
= 0;
724 (void) snprintf(newbot
, sizeof(newbot
),
725 "Level %-2d Gold %-5lu Hp %3d(%d) Ac %-2d Str ",
726 dlevel
, u
.ugold
, u
.uhp
, u
.uhpmax
, u
.uac
);
728 (void) snprintf(newbot
, sizeof(newbot
),
729 "Level %-2d Hp %3d(%d) Ac %-2d Str ",
730 dlevel
, u
.uhp
, u
.uhpmax
, u
.uac
);
731 #endif /* GOLD_ON_BOTL */
734 (void) strlcat(newbot
, "18/**", sizeof(newbot
));
736 pos
= strlen(newbot
);
737 (void) snprintf(newbot
+pos
, sizeof(newbot
)-pos
,
738 "18/%02d", u
.ustr
- 18);
741 pos
= strlen(newbot
);
742 (void) snprintf(newbot
+pos
, sizeof(newbot
)-pos
,
745 pos
= strlen(newbot
);
747 (void) snprintf(newbot
+pos
, sizeof(newbot
)-pos
,
748 " Exp %2d/%-5lu ", u
.ulevel
, u
.uexp
);
750 (void) snprintf(newbot
+pos
, sizeof(newbot
)-pos
,
751 " Exp %2u ", u
.ulevel
);
752 #endif /* EXP_ON_BOTL */
753 (void) strlcat(newbot
, hu_stat
[u
.uhs
], sizeof(newbot
));
755 pos
= strlen(newbot
);
756 (void) snprintf(newbot
+pos
, sizeof(newbot
)-pos
,
759 if (strlen(newbot
) >= COLNO
) {
763 if (*bp0
!= ' ' || bp0
[1] != ' ' || bp0
[2] != ' ')
767 for (i
= 1; i
< COLNO
; i
++) {
770 (void) putchar(*nb
? *nb
: ' ');
778 (void) strcpy(oldbot
, newbot
);
783 mstatusline(struct monst
*mtmp
)
785 pline("Status of %s: ", monnam(mtmp
));
786 pline("Level %-2d Gold %-5lu Hp %3d(%d) Ac %-2d Dam %d",
787 mtmp
->data
->mlevel
, mtmp
->mgold
, mtmp
->mhp
, mtmp
->mhpmax
,
788 mtmp
->data
->ac
, (mtmp
->data
->damn
+ 1) * (mtmp
->data
->damd
+ 1));
790 #endif /* WAN_PROBING */
795 if (flags
.toplin
== 1)