Source:NetHack 2.3e/objnam.c
Jump to navigation
Jump to search
Below is the full text to objnam.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: @(#)objnam.c 2.3 88/01/21 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. #include "hack.h" 5. #define Sprintf (void) sprintf 6. #define Strcat (void) strcat 7. #define Strcpy (void) strcpy 8. #define PREFIX 15 9. extern char *eos(); 10. extern int bases[]; 11. 12. char * 13. strprepend(s,pref) register char *s, *pref; { 14. register int i = strlen(pref); 15. if(i > PREFIX) { 16. pline("WARNING: prefix too short."); 17. return(s); 18. } 19. s -= i; 20. (void) strncpy(s, pref, i); /* do not copy trailing 0 */ 21. return(s); 22. } 23. 24. char * 25. sitoa(a) int a; { 26. static char buf[13]; 27. Sprintf(buf, (a < 0) ? "%d" : "+%d", a); 28. return(buf); 29. } 30. 31. char * 32. typename(otyp) 33. register int otyp; 34. { 35. static char buf[BUFSZ]; 36. register struct objclass *ocl = &objects[otyp]; 37. register char *an = ocl->oc_name; 38. register char *dn = ocl->oc_descr; 39. register char *un = ocl->oc_uname; 40. register int nn = ocl->oc_name_known; 41. switch(ocl->oc_olet) { 42. case POTION_SYM: 43. Strcpy(buf, "potion"); 44. break; 45. case SCROLL_SYM: 46. Strcpy(buf, "scroll"); 47. break; 48. case WAND_SYM: 49. Strcpy(buf, "wand"); 50. break; 51. #ifdef SPELLS 52. case SPBOOK_SYM: 53. Strcpy(buf, "spellbook"); 54. break; 55. #endif 56. case RING_SYM: 57. Strcpy(buf, "ring"); 58. break; 59. default: 60. if(nn) { 61. Strcpy(buf, an); 62. if(otyp >= TURQUOISE && otyp <= JADE) 63. Strcat(buf, " stone"); 64. if(un) 65. Sprintf(eos(buf), " called %s", un); 66. if(dn) 67. Sprintf(eos(buf), " (%s)", dn); 68. } else { 69. Strcpy(buf, dn ? dn : an); 70. if(ocl->oc_olet == GEM_SYM) 71. Strcat(buf, " gem"); 72. if(un) 73. Sprintf(eos(buf), " called %s", un); 74. } 75. return(buf); 76. } 77. /* here for ring/scroll/potion/wand */ 78. if(nn) 79. Sprintf(eos(buf), " of %s", an); 80. if(un) 81. Sprintf(eos(buf), " called %s", un); 82. if(dn) 83. Sprintf(eos(buf), " (%s)", dn); 84. return(buf); 85. } 86. 87. char * 88. xname(obj) 89. register struct obj *obj; 90. { 91. static char bufr[BUFSZ]; 92. register char *buf = &(bufr[PREFIX]); /* leave room for "17 -3 " */ 93. register int nn = objects[obj->otyp].oc_name_known; 94. register char *an = objects[obj->otyp].oc_name; 95. register char *dn = objects[obj->otyp].oc_descr; 96. register char *un = objects[obj->otyp].oc_uname; 97. register int pl = (obj->quan != 1); 98. #ifdef KAA 99. if(!obj->dknown && !Blind && obj->olet != WEAPON_SYM) obj->dknown=1; 100. #else 101. if(!obj->dknown && !Blind) obj->dknown = 1; /* %% doesnt belong here */ 102. #endif 103. switch(obj->olet) { 104. case AMULET_SYM: 105. Strcpy(buf, (obj->spe < 0 && obj->known) 106. ? "cheap plastic imitation of the " : ""); 107. Strcat(buf,"Amulet of Yendor"); 108. break; 109. case TOOL_SYM: 110. if(!nn) { 111. Strcpy(buf, dn); 112. break; 113. } 114. Strcpy(buf,an); 115. break; 116. case FOOD_SYM: 117. if(obj->otyp == DEAD_HOMUNCULUS && pl) { 118. pl = 0; 119. Strcpy(buf, "dead homunculi"); 120. break; 121. } 122. /* fungis ? */ 123. #ifdef KAA /* The fungus mistake was a D&D holdover. */ 124. if(obj->otyp == DEAD_VIOLET_FUNGUS && pl) { 125. pl = 0; 126. Strcpy(buf, "dead violet fungi"); 127. break; 128. } 129. #endif 130. /* fall into next case */ 131. case WEAPON_SYM: 132. if(obj->otyp == WORM_TOOTH && pl) { 133. pl = 0; 134. Strcpy(buf, "worm teeth"); 135. break; 136. } 137. if(obj->otyp == CRYSKNIFE && pl) { 138. pl = 0; 139. Strcpy(buf, "crysknives"); 140. break; 141. } 142. /* fall into next case */ 143. case ARMOR_SYM: 144. case CHAIN_SYM: 145. case ROCK_SYM: 146. Strcpy(buf,an); 147. break; 148. case BALL_SYM: 149. Sprintf(buf, "%sheavy iron ball", 150. (obj->owt > objects[obj->otyp].oc_weight) ? "very " : ""); 151. break; 152. case POTION_SYM: 153. if(nn || un || !obj->dknown) { 154. Strcpy(buf, "potion"); 155. if(pl) { 156. pl = 0; 157. Strcat(buf, "s"); 158. } 159. if(!obj->dknown) break; 160. if(un) { 161. Strcat(buf, " called "); 162. Strcat(buf, un); 163. } else { 164. Strcat(buf, " of "); 165. Strcat(buf, an); 166. } 167. } else { 168. Strcpy(buf, dn); 169. Strcat(buf, " potion"); 170. } 171. break; 172. case SCROLL_SYM: 173. Strcpy(buf, "scroll"); 174. if(pl) { 175. pl = 0; 176. Strcat(buf, "s"); 177. } 178. if(!obj->dknown) break; 179. if(nn) { 180. Strcat(buf, " of "); 181. Strcat(buf, an); 182. } else if(un) { 183. Strcat(buf, " called "); 184. Strcat(buf, un); 185. } else { 186. Strcat(buf, " labeled "); 187. Strcat(buf, dn); 188. } 189. break; 190. case WAND_SYM: 191. if(!obj->dknown) 192. Sprintf(buf, "wand"); 193. else if(nn) 194. Sprintf(buf, "wand of %s", an); 195. else if(un) 196. Sprintf(buf, "wand called %s", un); 197. else 198. Sprintf(buf, "%s wand", dn); 199. break; 200. #ifdef SPELLS 201. case SPBOOK_SYM: 202. if(!obj->dknown) 203. Sprintf(buf, "spellbook"); 204. else if(nn) 205. Sprintf(buf, "spellbook of %s", an); 206. else if(un) 207. Sprintf(buf, "spellbook called %s", un); 208. else 209. Sprintf(buf, "%s spellbook", dn); 210. break; 211. #endif 212. case RING_SYM: 213. if(!obj->dknown) 214. Sprintf(buf, "ring"); 215. else if(nn) 216. Sprintf(buf, "ring of %s", an); 217. else if(un) 218. Sprintf(buf, "ring called %s", un); 219. else 220. Sprintf(buf, "%s ring", dn); 221. break; 222. case GEM_SYM: 223. if(!obj->dknown) { 224. Strcpy(buf, "gem"); 225. break; 226. } 227. if(!nn) { 228. #ifdef KAA 229. if(un) { 230. if (!pl) Sprintf(buf,"gem called %s",un); 231. else Sprintf(buf,"gems called %s",un); 232. pl=0; 233. } else 234. #endif 235. Sprintf(buf, "%s gem", dn); 236. break; 237. } 238. Strcpy(buf, an); 239. if(obj->otyp >= TURQUOISE && obj->otyp <= JADE) 240. Strcat(buf, " stone"); 241. break; 242. default: 243. Sprintf(buf,"glorkum %c (0%o) %u %d", 244. obj->olet,obj->olet,obj->otyp,obj->spe); 245. } 246. if(pl) { 247. register char *p; 248. 249. for(p = buf; *p; p++) { 250. if(!strncmp(" of ", p, 4)) { 251. /* pieces of, cloves of, lumps of */ 252. register int c1, c2 = 's'; 253. 254. do { 255. c1 = c2; c2 = *p; *p++ = c1; 256. } while(c1); 257. goto nopl; 258. } 259. } 260. p = eos(buf)-1; 261. if(*p == 's' || *p == 'z' || *p == 'x' || 262. (*p == 'h' && p[-1] == 's')) 263. Strcat(buf, "es"); /* boxes */ 264. else if(*p == 'y' && !index(vowels, p[-1])) 265. Strcpy(p, "ies"); /* rubies, zruties */ 266. else 267. Strcat(buf, "s"); 268. } 269. nopl: 270. if(obj->onamelth) { 271. Strcat(buf, " named "); 272. Strcat(buf, ONAME(obj)); 273. } 274. return(buf); 275. } 276. 277. char * 278. doname(obj) 279. register struct obj *obj; 280. { 281. char prefix[PREFIX]; 282. register char *bp = xname(obj); 283. if(obj->quan != 1) 284. Sprintf(prefix, "%u ", obj->quan); 285. else 286. Strcpy(prefix, "a "); 287. if((obj->cursed && obj->known)) 288. Strcat(prefix, "cursed "); 289. switch(obj->olet) { 290. case AMULET_SYM: 291. if(strncmp(bp, "cheap ", 6)) 292. Strcpy(prefix, "the "); 293. break; 294. case ARMOR_SYM: 295. if(obj->owornmask & W_ARMOR) 296. Strcat(bp, " (being worn)"); 297. /* fall into next case */ 298. case WEAPON_SYM: 299. if(obj->known) { 300. #ifdef KAA 301. /* dknown is special for weapons */ 302. if(obj->dknown && obj->olet == WEAPON_SYM) 303. Strcat(prefix,"blessed "); 304. #endif 305. Strcat(prefix, sitoa(obj->spe)); 306. Strcat(prefix, " "); 307. } 308. break; 309. #ifdef MARKER 310. case TOOL_SYM: /* temp. hack by GAN 11/18/86 */ 311. if(obj->owornmask & W_TOOL) { /* blindfold or badge */ 312. Strcat(bp, " (being worn)"); 313. break; 314. } 315. if(!(obj->otyp == MAGIC_MARKER || obj->otyp == LAMP)) break; 316. /* if marker or lamp fall trough to show charges */ 317. #endif 318. case WAND_SYM: 319. if(obj->known) 320. Sprintf(eos(bp), " (%d)", obj->spe); 321. break; 322. case RING_SYM: 323. if(obj->owornmask & W_RINGR) Strcat(bp, " (on right "); 324. if(obj->owornmask & W_RINGL) Strcat(bp, " (on left "); 325. if(obj->owornmask & W_RING) { 326. if (humanoid(u.usym)) Strcat(bp, "hand)"); 327. else Strcat(bp, "paw)"); 328. } 329. if(obj->known && (objects[obj->otyp].bits & SPEC)) { 330. Strcat(prefix, sitoa(obj->spe)); 331. Strcat(prefix, " "); 332. } 333. break; 334. } 335. if(obj->owornmask & W_WEP) { 336. Strcat(bp, " (weapon in "); 337. if (humanoid(u.usym)) Strcat(bp, "hand)"); 338. else Strcat(bp, "paw)"); 339. } 340. if(obj->unpaid) 341. Strcat(bp, " (unpaid)"); 342. if(!strcmp(prefix, " a ") && index(vowels, *bp)) 343. Strcpy(prefix, " an "); 344. bp = strprepend(bp, prefix); 345. return(bp); 346. } 347. 348. /* used only in fight.c (thitu) */ 349. setan(str,buf) 350. register char *str,*buf; 351. { 352. if(index(vowels,*str)) 353. Sprintf(buf, "an %s", str); 354. else 355. Sprintf(buf, "a %s", str); 356. } 357. 358. char * 359. aobjnam(otmp,verb) register struct obj *otmp; register char *verb; { 360. register char *bp = xname(otmp); 361. char prefix[PREFIX]; 362. if(otmp->quan != 1) { 363. Sprintf(prefix, "%u ", otmp->quan); 364. bp = strprepend(bp, prefix); 365. } 366. 367. if(verb) { 368. /* verb is given in plural (i.e., without trailing s) */ 369. Strcat(bp, " "); 370. if(otmp->quan != 1) 371. Strcat(bp, verb); 372. else if(!strcmp(verb, "are")) 373. Strcat(bp, "is"); 374. else { 375. Strcat(bp, verb); 376. Strcat(bp, "s"); 377. } 378. } 379. return(bp); 380. } 381. 382. char * 383. Doname(obj) 384. register struct obj *obj; 385. { 386. register char *s = doname(obj); 387. 388. if('a' <= *s && *s <= 'z') *s -= ('a' - 'A'); 389. return(s); 390. } 391. 392. char *wrp[] = { "wand", "ring", "potion", "scroll", "gem" 393. #ifdef SPELLS 394. , "spellbook" 395. #endif 396. }; 397. char wrpsym[] = { WAND_SYM, RING_SYM, POTION_SYM, SCROLL_SYM, GEM_SYM 398. #ifdef SPELLS 399. , SPBOOK_SYM 400. #endif 401. }; 402. 403. struct obj * 404. readobjnam(bp) register char *bp; { 405. register char *p; 406. register int i; 407. int cnt, spe, spesgn, typ, heavy; 408. char let; 409. char *un, *dn, *an; 410. #ifdef KAA 411. int blessed=0; 412. #endif 413. /* int the = 0; char *oname = 0; */ 414. cnt = spe = spesgn = typ = heavy = 0; 415. let = 0; 416. an = dn = un = 0; 417. for(p = bp; *p; p++) /* set the string to lower case */ 418. if('A' <= *p && *p <= 'Z') *p += 'a'-'A'; 419. if(!strncmp(bp, "the ", 4)){ 420. /* the = 1; */ 421. bp += 4; 422. } else if(!strncmp(bp, "an ", 3)){ 423. cnt = 1; 424. bp += 3; 425. } else if(!strncmp(bp, "a ", 2)){ 426. cnt = 1; 427. bp += 2; 428. } 429. if(!cnt && digit(*bp)){ 430. cnt = atoi(bp); 431. while(digit(*bp)) bp++; 432. while(*bp == ' ') bp++; 433. } 434. if(!cnt) cnt = 1; /* %% what with "gems" etc. ? */ 435. #ifdef KAA 436. if(!strncmp(bp, "blessed ",8)) { 437. blessed=1; 438. bp += 8; 439. } 440. #endif 441. if(*bp == '+' || *bp == '-'){ 442. spesgn = (*bp++ == '+') ? 1 : -1; 443. spe = atoi(bp); 444. while(digit(*bp)) bp++; 445. while(*bp == ' ') bp++; 446. } else { 447. p = rindex(bp, '('); 448. if(p) { 449. if(p > bp && p[-1] == ' ') p[-1] = 0; 450. else *p = 0; 451. p++; 452. spe = atoi(p); 453. while(digit(*p)) p++; 454. if(strcmp(p, ")")) spe = 0; 455. else spesgn = 1; 456. } 457. } 458. /* now we have the actual name, as delivered by xname, say 459. green potions called whisky 460. scrolls labeled "QWERTY" 461. egg 462. dead zruties 463. fortune cookies 464. very heavy iron ball named hoei 465. wand of wishing 466. elven cloak 467. */ 468. for(p = bp; *p; p++) if(!strncmp(p, " named ", 7)) { 469. *p = 0; 470. /* oname = p+7; */ 471. } 472. for(p = bp; *p; p++) if(!strncmp(p, " called ", 8)) { 473. *p = 0; 474. un = p+8; 475. } 476. for(p = bp; *p; p++) if(!strncmp(p, " labeled ", 9)) { 477. *p = 0; 478. dn = p+9; 479. } 480. 481. /* first change to singular if necessary */ 482. if(cnt != 1) { 483. /* find "cloves of garlic", "worthless pieces of blue glass" */ 484. for(p = bp; *p; p++) if(!strncmp(p, "s of ", 5)){ 485. while(*p = p[1]) p++; 486. goto sing; 487. } 488. /* remove -s or -es (boxes) or -ies (rubies, zruties) */ 489. p = eos(bp); 490. if(p[-1] == 's') { 491. if(p[-2] == 'e') { 492. if(p[-3] == 'i') { 493. #ifdef KAA 494. if(!strcmp(p-7, "cookies") || !strcmp(p-4, "pies")) 495. #else 496. if(!strcmp(p-7, "cookies")) 497. #endif 498. goto mins; 499. Strcpy(p-3, "y"); 500. goto sing; 501. } 502. 503. /* note: cloves / knives from clove / knife */ 504. if(!strcmp(p-6, "knives")) { 505. Strcpy(p-3, "fe"); 506. goto sing; 507. } 508. 509. /* note: nurses, axes but boxes */ 510. if(!strcmp(p-5, "boxes")) { 511. p[-2] = 0; 512. goto sing; 513. } 514. } 515. mins: 516. p[-1] = 0; 517. } else { 518. if(!strcmp(p-9, "homunculi") 519. #ifdef KAA 520. || !strcmp(p-5, "fungi") 521. #endif 522. ) { 523. Strcpy(p-1, "us"); /* !! makes string longer */ 524. goto sing; 525. } 526. if(!strcmp(p-5, "teeth")) { 527. Strcpy(p-5, "tooth"); 528. goto sing; 529. } 530. /* here we cannot find the plural suffix */ 531. } 532. } 533. sing: 534. if(!strcmp(bp, "amulet of yendor")) { 535. typ = AMULET_OF_YENDOR; 536. goto typfnd; 537. } 538. if(!strcmp(bp, "ring mail")){ /* Note: ring mail is not a ring ! */ 539. let = ARMOR_SYM; 540. an = bp; 541. goto srch; 542. } 543. 544. #ifdef SHIRT 545. if (!strcmp(bp, "hawaiian shirt")) { 546. *(bp) = 'H'; 547. an = bp; 548. goto srch; 549. } 550. #endif 551. p = eos(bp); 552. #if defined(KOPS) && !defined(KJSMODS) 553. if (!strcmp(p-3, "kop")) { 554. *(p-3) = 'K'; 555. an = bp; 556. goto srch; 557. } 558. #endif 559. for(i = 0; i < sizeof(wrpsym); i++) { 560. register int j = strlen(wrp[i]); 561. if(!strncmp(bp, wrp[i], j)){ 562. let = wrpsym[i]; 563. bp += j; 564. if(!strncmp(bp, " of ", 4)) an = bp+4; 565. /* else if(*bp) ?? */ 566. goto srch; 567. } 568. if(!strcmp(p-j, wrp[i])){ 569. let = wrpsym[i]; 570. p -= j; 571. *p = 0; 572. if(p[-1] == ' ') p[-1] = 0; 573. dn = bp; 574. goto srch; 575. } 576. } 577. if(!strcmp(p-6, " stone")){ 578. p[-6] = 0; 579. let = GEM_SYM; 580. an = bp; 581. goto srch; 582. } 583. #ifdef KAA 584. if(!strcmp(p-10, "gold piece") || !strcmp(p-7, "zorkmid")) { 585. if (cnt > 5000) cnt=5000; 586. if (cnt < 1) cnt=1; 587. pline("%d gold piece%s.", cnt, cnt==1 ? "" : "s"); 588. u.ugold += cnt; 589. flags.botl=1; 590. return(0); 591. } 592. #endif 593. if(!strcmp(bp, "very heavy iron ball")){ 594. heavy = 1; 595. typ = HEAVY_IRON_BALL; 596. goto typfnd; 597. } 598. an = bp; 599. srch: 600. if(!an && !dn && !un) 601. goto any; 602. i = 1; 603. if(let) i = bases[letindex(let)]; 604. while(i <= NROFOBJECTS && (!let || objects[i].oc_olet == let)){ 605. register char *zn = objects[i].oc_name; 606. 607. if(!zn) goto nxti; 608. if(an && strcmp(an, zn)) 609. goto nxti; 610. if(dn && (!(zn = objects[i].oc_descr) || strcmp(dn, zn))) 611. goto nxti; 612. if(un && (!(zn = objects[i].oc_uname) || strcmp(un, zn))) 613. goto nxti; 614. typ = i; 615. goto typfnd; 616. nxti: 617. i++; 618. } 619. any: 620. if(!let) let = wrpsym[rn2(sizeof(wrpsym))]; 621. typ = probtype(let); 622. typfnd: 623. { register struct obj *otmp; 624. extern struct obj *mksobj(); 625. let = objects[typ].oc_olet; 626. otmp = mksobj(typ); 627. if(heavy) otmp->owt += 15; 628. 629. if(cnt > 0 && index("%?!*)", let) && 630. (cnt < rnd(6) || 631. #ifdef WIZARD 632. wizard || 633. #endif 634. #ifdef KAA 635. (let == WEAPON_SYM && typ <= ROCK && cnt <= 20) 636. #else 637. (let == WEAPON_SYM && typ <= ROCK && cnt < 20) 638. #endif 639. )) otmp->quan = cnt; 640. 641. if(spe > rnd(5) && spe > otmp->spe) { 642. #ifdef WIZARD 643. if(!wizard) 644. #endif 645. spe = 0; 646. } else if(let == WAND_SYM) 647. spe = otmp->spe; 648. #ifdef KAA 649. if(let==WEAPON_SYM && blessed) { 650. if(u.uluck < 0) otmp->cursed=1; 651. else otmp->dknown=1; 652. } 653. #endif 654. if(spe > 2 && u.uluck < 0) 655. spesgn = -1; 656. if(let != WAND_SYM && spesgn == -1) 657. spe = -spe; 658. if(let == BALL_SYM) 659. spe = 0; 660. else if(let == AMULET_SYM) 661. spe = -1; 662. else if(typ == WAN_WISHING && rn2(10)) 663. spe = (rn2(10) ? -1 : 0); 664. #ifdef MARKER 665. else if(typ == MAGIC_MARKER) 666. spe = rn1(50,50); 667. #endif 668. else if(typ == LAMP) 669. spe = rnd(10); 670. else if(typ == MAGIC_LAMP) 671. spe = 1; 672. otmp->spe = spe; 673. 674. if(spesgn == -1) 675. otmp->cursed = 1; 676. 677. return(otmp); 678. } 679. }