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