Source:NetHack 1.3d/pri.c

From NetHackWiki
Jump to: navigation, search

Below is the full text to pri.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/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.    /*	SCCS Id: @(#)pri.c	1.3	87/07/14
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* pri.c - version 1.0.3 */
4.    
5.    #include <stdio.h>
6.    #include "hack.h"
7.    
8.    #define DEBUG
9.    xchar scrlx, scrhx, scrly, scrhy;	/* corners of new area on screen */
10.   
11.   extern char *hu_stat[];	/* in eat.c */
12.   extern char *CD;
13.   
14.   swallowed()
15.   {
16.   	char *ulook = "|@|";
17.   	ulook[1] = u.usym;
18.   
19.   	cls();
20.   	curs(u.ux-1, u.uy+1);
21.   	fputs("/-\\", stdout);
22.   	curx = u.ux+2;
23.   	curs(u.ux-1, u.uy+2);
24.   	fputs(ulook, stdout);
25.   	curx = u.ux+2;
26.   	curs(u.ux-1, u.uy+3);
27.   	fputs("\\-/", stdout);
28.   	curx = u.ux+2;
29.   	u.udispl = 1;
30.   	u.udisx = u.ux;
31.   	u.udisy = u.uy;
32.   }
33.   
34.   setclipped(){
35.   	error("Hack needs a screen of size at least %d by %d.\n",
36.   		ROWNO+2, COLNO);
37.   }
38.   
39.   #ifdef DGK
40.   static int multipleAts;		/* TRUE if we have many at()'s to do */
41.   static int DECgraphics;		/* The graphics mode toggle */
42.   
43.   #define DECgraphicsON() ((void) putchar('\16'), DECgraphics = TRUE)
44.   #define DECgraphicsOFF() ((void) putchar('\17'), DECgraphics = FALSE)
45.   #endif
46.   
47.   at(x,y,ch)
48.   register xchar x,y;
49.   char ch;
50.   {
51.   #ifndef lint
52.   	/* if xchar is unsigned, lint will complain about  if(x < 0)  */
53.   	if(x < 0 || x > COLNO-1 || y < 0 || y > ROWNO-1) {
54.   		impossible("At gets 0%o at %d %d.", ch, x, y);
55.   		return;
56.   	}
57.   #endif
58.   	if(!ch) {
59.   		impossible("At gets null at %d %d.", x, y);
60.   		return;
61.   	}
62.   	y += 2;
63.   	curs(x,y);
64.   #ifdef DGK
65.   	if (flags.DECRainbow) {
66.   		/* If there are going to be many at()s in a row without
67.   		 * intervention, only change the graphics mode when the
68.   		 * character changes between graphic and regular.
69.   		 */
70.   		if (multipleAts) {
71.   			if (ch & 0x80) {
72.   				if (!DECgraphics)
73.   					DECgraphicsON();
74.   				(void) putchar(ch ^ 0x80); /* Strip 8th bit */
75.   			} else {
76.   				if (DECgraphics)
77.   					DECgraphicsOFF();
78.   				(void) putchar(ch);
79.   			}
80.   		/* Otherwise, we don't know how many at()s will be happening
81.   		 * before printing of normal strings, so change to graphics
82.   		 * mode when necessary, then change right back.
83.   		 */
84.   		} else {
85.   			if (ch & 0x80) {
86.   				DECgraphicsON();
87.   				(void) putchar(ch ^ 0x80); /* Strip 8th bit */
88.   				DECgraphicsOFF();
89.   			} else
90.   				(void) putchar(ch);
91.   		}
92.   	} else
93.   #endif
94.   		(void) putchar(ch);
95.   	curx++;
96.   }
97.   
98.   prme(){
99.   	if(!Invisible) at(u.ux,u.uy,u.usym);
100.  }
101.  
102.  doredraw()
103.  {
104.  	docrt();
105.  	return(0);
106.  }
107.  
108.  docrt()
109.  {
110.  	register x,y;
111.  	register struct rm *room;
112.  	register struct monst *mtmp;
113.  
114.  	if(u.uswallow) {
115.  		swallowed();
116.  		return;
117.  	}
118.  	cls();
119.  
120.  /* Some ridiculous code to get display of @ and monsters (almost) right */
121.  	if(!Invisible) {
122.  		levl[(u.udisx = u.ux)][(u.udisy = u.uy)].scrsym = u.usym;
123.  		levl[u.udisx][u.udisy].seen = 1;
124.  		u.udispl = 1;
125.  	} else	u.udispl = 0;
126.  
127.  	seemons();	/* reset old positions */
128.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
129.  		mtmp->mdispl = 0;
130.  	seemons();	/* force new positions to be shown */
131.  /* This nonsense should disappear soon --------------------------------- */
132.  
133.  #ifdef DGK
134.  	/* For DEC Rainbows, we must translate each character to strip
135.  	 * out the 8th bit if necessary.
136.  	 */
137.  	if (flags.DECRainbow) {
138.  		multipleAts = TRUE;
139.  		for(y = 0; y < ROWNO; y++)
140.  			for(x = 0; x < COLNO; x++)
141.  				if((room = &levl[x][y])->new) {
142.  					room->new = 0;
143.  					at(x,y,room->scrsym);
144.  				} else if(room->seen)
145.  					at(x,y,room->scrsym);
146.  		multipleAts = FALSE;
147.  		if (DECgraphics)
148.  			DECgraphicsOFF();
149.  	} else {
150.  	/* Otherwise, line buffer the output to do the redraw in
151.  	 * about 2/3 of the time.
152.  	 */
153.  		for(y = 0; y < ROWNO; y++) {
154.  			char buf[COLNO+1];
155.  			int start, end;
156.  
157.  			memset(buf, ' ', COLNO);
158.  			for(x = 0, start = -1, end = -1; x < COLNO; x++)
159.  				if((room = &levl[x][y])->new) {
160.  					room->new = 0;
161.  					buf[x] = room->scrsym;
162.  					if (start < 0)
163.  						start = x;
164.  					end = x;
165.  				} else if(room->seen) {
166.  					buf[x] = room->scrsym;
167.  					if (start < 0)
168.  						start = x;
169.  					end = x;
170.  				}
171.  			if (end >= 0) {
172.  				buf[end + 1] = '\0';
173.  				curs(start, y + 2);
174.  				fputs(buf + start, stdout);
175.  				curx = end + 1;
176.  			}
177.  		}
178.  	}
179.  #else
180.  	for(y = 0; y < ROWNO; y++)
181.  		for(x = 0; x < COLNO; x++)
182.  			if((room = &levl[x][y])->new) {
183.  				room->new = 0;
184.  				at(x,y,room->scrsym);
185.  			} else if(room->seen)
186.  				at(x,y,room->scrsym);
187.  #endif
188.  	scrlx = COLNO;
189.  	scrly = ROWNO;
190.  	scrhx = scrhy = 0;
191.  	flags.botlx = 1;
192.  	bot();
193.  }
194.  
195.  docorner(xmin,ymax) register xmin,ymax; {
196.  	register x,y;
197.  	register struct rm *room;
198.  	register struct monst *mtmp;
199.  
200.  	if(u.uswallow) {	/* Can be done more efficiently */
201.  		swallowed();
202.  		return;
203.  	}
204.  
205.  	seemons();	/* reset old positions */
206.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
207.  	    if(mtmp->mx >= xmin && mtmp->my < ymax)
208.  		mtmp->mdispl = 0;
209.  	seemons();	/* force new positions to be shown */
210.  
211.  #ifdef DGK
212.  	if (flags.DECRainbow)
213.  		multipleAts = TRUE;
214.  #endif
215.  	for(y = 0; y < ymax; y++) {
216.  		if(y > ROWNO && CD) break;
217.  		curs(xmin,y+2);
218.  		cl_end();
219.  		if(y < ROWNO) {
220.  		    for(x = xmin; x < COLNO; x++) {
221.  			if((room = &levl[x][y])->new) {
222.  				room->new = 0;
223.  				at(x,y,room->scrsym);
224.  			} else
225.  				if(room->seen)
226.  					at(x,y,room->scrsym);
227.  		    }
228.  		}
229.  	}
230.  #ifdef DGK
231.  	if (flags.DECRainbow) {
232.  		multipleAts = FALSE;
233.  		if (DECgraphics)
234.  			DECgraphicsOFF();
235.  	}
236.  #endif
237.  	if(ymax > ROWNO) {
238.  		cornbot(xmin-1);
239.  		if(ymax > ROWNO+1 && CD) {
240.  			curs(1,ROWNO+3);
241.  			cl_eos();
242.  		}
243.  	}
244.  }
245.  
246.  /* Trolls now regenerate thanks to KAA */
247.  
248.  seeobjs(){
249.  register struct obj *obj, *obj2;
250.  	for(obj = fobj; obj; obj = obj2) {
251.  	    obj2 = obj->nobj;
252.  	    if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE) {
253.  
254.  		if (obj->otyp == DEAD_TROLL && obj->age + 20 < moves) {
255.  			delobj(obj);
256.  			if (cansee(obj->ox, obj->oy)) 
257.  				pline("The troll rises from the dead!");
258.  			(void) makemon(&mons[38],obj->ox, obj->oy);
259.  		} else if (obj->age + 250 < moves) delobj(obj);
260.  	    }
261.  	}
262.  
263.  	for(obj = invent; obj; obj = obj2) {
264.  	    obj2 = obj->nobj;
265.  	    if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE) {
266.  
267.  		if (obj->otyp == DEAD_TROLL && obj->age + 20 < moves) {
268.  		    if (obj == uwep)
269.  			pline("The dead troll writhes out of your grasp!");
270.  		    else
271.  			pline("You feel squirming in your backpack!");
272.  		    (void)makemon(&mons[38],u.ux,u.uy);
273.  		    useup(obj);
274.  		} else if (obj->age + 250 < moves) useup(obj);
275.  	    }
276.  	}
277.  }
278.  
279.  seemons(){
280.  register struct monst *mtmp;
281.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
282.  		if(mtmp->data->mlet == ';')
283.  			mtmp->minvis = (u.ustuck != mtmp &&
284.  					levl[mtmp->mx][mtmp->my].typ == POOL);
285.  		pmon(mtmp);
286.  #ifndef NOWORM
287.  		if(mtmp->wormno) wormsee(mtmp->wormno);
288.  #endif
289.  	}
290.  }
291.  
292.  pmon(mon) register struct monst *mon; {
293.  register int show = (Blind && Telepat) || canseemon(mon);
294.  	if(mon->mdispl){
295.  		if(mon->mdx != mon->mx || mon->mdy != mon->my || !show)
296.  			unpmon(mon);
297.  	}
298.  
299.  /* If you're hallucinating, the monster must be redrawn even if it has
300.     already been printed.  Problem: the monster must also be redrawn right
301.     after hallucination is over, so it looks normal again.  Therefore 
302.     code similar to pmon is in timeout.c. */
303.  	if(show && (!mon->mdispl || Hallucination)) {
304.  		if (Hallucination) 
305.  		atl(mon->mx,mon->my,
306.  			(!mon->mimic || Protection_from_shape_changers) ?
307.  				rndmonsym() :
308.  # ifdef DGK
309.  				(mon->mappearance==symbol.door) ? symbol.door
310.  # else
311.  				(mon->mappearance == DOOR_SYM) ? DOOR_SYM
312.  # endif
313.  				: rndobjsym());
314.  		else
315.  
316.  		atl(mon->mx,mon->my,
317.  		 (!mon->mappearance
318.  		  || u.uprops[PROP(RIN_PROTECTION_FROM_SHAPE_CHAN)].p_flgs
319.  		 ) ? mon->data->mlet : mon->mappearance);
320.  		mon->mdispl = 1;
321.  		mon->mdx = mon->mx;
322.  		mon->mdy = mon->my;
323.  	}
324.  }
325.  
326.  unpmon(mon) register struct monst *mon; {
327.  	if(mon->mdispl){
328.  		newsym(mon->mdx, mon->mdy);
329.  		mon->mdispl = 0;
330.  	}
331.  }
332.  
333.  nscr()
334.  {
335.  	register x,y;
336.  	register struct rm *room;
337.  
338.  	if(u.uswallow || u.ux == FAR || flags.nscrinh) return;
339.  	pru();
340.  	for(y = scrly; y <= scrhy; y++)
341.  		for(x = scrlx; x <= scrhx; x++)
342.  			if((room = &levl[x][y])->new) {
343.  				room->new = 0;
344.  				at(x,y,room->scrsym);
345.  			}
346.  	scrhx = scrhy = 0;
347.  	scrlx = COLNO;
348.  	scrly = ROWNO;
349.  }
350.  
351.  /* 100 suffices for bot(); no relation with COLNO */
352.  char oldbot[100], newbot[100];
353.  cornbot(lth)
354.  register int lth;
355.  {
356.  	if(lth < sizeof(oldbot)) {
357.  		oldbot[lth] = 0;
358.  		flags.botl = 1;
359.  	}
360.  }
361.  
362.  bot()
363.  {
364.  register char *ob = oldbot, *nb = newbot;
365.  register int i;
366.  extern char *eos();
367.  	if(flags.botlx) *ob = 0;
368.  	flags.botl = flags.botlx = 0;
369.  	(void) sprintf(newbot,
370.  #ifdef GOLD_ON_BOTL
371.  # ifdef SPELLS
372.  		"Lev %-2d Gp %-5lu Hp %3d(%d) Ep %3d(%d) Ac %-2d  ",
373.  		dlevel, u.ugold,
374.  #  ifdef KAA
375.  		u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax : u.uhpmax,
376.  		u.uen, u.uenmax, u.uac);
377.  #  else
378.  		u.uhp, u.uhpmax, u.uen, u.uenmax, u.uac);
379.  #  endif
380.  # else
381.  		"Level %-2d  Gold %-5lu  Hp %3d(%d)  Ac %-2d  ",
382.  		dlevel, u.ugold,
383.  #  ifdef KAA
384.  		u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax : u.uhpmax,
385.  		u.uac);
386.  #  else
387.  		u.uhp, u.uhpmax, u.uac);
388.  #  endif
389.  # endif
390.  #else
391.  # ifdef SPELLS
392.  		"Level %-2d Hp %3d(%d) Energy %3d(%d) Ac %-2d ",
393.  		dlevel,
394.  #  ifdef KAA
395.  		u.mtimedone ? u.mhp : u.uhp, u.mtimedone ? u.mhmax, u.uhpmax,
396.  		u.uen, u.uenmax, u.uac);
397.  #  else
398.  		u.uhp, u.uhpmax, u.uen, u.uenmax, u.uac);
399.  #  endif
400.  # else
401.  		"Level %-2d   Hp %3d(%d)   Ac %-2d   ",
402.  		dlevel,
403.  #  ifdef KAA
404.  		u.mtimedone ? u.mhp : u.uhp, u.mtimedone ? u.mhmax, u.uhpmax,
405.  		u.uac);
406.  #  else
407.  		u.uhp, u.uhpmax, u.uac);
408.  #  endif
409.  # endif
410.  #endif
411.  #ifdef KAA
412.  	if (u.mtimedone)
413.  		(void) sprintf(eos(newbot), "HD %d", mons[u.umonnum].mlevel);
414.  	else
415.  #endif
416.  	    if(u.ustr>18) {
417.  		if(u.ustr>117)
418.  		    (void) strcat(newbot,"Str 18/**");
419.  		else
420.  		    (void) sprintf(eos(newbot), "Str 18/%02d",u.ustr-18);
421.  	    } else
422.  		(void) sprintf(eos(newbot), "Str %-2d   ",u.ustr);
423.  #ifdef EXP_ON_BOTL
424.  	(void) sprintf(eos(newbot), "  Exp %2d/%-5lu ", u.ulevel,u.uexp);
425.  #else
426.  	(void) sprintf(eos(newbot), "   Exp %2u  ", u.ulevel);
427.  #endif
428.  	(void) strcat(newbot, hu_stat[u.uhs]);
429.  	if(flags.time)
430.  	    (void) sprintf(eos(newbot), "  %ld", moves);
431.  	if(strlen(newbot) >= COLNO) {
432.  		register char *bp0, *bp1;
433.  		bp0 = bp1 = newbot;
434.  		do {
435.  			if(*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ')
436.  				*bp1++ = *bp0;
437.  		} while(*bp0++);
438.  	}
439.  	for(i = 1; i<COLNO; i++) {
440.  		if(*ob != *nb){
441.  			curs(i,ROWNO+2);
442.  			(void) putchar(*nb ? *nb : ' ');
443.  			curx++;
444.  		}
445.  		if(*ob) ob++;
446.  		if(*nb) nb++;
447.  	}
448.  	(void) strcpy(oldbot, newbot);
449.  }
450.  
451.  #if defined(WAN_PROBING) || defined(KAA)
452.  mstatusline(mtmp) register struct monst *mtmp; {
453.  	pline("Status of %s: ", monnam(mtmp));
454.  	pline("Level %-2d  Gold %-5lu  Hp %3d(%d)",
455.  	    mtmp->data->mlevel, mtmp->mgold, mtmp->mhp, mtmp->mhpmax);
456.  	pline("Ac %-2d  Dam %d %s %s",
457.  	    mtmp->data->ac, (mtmp->data->damn + 1) * (mtmp->data->damd + 1),
458.  	    mtmp->mcan ? ", cancelled" : "" ,mtmp->mtame ? " (tame)" : "");
459.  }
460.  
461.  extern char plname[];
462.  ustatusline() {
463.  	pline("Status of %s ", plname);
464.  	pline("Level %d, gold %lu, hit points %d(%d), AC %d.",
465.  # ifdef KAA
466.  		u.ulevel, u.ugold, u.mtimedone ? u.mh : u.uhp,
467.  		u.mtimedone ? u.mhmax : u.uhpmax, u.uac);
468.  # else
469.  		u.ulevel, u.ugold, u.uhp, u.uhpmax, u.uac);
470.  # endif
471.  }
472.  #endif
473.  
474.  cls(){
475.  	if(flags.toplin == 1)
476.  		more();
477.  	flags.toplin = 0;
478.  
479.  	clear_screen();
480.  
481.  	flags.botlx = 1;
482.  }
483.  
484.  rndmonsym() {
485.  	register int x;
486.  	if((x=rn2(58)) < 26)
487.  		return('a'+x);
488.  	else if (x<52)
489.  		return('A'+x-26);
490.  	else switch(x) {
491.  		case 52: return(';');
492.  		case 53: return('&');
493.  		case 54: return(':');
494.  		case 55: return('\);
495.  		case 56: return(',');
496.  		case 57: return('9');
497.  		default: impossible("Bad random monster %d",x); return('{');
498.  	}
499.  }
500.  
501.  rndobjsym() {
502.  	char *rndsym=")[!?%/=*($'";
503.  	return *(rndsym+rn2(11));
504.  }
505.  
506.  char *hcolors[] = { "ultraviolet","infrared","hot pink", "psychedelic",
507.  "bluish-orange","reddish-green","dark white","light black","loud",
508.  "salty","sweet","sour","bitter","luminescent","striped","polka-dotted",
509.  "square","round","triangular","brilliant","navy blue","cerise",
510.  "charteruse","copper","sea green","spiral","swirly","blotchy",
511.  "fluorescent green","burnt orange","indigo","amber","tan",
512.  "sky blue-pink","lemon yellow" };
513.  
514.  char *
515.  hcolor() {
516.  	return hcolors[rn2(35)];
517.  }