Source:NetHack 2.3e/pri.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to pri.c from the source code of NetHack 2.3e.

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

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

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