Source:Hack 1.0/hack.pri.c

From NetHackWiki
Jump to: navigation, search

Below is the full text to hack.pri.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.pri.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

Screenshots and source code from Hack are used under the CWI license.

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