Source:NetHack 1.3d/pri.c

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

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