|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.