Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / games / hack / hack.pri.c
CommitLineData
984263bc
MD
1/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2/* hack.pri.c - version 1.0.3 */
3/* $FreeBSD: src/games/hack/hack.pri.c,v 1.5 1999/11/16 10:26:37 marcel Exp $ */
1de703da 4/* $DragonFly: src/games/hack/hack.pri.c,v 1.2 2003/06/17 04:25:24 dillon Exp $ */
984263bc
MD
5
6#include "hack.h"
7#include <stdio.h>
8xchar scrlx, scrhx, scrly, scrhy; /* corners of new area on screen */
9
10extern char *hu_stat[]; /* in eat.c */
11extern char *CD;
12
13swallowed()
14{
15 char *ulook = "|@|";
16 ulook[1] = u.usym;
17
18 cls();
19 curs(u.ux-1, u.uy+1);
20 fputs("/-\\", stdout);
21 curx = u.ux+2;
22 curs(u.ux-1, u.uy+2);
23 fputs(ulook, stdout);
24 curx = u.ux+2;
25 curs(u.ux-1, u.uy+3);
26 fputs("\\-/", stdout);
27 curx = u.ux+2;
28 u.udispl = 1;
29 u.udisx = u.ux;
30 u.udisy = u.uy;
31}
32
33
34/*VARARGS1*/
35boolean panicking;
36
37panic(str,a1,a2,a3,a4,a5,a6)
38char *str;
39{
40 if(panicking++) exit(1); /* avoid loops - this should never happen*/
41 home();
42 puts(" Suddenly, the dungeon collapses.");
43 fputs(" ERROR: ", stdout);
44 printf(str,a1,a2,a3,a4,a5,a6);
45#ifdef DEBUG
46#ifdef UNIX
47 if(!fork())
48 abort(); /* generate core dump */
49#endif UNIX
50#endif DEBUG
51 more(); /* contains a fflush() */
52 done("panicked");
53}
54
55atl(x,y,ch)
56int x,y;
57{
58 struct rm *crm = &levl[x][y];
59
60 if(x<0 || x>COLNO-1 || y<0 || y>ROWNO-1){
61 impossible("atl(%d,%d,%c)",x,y,ch);
62 return;
63 }
64 if(crm->seen && crm->scrsym == ch) return;
65 crm->scrsym = ch;
66 crm->new = 1;
67 on_scr(x,y);
68}
69
70on_scr(x,y)
71int x,y;
72{
73 if(x < scrlx) scrlx = x;
74 if(x > scrhx) scrhx = x;
75 if(y < scrly) scrly = y;
76 if(y > scrhy) scrhy = y;
77}
78
79/* call: (x,y) - display
80 (-1,0) - close (leave last symbol)
81 (-1,-1)- close (undo last symbol)
82 (-1,let)-open: initialize symbol
83 (-2,let)-change let
84*/
85
86tmp_at(x,y) schar x,y; {
87static schar prevx, prevy;
88static char let;
89 if((int)x == -2){ /* change let call */
90 let = y;
91 return;
92 }
93 if((int)x == -1 && (int)y >= 0){ /* open or close call */
94 let = y;
95 prevx = -1;
96 return;
97 }
98 if(prevx >= 0 && cansee(prevx,prevy)) {
99 delay_output(50);
100 prl(prevx, prevy); /* in case there was a monster */
101 at(prevx, prevy, levl[prevx][prevy].scrsym);
102 }
103 if(x >= 0){ /* normal call */
104 if(cansee(x,y)) at(x,y,let);
105 prevx = x;
106 prevy = y;
107 } else { /* close call */
108 let = 0;
109 prevx = -1;
110 }
111}
112
113/* like the previous, but the symbols are first erased on completion */
114Tmp_at(x,y) schar x,y; {
115static char let;
116static xchar cnt;
117static coord tc[COLNO]; /* but watch reflecting beams! */
118int xx,yy;
119 if((int)x == -1) {
120 if(y > 0) { /* open call */
121 let = y;
122 cnt = 0;
123 return;
124 }
125 /* close call (do not distinguish y==0 and y==-1) */
126 while(cnt--) {
127 xx = tc[cnt].x;
128 yy = tc[cnt].y;
129 prl(xx, yy);
130 at(xx, yy, levl[xx][yy].scrsym);
131 }
132 cnt = let = 0; /* superfluous */
133 return;
134 }
135 if((int)x == -2) { /* change let call */
136 let = y;
137 return;
138 }
139 /* normal call */
140 if(cansee(x,y)) {
141 if(cnt) delay_output(50);
142 at(x,y,let);
143 tc[cnt].x = x;
144 tc[cnt].y = y;
145 if(++cnt >= COLNO) panic("Tmp_at overflow?");
146 levl[x][y].new = 0; /* prevent pline-nscr erasing --- */
147 }
148}
149
150setclipped(){
151 error("Hack needs a screen of size at least %d by %d.\n",
152 ROWNO+2, COLNO);
153}
154
155at(x,y,ch)
156xchar x,y;
157char ch;
158{
159#ifndef lint
160 /* if xchar is unsigned, lint will complain about if(x < 0) */
161 if(x < 0 || x > COLNO-1 || y < 0 || y > ROWNO-1) {
162 impossible("At gets 0%o at %d %d.", ch, x, y);
163 return;
164 }
165#endif lint
166 if(!ch) {
167 impossible("At gets null at %d %d.", x, y);
168 return;
169 }
170 y += 2;
171 curs(x,y);
172 (void) putchar(ch);
173 curx++;
174}
175
176prme(){
177 if(!Invisible) at(u.ux,u.uy,u.usym);
178}
179
180doredraw()
181{
182 docrt();
183 return(0);
184}
185
186docrt()
187{
188 int x,y;
189 struct rm *room;
190 struct monst *mtmp;
191
192 if(u.uswallow) {
193 swallowed();
194 return;
195 }
196 cls();
197
198/* Some ridiculous code to get display of @ and monsters (almost) right */
199 if(!Invisible) {
200 levl[(u.udisx = u.ux)][(u.udisy = u.uy)].scrsym = u.usym;
201 levl[u.udisx][u.udisy].seen = 1;
202 u.udispl = 1;
203 } else u.udispl = 0;
204
205 seemons(); /* reset old positions */
206 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
207 mtmp->mdispl = 0;
208 seemons(); /* force new positions to be shown */
209/* This nonsense should disappear soon --------------------------------- */
210
211 for(y = 0; y < ROWNO; y++)
212 for(x = 0; x < COLNO; x++)
213 if((room = &levl[x][y])->new) {
214 room->new = 0;
215 at(x,y,room->scrsym);
216 } else if(room->seen)
217 at(x,y,room->scrsym);
218 scrlx = COLNO;
219 scrly = ROWNO;
220 scrhx = scrhy = 0;
221 flags.botlx = 1;
222 bot();
223}
224
225docorner(xmin,ymax) int xmin,ymax; {
226 int x,y;
227 struct rm *room;
228 struct monst *mtmp;
229
230 if(u.uswallow) { /* Can be done more efficiently */
231 swallowed();
232 return;
233 }
234
235 seemons(); /* reset old positions */
236 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
237 if(mtmp->mx >= xmin && mtmp->my < ymax)
238 mtmp->mdispl = 0;
239 seemons(); /* force new positions to be shown */
240
241 for(y = 0; y < ymax; y++) {
242 if(y > ROWNO && CD) break;
243 curs(xmin,y+2);
244 cl_end();
245 if(y < ROWNO) {
246 for(x = xmin; x < COLNO; x++) {
247 if((room = &levl[x][y])->new) {
248 room->new = 0;
249 at(x,y,room->scrsym);
250 } else
251 if(room->seen)
252 at(x,y,room->scrsym);
253 }
254 }
255 }
256 if(ymax > ROWNO) {
257 cornbot(xmin-1);
258 if(ymax > ROWNO+1 && CD) {
259 curs(1,ROWNO+3);
260 cl_eos();
261 }
262 }
263}
264
265curs_on_u(){
266 curs(u.ux, u.uy+2);
267}
268
269pru()
270{
271 if(u.udispl && (Invisible || u.udisx != u.ux || u.udisy != u.uy))
272 /* if(! levl[u.udisx][u.udisy].new) */
273 if(!vism_at(u.udisx, u.udisy))
274 newsym(u.udisx, u.udisy);
275 if(Invisible) {
276 u.udispl = 0;
277 prl(u.ux,u.uy);
278 } else
279 if(!u.udispl || u.udisx != u.ux || u.udisy != u.uy) {
280 atl(u.ux, u.uy, u.usym);
281 u.udispl = 1;
282 u.udisx = u.ux;
283 u.udisy = u.uy;
284 }
285 levl[u.ux][u.uy].seen = 1;
286}
287
288#ifndef NOWORM
289#include "def.wseg.h"
290extern struct wseg *m_atseg;
291#endif NOWORM
292
293/* print a position that is visible for @ */
294prl(x,y)
295{
296 struct rm *room;
297 struct monst *mtmp;
298 struct obj *otmp;
299
300 if(x == u.ux && y == u.uy && (!Invisible)) {
301 pru();
302 return;
303 }
304 if(!isok(x,y)) return;
305 room = &levl[x][y];
306 if((!room->typ) ||
307 (IS_ROCK(room->typ) && levl[u.ux][u.uy].typ == CORR))
308 return;
309 if((mtmp = m_at(x,y)) && !mtmp->mhide &&
310 (!mtmp->minvis || See_invisible)) {
311#ifndef NOWORM
312 if(m_atseg)
313 pwseg(m_atseg);
314 else
315#endif NOWORM
316 pmon(mtmp);
317 }
318 else if((otmp = o_at(x,y)) && room->typ != POOL)
319 atl(x,y,otmp->olet);
320 else if(mtmp && (!mtmp->minvis || See_invisible)) {
321 /* must be a hiding monster, but not hiding right now */
322 /* assume for the moment that long worms do not hide */
323 pmon(mtmp);
324 }
325 else if(g_at(x,y) && room->typ != POOL)
326 atl(x,y,'$');
327 else if(!room->seen || room->scrsym == ' ') {
328 room->new = room->seen = 1;
329 newsym(x,y);
330 on_scr(x,y);
331 }
332 room->seen = 1;
333}
334
335char
336news0(x,y)
337xchar x,y;
338{
339 struct obj *otmp;
340 struct trap *ttmp;
341 struct rm *room;
342 char tmp;
343
344 room = &levl[x][y];
345 if(!room->seen) tmp = ' ';
346 else if(room->typ == POOL) tmp = POOL_SYM;
347 else if(!Blind && (otmp = o_at(x,y))) tmp = otmp->olet;
348 else if(!Blind && g_at(x,y)) tmp = '$';
349 else if(x == xupstair && y == yupstair) tmp = '<';
350 else if(x == xdnstair && y == ydnstair) tmp = '>';
351 else if((ttmp = t_at(x,y)) && ttmp->tseen) tmp = '^';
352 else switch(room->typ) {
353 case SCORR:
354 case SDOOR:
355 tmp = room->scrsym; /* %% wrong after killing mimic ! */
356 break;
357 case HWALL:
358 tmp = '-';
359 break;
360 case VWALL:
361 tmp = '|';
362 break;
363 case LDOOR:
364 case DOOR:
365 tmp = '+';
366 break;
367 case CORR:
368 tmp = CORR_SYM;
369 break;
370 case ROOM:
371 if(room->lit || cansee(x,y) || Blind) tmp = '.';
372 else tmp = ' ';
373 break;
374/*
375 case POOL:
376 tmp = POOL_SYM;
377 break;
378*/
379 default:
380 tmp = ERRCHAR;
381 }
382 return(tmp);
383}
384
385newsym(x,y)
386int x,y;
387{
388 atl(x,y,news0(x,y));
389}
390
391/* used with wand of digging (or pick-axe): fill scrsym and force display */
392/* also when a POOL evaporates */
393mnewsym(x,y)
394int x,y;
395{
396 struct rm *room;
397 char newscrsym;
398
399 if(!vism_at(x,y)) {
400 room = &levl[x][y];
401 newscrsym = news0(x,y);
402 if(room->scrsym != newscrsym) {
403 room->scrsym = newscrsym;
404 room->seen = 0;
405 }
406 }
407}
408
409nosee(x,y)
410int x,y;
411{
412 struct rm *room;
413
414 if(!isok(x,y)) return;
415 room = &levl[x][y];
416 if(room->scrsym == '.' && !room->lit && !Blind) {
417 room->scrsym = ' ';
418 room->new = 1;
419 on_scr(x,y);
420 }
421}
422
423#ifndef QUEST
424prl1(x,y)
425int x,y;
426{
427 if(u.dx) {
428 if(u.dy) {
429 prl(x-(2*u.dx),y);
430 prl(x-u.dx,y);
431 prl(x,y);
432 prl(x,y-u.dy);
433 prl(x,y-(2*u.dy));
434 } else {
435 prl(x,y-1);
436 prl(x,y);
437 prl(x,y+1);
438 }
439 } else {
440 prl(x-1,y);
441 prl(x,y);
442 prl(x+1,y);
443 }
444}
445
446nose1(x,y)
447int x,y;
448{
449 if(u.dx) {
450 if(u.dy) {
451 nosee(x,u.uy);
452 nosee(x,u.uy-u.dy);
453 nosee(x,y);
454 nosee(u.ux-u.dx,y);
455 nosee(u.ux,y);
456 } else {
457 nosee(x,y-1);
458 nosee(x,y);
459 nosee(x,y+1);
460 }
461 } else {
462 nosee(x-1,y);
463 nosee(x,y);
464 nosee(x+1,y);
465 }
466}
467#endif QUEST
468
469vism_at(x,y)
470int x,y;
471{
472 struct monst *mtmp;
473
474 return((x == u.ux && y == u.uy && !Invisible)
475 ? 1 :
476 (mtmp = m_at(x,y))
477 ? ((Blind && Telepat) || canseemon(mtmp)) :
478 0);
479}
480
481#ifdef NEWSCR
482pobj(obj) struct obj *obj; {
483int show = (!obj->oinvis || See_invisible) &&
484 cansee(obj->ox,obj->oy);
485 if(obj->odispl){
486 if(obj->odx != obj->ox || obj->ody != obj->oy || !show)
487 if(!vism_at(obj->odx,obj->ody)){
488 newsym(obj->odx, obj->ody);
489 obj->odispl = 0;
490 }
491 }
492 if(show && !vism_at(obj->ox,obj->oy)){
493 atl(obj->ox,obj->oy,obj->olet);
494 obj->odispl = 1;
495 obj->odx = obj->ox;
496 obj->ody = obj->oy;
497 }
498}
499#endif NEWSCR
500
501unpobj(obj) struct obj *obj; {
502/* if(obj->odispl){
503 if(!vism_at(obj->odx, obj->ody))
504 newsym(obj->odx, obj->ody);
505 obj->odispl = 0;
506 }
507*/
508 if(!vism_at(obj->ox,obj->oy))
509 newsym(obj->ox,obj->oy);
510}
511
512seeobjs(){
513struct obj *obj, *obj2;
514 for(obj = fobj; obj; obj = obj2) {
515 obj2 = obj->nobj;
516 if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
517 && obj->age + 250 < moves)
518 delobj(obj);
519 }
520 for(obj = invent; obj; obj = obj2) {
521 obj2 = obj->nobj;
522 if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
523 && obj->age + 250 < moves)
524 useup(obj);
525 }
526}
527
528seemons(){
529struct monst *mtmp;
530 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
531 if(mtmp->data->mlet == ';')
532 mtmp->minvis = (u.ustuck != mtmp &&
533 levl[mtmp->mx][mtmp->my].typ == POOL);
534 pmon(mtmp);
535#ifndef NOWORM
536 if(mtmp->wormno) wormsee(mtmp->wormno);
537#endif NOWORM
538 }
539}
540
541pmon(mon) struct monst *mon; {
542int show = (Blind && Telepat) || canseemon(mon);
543 if(mon->mdispl){
544 if(mon->mdx != mon->mx || mon->mdy != mon->my || !show)
545 unpmon(mon);
546 }
547 if(show && !mon->mdispl){
548 atl(mon->mx,mon->my,
549 (!mon->mappearance
550 || u.uprops[PROP(RIN_PROTECTION_FROM_SHAPE_CHANGERS)].p_flgs
551 ) ? mon->data->mlet : mon->mappearance);
552 mon->mdispl = 1;
553 mon->mdx = mon->mx;
554 mon->mdy = mon->my;
555 }
556}
557
558unpmon(mon) struct monst *mon; {
559 if(mon->mdispl){
560 newsym(mon->mdx, mon->mdy);
561 mon->mdispl = 0;
562 }
563}
564
565nscr()
566{
567 int x,y;
568 struct rm *room;
569
570 if(u.uswallow || u.ux == FAR || flags.nscrinh) return;
571 pru();
572 for(y = scrly; y <= scrhy; y++)
573 for(x = scrlx; x <= scrhx; x++)
574 if((room = &levl[x][y])->new) {
575 room->new = 0;
576 at(x,y,room->scrsym);
577 }
578 scrhx = scrhy = 0;
579 scrlx = COLNO;
580 scrly = ROWNO;
581}
582
583/* 100 suffices for bot(); no relation with COLNO */
584char oldbot[100], newbot[100];
585cornbot(lth)
586int lth;
587{
588 if(lth < sizeof(oldbot)) {
589 oldbot[lth] = 0;
590 flags.botl = 1;
591 }
592}
593
594bot()
595{
596char *ob = oldbot, *nb = newbot;
597int i;
598extern char *eos();
599 if(flags.botlx) *ob = 0;
600 flags.botl = flags.botlx = 0;
601#ifdef GOLD_ON_BOTL
602 (void) sprintf(newbot,
603 "Level %-2d Gold %-5lu Hp %3d(%d) Ac %-2d Str ",
604 dlevel, u.ugold, u.uhp, u.uhpmax, u.uac);
605#else
606 (void) sprintf(newbot,
607 "Level %-2d Hp %3d(%d) Ac %-2d Str ",
608 dlevel, u.uhp, u.uhpmax, u.uac);
609#endif GOLD_ON_BOTL
610 if(u.ustr>18) {
611 if(u.ustr>117)
612 (void) strcat(newbot,"18/**");
613 else
614 (void) sprintf(eos(newbot), "18/%02d",u.ustr-18);
615 } else
616 (void) sprintf(eos(newbot), "%-2d ",u.ustr);
617#ifdef EXP_ON_BOTL
618 (void) sprintf(eos(newbot), " Exp %2d/%-5lu ", u.ulevel,u.uexp);
619#else
620 (void) sprintf(eos(newbot), " Exp %2u ", u.ulevel);
621#endif EXP_ON_BOTL
622 (void) strcat(newbot, hu_stat[u.uhs]);
623 if(flags.time)
624 (void) sprintf(eos(newbot), " %ld", moves);
625 if(strlen(newbot) >= COLNO) {
626 char *bp0, *bp1;
627 bp0 = bp1 = newbot;
628 do {
629 if(*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ')
630 *bp1++ = *bp0;
631 } while(*bp0++);
632 }
633 for(i = 1; i<COLNO; i++) {
634 if(*ob != *nb){
635 curs(i,ROWNO+2);
636 (void) putchar(*nb ? *nb : ' ');
637 curx++;
638 }
639 if(*ob) ob++;
640 if(*nb) nb++;
641 }
642 (void) strcpy(oldbot, newbot);
643}
644
645#ifdef WAN_PROBING
646mstatusline(mtmp) struct monst *mtmp; {
647 pline("Status of %s: ", monnam(mtmp));
648 pline("Level %-2d Gold %-5lu Hp %3d(%d) Ac %-2d Dam %d",
649 mtmp->data->mlevel, mtmp->mgold, mtmp->mhp, mtmp->mhpmax,
650 mtmp->data->ac, (mtmp->data->damn + 1) * (mtmp->data->damd + 1));
651}
652#endif WAN_PROBING
653
654cls(){
655 if(flags.toplin == 1)
656 more();
657 flags.toplin = 0;
658
659 clear_screen();
660
661 flags.botlx = 1;
662}