Source:NetHack 3.0.0/pri.c
Jump to navigation
Jump to search
Below is the full text to pri.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/pri.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)pri.c 3.0 89/06/16 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* block some unused #defines to avoid overloading some cpp's */ 6. #define MONATTK_H 7. #include "hack.h" 8. #include <ctype.h> /* for isalpha() */ 9. 10. static void hilite P((uchar, uchar)); 11. static void cornbot P((int)); 12. static boolean ismnst P((char)); 13. #if !defined(DECRAINBOW) && !defined(UNIX) 14. # define g_putch (void) putchar 15. #endif 16. 17. #ifndef g_putch 18. static boolean GFlag = FALSE; /* graphic flag */ 19. #endif 20. 21. /* 100 suffices for bot(); must be larger than COLNO */ 22. #define MAXCO 100 23. static char oldbot1[MAXCO], newbot1[MAXCO]; 24. static char oldbot2[MAXCO], newbot2[MAXCO]; 25. static const char *dispst = "*0#@#0#*0#@#0#*0#@#0#*0#@#0#*0#@#0#*"; 26. static int mrank_sz = 0; /* loaded by max_rank_sz (called in u_init) */ 27. 28. void 29. swallowed(first) 30. register int first; 31. { 32. if(first) cls(); 33. else { 34. curs(u.ustuck->mdx-1, u.ustuck->mdy+1); 35. (void) fputs(" ", stdout); 36. curx = u.ustuck->mdx+2; 37. curs(u.ustuck->mdx-1, u.ustuck->mdy+2); 38. (void) fputs(" ", stdout); 39. curx = u.ustuck->mdx+2; 40. curs(u.ustuck->mdx-1, u.ustuck->mdy+3); 41. (void) fputs(" ", stdout); 42. curx = u.ustuck->mdx+2; 43. } 44. curs(u.ux-1, u.uy+1); 45. (void) fputs("/-\\", stdout); 46. curx = u.ux+2; 47. curs(u.ux-1, u.uy+2); 48. (void) putchar('|'); 49. hilite(u.usym, AT_MON); 50. (void) putchar('|'); 51. curx = u.ux+2; 52. curs(u.ux-1, u.uy+3); 53. (void) fputs("\\-/", stdout); 54. curx = u.ux+2; 55. u.udispl = 1; 56. u.udisx = u.ux; 57. u.udisy = u.uy; 58. } 59. 60. void 61. setclipped() 62. { 63. error("NetHack needs a screen of size at least %d by %d.\n", 64. ROWNO+3, COLNO); 65. } 66. 67. /* 68. * Allow for a different implementation than this... 69. */ 70. 71. #ifndef g_putch 72. 73. static void 74. g_putch(ch) 75. uchar ch; 76. { 77. if (ch & 0x80) { 78. if (!GFlag) { 79. graph_on(); 80. GFlag = TRUE; 81. } 82. (void) putchar(ch ^ 0x80); /* Strip 8th bit */ 83. } else { 84. if (GFlag) { 85. graph_off(); 86. GFlag = FALSE; 87. } 88. (void) putchar(ch); 89. } 90. } 91. 92. #endif 93. 94. static boolean 95. showmon(mon) 96. register struct monst *mon; 97. { 98. register boolean show = (Blind && Telepat) || canseemon(mon); 99. 100. if (!show && (HTelepat & WORN_HELMET)) 101. show = (dist(mon->mx, mon->my) <= (BOLT_LIM * BOLT_LIM)); 102. return(show); 103. } 104. 105. void 106. at(x,y,ch,typ) 107. register xchar x,y; 108. uchar ch,typ; 109. { 110. #ifndef LINT 111. /* if xchar is unsigned, lint will complain about if(x < 0) */ 112. if(x < 0 || x > COLNO-1 || y < 0 || y > ROWNO-1) { 113. impossible("At gets 0%o at %d %d.", ch, x, y); 114. return; 115. } 116. #endif 117. if(!ch) { 118. impossible("At gets null at %d %d.", x, y); 119. return; 120. } 121. 122. if (typ == AT_APP 123. #ifndef MSDOS 124. && flags.standout 125. #endif 126. ) 127. /* don't hilite if this isn't a monster or object. 128. * 129. * not complete; a scroll dropped by some monster 130. * on an unseen doorway which is later magic mapped 131. * will still hilite the doorway symbol. -3. 132. */ 133. if (!vism_at(x,y) && 134. (!levl[x][y].omask && !levl[x][y].gmask || is_pool(x,y))) 135. typ = AT_MAP; 136. 137. y += 2; 138. curs(x,y); 139. 140. hilite(ch,typ); 141. curx++; 142. } 143. 144. void 145. prme(){ 146. if(!Invisible 147. #ifdef POLYSELF 148. && !u.uundetected 149. #endif 150. ) at(u.ux,u.uy,u.usym,AT_U); 151. } 152. 153. void 154. shieldeff(x, y) /* produce a magical shield effect at x,y */ 155. register xchar x, y; 156. { 157. register char *ch; 158. register struct monst *mtmp = 0; 159. 160. if((x != u.ux) || (y != u.uy)) { 161. if(!(mtmp = m_at(x, y))) { 162. 163. impossible("shield effect at %d,%d", x, y); 164. return; 165. } 166. if(!showmon(mtmp)) return; 167. } 168. 169. for(ch = dispst; *ch; ch++) { 170. at(x, y, (uchar) *ch, AT_ZAP); 171. (void) fflush(stdout); 172. delay_output(); 173. delay_output(); 174. } 175. 176. nomul(0); 177. if(!mtmp) { 178. if(Invisible) { 179. prl(x, y); 180. at(x, y, levl[x][y].scrsym, AT_APP); 181. } else prme(); 182. } else { 183. mtmp->mdispl = 0; /* make sure it gets redrawn */ 184. prl(x, y); 185. if(mtmp->minvis) 186. at(x, y, levl[x][y].scrsym, AT_APP); 187. else at(x, y, (uchar) mtmp->data->mlet, AT_MON); 188. } 189. 190. return; 191. } 192. 193. int 194. doredraw() 195. { 196. docrt(); 197. return 0; 198. } 199. 200. void 201. docrt() 202. { 203. register int x,y; 204. register struct rm *room; 205. register struct monst *mtmp; 206. 207. if(u.uswallow) { 208. swallowed(1); 209. return; 210. } 211. cls(); 212. 213. /* Some ridiculous code to get display of @ and monsters (almost) right */ 214. if(!Invisible 215. #ifdef POLYSELF 216. || u.uundetected 217. #endif 218. ) { 219. levl[(u.udisx = u.ux)][(u.udisy = u.uy)].scrsym = u.usym; 220. levl[u.udisx][u.udisy].seen = 1; 221. u.udispl = 1; 222. } else u.udispl = 0; 223. 224. seemons(); /* reset old positions */ 225. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 226. mtmp->mdispl = 0; 227. seemons(); /* force new positions to be shown */ 228. 229. #if defined(DGK) && !defined(MSDOSCOLOR) 230. /* Otherwise, line buffer the output to do the redraw in 231. * about 2/3 of the time. 232. */ 233. for(y = 0; y < ROWNO; y++) { 234. char buf[COLNO+1]; 235. int start, end; 236. #ifdef TOS 237. setmem(buf, COLNO, ' '); 238. #else 239. memset(buf, ' ', COLNO); 240. #endif /* TOS */ 241. for(x = 0, start = -1, end = -1; x < COLNO; x++) 242. if((room = &levl[x][y])->new) { 243. room->new = 0; 244. buf[x] = room->scrsym; 245. if (start < 0) 246. start = x; 247. end = x; 248. } else if(room->seen) { 249. buf[x] = room->scrsym; 250. if (start < 0) 251. start = x; 252. end = x; 253. } 254. if (end >= 0) { 255. buf[end + 1] = '\0'; 256. curs(start, y + 2); 257. (void) fputs(buf + start, stdout); 258. curx = end + 1; 259. } 260. } 261. #else /* DGK && !MSDOSCOLOR */ 262. for(y = 0; y < ROWNO; y++) 263. for(x = 0; x < COLNO; x++) 264. if((room = &levl[x][y])->new) { 265. room->new = 0; 266. at(x,y,room->scrsym,AT_APP); 267. } else if(room->seen) 268. at(x,y,room->scrsym,AT_APP); 269. #endif /* DGK && !MSDOSCOLOR */ 270. #ifndef g_putch 271. if (GFlag) { 272. graph_off(); 273. GFlag = FALSE; 274. } 275. #endif 276. scrlx = COLNO; 277. scrly = ROWNO; 278. scrhx = scrhy = 0; 279. cornbot(0); 280. bot(); 281. } 282. 283. static void 284. cornbot(lth) 285. register int lth; 286. { 287. oldbot1[lth] = 0; 288. oldbot2[lth] = 0; 289. flags.botl = 1; 290. } 291. 292. void 293. docorner(xmin, ymax) 294. register int xmin, ymax; 295. { 296. register int x, y; 297. register struct rm *room; 298. register struct monst *mtmp; 299. 300. if(u.uswallow) { /* Can be done more efficiently */ 301. swallowed(1); 302. return; 303. } 304. 305. seemons(); /* reset old positions */ 306. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 307. if(mtmp->mx >= xmin && mtmp->my < ymax) 308. mtmp->mdispl = 0; 309. seemons(); /* force new positions to be shown */ 310. 311. for(y = 0; y < ymax; y++) { 312. if(y > ROWNO+1 && CD) break; 313. curs(xmin,y+2); 314. cl_end(); 315. if(y < ROWNO) { 316. for(x = xmin; x < COLNO; x++) { 317. if((room = &levl[x][y])->new) { 318. room->new = 0; 319. at(x,y,room->scrsym,AT_APP); 320. } else 321. if(room->seen) 322. at(x,y,room->scrsym,AT_APP); 323. } 324. } 325. } 326. #ifndef g_putch 327. if (GFlag) { 328. graph_off(); 329. GFlag = FALSE; 330. } 331. #endif 332. /* Note: y values: 0 to ymax-1 333. * screen positions from y: 2 to ymax+1 334. * whole screen: 1 to ROWNO+3 335. * top line: 1 336. * dungeon display: 2 to ROWNO+1 337. * first bottom line: ROWNO+2 338. * second bottom line: ROWNO+3 339. * lines on screen: ROWNO+3 340. */ 341. if(ymax > ROWNO) { 342. cornbot(xmin-1); 343. if(ymax > ROWNO+2 && CD) { /* clear portion of long */ 344. curs(1,ROWNO+4); /* screen below status lines */ 345. cl_eos(); 346. } 347. } 348. } 349. 350. void 351. seeglds() 352. { 353. register struct gold *gold, *gold2; 354. 355. for(gold = fgold; gold; gold = gold2) { 356. gold2 = gold->ngold; 357. if(Hallucination && cansee(gold->gx,gold->gy)) 358. if(!(gold->gx == u.ux && gold->gy == u.uy) || Invisible) 359. atl(gold->gx,gold->gy,rndobjsym()); 360. } 361. } 362. 363. /* Trolls now regenerate thanks to KAA */ 364. 365. void 366. seeobjs() 367. { 368. register struct obj *obj, *obj2; 369. 370. for(obj = fobj; obj; obj = obj2) { 371. obj2 = obj->nobj; 372. 373. if(Hallucination && cansee(obj->ox,obj->oy)) 374. if(!(obj->ox == u.ux && obj->oy == u.uy) || Invisible) 375. atl(obj->ox,obj->oy,rndobjsym()); 376. 377. if(obj->olet == FOOD_SYM && obj->otyp == CORPSE) { 378. 379. if(mons[obj->corpsenm].mlet == S_TROLL && 380. obj->age + 20 < moves) { 381. boolean visible = cansee(obj->ox,obj->oy); 382. struct monst *mtmp = revive(obj, FALSE); 383. 384. if (mtmp && visible) 385. pline("%s rises from the dead!", Monnam(mtmp)); 386. } else if (obj->age + 250 < moves) delobj(obj); 387. } 388. } 389. 390. for(obj = invent; obj; obj = obj2) { 391. obj2 = obj->nobj; 392. if(obj->otyp == CORPSE) { 393. if(mons[obj->corpsenm].mlet == S_TROLL 394. && obj->age + 20 < moves) { 395. boolean wielded = (obj==uwep); 396. struct monst *mtmp = revive(obj, TRUE); 397. 398. if (mtmp && wielded) 399. pline("The %s %s writhes out of your grasp!", 400. mtmp->data->mname, xname(obj)); 401. else if (mtmp) 402. You("feel squirming in your backpack!"); 403. } else if (obj->age + 250 < moves) useup(obj); 404. } 405. } 406. } 407. 408. void 409. seemons() 410. { 411. register struct monst *mtmp; 412. 413. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 414. if(mtmp->data->mlet == S_EEL) 415. mtmp->minvis = (u.ustuck != mtmp && is_pool(mtmp->mx,mtmp->my)); 416. pmon(mtmp); 417. #ifdef WORM 418. if(mtmp->wormno) wormsee(mtmp->wormno); 419. #endif 420. } 421. } 422. 423. void 424. pmon(mon) 425. register struct monst *mon; 426. { 427. register int show = showmon(mon); 428. 429. if(mon->mdispl) 430. if(mon->mdx != mon->mx || mon->mdy != mon->my || !show) 431. unpmon(mon); 432. 433. /* If you're hallucinating, the monster must be redrawn even if it has 434. * already been printed. 435. */ 436. if(show && (!mon->mdispl || Hallucination)) { 437. if (Hallucination) 438. atl(mon->mx,mon->my, 439. (char) ((!mon->mimic || Protection_from_shape_changers) ? 440. rndmonsym() : (mon->mappearance == DOOR_SYM) ? 441. DOOR_SYM : rndobjsym())); 442. else 443. 444. atl(mon->mx,mon->my, 445. (!mon->mappearance || 446. Protection_from_shape_changers) ? 447. mon->data->mlet : mon->mappearance); 448. mon->mdispl = 1; 449. mon->mdx = mon->mx; 450. mon->mdy = mon->my; 451. } 452. #ifndef g_putch 453. if (GFlag) { 454. graph_off(); 455. GFlag = FALSE; 456. } 457. #endif 458. } 459. 460. void 461. unpmon(mon) 462. register struct monst *mon; 463. { 464. if(mon->mdispl) { 465. newsym(mon->mdx, mon->mdy); 466. mon->mdispl = 0; 467. } 468. } 469. 470. void 471. nscr() { 472. register int x, y; 473. register struct rm *room; 474. 475. if(u.uswallow || u.ux == FAR || flags.nscrinh) return; 476. pru(); 477. for(y = scrly; y <= scrhy; y++) 478. for(x = scrlx; x <= scrhx; x++) 479. if((room = &levl[x][y])->new) { 480. room->new = 0; 481. at(x,y,room->scrsym,AT_APP); 482. } 483. #ifndef g_putch 484. if (GFlag) { 485. graph_off(); 486. GFlag = FALSE; 487. } 488. #endif 489. scrhx = scrhy = 0; 490. scrlx = COLNO; 491. scrly = ROWNO; 492. } 493. 494. /* Make sure that there are 18 entries in the rank arrays. */ 495. /* 0 and even entries are male ranks, odd entries are female. */ 496. 497. static const char *mage_ranks[] = { 498. "Evoker", 499. "Evoker", 500. "Conjurer", 501. "Conjurer", 502. "Thaumaturge", 503. "Thaumaturge", 504. "Magician", 505. "Magician", 506. "Enchanter", 507. "Enchanter", 508. "Sorcerer", 509. "Sorceress", 510. "Necromancer", 511. "Necromancer", 512. "Wizard", 513. "Wizard", 514. "Mage", 515. "Mage" 516. }; 517. 518. static const char *priest_ranks[] = { 519. "Aspirant", 520. "Aspirant", 521. "Acolyte", 522. "Acolyte", 523. "Adept", 524. "Adept", 525. "Priest", 526. "Priestess", 527. "Curate", 528. "Curate", 529. "Canon", 530. "Canoness", 531. "Lama", 532. "Lama", 533. "Patriarch", 534. "Matriarch", 535. "High Priest", 536. "High Priestess" 537. }; 538. 539. static const char *thief_ranks[] = { 540. "Footpad", 541. "Footpad", 542. "Cutpurse", 543. "Cutpurse", 544. "Rogue", 545. "Rogue", 546. "Pilferer", 547. "Pilferer", 548. "Robber", 549. "Robber", 550. "Burglar", 551. "Burglar", 552. "Filcher", 553. "Filcher", 554. "Magsman", 555. "Magswoman", 556. "Thief", 557. "Thief" 558. }; 559. 560. static const char *fighter_ranks[] = { 561. "Stripling", 562. "Stripling", 563. "Skirmisher", 564. "Skirmisher", 565. "Fighter", 566. "Fighter", 567. "Man-at-arms", 568. "Woman-at-arms", 569. "Warrior", 570. "Warrior", 571. "Swashbuckler", 572. "Swashbuckler", 573. "Hero", 574. "Heroine", 575. "Champion", 576. "Champion", 577. "Lord", 578. "Lady" 579. }; 580. 581. static const char *tourist_ranks[] = { 582. "Rambler", 583. "Rambler", 584. "Sightseer", 585. "Sightseer", 586. "Excursionist", 587. "Excursionist", 588. "Peregrinator", 589. "Peregrinator", 590. "Traveler", 591. "Traveler", 592. "Journeyer", 593. "Journeyer", 594. "Voyager", 595. "Voyager", 596. "Explorer", 597. "Explorer", 598. "Adventurer", 599. "Adventurer" 600. }; 601. 602. static const char *nomad_ranks[] = { 603. "Troglodyte", 604. "Troglodyte", 605. "Aborigine", 606. "Aborigine", 607. "Wanderer", 608. "Wanderer", 609. "Vagrant", 610. "Vagrant", 611. "Wayfarer", 612. "Wayfarer", 613. "Roamer", 614. "Roamer", 615. "Nomad", 616. "Nomad", 617. "Rover", 618. "Rover", 619. "Pioneer", 620. "Pioneer" 621. }; 622. 623. static const char *knight_ranks[] = { 624. "Gallant", 625. "Gallant", 626. "Esquire", 627. "Esquire", 628. "Bachelor", 629. "Bachelor", 630. "Sergeant", 631. "Sergeant", 632. "Knight", 633. "Knight", 634. "Banneret", 635. "Banneret", 636. "Chevalier", 637. "Chevalier", 638. "Seignieur", 639. "Seignieur", 640. "Paladin", 641. "Paladin" 642. }; 643. 644. static const char *archeo_ranks[] = { 645. "Digger", 646. "Digger", 647. "Field Worker", 648. "Field Worker", 649. "Investigator", 650. "Investigator", 651. "Exhumer", 652. "Exhumer", 653. "Excavator", 654. "Excavator", 655. "Spelunker", 656. "Spelunker", 657. "Speleologist", 658. "Speleologist", 659. "Collector", 660. "Collector", 661. "Curator", 662. "Curator" 663. }; 664. 665. static const char *healer_ranks[] = { 666. "Pre-Med", 667. "Pre-Med", 668. "Med Student", 669. "Med Student", 670. "Medic", 671. "Medic", 672. "Intern", 673. "Intern", 674. "Doctor", 675. "Doctor", 676. "Physician", 677. "Physician", 678. "Specialist", 679. "Specialist", 680. "Surgeon", 681. "Surgeon", 682. "Chief Surgeon", 683. "Chief Surgeon" 684. }; 685. 686. static const char *barbarian_ranks[] = { 687. "Plunderer", 688. "Plunderess", 689. "Pillager", 690. "Pillager", 691. "Bandit", 692. "Bandit", 693. "Brigand", 694. "Brigand", 695. "Raider", 696. "Raider", 697. "Reaver", 698. "Reaver", 699. "Slayer", 700. "Slayer", 701. "Chieftain", 702. "Chieftainess", 703. "Conqueror", 704. "Conqueress" 705. }; 706. 707. static const char *ninja_ranks[] = { 708. "Chigo", 709. "Chigo", 710. "Bushi", 711. "Bushi", 712. "Genin", 713. "Genin", 714. "Genin", 715. "Genin", 716. "Chunin", 717. "Chunin", 718. "Chunin", 719. "Chunin", 720. "Jonin", 721. "Jonin", 722. "Jonin", 723. "Jonin", 724. "Jonin", 725. "Jonin", 726. }; 727. 728. static const char *elf_ranks[] = { 729. "Edhel", 730. "Elleth", 731. "Edhel", 732. "Elleth", /* elf-maid */ 733. "Ohtar", /* warrior */ 734. "Ohtie", 735. "Kano", /* commander (Q.) ['a] */ 736. "Kanie", /* educated guess, until further research- SAC */ 737. "Arandur", /* king's servant, minister (Q.) - educated guess */ 738. "Aranduriel", /* educated guess */ 739. "Hir", /* lord (S.) */ 740. "Hiril", /* lady (S.) ['ir] */ 741. "Aredhel", /* noble elf (S.) */ 742. "Arwen", /* noble maiden (S.) */ 743. "Ernil", /* prince (S.) */ 744. "Elentariel", /* elf-maiden (Q.) */ 745. "Elentar", /* Star-king (Q.) */ 746. "Elentari", /* Star-queen (Q.) */ /* Elbereth (S.) */ 747. }; 748. 749. static const char ** 750. rank_array() { 751. register const char **ranks; 752. 753. switch(pl_character[0]) { 754. case 'A': ranks = archeo_ranks; break; 755. case 'B': ranks = barbarian_ranks; break; 756. case 'C': ranks = nomad_ranks; break; 757. case 'E': ranks = elf_ranks; break; 758. case 'H': ranks = healer_ranks; break; 759. case 'K': ranks = knight_ranks; break; 760. case 'P': ranks = priest_ranks; break; 761. case 'R': ranks = thief_ranks; break; 762. case 'S': ranks = ninja_ranks; break; 763. case 'T': ranks = tourist_ranks; break; 764. case 'V': ranks = fighter_ranks; break; 765. case 'W': ranks = mage_ranks; break; 766. default: ranks = 0; break; 767. } 768. return(ranks); 769. } 770. 771. static char * 772. rank() { 773. register int place; 774. register const char **ranks = rank_array(); 775. 776. if(u.ulevel < 3) place = 0; 777. else if(u.ulevel < 6) place = 2; 778. else if(u.ulevel < 10) place = 4; 779. else if(u.ulevel < 14) place = 6; 780. else if(u.ulevel < 18) place = 8; 781. else if(u.ulevel < 22) place = 10; 782. else if(u.ulevel < 26) place = 12; 783. else if(u.ulevel < 30) place = 14; 784. else place = 16; 785. if(flags.female) place++; 786. 787. if (!!ranks) return(ranks[place]); 788. return(pl_character); 789. } 790. 791. void 792. max_rank_sz() { 793. register int i, maxr = 0; 794. register const char **ranks = rank_array(); 795. 796. if (!!ranks) { 797. for(i = flags.female; i < 18; i += 2) 798. if(strlen(ranks[i]) > maxr) maxr = strlen(ranks[i]); 799. mrank_sz = maxr; 800. } 801. else mrank_sz = strlen(pl_character); 802. } 803. 804. static void 805. fillbot(row,oldbot,newbot) 806. int row; 807. char *oldbot, *newbot; 808. { 809. register char *ob = oldbot, *nb = newbot; 810. register int i; 811. int fillcol; 812. 813. fillcol = min(CO, MAXCO-1); 814. 815. /* compress in case line too long */ 816. if(strlen(newbot) >= fillcol) { 817. register char *bp0 = newbot, *bp1 = newbot; 818. 819. do { 820. if(*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ') 821. *bp1++ = *bp0; 822. } while(*bp0++); 823. } 824. newbot[fillcol] = '\0'; 825. 826. for(i = 1; i < fillcol; i++) { 827. if(!*nb) { 828. if(*ob || flags.botlx) { 829. /* last char printed may be in middle of line */ 830. curs(strlen(newbot)+1,row); 831. cl_end(); 832. } 833. break; 834. } 835. if(*ob != *nb) { 836. curs(i,row); 837. (void) putchar(*nb); 838. curx++; 839. } 840. if(*ob) ob++; 841. nb++; 842. } 843. Strcpy(oldbot, newbot); 844. } 845. 846. static void 847. bot1() 848. { 849. register int i,j; 850. 851. Strcpy(newbot1, plname); 852. if('a' <= newbot1[0] && newbot1[0] <= 'z') newbot1[0] += 'A'-'a'; 853. newbot1[10] = 0; 854. Sprintf(eos(newbot1)," the "); 855. #ifdef POLYSELF 856. if (u.mtimedone) { 857. char mbot[BUFSZ]; 858. int k = 0; 859. 860. Strcpy(mbot, mons[u.umonnum].mname); 861. while(mbot[k] != 0) { 862. if ((k == 0 || (k > 0 && mbot[k-1] == ' ')) && 863. 'a' <= mbot[k] && mbot[k] <= 'z') 864. mbot[k] += 'A' - 'a'; 865. k++; 866. } 867. Sprintf(eos(newbot1), mbot); 868. } else 869. Sprintf(eos(newbot1), rank()); 870. #else 871. Sprintf(eos(newbot1), rank()); 872. #endif 873. Sprintf(eos(newbot1)," "); 874. i = mrank_sz + 15; 875. j = strlen(newbot1); 876. if((i - j) > 0) 877. do { Sprintf(eos(newbot1)," "); /* pad with spaces */ 878. i--; 879. } while((i - j) > 0); 880. if(ACURR(A_STR)>18) { 881. if(ACURR(A_STR)>118) 882. Sprintf(eos(newbot1),"St:%2d ",ACURR(A_STR)-100); 883. else if(ACURR(A_STR)<118) 884. Sprintf(eos(newbot1), "St:18/%02d ",ACURR(A_STR)-18); 885. else 886. Sprintf(eos(newbot1),"St:18/** "); 887. } else 888. Sprintf(eos(newbot1), "St:%-1d ",ACURR(A_STR)); 889. Sprintf(eos(newbot1), 890. "Dx:%-1d Co:%-1d In:%-1d Wi:%-1d Ch:%-1d", 891. ACURR(A_DEX), ACURR(A_CON), ACURR(A_INT), ACURR(A_WIS), ACURR(A_CHA)); 892. Sprintf(eos(newbot1), (u.ualigntyp == U_CHAOTIC) ? " Chaotic" : 893. (u.ualigntyp == U_NEUTRAL) ? " Neutral" : " Lawful"); 894. #ifdef SCORE_ON_BOTL 895. Sprintf(eos(newbot1)," S:%lu" 896. ,(u.ugold - u.ugold0 > 0 ? u.ugold - u.ugold0 : 0) 897. + u.urexp + (50 * maxdlevel) 898. + (maxdlevel > 20? 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20) :0)); 899. #endif 900. fillbot(ROWNO+2, oldbot1, newbot1); 901. } 902. 903. static void 904. bot2() 905. { 906. #ifdef ENDGAME 907. if(dlevel == ENDLEVEL) 908. Sprintf(newbot2, "EndLevel "); 909. else 910. #endif 911. #ifdef SPELLS 912. Sprintf(newbot2, "Dlvl:%-2d ", dlevel); 913. #else 914. Sprintf(newbot2, "Level:%-1d ", dlevel); 915. #endif 916. Sprintf(eos(newbot2), 917. #ifdef SPELLS 918. "G:%-2ld HP:%d(%d) Pw:%d(%d) AC:%-2d", 919. u.ugold, 920. # ifdef POLYSELF 921. u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax : u.uhpmax, 922. u.uen, u.uenmax, u.uac); 923. # else 924. u.uhp, u.uhpmax, u.uen, u.uenmax, u.uac); 925. # endif 926. #else 927. "Gold:%-1lu HP:%d(%d) AC:%-1d", 928. u.ugold, 929. # ifdef POLYSELF 930. u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax : u.uhpmax, 931. u.uac); 932. # else 933. u.uhp, u.uhpmax, u.uac); 934. # endif 935. #endif 936. #ifdef POLYSELF 937. if (u.mtimedone) 938. Sprintf(eos(newbot2), " HD:%d", mons[u.umonnum].mlevel); 939. else 940. #endif 941. #ifdef EXP_ON_BOTL 942. Sprintf(eos(newbot2), " Xp:%u/%-1ld", u.ulevel,u.uexp); 943. #else 944. Sprintf(eos(newbot2), " Exp:%u", u.ulevel); 945. #endif 946. if(flags.time) 947. Sprintf(eos(newbot2), " T:%ld", moves); 948. if(strcmp(hu_stat[u.uhs], " ")) { 949. Sprintf(eos(newbot2), " "); 950. Strcat(newbot2, hu_stat[u.uhs]); 951. } 952. if(Confusion) Sprintf(eos(newbot2), " Conf"); 953. if(Sick) Sprintf(eos(newbot2), " Sick"); 954. if(Blinded) Sprintf(eos(newbot2), " Blind"); 955. if(Stunned) Sprintf(eos(newbot2), " Stun"); 956. if(Hallucination) Sprintf(eos(newbot2), " Hallu"); 957. fillbot(ROWNO+3, oldbot2, newbot2); 958. } 959. 960. void 961. bot() { 962. register char *ob1 = oldbot1, *ob2 = oldbot2; 963. if(flags.botlx) *ob1 = *ob2 = 0; 964. bot1(); 965. bot2(); 966. flags.botl = flags.botlx = 0; 967. } 968. 969. 970. void 971. mstatusline(mtmp) 972. register struct monst *mtmp; 973. { 974. pline("Status of %s (%s): ", mon_nam(mtmp), 975. (mtmp->data->maligntyp <= -1) ? "chaotic" : 976. mtmp->data->maligntyp ? "lawful" : "neutral"); 977. pline("Level %d Gold %lu HP %d(%d)", 978. mtmp->m_lev, mtmp->mgold, mtmp->mhp, mtmp->mhpmax); 979. pline("AC %d%s%s", mtmp->data->ac, 980. mtmp->mcan ? ", cancelled" : "" ,mtmp->mtame ? ", tame" : ""); 981. } 982. 983. void 984. ustatusline() 985. { 986. pline("Status of %s (%s%s):", plname, 987. (u.ualign > 3) ? "stridently " : 988. (u.ualign == 3) ? "" : 989. (u.ualign >= 1) ? "haltingly " : 990. (u.ualign == 0) ? "nominally " : 991. "insufficiently ", 992. (u.ualigntyp == U_CHAOTIC) ? "chaotic" : 993. u.ualigntyp ? "lawful" : "neutral"); 994. pline("Level %d Gold %lu HP %d(%d) AC %d", 995. # ifdef POLYSELF 996. u.mtimedone ? mons[u.umonnum].mlevel : u.ulevel, 997. u.ugold, u.mtimedone ? u.mh : u.uhp, 998. u.mtimedone ? u.mhmax : u.uhpmax, u.uac); 999. # else 1000. u.ulevel, u.ugold, u.uhp, u.uhpmax, u.uac); 1001. # endif 1002. } 1003. 1004. void 1005. cls() 1006. { 1007. extern xchar tlx, tly; 1008. 1009. if(flags.toplin == 1) 1010. more(); 1011. flags.toplin = 0; 1012. 1013. clear_screen(); 1014. 1015. tlx = tly = 1; 1016. 1017. flags.botlx = 1; 1018. } 1019. 1020. char 1021. rndmonsym() 1022. { 1023. return(mons[rn2(NUMMONS - 1)].mlet); 1024. } 1025. 1026. static const char objsyms[] = { 1027. WEAPON_SYM, ARMOR_SYM, POTION_SYM, SCROLL_SYM, WAND_SYM, 1028. #ifdef SPELLS 1029. SPBOOK_SYM, 1030. #endif 1031. RING_SYM, AMULET_SYM, FOOD_SYM, TOOL_SYM, GEM_SYM, GOLD_SYM, ROCK_SYM }; 1032. 1033. char 1034. rndobjsym() 1035. { 1036. return objsyms[rn2(SIZE(objsyms))]; 1037. } 1038. 1039. static const char *hcolors[] = { 1040. "ultraviolet", "infrared", "hot pink", "psychedelic", 1041. "bluish-orange", "reddish-green", "dark white", 1042. "light black", "loud", "salty", "sweet", "sour", 1043. "bitter", "luminescent", "striped", "polka-dotted", 1044. "square", "round", "triangular", "brilliant", 1045. "navy blue", "cerise", "chartreuse", "mauve", 1046. "lime green", "copper", "sea green", "spiral", 1047. "swirly", "blotchy", "fluorescent green", 1048. "burnt orange", "indigo", "amber", "tan", 1049. "sky blue-pink", "lemon yellow", "off-white", 1050. "paisley", "plaid", "argyle", "incandescent"}; 1051. 1052. const char * 1053. hcolor() 1054. { 1055. return hcolors[rn2(SIZE(hcolors))]; 1056. } 1057. 1058. /* Bug: if a level character is the same as an object/monster, it may be 1059. * hilited, because we use a kludge to figure out if a character is an 1060. * object/monster symbol. It's smarter than it was in 2.3, but you 1061. * can still fool it (ex. if an object is in a doorway you have not seen, 1062. * and you look at a map, the '+' will be taken as a spellbook symbol). 1063. * 1064. * The problem is that whenever a portion of the map needs to be redrawn 1065. * (by ^R, after an inventory dropover, after regurgitation...), the 1066. * levl[][].scrsym field is used to redraw the map. A great duplication 1067. * of code would be needed to trace back every scrsym to find out what color 1068. * it should be. 1069. * 1070. * What is really needed is a levl[][].color field; the color be figured 1071. * out at the same time as the screen symbol, and be restored with 1072. * redraws. Unfortunately, as this requires much time and testing, 1073. * it will have to wait for NetHack 3.1. -3. 1074. */ 1075. 1076. static void 1077. hilite(let,typ) 1078. uchar let, typ; 1079. { 1080. 1081. if (let == ' ' 1082. #ifndef MSDOS 1083. || !flags.standout 1084. #endif 1085. ) { 1086. /* don't hilite spaces; it's pointless colorwise, 1087. and also hilites secret corridors and dark areas. -3. */ 1088. g_putch(let); 1089. return; 1090. } 1091. 1092. if (!typ) { 1093. char *isobjct = index(obj_symbols, (char) let); 1094. 1095. if (let == GOLD_SYM) 1096. typ = AT_GLD; 1097. #ifdef MSDOSCOLOR 1098. else if (let == POOL_SYM) 1099. if (HI_BLUE == HI) typ = AT_MAP; 1100. else typ = AT_BLUE; 1101. #endif 1102. else if (isobjct != NULL || let == S_MIMIC_DEF) 1103. /* is an object */ 1104. typ = AT_OBJ; 1105. else if (ismnst((char) let)) 1106. /* is a monster */ 1107. typ = AT_MON; 1108. } 1109. #ifndef MSDOSCOLOR 1110. if (typ == AT_MON) revbeg(); 1111. #else 1112. switch (typ) { 1113. case AT_MON: 1114. xputs(let != S_MIMIC_DEF ? HI_MON : HI_OBJ); 1115. break; 1116. case AT_OBJ: 1117. xputs(let == GOLD_SYM ? HI_GOLD : HI_OBJ); 1118. break; 1119. case AT_MAP: 1120. if (!(typ = (let == POOL_SYM))) 1121. break; 1122. case AT_BLUE: 1123. xputs(HI_BLUE); 1124. break; 1125. case AT_ZAP: 1126. xputs(HI_ZAP); 1127. break; 1128. case AT_RED: 1129. xputs(HI_RED); 1130. break; 1131. case AT_WHITE: 1132. xputs(HI_WHITE); 1133. break; 1134. } 1135. #endif 1136. 1137. g_putch(let); 1138. 1139. #ifdef MSDOSCOLOR 1140. if (typ) xputs(HE); 1141. #else 1142. if (typ == AT_MON) m_end(); 1143. #endif 1144. } 1145. 1146. static boolean 1147. ismnst(let) 1148. char let; 1149. { 1150. register int ct; 1151. register struct permonst *ptr; 1152. 1153. if (let & 0x80) return 0; 1154. if (isalpha(let)) return 1; /* for speed */ 1155. 1156. for (ct = 0 ; ct < NUMMONS; ct++) { 1157. ptr = &mons[ct]; 1158. if(ptr->mlet == let) return 1; 1159. } 1160. #ifdef WORM 1161. if (let == S_WORM_TAIL) return 1; 1162. #endif 1163. return 0; 1164. }