Source:NetHack 2.2a/pri.c

Below is the full text to pri.c from the source code of NetHack 2.2a. To link to a particular line, write [[NetHack 2.2a/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	2.1	87/11/09 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.     4.    #include   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 ats 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 ats 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.  	if(strlen(newbot) >= COLNO) {  440.  		register char *bp0, *bp1;  441.  		bp0 = bp1 = newbot;  442. do { 443. 			if(*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ') 444. 				*bp1++ = *bp0; 445. 		} while(*bp0++); 446. 	}  447.  	for(i = 1; idata->mlevel, mtmp->mgold, mtmp->mhp, mtmp->mhpmax); 464. 	pline("Ac %-2d  Dam %d %s %s",  465.  	    mtmp->data->ac, (mtmp->data->damn + 1) * (mtmp->data->damd + 1),  466.  	    mtmp->mcan ? ", cancelled" : "" ,mtmp->mtame ? " (tame)" : ""); 467. }  468.   469.  extern char plname[]; 470. ustatusline { 471. 	pline("Status of %s ", plname); 472. 	pline("Level %d, gold %lu, hit points %d(%d), AC %d.",  473.  # ifdef KAA  474.  		u.ulevel, u.ugold, u.mtimedone ? u.mh : u.uhp,  475.  		u.mtimedone ? u.mhmax : u.uhpmax, u.uac); 476. # else 477. 		u.ulevel, u.ugold, u.uhp, u.uhpmax, u.uac);  478.  # endif  479.  }  480.  #endif  481.   482.  cls{  483.  	if(flags.toplin == 1)  484.  		more;  485.  	flags.toplin = 0;  486.   487.  	clear_screen;  488.   489.  	flags.botlx = 1;  490.  }  491.   492.  rndmonsym {  493.  	register int x;  494.  	if((x=rn2(58)) < 26)  495.  		return('a'+x);  496.  	else if (x<52)  497.  		return('A'+x-26);  498.  	else switch(x) {  499.  		case 52: return(';');  500.  		case 53: return('&');  501.  		case 54: return(':');  502.  		case 55: return('\'');  503.  		case 56: return(',');  504.  		case 57: return('9');  505.  		default: impossible("Bad random monster %d",x); return('{');  506.  	}  507.  }  508.   509.  rndobjsym {  510.  	char *rndsym=")[!?%/=*($`";  511.  	return *(rndsym+rn2(11));  512.  }  513.   514.  char *hcolors[] = { "ultraviolet","infrared","hot pink", "psychedelic", 515. "bluish-orange","reddish-green","dark white","light black","loud", 516. "salty","sweet","sour","bitter","luminescent","striped","polka-dotted", 517. "square","round","triangular","brilliant","navy blue","cerise", 518. "chartreuse","copper","sea green","spiral","swirly","blotchy", 519. "fluorescent green","burnt orange","indigo","amber","tan", 520. "sky blue-pink","lemon yellow" }; 521.  522.  char * 523. hcolor { 524. 	return hcolors[rn2(35)]; 525. }  526.   527.  #ifdef MSDOSCOLOR 528. /* what if a level character is the same as an object/monster? */ 529.   530.  extern char obj_symbols[]; 531.  532.  hilite(let) 533. char let; 534. {  535.  	char *isobjct = index(obj_symbols, let); 536. 	int ismnst; 537.  538.  	if (!HI || !HE) { 539. 		(void) putchar(let); 540. 		return; 541. 	}  542.  	if (isobjct != NULL || let == GOLD_SYM) { 543. 	/* is an object */ 544. 		printf("%s%c%s", HI_OBJ, let, HE); 545. 	} else if (ismnst(let)) { 546. 	/* is a monster */ 547. 		printf("%s%c%s", HI_MON, let, HE); 548. 	} else { 549. 	/* default */ 550. 		(void) putchar(let); 551. 	}  552.  }  553.   554.  int 555. ismnst(let) 556. char let; 557. {  558.  	register int ct; 559. 	register struct permonst *ptr; 560.  561.  	for (ct = 0 ; ct < CMNUM + 2 ; ct++) { 562. 		ptr = &mons[ct]; 563. 		if(ptr->mlet == let) return(1); 564. 	}  565.  	if (let == '1') return(1); 566. 	else if (let == '2') return(1); 567. 	else if (let == ';') return(1); 568. 	else return(0); 569. }  570.  #endif