Source:NetHack 2.3e/makedefs.c
Revision as of 22:59, 3 July 2024 by Furey (talk | contribs) (Delete link-to-particular-source instructions. Source code covers that now. "the latest release" -> "newer releases".)
Below is the full text to makedefs.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. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2. /* makedefs.c - NetHack version 2.3 */ 3. 4. static char SCCS_Id[] = "@(#)makedefs.c 2.3\t88/02/18"; 5. 6. #include <stdio.h> 7. #include "config.h" 8. 9. #ifdef MSDOS 10. #undef exit 11. #define freopen _freopen 12. #define alloc malloc 13. #define RDMODE "r" 14. #define WRMODE "w" 15. #else 16. #define RDMODE "r+" 17. #define WRMODE "w+" 18. #endif 19. 20. /* construct definitions of object constants */ 21. #define OBJ_FILE "objects.h" 22. #define ONAME_FILE "onames.h" 23. #define TRAP_FILE "trap.h" 24. #define DATE_FILE "date.h" 25. #define RUMOR_FILE "rumors" 26. #define DATA_FILE "data" 27. 28. char inline[256], outline[256]; 29. 30. main(argc, argv) 31. int argc; 32. char *argv[]; 33. { 34. char *option; 35. 36. if(argc == 2) { 37. option = argv[1]; 38. switch (option[1]) { 39. 40. case 'o': 41. case 'O': do_objs(); 42. break; 43. case 't': 44. case 'T': do_traps(); 45. break; 46. case 'r': 47. case 'R': do_rumors(); 48. break; 49. 50. case 'd': do_data(); 51. break; 52. 53. case 'D': do_date(); 54. break; 55. default: 56. fprintf(stderr, "Unknown option '%c'.\n", option[1]); 57. exit(1); 58. } 59. exit(0); 60. } else fprintf(stderr, "Bad arg count (%d).\n", argc-1); 61. exit(1); 62. } 63. 64. do_traps() { 65. int ntrap, getpid(); 66. char tmpfile[30]; 67. FILE *freopen(); 68. 69. sprintf(tmpfile, "makedefs.%d", getpid()); 70. if(freopen(tmpfile, WRMODE, stdout) == NULL) { 71. 72. perror(tmpfile); 73. exit(1); 74. } 75. if(freopen(TRAP_FILE, RDMODE, stdin) == NULL) { 76. 77. perror(TRAP_FILE); 78. exit(1); 79. } 80. 81. while(gets(inline) != NULL) { 82. 83. puts(inline); 84. if(!strncmp(inline, "/* DO NOT REMOVE THIS LINE */", 29)) break; 85. } 86. ntrap = 10; 87. printf("\n"); 88. #ifdef NEWTRAPS 89. printf("#define\tMGTRP\t\t%d\n", ntrap++); 90. printf("#define\tSQBRD\t\t%d\n", ntrap++); 91. #endif 92. #ifdef SPIDERS 93. printf("#define\tWEB\t\t%d\n", ntrap++); 94. #endif 95. #ifdef NEWCLASS 96. printf("#define\tSPIKED_PIT\t%d\n", ntrap++); 97. printf("#define\tLEVEL_TELEP\t%d\n", ntrap++); 98. #endif 99. #ifdef SPELLS 100. printf("#define\tANTI_MAGIC\t%d\n", ntrap++); 101. #endif 102. #ifdef KAA 103. printf("#define\tRUST_TRAP\t%d\n", ntrap++); 104. # ifdef RPH 105. printf("#define\tPOLY_TRAP\t%d\n", ntrap++); 106. # endif 107. #endif 108. #ifdef SAC 109. printf("#define\tLANDMINE\t%d\n", ntrap++); 110. #endif /* SAC */ 111. printf("\n#define\tTRAPNUM\t%d\n", ntrap); 112. fclose(stdin); 113. fclose(stdout); 114. #ifdef MSDOS 115. remove(TRAP_FILE); 116. #endif 117. rename(tmpfile, TRAP_FILE); 118. } 119. 120. 121. struct hline { 122. struct hline *next; 123. char *line; 124. } *f_line; 125. 126. do_rumors(){ 127. struct hline *c_line; 128. char infile[30]; 129. FILE *freopen(); 130. 131. if(freopen(RUMOR_FILE, WRMODE, stdout) == NULL) { 132. 133. perror(RUMOR_FILE); 134. exit(1); 135. } 136. #ifdef MSDOS 137. sprintf(infile, "%s.bas", RUMOR_FILE); 138. #else 139. sprintf(infile, "%s.base", RUMOR_FILE); 140. #endif 141. if(freopen(infile, RDMODE, stdin) == NULL) { 142. 143. perror(infile); 144. exit(1); 145. } 146. 147. while(gets(inline) != NULL) puts(inline); 148. 149. #ifdef KAA 150. sprintf(infile, "%s.kaa", RUMOR_FILE); 151. if(freopen(infile, RDMODE, stdin) == NULL) perror(infile); 152. 153. while(gets(inline) != NULL) puts(inline); 154. #endif 155. 156. #ifdef NEWCLASS 157. sprintf(infile, "%s.mrx", RUMOR_FILE); 158. if(freopen(infile, RDMODE, stdin) == NULL) perror(infile); 159. 160. while(gets(inline) != NULL) puts(inline); 161. #endif 162. fclose(stdin); 163. fclose(stdout); 164. } 165. 166. do_date(){ 167. int getpid(); 168. long clock, time(); 169. char tmpfile[30], cbuf[30], *c, *ctime(); 170. FILE *freopen(); 171. 172. sprintf(tmpfile, "makedefs.%d", getpid()); 173. if(freopen(tmpfile, WRMODE, stdout) == NULL) { 174. 175. perror(tmpfile); 176. exit(1); 177. } 178. if(freopen(DATE_FILE, RDMODE, stdin) == NULL) { 179. 180. perror(DATE_FILE); 181. exit(1); 182. } 183. 184. while(gets(inline) != NULL) { 185. 186. if(!strncmp(inline, "char datestring[] = ", 20)) break; 187. puts(inline); 188. } 189. time(&clock); 190. strcpy(cbuf, ctime(&clock)); 191. for(c = cbuf; *c != '\n'; c++); *c = 0; /* strip off the '\n' */ 192. printf("char datestring[] = %c%s%c;\n", '"', cbuf, '"'); 193. 194. fclose(stdin); 195. fclose(stdout); 196. #ifdef MSDOS 197. remove(DATE_FILE); 198. #endif 199. rename(tmpfile, DATE_FILE); 200. } 201. 202. do_data(){ 203. int getpid(); 204. char tmpfile[30]; 205. FILE *freopen(); 206. 207. sprintf(tmpfile, "%s.base", DATA_FILE); 208. if(freopen(tmpfile, RDMODE, stdin) == NULL) { 209. 210. perror(tmpfile); 211. exit(1); 212. } 213. if(freopen(DATA_FILE, WRMODE, stdout) == NULL) { 214. 215. perror(DATA_FILE); 216. exit(1); 217. } 218. 219. while(gets(inline) != NULL) { 220. #ifdef KOPS 221. if(!strcmp(inline, "K a kobold")) 222. printf("K\ta Keystone Kop\n"); 223. else 224. #endif 225. #ifdef KAA 226. if(!strcmp(inline, "Q a quasit")) 227. printf("Q\ta quantum mechanic\n"); 228. else 229. #endif 230. #ifdef ROCKMOLE 231. if(!strcmp(inline, "r a giant rat")) 232. printf("r\ta rockmole\n"); 233. else 234. #endif 235. #ifdef SPIDERS 236. if(!strcmp(inline, "s a scorpion")) 237. printf("s\ta giant spider\n"); 238. else if (!strcmp(inline, "\" an amulet")) 239. printf("\"\tan amulet (or a web)\n"); 240. else 241. #endif 242. #ifdef SINKS 243. if (!strcmp(inline, "# a corridor")) 244. printf("#\ta corridor (or a kitchen sink)\n"); 245. else 246. #endif 247. #ifdef SPELLS 248. if (!strcmp(inline, "+ a door")) 249. printf("+\ta door (or a spell book)\n"); 250. else 251. #endif 252. #ifdef FOUNTAINS 253. if(!strcmp(inline, "} water filled area")) { 254. puts(inline); 255. printf("{\ta fountain\n"); 256. } else 257. #endif 258. #ifdef NEWCLASS 259. if(!strcmp(inline, "^ a trap")) { 260. puts(inline); 261. printf("\\\tan opulent throne.\n"); 262. } else 263. #endif 264. puts(inline); 265. } 266. #ifdef SAC 267. printf("3\ta soldier;\n"); 268. printf("\tThe soldiers of Yendor are well-trained in the art of war,\n"); 269. printf("\tmany trained by the wizard himself. Some say the soldiers\n"); 270. printf("\tare explorers who were unfortunate enough to be captured,\n"); 271. printf("\tand put under the wizard's spell. Those who have survived\n"); 272. printf("\tencounters with soldiers say they travel together in\n"); 273. printf("\tplatoons, and are fierce fighters. Because of the load of\n"); 274. printf("\ttheir combat gear, however, one can usually run away from\n"); 275. printf("\tthem, and doing so is considered a wise thing.\n"); 276. #endif 277. #ifdef RPH 278. printf("8\tthe medusa;\n"); 279. printf("\tThis hideous creature from ancient Greek myth was the doom\n"); 280. printf("\tof many a valiant adventurer. It is said that one gaze from\n"); 281. printf("\tits eyes could turn a man to stone. One bite from the nest\n"); 282. printf("\tof snakes which crown its head could cause instant death.\n"); 283. printf("\tThe only way to kill this monstrosity is to turn its gaze\n"); 284. printf("\tback upon itself.\n"); 285. #endif 286. #ifdef KAA 287. printf("9\ta giant;\n"); 288. printf("\tGiants have always walked the earth, though they are rare in\n"); 289. printf("\tthese times. They range in size from little over nine feet\n"); 290. printf("\tto a towering twenty feet or more. The larger ones use huge\n"); 291. printf("\tboulders as weapons, hurling them over large distances. All\n"); 292. printf("\ttypes of giants share a love for men - roasted, boiled, or\n"); 293. printf("\tfried. Their table manners are legendary.\n"); 294. #endif 295. fclose(stdin); 296. fclose(stdout); 297. } 298. 299. #define LINSZ 1000 300. #define STRSZ 40 301. 302. int fd; 303. struct objdef { 304. 305. struct objdef *next; 306. char string[STRSZ]; 307. } *more, *current; 308. 309. do_objs(){ 310. register int index = 0; 311. register int propct = 0; 312. #ifdef SPELLS 313. register int nspell = 0; 314. #endif 315. FILE *freopen(); 316. register char *sp; 317. char *limit(); 318. int skip; 319. 320. fd = open(OBJ_FILE, 0); 321. if(fd < 0) { 322. perror(OBJ_FILE); 323. exit(1); 324. } 325. 326. if(freopen(ONAME_FILE, WRMODE, stdout) == NULL) { 327. perror(ONAME_FILE); 328. exit(1); 329. } 330. 331. current = 0; newobj(); 332. skipuntil("objects[] = {"); 333. 334. while(getentry(&skip)) { 335. if(!*(current->string)){ 336. if (skip) index++; 337. continue; 338. } 339. for(sp = current->string; *sp; sp++) 340. if(*sp == ' ' || *sp == '\t' || *sp == '-') 341. *sp = '_'; 342. 343. /* Do not process duplicates caused by #ifdef/#else pairs. */ 344. /* M. Stephenson */ 345. if (! duplicate()) { 346. 347. if(!strncmp(current->string, "RIN_", 4)) 348. propct = specprop(current->string+4, propct); 349. for(sp = current->string; *sp; sp++) capitalize(sp); 350. /* avoid trouble with stupid C preprocessors */ 351. if(!strncmp(current->string, "WORTHLESS_PIECE_OF_", 19)) 352. printf("/* #define\t%s\t%d */\n", current->string, index++); 353. else { 354. #ifdef SPELLS 355. if(!strncmp(current->string, "SPE_", 4)) nspell++; 356. printf("#define\t%s\t%d\n", limit(current->string), index++); 357. #else 358. if(strncmp(current->string, "SPE_", 4)) 359. printf("#define\t%s\t%d\n", limit(current->string), index++); 360. #endif 361. } 362. newobj(); 363. } 364. } 365. printf("\n#define CORPSE DEAD_HUMAN\n"); 366. #ifdef KOPS 367. printf("#define DEAD_KOP DEAD_KOBOLD\n"); 368. #endif 369. #ifdef SPIDERS 370. printf("#define DEAD_GIANT_SPIDER DEAD_GIANT_SCORPION\n"); 371. #endif 372. #ifdef ROCKMOLE 373. printf("#define DEAD_ROCKMOLE DEAD_GIANT_RAT\n"); 374. #endif 375. #ifndef KAA 376. printf("#define DEAD_QUASIT DEAD_QUANTUM_MECHANIC\n"); 377. printf("#define DEAD_VIOLET_FUNGI DEAD_VIOLET_FUNGUS\n"); 378. #endif 379. printf("#define LAST_GEM (JADE+1)\n"); 380. printf("#define LAST_RING %d\n", propct); 381. #ifdef SPELLS 382. printf("#define MAXSPELL %d\n", nspell+1); 383. #endif 384. printf("#define NROFOBJECTS %d\n", index-1); 385. exit(0); 386. } 387. 388. static char temp[32]; 389. 390. char * 391. limit(name) /* limit a name to 30 characters length */ 392. char *name; 393. { 394. strncpy(temp, name, 30); 395. temp[30] = 0; 396. return(temp); 397. } 398. 399. newobj() 400. { 401. extern long *alloc(); 402. 403. more = current; 404. current = (struct objdef *)alloc(sizeof(struct objdef)); 405. current->next = more; 406. } 407. 408. struct inherent { 409. 410. char *attrib, 411. *monsters; 412. } abilities[] = { "Regeneration", "TVi", 413. "See_invisible", "I", 414. "Poison_resistance", "abcghikqsuvxyADFQSVWXZ&", 415. "Fire_resistance", "gD&", 416. "Cold_resistance", "gFY", 417. "Shock_resistance", "g;", 418. "Teleportation", "LNt", 419. "Teleport_control", "t", 420. "", "" }; 421. 422. specprop(name, count) 423. 424. char *name; 425. int count; 426. { 427. int i; 428. char *tname, *limit(); 429. 430. tname = limit(name); 431. capitalize(tname); 432. for(i = 0; strlen(abilities[i].attrib); i++) 433. if(!strcmp(abilities[i].attrib, tname)) { 434. 435. printf("#define\tH%s\tu.uprops[%d].p_flgs\n", tname, count); 436. printf("#define\t%s\t((H%s) || index(\"%s\", u.usym))\n", 437. tname, tname, abilities[i].monsters); 438. return(++count); 439. } 440. 441. printf("#define\t%s\tu.uprops[%d].p_flgs\n", tname, count); 442. return(++count); 443. } 444. 445. char line[LINSZ], *lp = line, *lp0 = line, *lpe = line; 446. int xeof; 447. 448. readline(){ 449. register int n = read(fd, lp0, (line+LINSZ)-lp0); 450. if(n < 0){ 451. printf("Input error.\n"); 452. exit(1); 453. } 454. if(n == 0) xeof++; 455. lpe = lp0+n; 456. } 457. 458. char 459. nextchar(){ 460. if(lp == lpe){ 461. readline(); 462. lp = lp0; 463. } 464. return((lp == lpe) ? 0 : *lp++); 465. } 466. 467. skipuntil(s) char *s; { 468. register char *sp0, *sp1; 469. loop: 470. while(*s != nextchar()) 471. if(xeof) { 472. printf("Cannot skipuntil %s\n", s); 473. exit(1); 474. } 475. if(strlen(s) > lpe-lp+1){ 476. register char *lp1, *lp2; 477. lp2 = lp; 478. lp1 = lp = lp0; 479. while(lp2 != lpe) *lp1++ = *lp2++; 480. lp2 = lp0; /* save value */ 481. lp0 = lp1; 482. readline(); 483. lp0 = lp2; 484. if(strlen(s) > lpe-lp+1) { 485. printf("error in skipuntil"); 486. exit(1); 487. } 488. } 489. sp0 = s+1; 490. sp1 = lp; 491. while(*sp0 && *sp0 == *sp1) sp0++, sp1++; 492. if(!*sp0){ 493. lp = sp1; 494. return(1); 495. } 496. goto loop; 497. } 498. 499. getentry(skip) int *skip; { 500. int inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0; 501. int prefix = 0; 502. char ch; 503. #define NSZ 10 504. char identif[NSZ], *ip; 505. current->string[0] = current->string[4] = 0; 506. /* read until {...} or XXX(...) followed by , 507. skip comment and #define lines 508. deliver 0 on failure 509. */ 510. while(1) { 511. ch = nextchar(); 512. swi: 513. if(letter(ch)){ 514. ip = identif; 515. do { 516. if(ip < identif+NSZ-1) *ip++ = ch; 517. ch = nextchar(); 518. } while(letter(ch) || digit(ch)); 519. *ip = 0; 520. while(ch == ' ' || ch == '\t') ch = nextchar(); 521. if(ch == '(' && !inparens && !stringseen) 522. if(!strcmp(identif, "WAND") || 523. !strcmp(identif, "RING") || 524. !strcmp(identif, "POTION") || 525. !strcmp(identif, "SPELL") || 526. !strcmp(identif, "SCROLL")) 527. (void) strncpy(current->string, identif, 3), 528. current->string[3] = '_', 529. prefix = 4; 530. } 531. switch(ch) { 532. case '/': 533. /* watch for comment */ 534. if((ch = nextchar()) == '*') 535. skipuntil("*/"); 536. goto swi; 537. case '{': 538. inbraces++; 539. continue; 540. case '(': 541. inparens++; 542. continue; 543. case '}': 544. inbraces--; 545. if(inbraces < 0) return(0); 546. continue; 547. case ')': 548. inparens--; 549. if(inparens < 0) { 550. printf("too many ) ?"); 551. exit(1); 552. } 553. continue; 554. case '\n': 555. /* watch for #define at begin of line */ 556. if((ch = nextchar()) == '#'){ 557. register char pch; 558. /* skip until '\n' not preceded by '\\' */ 559. do { 560. pch = ch; 561. ch = nextchar(); 562. } while(ch != '\n' || pch == '\\'); 563. continue; 564. } 565. goto swi; 566. case ',': 567. if(!inparens && !inbraces){ 568. if(prefix && !current->string[prefix]) { 569. #ifndef SPELLS 570. *skip = strncmp(current->string, "SPE_", 4); 571. #else 572. *skip = 1; 573. #endif 574. current->string[0] = 0; 575. } 576. if(stringseen) return(1); 577. printf("unexpected ,\n"); 578. exit(1); 579. } 580. commaseen++; 581. continue; 582. case '\: 583. if((ch = nextchar()) == '\\') ch = nextchar(); 584. if(nextchar() != '\){ 585. printf("strange character denotation?\n"); 586. exit(1); 587. } 588. continue; 589. case '"': 590. { 591. register char *sp = current->string + prefix; 592. register char pch; 593. register int store = (inbraces || inparens) 594. && !stringseen++ && !commaseen; 595. do { 596. pch = ch; 597. ch = nextchar(); 598. if(store && sp < current->string+STRSZ) 599. *sp++ = ch; 600. } while(ch != '"' || pch == '\\'); 601. if(store) *--sp = 0; 602. continue; 603. } 604. } 605. } 606. } 607. 608. duplicate() { 609. 610. char s[STRSZ]; 611. register char *c; 612. register struct objdef *testobj; 613. 614. strcpy (s, current->string); 615. for(c = s; *c != 0; c++) capitalize(c); 616. 617. for(testobj = more; testobj != 0; testobj = testobj->next) 618. if(! strcmp(s, testobj->string)) return(1); 619. 620. return(0); 621. } 622. 623. capitalize(sp) register char *sp; { 624. if('a' <= *sp && *sp <= 'z') *sp += 'A'-'a'; 625. } 626. 627. letter(ch) register char ch; { 628. return( ('a' <= ch && ch <= 'z') || 629. ('A' <= ch && ch <= 'Z') ); 630. } 631. 632. digit(ch) register char ch; { 633. return( '0' <= ch && ch <= '9' ); 634. } 635. 636. /* a copy of the panic code from hack.pri.c, edited for standalone use */ 637. 638. boolean panicking = 0; 639. 640. panic(str,a1,a2,a3,a4,a5,a6) 641. char *str; 642. { 643. if(panicking++) exit(1); /* avoid loops - this should never happen*/ 644. fputs(" ERROR: ", stdout); 645. printf(str,a1,a2,a3,a4,a5,a6); 646. #ifdef DEBUG 647. # ifdef UNIX 648. if(!fork()) 649. abort(); /* generate core dump */ 650. # endif 651. #endif 652. exit(1); 653. } 654. 655. #if defined(SYSV) || defined(GENIX) 656. rename(oldname, newname) 657. char *oldname, *newname; 658. { 659. if (strcmp(oldname, newname)) { 660. 661. unlink(newname); 662. link(oldname, newname); 663. unlink(oldname); 664. } 665. } 666. #endif 667. 668. #ifdef MSDOS 669. /* Get around bug in freopen when opening for writing */ 670. /* Supplied by Nathan Glasser (nathan@mit-eddie) */ 671. #undef freopen 672. FILE *_freopen(fname, fmode, fp) 673. char *fname, *fmode; 674. FILE *fp; 675. { 676. if (!strncmp(fmode,"w",1)) 677. { 678. FILE *tmpfp; 679. 680. if ((tmpfp = fopen(fname,fmode)) == NULL) 681. return(NULL); 682. if (dup2(fileno(tmpfp),fileno(fp)) < 0) 683. return(NULL); 684. fclose(tmpfp); 685. return(fp); 686. } 687. else 688. return(freopen(fname,fmode,fp)); 689. } 690. 691. # ifdef __TURBOC__ 692. int getpid() { 693. return(1); 694. } 695. # endif 696. #endif