Source:NetHack 3.1.0/engrave.c
From Wikihack
Below is the full text to engrave.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/engrave.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. |
1. /* SCCS Id: @(#)engrave.c 3.1 92/02/25 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #include "lev.h" 7. #include <ctype.h> 8. 9. STATIC_VAR struct engr NEARDATA *head_engr; 10. 11. STATIC_DCL void FDECL(del_engr, (struct engr *)); 12. 13. #ifdef OVLB 14. /* random engravings */ 15. const char *random_mesg[] = { 16. "Elbereth", "ad ae?ar um", 17. "?la? ?as he??", 18. /* take-offs and other famous engravings */ 19. "Owlbreath", "?ala??iel", 20. "?ilroy wa? h?re", 21. "A.S. ->", "<- A.S.", /* Journey to the Center of the Earth */ 22. "Y?u won t get i? up ?he ste?s", /* Adventure */ 23. "Lasc?ate o?ni sp?ranz? o vo? c?'en?rate", /* Inferno */ 24. "Well Come", /* Prisoner */ 25. "W? ap?l???ze for t?e inc?nve??e?ce", /* So Long... */ 26. "S?e you n?xt Wed?esd?y", /* Thriller */ 27. "Fo? a ?ood time c?ll 8?7-53?9", 28. }; 29. 30. const char * 31. random_engraving() 32. { 33. char *rumor, *s; 34. 35. /* a random engraving may come from the "rumors" file, or from the 36. list above */ 37. rumor = getrumor(0); 38. if (rn2(4) && *rumor) { 39. for (s = rumor; *s; s++) 40. if (!rn2(7) && *s != ' ') *s = '?'; 41. if (s[-1] == '.') s[-1] = 0; 42. return (const char *)rumor; 43. } 44. else 45. return random_mesg[rn2(SIZE(random_mesg))]; 46. } 47. #endif /* OVLB */ 48. #ifdef OVL0 49. 50. struct engr * 51. engr_at(x,y) register xchar x,y; { 52. register struct engr *ep = head_engr; 53. while(ep) { 54. if(x == ep->engr_x && y == ep->engr_y) 55. return(ep); 56. ep = ep->nxt_engr; 57. } 58. return((struct engr *) 0); 59. } 60. 61. #ifdef ELBERETH 62. int 63. sengr_at(s,x,y) 64. register const char *s; 65. register xchar x,y; 66. { 67. register struct engr *ep = engr_at(x,y); 68. register char *t; 69. register int n; 70. 71. if(ep && ep->engr_time <= moves) { 72. t = ep->engr_txt; 73. /* 74. if(!strcmp(s,t)) return(1); 75. */ 76. n = strlen(s); 77. while(*t) { 78. if(!strncmp(s,t,n)) return(1); 79. t++; 80. } 81. } 82. return(0); 83. } 84. #endif 85. 86. #endif /* OVL0 */ 87. #ifdef OVL2 88. 89. void 90. u_wipe_engr(cnt) 91. register int cnt; 92. { 93. if(!u.uswallow && !Levitation) 94. wipe_engr_at(u.ux, u.uy, cnt); 95. } 96. 97. #endif /* OVL2 */ 98. #ifdef OVL1 99. 100. void 101. wipe_engr_at(x,y,cnt) register xchar x,y,cnt; { 102. register struct engr *ep = engr_at(x,y); 103. register int lth,pos; 104. char ch; 105. if(ep){ 106. if(ep->engr_type != BURN) { 107. if(ep->engr_type != DUST && ep->engr_type != BLOOD) { 108. cnt = rn2(1 + 50/(cnt+1)) ? 0 : 1; 109. } 110. lth = strlen(ep->engr_txt); 111. if(lth && cnt > 0 ) { 112. while(cnt--) { 113. pos = rn2(lth); 114. if((ch = ep->engr_txt[pos]) == ' ') 115. continue; 116. ep->engr_txt[pos] = (ch != '?') ? '?' : ' '; 117. } 118. } 119. while(lth && ep->engr_txt[lth-1] == ' ') 120. ep->engr_txt[--lth] = 0; 121. while(ep->engr_txt[0] == ' ') 122. ep->engr_txt++; 123. if(!ep->engr_txt[0]) del_engr(ep); 124. } 125. } 126. } 127. 128. #endif /* OVL1 */ 129. #ifdef OVL2 130. 131. void 132. read_engr_at(x,y) 133. register int x,y; 134. { 135. register struct engr *ep = engr_at(x,y); 136. register int sensed = 0; 137. 138. if(ep && ep->engr_txt[0]) { 139. switch(ep->engr_type) { 140. case DUST: 141. if(!Blind) { 142. sensed = 1; 143. pline("Something is written here in the dust."); 144. } 145. break; 146. case ENGRAVE: 147. if(!Blind || !Levitation) { 148. sensed = 1; 149. pline("Something is engraved here on the floor."); 150. } 151. break; 152. case BURN: 153. if(!Blind || !Levitation) { 154. sensed = 1; 155. pline("Some text has been burned into the floor here."); 156. } 157. break; 158. case MARK: 159. if(!Blind) { 160. sensed = 1; 161. pline("There's some graffiti on the floor here."); 162. } 163. break; 164. case BLOOD: 165. /* "It's a message! Scrawled in blood!" 166. * "What's it say?" 167. * "It says... `See you next Wednesday.'" -- Thriller 168. */ 169. if(!Blind) { 170. sensed = 1; 171. You("see a message scrawled in blood here."); 172. } 173. break; 174. default: 175. impossible("Something is written in a very strange way."); 176. sensed = 1; 177. } 178. if (sensed) { 179. You("%s: \"%s\".", 180. (Blind) ? "feel the words" : "read", ep->engr_txt); 181. if(flags.run > 1) nomul(0); 182. } 183. } 184. } 185. 186. #endif /* OVL2 */ 187. #ifdef OVLB 188. 189. void 190. make_engr_at(x,y,s,e_time,e_type) 191. register int x,y; 192. register const char *s; 193. register long e_time; 194. register xchar e_type; 195. { 196. register struct engr *ep; 197. 198. if(ep = engr_at(x,y)) 199. del_engr(ep); 200. ep = newengr(strlen(s) + 1); 201. ep->nxt_engr = head_engr; 202. head_engr = ep; 203. ep->engr_x = x; 204. ep->engr_y = y; 205. ep->engr_txt = (char *)(ep + 1); 206. Strcpy(ep->engr_txt, s); 207. if(strcmp(s, "Elbereth")) exercise(A_WIS, TRUE); 208. ep->engr_time = e_time; 209. ep->engr_type = e_type > 0 ? e_type : rnd(N_ENGRAVE); 210. ep->engr_lth = strlen(s) + 1; 211. } 212. 213. /* 214. * freehand - returns true if player has a free hand 215. */ 216. int 217. freehand() 218. { 219. return(!uwep || !welded(uwep) || 220. (!bimanual(uwep) && (!uarms || !uarms->cursed))); 221. /* if ((uwep && bimanual(uwep)) || 222. (uwep && uarms)) 223. return(0); 224. else 225. return(1);*/ 226. } 227. 228. static const char NEARDATA styluses[] = 229. { ALL_CLASSES, ALLOW_NONE, TOOL_CLASS, WEAPON_CLASS, WAND_CLASS, 230. GEM_CLASS, RING_CLASS, 0 }; 231. 232. /* Mohs' Hardness Scale: 233. * 1 - Talc 6 - Orthoclase 234. * 2 - Gypsum 7 - Quartz 235. * 3 - Calcite 8 - Topaz 236. * 4 - Fluorite 9 - Corundum 237. * 5 - Apatite 10 - Diamond 238. * 239. * Since granite is a igneous rock hardness ~ 7, anything >= 8 should 240. * probably be able to scratch the rock. 241. * Devaluation of less hard gems is not easily possible because obj struct 242. * does not contain individual oc_cost currently. 7/91 243. * 244. * dilithium - ?? * jade - 5-6 (nephrite) 245. * diamond - 10 * turquoise - 5-6 246. * ruby - 9 (corundum) * opal - 5-6 247. * sapphire - 9 (corundum) * iron - 4-5 248. * topaz - 8 * fluorite - 4 249. * emerald - 7.5-8 (beryl) * brass - 3-4 250. * aquamarine - 7.5-8 (beryl) * gold - 2.5-3 251. * garnet - 7.25 (var. 6.5-8) * silver - 2.5-3 252. * agate - 7 (quartz) * copper - 2.5-3 253. * amethyst - 7 (quartz) * amber - 2-2.5 254. * jasper - 7 (quartz) * 255. * onyx - 7 (quartz) * steel - 5-8.5 (usu. weapon) 256. * moonstone - 6 (orthoclase) * 257. */ 258. 259. static const short NEARDATA hard_gems[] = 260. { DIAMOND, RUBY, SAPPHIRE, TOPAZ, EMERALD, AQUAMARINE, GARNET, 0 }; 261. 262. static const char NEARDATA *hard_ring_names[] = 263. {"diamond", "ruby", "sapphire", "emerald", "topaz", ""}; 264. 265. /* return 1 if action took 1 (or more) moves, 0 if error or aborted */ 266. int 267. doengrave() 268. { 269. boolean dengr = FALSE; /* TRUE if we wipe out the current engraving */ 270. boolean doblind = FALSE;/* TRUE if engraving blinds the player */ 271. boolean doknown = FALSE;/* TRUE if we identify the stylus */ 272. boolean eow = FALSE; /* TRUE if we are overwriting oep */ 273. boolean jello = FALSE; /* TRUE if we are engraving in slime */ 274. boolean ptext = TRUE; /* TRUE if we must prompt for engrave text */ 275. boolean teleengr =FALSE;/* TRUE if we move the old engraving */ 276. boolean zapwand = FALSE;/* TRUE if we remove a wand charge */ 277. xchar type = DUST; /* Type of engraving made */ 278. char buf[BUFSZ]; /* Buffer for final/poly engraving text */ 279. char ebuf[BUFSZ]; /* Buffer for initial engraving text */ 280. char qbuf[QBUFSZ]; /* Buffer for query text */ 281. const char *everb; /* Present tense of engraving type */ 282. const char *eloc; /* Where the engraving is (ie dust/floor/...) */ 283. const char *post_engr_text; /* Text displayed after engraving prompt */ 284. register char *sp; /* Place holder for space count of engr text */ 285. register int len; /* # of nonspace chars of new engraving text */ 286. register int maxelen; /* Max allowable length of new engraving text */ 287. register int spct; /* # of spaces in new engraving text */ 288. register struct engr *oep = engr_at(u.ux,u.uy); 289. /* The current engraving */ 290. register struct obj *otmp; /* Object selected with which to engrave */ 291. 292. 293. multi = 0; /* moves consumed */ 294. nomovemsg = (char *)0; /* occupation end message */ 295. 296. buf[0] = (char)0; 297. ebuf[0] = (char)0; 298. post_engr_text = (char *)0; 299. maxelen = BUFSZ - 1; 300. 301. /* Can the adventurer engrave at all? */ 302. 303. if(u.uswallow) { 304. if (is_animal(u.ustuck->data)) { 305. pline("What would you write? \"Jonah was here\"?"); 306. return(0); 307. } else if (is_whirly(u.ustuck->data)) { 308. You("can't reach the ground."); 309. return(0); 310. } else 311. jello = TRUE; 312. } else if (is_lava(u.ux, u.uy)) { 313. You("can't write on the lava!"); 314. return(0); 315. } else if (is_pool(u.ux,u.uy) || IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { 316. You("can't write on the water!"); 317. return(0); 318. } 319. if(Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)/* in bubble */) { 320. You("can't write in thin air!"); 321. return(0); 322. } 323. #ifdef POLYSELF 324. if (cantwield(uasmon)) { 325. You("can't even hold anything!"); 326. return(0); 327. } 328. #endif 329. if (check_capacity(NULL)) return (0); 330. 331. /* One may write with finger, or weapon, or wand, or..., or... 332. * Edited by GAN 10/20/86 so as not to change weapon wielded. 333. */ 334. 335. otmp = getobj(styluses, "write with"); 336. if(!otmp) return(0); /* otmp == zeroobj if fingers */ 337. 338. /* There's no reason you should be able to write with a wand 339. * while both your hands are tied up. 340. */ 341. if (!freehand() && otmp != uwep && !otmp->owornmask) { 342. You("have no free %s to write with!", body_part(HAND)); 343. return(0); 344. } 345. 346. if (jello) { 347. You("tickle %s with your %s.", mon_nam(u.ustuck), 348. (otmp == &zeroobj) ? makeplural(body_part(FINGER)) : 349. xname(otmp)); 350. Your("message dissolves..."); 351. return(0); 352. } 353. if(Levitation && otmp->oclass != WAND_CLASS){ /* riv05!a3 */ 354. You("can't reach the floor!"); 355. return(0); 356. } 357. 358. /* SPFX for items */ 359. 360. switch (otmp->oclass) { 361. default: 362. case AMULET_CLASS: 363. case CHAIN_CLASS: 364. case POTION_CLASS: 365. case GOLD_CLASS: 366. break; 367. 368. case RING_CLASS: 369. /* "diamond" rings and others should work */ 370. { 371. register int i, j; 372. 373. for (i=0, j=strlen(hard_ring_names[i]); j; i++) 374. if ( !strncmp(hard_ring_names[i], 375. OBJ_DESCR(objects[otmp->otyp]), 376. j=strlen(hard_ring_names[i])) ) { 377. type = ENGRAVE; 378. break; 379. } 380. } 381. break; 382. 383. case GEM_CLASS: 384. /* diamonds & other gems should work */ 385. { 386. register int i; 387. 388. for (i=0; hard_gems[i]; i++) 389. if (otmp->otyp == hard_gems[i]) { 390. type = ENGRAVE; 391. break; 392. } 393. } 394. break; 395. 396. /* Objects too large to engrave with */ 397. case BALL_CLASS: 398. case ROCK_CLASS: 399. case ARMOR_CLASS: 400. You("can't engrave with such a large object!"); 401. ptext = FALSE; 402. break; 403. 404. /* Objects too silly to engrave with */ 405. case FOOD_CLASS: 406. case SCROLL_CLASS: 407. case SPBOOK_CLASS: 408. Your("%s would get too dirty.", xname(otmp)); 409. ptext = FALSE; 410. break; 411. 412. case RANDOM_CLASS: /* This should mean fingers */ 413. break; 414. 415. /* The charge is removed from the wand before prompting for 416. * the engraving text, because all kinds of setup decisions 417. * and pre-engraving messages are based upon knowing what type 418. * of engraving the wand is going to do. Also, the player 419. * will have potentially seen "You wrest .." message, and 420. * therefore will know they are using a charge. 421. */ 422. case WAND_CLASS: 423. if (zappable(otmp)) { 424. zapwand = TRUE; 425. if (Levitation) ptext = FALSE; 426. 427. switch (otmp->otyp) { 428. /* DUST wands */ 429. default: 430. break; 431. 432. /* NODIR wands */ 433. case WAN_LIGHT: 434. case WAN_SECRET_DOOR_DETECTION: 435. case WAN_CREATE_MONSTER: 436. case WAN_WISHING: 437. zapnodir(otmp); 438. break; 439. 440. /* IMMEDIATE wands */ 441. /* If wand is "IMMEDIATE", remember to effect the 442. * previous engraving even if turning to dust., 443. */ 444. case WAN_STRIKING: 445. post_engr_text = 446. "The wand unsuccessfully fights your attempt to write!"; 447. break; 448. case WAN_SLOW_MONSTER: 449. if (!Blind) 450. post_engr_text = "The bugs on the ground slow down!"; 451. break; 452. case WAN_SPEED_MONSTER: 453. if (!Blind) 454. post_engr_text = "The bugs on the ground speed up!"; 455. break; 456. case WAN_POLYMORPH: 457. if(oep) { 458. if (!Blind) { 459. type = (xchar)0; /* random */ 460. Strcpy(buf,random_engraving()); 461. } 462. dengr = TRUE; 463. } 464. break; 465. case WAN_NOTHING: 466. case WAN_UNDEAD_TURNING: 467. case WAN_OPENING: 468. case WAN_LOCKING: 469. case WAN_PROBING: 470. break; 471. 472. /* RAY wands */ 473. case WAN_MAGIC_MISSILE: 474. ptext = TRUE; 475. if (!Blind) 476. post_engr_text = 477. "The ground is riddled by bullet holes!"; 478. break; 479. 480. /* can't tell sleep from death - Eric Backus */ 481. case WAN_SLEEP: 482. case WAN_DEATH: 483. if (!Blind) 484. post_engr_text = 485. "The bugs on the ground stop moving!"; 486. break; 487. 488. case WAN_COLD: 489. if (!Blind) 490. post_engr_text = 491. "A few ice cubes drop from the wand."; 492. if(!oep || (oep->engr_type != BURN)) 493. break; 494. case WAN_CANCELLATION: 495. case WAN_MAKE_INVISIBLE: 496. if(oep) { 497. if (!Blind) 498. pline("The engraving on the floor vanishes!"); 499. dengr = TRUE; 500. } 501. break; 502. case WAN_TELEPORTATION: 503. if (oep) { 504. if (!Blind) 505. pline("The engraving on the floor vanishes!"); 506. teleengr = TRUE; 507. } 508. break; 509. 510. /* type = ENGRAVE wands */ 511. case WAN_DIGGING: 512. ptext = TRUE; 513. type = ENGRAVE; 514. if(!objects[otmp->otyp].oc_name_known) { 515. if (flags.verbose) 516. pline("This %s is a wand of digging!", 517. xname(otmp)); 518. doknown = TRUE; 519. } 520. if (!Blind) 521. post_engr_text = "Gravel flies up from the floor."; 522. else 523. post_engr_text = "You hear drilling!"; 524. break; 525. 526. /* type = BURN wands */ 527. case WAN_FIRE: 528. ptext = TRUE; 529. type = BURN; 530. if(!objects[otmp->otyp].oc_name_known) { 531. if (flags.verbose) 532. pline("This %s is a wand of fire!", xname(otmp)); 533. doknown = TRUE; 534. } 535. if (!Blind) 536. post_engr_text = "Flames fly from the wand."; 537. else 538. post_engr_text = "You feel the wand heat up."; 539. break; 540. case WAN_LIGHTNING: 541. ptext = TRUE; 542. type = BURN; 543. if(!objects[otmp->otyp].oc_name_known) { 544. if (flags.verbose) 545. pline("This %s is a wand of lightning!", 546. xname(otmp)); 547. doknown = TRUE; 548. } 549. if (!Blind) { 550. post_engr_text = "Lightning arcs from the wand."; 551. doblind = TRUE; 552. } else 553. post_engr_text = "You hear crackling!"; 554. break; 555. 556. /* type = MARK wands */ 557. /* type = BLOOD wands */ 558. } 559. } else /* end if zappable */ 560. if (Levitation) { 561. You("can't reach the floor!"); 562. return(0); 563. } 564. break; 565. 566. case WEAPON_CLASS: 567. if(is_blade(otmp)) 568. if ((int)otmp->spe > -3) 569. type = ENGRAVE; 570. else 571. Your("%s too dull for engraving.", aobjnam(otmp,"are")); 572. break; 573. 574. case TOOL_CLASS: 575. if(otmp == ublindf) { 576. pline( 577. "That is a bit difficult to engrave with, don't you think?"); 578. return(0); 579. } 580. switch (otmp->otyp) { 581. case MAGIC_MARKER: 582. if (otmp->spe <= 0) 583. Your("marker has dried out."); 584. else 585. type = MARK; 586. break; 587. case TOWEL: 588. /* Can't really engrave with a towel */ 589. ptext = FALSE; 590. if (oep) 591. if ((oep->engr_type == DUST ) || 592. (oep->engr_type == BLOOD) || 593. (oep->engr_type == MARK )) { 594. if (!Blind) 595. You("wipe out the message here."); 596. else 597. Your("%s gets dusty.", xname(otmp)); 598. dengr = TRUE; 599. } else 600. Your("%s can't wipe out this engraving.", 601. xname(otmp)); 602. else 603. Your("%s gets dusty.", xname(otmp)); 604. break; 605. default: 606. break; 607. } 608. break; 609. 610. case VENOM_CLASS: 611. #ifdef WIZARD 612. if (wizard) { 613. pline("Writing a poison pen letter??"); 614. break; 615. } 616. #endif 617. case ILLOBJ_CLASS: 618. impossible("You're engraving with an illegal object!"); 619. break; 620. } 621. 622. /* End of implement setup */ 623. 624. /* Identify stylus */ 625. if (doknown) { 626. makeknown(otmp->otyp); 627. more_experienced(0,10); 628. } 629. 630. if (teleengr) { 631. register int tx,ty; 632. 633. do { 634. tx = rn1(COLNO-3,2); 635. ty = rn2(ROWNO); 636. } while(!goodpos(tx,ty, (struct monst *)0, (struct permonst *)0)); 637. 638. oep->engr_x = tx; 639. oep->engr_y = ty; 640. 641. oep = (struct engr *)0; 642. } 643. 644. if (dengr) { 645. del_engr (oep); 646. oep = (struct engr *)0; 647. } 648. 649. /* Something has changed the engraving here */ 650. if (*buf) { 651. make_engr_at(u.ux, u.uy, buf, moves, type); 652. pline("The engraving now reads: \"%s\".", buf); 653. ptext = FALSE; 654. } 655. 656. if (zapwand && (otmp->spe < 0)) { 657. pline("%s %sturns to dust.", 658. The(xname(otmp)), Blind ? "" : "glows violently, then "); 659. You("are not going to get anywhere trying to write in the dust with your dust."); 660. useup(otmp); 661. ptext = FALSE; 662. } 663. 664. if (!ptext) { /* Early exit for some implements. */ 665. if (Levitation && (otmp->oclass == WAND_CLASS)) 666. You("can't reach the floor!"); 667. return(1); 668. } 669. 670. /* Special effects should have deleted the current engraving (if 671. * possible) by now. 672. */ 673. 674. if (oep) { 675. register char c = 'n'; 676. 677. /* Give player the choice to add to engraving. */ 678. 679. if ( (type == oep->engr_type) && (!Blind || 680. (oep->engr_type == BURN) || (oep->engr_type == ENGRAVE)) ) { 681. c = yn_function("Do you want to add to the current engraving?", 682. ynqchars, 'y'); 683. if (c == 'q') { 684. pline("Never mind."); 685. return(0); 686. } 687. } 688. 689. if (c == 'n' || Blind) 690. 691. if( (oep->engr_type == DUST) || (oep->engr_type == BLOOD) || 692. (oep->engr_type == MARK) ) { 693. if (!Blind) { 694. You("wipe out the message that was %s here.", 695. ((oep->engr_type == DUST) ? "written in the dust" : 696. ((oep->engr_type == BLOOD) ? "scrawled in blood" : 697. "written"))); 698. del_engr(oep); 699. oep = (struct engr *)0; 700. } else 701. /* Don't delete engr until after we *know* we're engraving */ 702. eow = TRUE; 703. } else 704. if ( (type == DUST) || (type == MARK) || (type == BLOOD) ) { 705. You( 706. "cannot wipe out the message that is %s the floor here.", 707. (oep->engr_type == BURN) ? "burned into" : 708. "engraved in"); 709. return(1); 710. } else 711. if ( (type != oep->engr_type) || (c == 'n') ) { 712. if (!Blind || !Levitation) 713. You("will overwrite the current message."); 714. eow = TRUE; 715. } 716. } 717. 718. switch(type){ 719. default: 720. everb = (oep && !eow ? "add to the weird writing on" : 721. "write strangely on"); 722. eloc = "the floor"; 723. break; 724. case DUST: 725. everb = (oep && !eow ? "add to the writing in" : 726. "write in"); 727. eloc = "the dust"; 728. break; 729. case ENGRAVE: 730. everb = (oep && !eow ? "add to the engraving in" : 731. "engrave in"); 732. eloc = "the floor"; 733. break; 734. case BURN: 735. everb = (oep && !eow ? "add to the text burned into" : 736. "burn into"); 737. eloc = "the floor"; 738. break; 739. case MARK: 740. everb = (oep && !eow ? "add to the graffiti on" : 741. "scribble on"); 742. eloc = "the floor"; 743. break; 744. case BLOOD: 745. everb = (oep && !eow ? "add to the scrawl on" : 746. "scrawl on"); 747. eloc = "the floor"; 748. break; 749. } 750. 751. /* Tell adventurer what is going on */ 752. if (otmp != &zeroobj) 753. You("%s %s with %s.", everb, eloc, doname(otmp)); 754. else 755. You("%s %s with your %s.", everb, eloc, 756. makeplural(body_part(FINGER))); 757. 758. /* Prompt for engraving! */ 759. Sprintf(qbuf,"What do you want to %s %s here?", everb, eloc); 760. getlin(qbuf, ebuf); 761. clear_nhwindow(WIN_MESSAGE); 762. 763. /* Mix up engraving if surface or state of mind is unsound. */ 764. /* Original kludge by stewr 870708. modified by njm 910722. */ 765. for (sp = ebuf; *sp; sp++) 766. if ( ((type == DUST || type == BLOOD) && !rn2(25)) || 767. (Blind && !rn2(9)) || (Confusion && !rn2(12)) || 768. (Stunned && !rn2(4)) || (Hallucination && !rn2(1)) ) 769. *sp = '!' + rn2(93); /* ASCII-code only */ 770. 771. /* Count the actual # of chars engraved not including spaces */ 772. len = strlen(ebuf); 773. 774. for (sp = ebuf, spct = 0; *sp; sp++) if (isspace(*sp)) spct++; 775. 776. if ( (len == spct) || index(ebuf, '\033') ) { 777. if (zapwand) { 778. if (!Blind) 779. pline("%s glows, then fades.", The(xname(otmp))); 780. return(1); 781. } else { 782. pline("Never mind."); 783. return(0); 784. } 785. } 786. 787. len -= spct; 788. 789. /* Previous engraving is overwritten */ 790. if (eow) { 791. del_engr(oep); 792. oep = (struct engr *)0; 793. } 794. 795. /* Figure out how long it took to engrave, and if player has 796. * engraved too much. 797. */ 798. switch(type){ 799. default: 800. multi = -(len/10); 801. if (multi) nomovemsg = "You finish your weird engraving."; 802. break; 803. case DUST: 804. multi = -(len/10); 805. if (multi) nomovemsg = "You finish writing in the dust."; 806. break; 807. case ENGRAVE: 808. multi = -(len/10); 809. if ((otmp->oclass == WEAPON_CLASS) && 810. ((otmp->otyp != ATHAME) || otmp->cursed)) { 811. multi = -len; 812. maxelen = ((otmp->spe + 3) * 2) + 1; 813. /* -2 = 3, -1 = 5, 0 = 7, +1 = 9, +2 = 11 814. * Note: this does not allow a +0 anything (except 815. * an athame) to engrave "Elbereth" all at once. 816. * However, you could now engrave "Elb", then 817. * "ere", then "th". 818. */ 819. Your("%s dull.", aobjnam(otmp, "get")); 820. if (len > maxelen) { 821. multi = -maxelen; 822. otmp->spe = -3; 823. } else 824. if (len > 1) otmp->spe -= len >> 1; 825. else otmp->spe -= 1; /* Prevent infinite engraving */ 826. } else 827. if ( (otmp->oclass == RING_CLASS) || 828. (otmp->oclass == GEM_CLASS) ) 829. multi = -len; 830. if (multi) nomovemsg = "You finish engraving."; 831. break; 832. case BURN: 833. multi = -(len/10); 834. if (multi) 835. nomovemsg = 836. "You finish burning your message into the floor."; 837. break; 838. case MARK: 839. multi = -(len/10); 840. if ((otmp->oclass == TOOL_CLASS) && 841. (otmp->otyp == MAGIC_MARKER)) { 842. maxelen = (otmp->spe) * 2; /* one charge / 2 letters */ 843. if (len > maxelen) { 844. Your("marker dries out."); 845. otmp->spe = 0; 846. multi = -(maxelen/10); 847. } else 848. if (len > 1) otmp->spe -= len >> 1; 849. else otmp->spe -= 1; /* Prevent infinite grafitti */ 850. } 851. if (multi) nomovemsg = "You finish defacing the dungeon."; 852. break; 853. case BLOOD: 854. multi = -(len/10); 855. if (multi) nomovemsg = "You finish scrawling."; 856. break; 857. } 858. 859. /* Chop engraving down to size if necessary */ 860. if (len > maxelen) { 861. for (sp = ebuf; (maxelen && *sp); sp++) 862. if (!isspace(*sp)) maxelen--; 863. if (!maxelen && *sp) { 864. *sp = (char)0; 865. if (multi) nomovemsg = "You cannot write any more."; 866. You("only are able to write \"%s\"", ebuf); 867. } 868. } 869. 870. /* Add to existing engraving */ 871. if (oep) Strcpy(buf, oep->engr_txt); 872. 873. (void) strncat(buf, ebuf, (BUFSZ - (int)strlen(buf) - 1)); 874. 875. make_engr_at(u.ux, u.uy, buf, (moves - multi), type); 876. 877. if (post_engr_text) pline(post_engr_text); 878. 879. if (doblind) { 880. You("are blinded by the flash!"); 881. make_blinded((long)rnd(50),FALSE); 882. } 883. 884. return(1); 885. } 886. 887. void 888. save_engravings(fd, mode) 889. int fd, mode; 890. { 891. register struct engr *ep = head_engr; 892. register struct engr *ep2; 893. #ifdef GCC_WARN 894. static long nulls[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 895. #endif 896. while(ep) { 897. ep2 = ep->nxt_engr; 898. if(ep->engr_lth && ep->engr_txt[0]){ 899. bwrite(fd, (genericptr_t)&(ep->engr_lth), sizeof(ep->engr_lth)); 900. bwrite(fd, (genericptr_t)ep, sizeof(struct engr) + ep->engr_lth); 901. } 902. if (mode & FREE_SAVE) 903. dealloc_engr(ep); 904. ep = ep2; 905. } 906. 907. #ifdef GCC_WARN 908. bwrite(fd, (genericptr_t)nulls, sizeof(unsigned)); 909. #else 910. bwrite(fd, (genericptr_t)nul, sizeof(unsigned)); 911. #endif 912. 913. if (mode & FREE_SAVE) 914. head_engr = 0; 915. } 916. 917. void 918. rest_engravings(fd) int fd; { 919. register struct engr *ep; 920. unsigned lth; 921. head_engr = 0; 922. while(1) { 923. mread(fd, (genericptr_t) <h, sizeof(unsigned)); 924. if(lth == 0) return; 925. ep = newengr(lth); 926. mread(fd, (genericptr_t) ep, sizeof(struct engr) + lth); 927. ep->nxt_engr = head_engr; 928. head_engr = ep; 929. ep->engr_txt = (char *) (ep + 1); /* Andreas Bormann */ 930. /* mark as finished for bones levels -- no problem for 931. * normal levels as the player must have finished engraving 932. * to be able to move again */ 933. ep->engr_time = moves; 934. } 935. } 936. 937. STATIC_OVL void 938. del_engr(ep) register struct engr *ep; { 939. register struct engr *ept; 940. if(ep == head_engr) 941. head_engr = ep->nxt_engr; 942. else { 943. for(ept = head_engr; ept; ept = ept->nxt_engr) { 944. if(ept->nxt_engr == ep) { 945. ept->nxt_engr = ep->nxt_engr; 946. goto fnd; 947. } 948. } 949. impossible("Error in del_engr?"); 950. return; 951. fnd: ; 952. } 953. dealloc_engr(ep); 954. } 955. 956. #endif /* OVLB */ 957. 958. /*engrave.c*/
