Source:NetHack 1.4f/pri.c

From NetHackWiki
Jump to navigation Jump to search

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