Source:NetHack 2.3e/pri.c
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