Source:NetHack 1.4f/pri.c

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

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   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 ats 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 ats 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; idata->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. }