Below is the full text to src/dungeon.c from NetHack 3.4.3. To link to a particular line, write [[dungeon.c#line123]], for example.
Top of file[]
1. /* SCCS Id: @(#)dungeon.c 3.4 1999/10/30 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4.
The NetHack General Public License applies to screenshots, source code and other content from NetHack. |
5. #include "hack.h" 6. #include "dgn_file.h" 7. #include "dlb.h" 8. 9. #ifdef OVL1 10. 11. #define DUNGEON_FILE "dungeon" 12. 13. #define X_START "x-strt" 14. #define X_LOCATE "x-loca" 15. #define X_GOAL "x-goal" 16. 17. struct proto_dungeon { 18. struct tmpdungeon tmpdungeon[MAXDUNGEON]; 19. struct tmplevel tmplevel[LEV_LIMIT]; 20. s_level *final_lev[LEV_LIMIT]; /* corresponding level pointers */ 21. struct tmpbranch tmpbranch[BRANCH_LIMIT]; 22. 23. int start; /* starting index of current dungeon sp levels */ 24. int n_levs; /* number of tmplevel entries */ 25. int n_brs; /* number of tmpbranch entries */ 26. }; 27. 28. int n_dgns; /* number of dungeons (used here, */ 29. /* and mklev.c) */ 30. static branch *branches = (branch *) 0; /* dungeon branch list */ 31. 32. struct lchoice { 33. int idx; 34. schar lev[MAXLINFO]; 35. schar playerlev[MAXLINFO]; 36. xchar dgn[MAXLINFO]; 37. char menuletter; 38. }; 39. 40. static void FDECL(Fread, (genericptr_t, int, int, dlb *)); 41. STATIC_DCL xchar FDECL(dname_to_dnum, (const char *)); 42. STATIC_DCL int FDECL(find_branch, (const char *, struct proto_dungeon *)); 43. STATIC_DCL xchar FDECL(parent_dnum, (const char *, struct proto_dungeon *)); 44. STATIC_DCL int FDECL(level_range, (XCHAR_P,int,int,int,struct proto_dungeon *,int *)); 45. STATIC_DCL xchar FDECL(parent_dlevel, (const char *, struct proto_dungeon *)); 46. STATIC_DCL int FDECL(correct_branch_type, (struct tmpbranch *)); 47. STATIC_DCL branch *FDECL(add_branch, (int, int, struct proto_dungeon *)); 48. STATIC_DCL void FDECL(add_level, (s_level *)); 49. STATIC_DCL void FDECL(init_level, (int,int,struct proto_dungeon *)); 50. STATIC_DCL int FDECL(possible_places, (int, boolean *, struct proto_dungeon *)); 51. STATIC_DCL xchar FDECL(pick_level, (boolean *, int)); 52. STATIC_DCL boolean FDECL(place_level, (int, struct proto_dungeon *)); 53. #ifdef WIZARD 54. STATIC_DCL const char *FDECL(br_string, (int)); 55. STATIC_DCL void FDECL(print_branch, (winid, int, int, int, BOOLEAN_P, struct lchoice *)); 56. #endif 57.
dumpit[]
58. #ifdef DEBUG 59. #define DD dungeons[i] 60. STATIC_DCL void NDECL(dumpit); 61. 62. STATIC_OVL void 63. dumpit() 64. { 65. int i; 66. s_level *x; 67. branch *br; 68. 69. for(i = 0; i < n_dgns; i++) { 70. fprintf(stderr, "\n#%d \"%s\" (%s):\n", i, 71. DD.dname, DD.proto); 72. fprintf(stderr, " num_dunlevs %d, dunlev_ureached %d\n", 73. DD.num_dunlevs, DD.dunlev_ureached); 74. fprintf(stderr, " depth_start %d, ledger_start %d\n", 75. DD.depth_start, DD.ledger_start); 76. fprintf(stderr, " flags:%s%s%s\n", 77. DD.flags.rogue_like ? " rogue_like" : "", 78. DD.flags.maze_like ? " maze_like" : "", 79. DD.flags.hellish ? " hellish" : ""); 80. getchar(); 81. } 82. fprintf(stderr,"\nSpecial levels:\n"); 83. for(x = sp_levchn; x; x = x->next) { 84. fprintf(stderr, "%s (%d): ", x->proto, x->rndlevs); 85. fprintf(stderr, "on %d, %d; ", x->dlevel.dnum, x->dlevel.dlevel); 86. fprintf(stderr, "flags:%s%s%s%s\n", 87. x->flags.rogue_like ? " rogue_like" : "", 88. x->flags.maze_like ? " maze_like" : "", 89. x->flags.hellish ? " hellish" : "", 90. x->flags.town ? " town" : ""); 91. getchar(); 92. } 93. fprintf(stderr,"\nBranches:\n"); 94. for (br = branches; br; br = br->next) { 95. fprintf(stderr, "%d: %s, end1 %d %d, end2 %d %d, %s\n", 96. br->id, 97. br->type == BR_STAIR ? "stair" : 98. br->type == BR_NO_END1 ? "no end1" : 99. br->type == BR_NO_END2 ? "no end2" : 100. br->type == BR_PORTAL ? "portal" : 101. "unknown", 102. br->end1.dnum, br->end1.dlevel, 103. br->end2.dnum, br->end2.dlevel, 104. br->end1_up ? "end1 up" : "end1 down"); 105. } 106. getchar(); 107. fprintf(stderr,"\nDone\n"); 108. getchar(); 109. } 110. #endif 111.
save_dungeon[]
112. /* Save the dungeon structures. */ 113. void 114. save_dungeon(fd, perform_write, free_data) 115. int fd; 116. boolean perform_write, free_data; 117. { 118. branch *curr, *next; 119. int count; 120. 121. if (perform_write) { 122. bwrite(fd, (genericptr_t) &n_dgns, sizeof n_dgns); 123. bwrite(fd, (genericptr_t) dungeons, sizeof(dungeon) * (unsigned)n_dgns); 124. bwrite(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology); 125. bwrite(fd, (genericptr_t) tune, sizeof tune); 126. 127. for (count = 0, curr = branches; curr; curr = curr->next) 128. count++; 129. bwrite(fd, (genericptr_t) &count, sizeof(count)); 130. 131. for (curr = branches; curr; curr = curr->next) 132. bwrite(fd, (genericptr_t) curr, sizeof (branch)); 133. 134. count = maxledgerno(); 135. bwrite(fd, (genericptr_t) &count, sizeof count); 136. bwrite(fd, (genericptr_t) level_info, 137. (unsigned)count * sizeof (struct linfo)); 138. bwrite(fd, (genericptr_t) &inv_pos, sizeof inv_pos); 139. } 140. 141. if (free_data) { 142. for (curr = branches; curr; curr = next) { 143. next = curr->next; 144. free((genericptr_t) curr); 145. } 146. branches = 0; 147. } 148. } 149.
restore_dungeon[]
150. /* Restore the dungeon structures. */ 151. void 152. restore_dungeon(fd) 153. int fd; 154. { 155. branch *curr, *last; 156. int count, i; 157. 158. mread(fd, (genericptr_t) &n_dgns, sizeof(n_dgns)); 159. mread(fd, (genericptr_t) dungeons, sizeof(dungeon) * (unsigned)n_dgns); 160. mread(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology); 161. mread(fd, (genericptr_t) tune, sizeof tune); 162. 163. last = branches = (branch *) 0; 164. 165. mread(fd, (genericptr_t) &count, sizeof(count)); 166. for (i = 0; i < count; i++) { 167. curr = (branch *) alloc(sizeof(branch)); 168. mread(fd, (genericptr_t) curr, sizeof(branch)); 169. curr->next = (branch *) 0; 170. if (last) 171. last->next = curr; 172. else 173. branches = curr; 174. last = curr; 175. } 176. 177. mread(fd, (genericptr_t) &count, sizeof(count)); 178. if (count >= MAXLINFO) 179. panic("level information count larger (%d) than allocated size", count); 180. mread(fd, (genericptr_t) level_info, (unsigned)count*sizeof(struct linfo)); 181. mread(fd, (genericptr_t) &inv_pos, sizeof inv_pos); 182. } 183.
Fread[]
184. static void 185. Fread(ptr, size, nitems, stream) 186. genericptr_t ptr; 187. int size, nitems; 188. dlb *stream; 189. { 190. int cnt; 191. 192. if((cnt = dlb_fread(ptr, size, nitems, stream)) != nitems) { 193. panic( 194. "Premature EOF on dungeon description file!\r\nExpected %d bytes - got %d.", 195. (size * nitems), (size * cnt)); 196. terminate(EXIT_FAILURE); 197. } 198. } 199.
dname_to_dnum[]
200. STATIC_OVL xchar 201. dname_to_dnum(s) 202. const char *s; 203. { 204. xchar i; 205. 206. for (i = 0; i < n_dgns; i++) 207. if (!strcmp(dungeons[i].dname, s)) return i; 208. 209. panic("Couldn't resolve dungeon number for name \"%s\".", s); 210. /*NOT REACHED*/ 211. return (xchar)0; 212. } 213.
find_level[]
214. s_level * 215. find_level(s) 216. const char *s; 217. { 218. s_level *curr; 219. for(curr = sp_levchn; curr; curr = curr->next) 220. if (!strcmpi(s, curr->proto)) break; 221. return curr; 222. } 223.
find_branch[]
224. /* Find the branch that links the named dungeon. */ 225. STATIC_OVL int 226. find_branch(s, pd) 227. const char *s; /* dungeon name */ 228. struct proto_dungeon *pd; 229. { 230. int i; 231. 232. if (pd) { 233. for (i = 0; i < pd->n_brs; i++) 234. if (!strcmp(pd->tmpbranch[i].name, s)) break; 235. if (i == pd->n_brs) panic("find_branch: can't find %s", s); 236. } else { 237. /* support for level tport by name */ 238. branch *br; 239. const char *dnam; 240. 241. for (br = branches; br; br = br->next) { 242. dnam = dungeons[br->end2.dnum].dname; 243. if (!strcmpi(dnam, s) || 244. (!strncmpi(dnam, "The ", 4) && !strcmpi(dnam + 4, s))) 245. break; 246. } 247. i = br ? ((ledger_no(&br->end1) << 8) | ledger_no(&br->end2)) : -1; 248. } 249. return i; 250. } 251. 252.
parent_dnum[]
253. /* 254. * Find the "parent" by searching the prototype branch list for the branch 255. * listing, then figuring out to which dungeon it belongs. 256. */ 257. STATIC_OVL xchar 258. parent_dnum(s, pd) 259. const char *s; /* dungeon name */ 260. struct proto_dungeon *pd; 261. { 262. int i; 263. xchar pdnum; 264. 265. i = find_branch(s, pd); 266. /* 267. * Got branch, now find parent dungeon. Stop if we have reached 268. * "this" dungeon (if we haven't found it by now it is an error). 269. */ 270. for (pdnum = 0; strcmp(pd->tmpdungeon[pdnum].name, s); pdnum++) 271. if ((i -= pd->tmpdungeon[pdnum].branches) < 0) 272. return(pdnum); 273. 274. panic("parent_dnum: couldn't resolve branch."); 275. /*NOT REACHED*/ 276. return (xchar)0; 277. } 278.
level_range[]
279. /* 280. * Return a starting point and number of successive positions a level 281. * or dungeon entrance can occupy. 282. * 283. * Note: This follows the acouple (instead of the rcouple) rules for a 284. * negative random component (rand < 0). These rules are found 285. * in dgn_comp.y. The acouple [absolute couple] section says that 286. * a negative random component means from the (adjusted) base to the 287. * end of the dungeon. 288. */ 289. STATIC_OVL int 290. level_range(dgn, base, rand, chain, pd, adjusted_base) 291. xchar dgn; 292. int base, rand, chain; 293. struct proto_dungeon *pd; 294. int *adjusted_base; 295. { 296. int lmax = dungeons[dgn].num_dunlevs; 297. 298. if (chain >= 0) { /* relative to a special level */ 299. s_level *levtmp = pd->final_lev[chain]; 300. if (!levtmp) panic("level_range: empty chain level!"); 301. 302. base += levtmp->dlevel.dlevel; 303. } else { /* absolute in the dungeon */ 304. /* from end of dungeon */ 305. if (base < 0) base = (lmax + base + 1); 306. } 307. 308. if (base < 1 || base > lmax) 309. panic("level_range: base value out of range"); 310. 311. *adjusted_base = base; 312. 313. if (rand == -1) { /* from base to end of dungeon */ 314. return (lmax - base + 1); 315. } else if (rand) { 316. /* make sure we don't run off the end of the dungeon */ 317. return (((base + rand - 1) > lmax) ? lmax-base+1 : rand); 318. } /* else only one choice */ 319. return 1; 320. } 321.
parent_dlevel[]
322. STATIC_OVL xchar 323. parent_dlevel(s, pd) 324. const char *s; 325. struct proto_dungeon *pd; 326. { 327. int i, j, num, base, dnum = parent_dnum(s, pd); 328. branch *curr; 329. 330. 331. i = find_branch(s, pd); 332. num = level_range(dnum, pd->tmpbranch[i].lev.base, 333. pd->tmpbranch[i].lev.rand, 334. pd->tmpbranch[i].chain, 335. pd, &base); 336. 337. /* KMH -- Try our best to find a level without an existing branch */ 338. i = j = rn2(num); 339. do { 340. if (++i >= num) i = 0; 341. for (curr = branches; curr; curr = curr->next) 342. if ((curr->end1.dnum == dnum && curr->end1.dlevel == base+i) || 343. (curr->end2.dnum == dnum && curr->end2.dlevel == base+i)) 344. break; 345. } while (curr && i != j); 346. return (base + i); 347. } 348.
correct_branch_type[]
349. /* Convert from the temporary branch type to the dungeon branch type. */ 350. STATIC_OVL int 351. correct_branch_type(tbr) 352. struct tmpbranch *tbr; 353. { 354. switch (tbr->type) { 355. case TBR_STAIR: return BR_STAIR; 356. case TBR_NO_UP: return tbr->up ? BR_NO_END1 : BR_NO_END2; 357. case TBR_NO_DOWN: return tbr->up ? BR_NO_END2 : BR_NO_END1; 358. case TBR_PORTAL: return BR_PORTAL; 359. } 360. impossible("correct_branch_type: unknown branch type"); 361. return BR_STAIR; 362. } 363.
insert_branch[]
364. /* 365. * Add the given branch to the branch list. The branch list is ordered 366. * by end1 dungeon and level followed by end2 dungeon and level. If 367. * extract_first is true, then the branch is already part of the list 368. * but needs to be repositioned. 369. */ 370. void 371. insert_branch(new_branch, extract_first) 372. branch *new_branch; 373. boolean extract_first; 374. { 375. branch *curr, *prev; 376. long new_val, curr_val, prev_val; 377. 378. if (extract_first) { 379. for (prev = 0, curr = branches; curr; prev = curr, curr = curr->next) 380. if (curr == new_branch) break; 381. 382. if (!curr) panic("insert_branch: not found"); 383. if (prev) 384. prev->next = curr->next; 385. else 386. branches = curr->next; 387. } 388. new_branch->next = (branch *) 0; 389. 390. /* Convert the branch into a unique number so we can sort them. */ 391. #define branch_val(bp) \ 392. ((((long)(bp)->end1.dnum * (MAXLEVEL+1) + \ 393. (long)(bp)->end1.dlevel) * (MAXDUNGEON+1) * (MAXLEVEL+1)) + \ 394. ((long)(bp)->end2.dnum * (MAXLEVEL+1) + (long)(bp)->end2.dlevel)) 395. 396. /* 397. * Insert the new branch into the correct place in the branch list. 398. */ 399. prev = (branch *) 0; 400. prev_val = -1; 401. new_val = branch_val(new_branch); 402. for (curr = branches; curr; 403. prev_val = curr_val, prev = curr, curr = curr->next) { 404. curr_val = branch_val(curr); 405. if (prev_val < new_val && new_val <= curr_val) break; 406. } 407. if (prev) { 408. new_branch->next = curr; 409. prev->next = new_branch; 410. } else { 411. new_branch->next = branches; 412. branches = new_branch; 413. } 414. } 415.
add_branch[]
416. /* Add a dungeon branch to the branch list. */ 417. STATIC_OVL branch * 418. add_branch(dgn, child_entry_level, pd) 419. int dgn; 420. int child_entry_level; 421. struct proto_dungeon *pd; 422. { 423. static int branch_id = 0; 424. int branch_num; 425. branch *new_branch; 426. 427. branch_num = find_branch(dungeons[dgn].dname,pd); 428. new_branch = (branch *) alloc(sizeof(branch)); 429. new_branch->next = (branch *) 0; 430. new_branch->id = branch_id++; 431. new_branch->type = correct_branch_type(&pd->tmpbranch[branch_num]); 432. new_branch->end1.dnum = parent_dnum(dungeons[dgn].dname, pd); 433. new_branch->end1.dlevel = parent_dlevel(dungeons[dgn].dname, pd); 434. new_branch->end2.dnum = dgn; 435. new_branch->end2.dlevel = child_entry_level; 436. new_branch->end1_up = pd->tmpbranch[branch_num].up ? TRUE : FALSE; 437. 438. insert_branch(new_branch, FALSE); 439. return new_branch; 440. } 441.
add_level[]
442. /* 443. * Add new level to special level chain. Insert it in level order with the 444. * other levels in this dungeon. This assumes that we are never given a 445. * level that has a dungeon number less than the dungeon number of the 446. * last entry. 447. */ 448. STATIC_OVL void 449. add_level(new_lev) 450. s_level *new_lev; 451. { 452. s_level *prev, *curr; 453. 454. prev = (s_level *) 0; 455. for (curr = sp_levchn; curr; curr = curr->next) { 456. if (curr->dlevel.dnum == new_lev->dlevel.dnum && 457. curr->dlevel.dlevel > new_lev->dlevel.dlevel) 458. break; 459. prev = curr; 460. } 461. if (!prev) { 462. new_lev->next = sp_levchn; 463. sp_levchn = new_lev; 464. } else { 465. new_lev->next = curr; 466. prev->next = new_lev; 467. } 468. } 469.
init_level[]
470. STATIC_OVL void 471. init_level(dgn, proto_index, pd) 472. int dgn, proto_index; 473. struct proto_dungeon *pd; 474. { 475. s_level *new_level; 476. struct tmplevel *tlevel = &pd->tmplevel[proto_index]; 477. 478. pd->final_lev[proto_index] = (s_level *) 0; /* no "real" level */ 479. #ifdef WIZARD 480. if (!wizard) 481. #endif 482. if (tlevel->chance <= rn2(100)) return; 483. 484. pd->final_lev[proto_index] = new_level = 485. (s_level *) alloc(sizeof(s_level)); 486. /* load new level with data */ 487. Strcpy(new_level->proto, tlevel->name); 488. new_level->boneid = tlevel->boneschar; 489. new_level->dlevel.dnum = dgn; 490. new_level->dlevel.dlevel = 0; /* for now */ 491. 492. new_level->flags.town = !!(tlevel->flags & TOWN); 493. new_level->flags.hellish = !!(tlevel->flags & HELLISH); 494. new_level->flags.maze_like = !!(tlevel->flags & MAZELIKE); 495. new_level->flags.rogue_like = !!(tlevel->flags & ROGUELIKE); 496. new_level->flags.align = ((tlevel->flags & D_ALIGN_MASK) >> 4); 497. if (!new_level->flags.align) 498. new_level->flags.align = 499. ((pd->tmpdungeon[dgn].flags & D_ALIGN_MASK) >> 4); 500. 501. new_level->rndlevs = tlevel->rndlevs; 502. new_level->next = (s_level *) 0; 503. } 504.
possible_places[]
505. STATIC_OVL int 506. possible_places(idx, map, pd) 507. int idx; /* prototype index */ 508. boolean *map; /* array MAXLEVEL+1 in length */ 509. struct proto_dungeon *pd; 510. { 511. int i, start, count; 512. s_level *lev = pd->final_lev[idx]; 513. 514. /* init level possibilities */ 515. for (i = 0; i <= MAXLEVEL; i++) map[i] = FALSE; 516. 517. /* get base and range and set those entried to true */ 518. count = level_range(lev->dlevel.dnum, pd->tmplevel[idx].lev.base, 519. pd->tmplevel[idx].lev.rand, 520. pd->tmplevel[idx].chain, 521. pd, &start); 522. for (i = start; i < start+count; i++) 523. map[i] = TRUE; 524. 525. /* mark off already placed levels */ 526. for (i = pd->start; i < idx; i++) { 527. if (pd->final_lev[i] && map[pd->final_lev[i]->dlevel.dlevel]) { 528. map[pd->final_lev[i]->dlevel.dlevel] = FALSE; 529. --count; 530. } 531. } 532. 533. return count; 534. } 535.
pick_level[]
536. /* Pick the nth TRUE entry in the given boolean array. */ 537. STATIC_OVL xchar 538. pick_level(map, nth) 539. boolean *map; /* an array MAXLEVEL+1 in size */ 540. int nth; 541. { 542. int i; 543. for (i = 1; i <= MAXLEVEL; i++) 544. if (map[i] && !nth--) return (xchar) i; 545. panic("pick_level: ran out of valid levels"); 546. return 0; 547. } 548.
indent[]
549. #ifdef DDEBUG 550. static void FDECL(indent,(int)); 551. 552. static void 553. indent(d) 554. int d; 555. { 556. while (d-- > 0) fputs(" ", stderr); 557. } 558. #endif 559.
place_level[]
560. /* 561. * Place a level. First, find the possible places on a dungeon map 562. * template. Next pick one. Then try to place the next level. If 563. * sucessful, we're done. Otherwise, try another (and another) until 564. * all possible places have been tried. If all possible places have 565. * been exausted, return false. 566. */ 567. STATIC_OVL boolean 568. place_level(proto_index, pd) 569. int proto_index; 570. struct proto_dungeon *pd; 571. { 572. boolean map[MAXLEVEL+1]; /* valid levels are 1..MAXLEVEL inclusive */ 573. s_level *lev; 574. int npossible; 575. #ifdef DDEBUG 576. int i; 577. #endif 578. 579. if (proto_index == pd->n_levs) return TRUE; /* at end of proto levels */ 580. 581. lev = pd->final_lev[proto_index]; 582. 583. /* No level created for this prototype, goto next. */ 584. if (!lev) return place_level(proto_index+1, pd); 585. 586. npossible = possible_places(proto_index, map, pd); 587. 588. for (; npossible; --npossible) { 589. lev->dlevel.dlevel = pick_level(map, rn2(npossible)); 590. #ifdef DDEBUG 591. indent(proto_index-pd->start); 592. fprintf(stderr,"%s: trying %d [ ", lev->proto, lev->dlevel.dlevel); 593. for (i = 1; i <= MAXLEVEL; i++) 594. if (map[i]) fprintf(stderr,"%d ", i); 595. fprintf(stderr,"]\n"); 596. #endif 597. if (place_level(proto_index+1, pd)) return TRUE; 598. map[lev->dlevel.dlevel] = FALSE; /* this choice didn't work */ 599. } 600. #ifdef DDEBUG 601. indent(proto_index-pd->start); 602. fprintf(stderr,"%s: failed\n", lev->proto); 603. #endif 604. return FALSE; 605. } 606. 607.
level_map[]
608. struct level_map { 609. const char *lev_name; 610. d_level *lev_spec; 611. } level_map[] = { 612. { "air", &air_level }, 613. { "asmodeus", &asmodeus_level }, 614. { "astral", &astral_level }, 615. { "baalz", &baalzebub_level }, 616. { "bigroom", &bigroom_level }, 617. { "castle", &stronghold_level }, 618. { "earth", &earth_level }, 619. { "fakewiz1", &portal_level }, 620. { "fire", &fire_level }, 621. { "juiblex", &juiblex_level }, 622. { "knox", &knox_level }, 623. { "medusa", &medusa_level }, 624. { "oracle", &oracle_level }, 625. { "orcus", &orcus_level }, 626. #ifdef REINCARNATION 627. { "rogue", &rogue_level }, 628. #endif 629. { "sanctum", &sanctum_level }, 630. { "valley", &valley_level }, 631. { "water", &water_level }, 632. { "wizard1", &wiz1_level }, 633. { "wizard2", &wiz2_level }, 634. { "wizard3", &wiz3_level }, 635. { X_START, &qstart_level }, 636. { X_LOCATE, &qlocate_level }, 637. { X_GOAL, &nemesis_level }, 638. { "", (d_level *)0 } 639. }; 640.
init_dungeons[]
641. void 642. init_dungeons() /* initialize the "dungeon" structs */ 643. { 644. dlb *dgn_file; 645. register int i, cl = 0, cb = 0; 646. register s_level *x; 647. struct proto_dungeon pd; 648. struct level_map *lev_map; 649. struct version_info vers_info; 650. 651. pd.n_levs = pd.n_brs = 0; 652. 653. dgn_file = dlb_fopen(DUNGEON_FILE, RDBMODE); 654. if (!dgn_file) { 655. char tbuf[BUFSZ]; 656. Sprintf(tbuf, "Cannot open dungeon description - \"%s", 657. DUNGEON_FILE); 658. #ifdef DLBRSRC /* using a resource from the executable */ 659. Strcat(tbuf, "\" resource!"); 660. #else /* using a file or DLB file */ 661. # if defined(DLB) 662. Strcat(tbuf, "\" from "); 663. # ifdef PREFIXES_IN_USE 664. Strcat(tbuf, "\n\""); 665. if (fqn_prefix[DATAPREFIX]) Strcat(tbuf, fqn_prefix[DATAPREFIX]); 666. # else 667. Strcat(tbuf, "\""); 668. # endif 669. Strcat(tbuf, DLBFILE); 670. # endif 671. Strcat(tbuf, "\" file!"); 672. #endif 673. #ifdef WIN32 674. interject_assistance(1, INTERJECT_PANIC, (genericptr_t)tbuf, 675. (genericptr_t)fqn_prefix[DATAPREFIX]); 676. #endif 677. panic(tbuf); 678. } 679. 680. /* validate the data's version against the program's version */ 681. Fread((genericptr_t) &vers_info, sizeof vers_info, 1, dgn_file); 682. /* we'd better clear the screen now, since when error messages come from 683. * check_version() they will be printed using pline(), which doesn't 684. * mix with the raw messages that might be already on the screen 685. */ 686. if (iflags.window_inited) clear_nhwindow(WIN_MAP); 687. if (!check_version(&vers_info, DUNGEON_FILE, TRUE)) 688. panic("Dungeon description not valid."); 689. 690. /* 691. * Read in each dungeon and transfer the results to the internal 692. * dungeon arrays. 693. */ 694. sp_levchn = (s_level *) 0; 695. Fread((genericptr_t)&n_dgns, sizeof(int), 1, dgn_file); 696. if (n_dgns >= MAXDUNGEON) 697. panic("init_dungeons: too many dungeons"); 698. 699. for (i = 0; i < n_dgns; i++) { 700. Fread((genericptr_t)&pd.tmpdungeon[i], 701. sizeof(struct tmpdungeon), 1, dgn_file); 702. #ifdef WIZARD 703. if(!wizard) 704. #endif 705. if(pd.tmpdungeon[i].chance && (pd.tmpdungeon[i].chance <= rn2(100))) { 706. int j; 707. 708. /* skip over any levels or branches */ 709. for(j = 0; j < pd.tmpdungeon[i].levels; j++) 710. Fread((genericptr_t)&pd.tmplevel[cl], sizeof(struct tmplevel), 711. 1, dgn_file); 712. 713. for(j = 0; j < pd.tmpdungeon[i].branches; j++) 714. Fread((genericptr_t)&pd.tmpbranch[cb], 715. sizeof(struct tmpbranch), 1, dgn_file); 716. n_dgns--; i--; 717. continue; 718. } 719. 720. Strcpy(dungeons[i].dname, pd.tmpdungeon[i].name); 721. Strcpy(dungeons[i].proto, pd.tmpdungeon[i].protoname); 722. dungeons[i].boneid = pd.tmpdungeon[i].boneschar; 723. 724. if(pd.tmpdungeon[i].lev.rand) 725. dungeons[i].num_dunlevs = (xchar)rn1(pd.tmpdungeon[i].lev.rand, 726. pd.tmpdungeon[i].lev.base); 727. else dungeons[i].num_dunlevs = (xchar)pd.tmpdungeon[i].lev.base; 728. 729. if(!i) { 730. dungeons[i].ledger_start = 0; 731. dungeons[i].depth_start = 1; 732. dungeons[i].dunlev_ureached = 1; 733. } else { 734. dungeons[i].ledger_start = dungeons[i-1].ledger_start + 735. dungeons[i-1].num_dunlevs; 736. dungeons[i].dunlev_ureached = 0; 737. } 738. 739. dungeons[i].flags.hellish = !!(pd.tmpdungeon[i].flags & HELLISH); 740. dungeons[i].flags.maze_like = !!(pd.tmpdungeon[i].flags & MAZELIKE); 741. dungeons[i].flags.rogue_like = !!(pd.tmpdungeon[i].flags & ROGUELIKE); 742. dungeons[i].flags.align = ((pd.tmpdungeon[i].flags & D_ALIGN_MASK) >> 4); 743. /* 744. * Set the entry level for this dungeon. The pd.tmpdungeon entry 745. * value means: 746. * < 0 from bottom (-1 == bottom level) 747. * 0 default (top) 748. * > 0 actual level (1 = top) 749. * 750. * Note that the entry_lev field in the dungeon structure is 751. * redundant. It is used only here and in print_dungeon(). 752. */ 753. if (pd.tmpdungeon[i].entry_lev < 0) { 754. dungeons[i].entry_lev = dungeons[i].num_dunlevs + 755. pd.tmpdungeon[i].entry_lev + 1; 756. if (dungeons[i].entry_lev <= 0) dungeons[i].entry_lev = 1; 757. } else if (pd.tmpdungeon[i].entry_lev > 0) { 758. dungeons[i].entry_lev = pd.tmpdungeon[i].entry_lev; 759. if (dungeons[i].entry_lev > dungeons[i].num_dunlevs) 760. dungeons[i].entry_lev = dungeons[i].num_dunlevs; 761. } else { /* default */ 762. dungeons[i].entry_lev = 1; /* defaults to top level */ 763. } 764. 765. if (i) { /* set depth */ 766. branch *br; 767. schar from_depth; 768. boolean from_up; 769. 770. br = add_branch(i, dungeons[i].entry_lev, &pd); 771. 772. /* Get the depth of the connecting end. */ 773. if (br->end1.dnum == i) { 774. from_depth = depth(&br->end2); 775. from_up = !br->end1_up; 776. } else { 777. from_depth = depth(&br->end1); 778. from_up = br->end1_up; 779. } 780. 781. /* 782. * Calculate the depth of the top of the dungeon via 783. * its branch. First, the depth of the entry point: 784. * 785. * depth of branch from "parent" dungeon 786. * + -1 or 1 depending on a up or down stair or 787. * 0 if portal 788. * 789. * Followed by the depth of the top of the dungeon: 790. * 791. * - (entry depth - 1) 792. * 793. * We'll say that portals stay on the same depth. 794. */ 795. dungeons[i].depth_start = from_depth 796. + (br->type == BR_PORTAL ? 0 : 797. (from_up ? -1 : 1)) 798. - (dungeons[i].entry_lev - 1); 799. } 800. 801. /* this is redundant - it should have been flagged by dgn_comp */ 802. if(dungeons[i].num_dunlevs > MAXLEVEL) 803. dungeons[i].num_dunlevs = MAXLEVEL; 804. 805. pd.start = pd.n_levs; /* save starting point */ 806. pd.n_levs += pd.tmpdungeon[i].levels; 807. if (pd.n_levs > LEV_LIMIT) 808. panic("init_dungeon: too many special levels"); 809. /* 810. * Read in the prototype special levels. Don't add generated 811. * special levels until they are all placed. 812. */ 813. for(; cl < pd.n_levs; cl++) { 814. Fread((genericptr_t)&pd.tmplevel[cl], 815. sizeof(struct tmplevel), 1, dgn_file); 816. init_level(i, cl, &pd); 817. } 818. /* 819. * Recursively place the generated levels for this dungeon. This 820. * routine will attempt all possible combinations before giving 821. * up. 822. */ 823. if (!place_level(pd.start, &pd)) 824. panic("init_dungeon: couldn't place levels"); 825. #ifdef DDEBUG 826. fprintf(stderr, "--- end of dungeon %d ---\n", i); 827. fflush(stderr); 828. getchar(); 829. #endif 830. for (; pd.start < pd.n_levs; pd.start++) 831. if (pd.final_lev[pd.start]) add_level(pd.final_lev[pd.start]); 832. 833. 834. pd.n_brs += pd.tmpdungeon[i].branches; 835. if (pd.n_brs > BRANCH_LIMIT) 836. panic("init_dungeon: too many branches"); 837. for(; cb < pd.n_brs; cb++) 838. Fread((genericptr_t)&pd.tmpbranch[cb], 839. sizeof(struct tmpbranch), 1, dgn_file); 840. } 841. (void) dlb_fclose(dgn_file); 842. 843. for (i = 0; i < 5; i++) tune[i] = 'A' + rn2(7); 844. tune[5] = 0; 845. 846. /* 847. * Find most of the special levels and dungeons so we can access their 848. * locations quickly. 849. */ 850. for (lev_map = level_map; lev_map->lev_name[0]; lev_map++) { 851. x = find_level(lev_map->lev_name); 852. if (x) { 853. assign_level(lev_map->lev_spec, &x->dlevel); 854. if (!strncmp(lev_map->lev_name, "x-", 2)) { 855. /* This is where the name substitution on the 856. * levels of the quest dungeon occur. 857. */ 858. Sprintf(x->proto, "%s%s", urole.filecode, &lev_map->lev_name[1]); 859. } else if (lev_map->lev_spec == &knox_level) { 860. branch *br; 861. /* 862. * Kludge to allow floating Knox entrance. We 863. * specify a floating entrance by the fact that 864. * its entrance (end1) has a bogus dnum, namely 865. * n_dgns. 866. */ 867. for (br = branches; br; br = br->next) 868. if (on_level(&br->end2, &knox_level)) break; 869. 870. if (br) br->end1.dnum = n_dgns; 871. /* adjust the branch's position on the list */ 872. insert_branch(br, TRUE); 873. } 874. } 875. } 876. /* 877. * I hate hardwiring these names. :-( 878. */ 879. quest_dnum = dname_to_dnum("The Quest"); 880. sokoban_dnum = dname_to_dnum("Sokoban"); 881. mines_dnum = dname_to_dnum("The Gnomish Mines"); 882. tower_dnum = dname_to_dnum("Vlad's Tower"); 883. 884. /* one special fixup for dummy surface level */ 885. if ((x = find_level("dummy")) != 0) { 886. i = x->dlevel.dnum; 887. /* the code above puts earth one level above dungeon level #1, 888. making the dummy level overlay level 1; but the whole reason 889. for having the dummy level is to make earth have depth -1 890. instead of 0, so adjust the start point to shift endgame up */ 891. if (dunlevs_in_dungeon(&x->dlevel) > 1 - dungeons[i].depth_start) 892. dungeons[i].depth_start -= 1; 893. /* TO DO: strip "dummy" out all the way here, 894. so that it's hidden from <ctrl/O> feedback. */ 895. } 896. 897. #ifdef DEBUG 898. dumpit(); 899. #endif 900. } 901.
dunlev[]
902. xchar 903. dunlev(lev) /* return the level number for lev in *this* dungeon */ 904. d_level *lev; 905. { 906. return(lev->dlevel); 907. } 908.
dunlevs_in_dungeon[]
909. xchar 910. dunlevs_in_dungeon(lev) /* return the lowest level number for *this* dungeon*/ 911. d_level *lev; 912. { 913. return(dungeons[lev->dnum].num_dunlevs); 914. } 915.
deepest_lev_reached[]
916. xchar 917. deepest_lev_reached(noquest) /* return the lowest level explored in the game*/ 918. boolean noquest; 919. { 920. /* this function is used for three purposes: to provide a factor 921. * of difficulty in monster generation; to provide a factor of 922. * difficulty in experience calculations (botl.c and end.c); and 923. * to insert the deepest level reached in the game in the topten 924. * display. the 'noquest' arg switch is required for the latter. 925. * 926. * from the player's point of view, going into the Quest is _not_ 927. * going deeper into the dungeon -- it is going back "home", where 928. * the dungeon starts at level 1. given the setup in dungeon.def, 929. * the depth of the Quest (thought of as starting at level 1) is 930. * never lower than the level of entry into the Quest, so we exclude 931. * the Quest from the topten "deepest level reached" display 932. * calculation. _However_ the Quest is a difficult dungeon, so we 933. * include it in the factor of difficulty calculations. 934. */ 935. register int i; 936. d_level tmp; 937. register schar ret = 0; 938. 939. for(i = 0; i < n_dgns; i++) { 940. if((tmp.dlevel = dungeons[i].dunlev_ureached) == 0) continue; 941. if(!strcmp(dungeons[i].dname, "The Quest") && noquest) continue; 942. 943. tmp.dnum = i; 944. if(depth(&tmp) > ret) ret = depth(&tmp); 945. } 946. return((xchar) ret); 947. } 948.
ledger_no[]
949. /* return a bookkeeping level number for purpose of comparisons and 950. * save/restore */ 951. xchar 952. ledger_no(lev) 953. d_level *lev; 954. { 955. return((xchar)(lev->dlevel + dungeons[lev->dnum].ledger_start)); 956. } 957.
maxledgerno[]
958. /* 959. * The last level in the bookkeeping list of level is the bottom of the last 960. * dungeon in the dungeons[] array. 961. * 962. * Maxledgerno() -- which is the max number of levels in the bookkeeping 963. * list, should not be confused with dunlevs_in_dungeon(lev) -- which 964. * returns the max number of levels in lev's dungeon, and both should 965. * not be confused with deepest_lev_reached() -- which returns the lowest 966. * depth visited by the player. 967. */ 968. xchar 969. maxledgerno() 970. { 971. return (xchar) (dungeons[n_dgns-1].ledger_start + 972. dungeons[n_dgns-1].num_dunlevs); 973. } 974.
ledger_to_dnum[]
975. /* return the dungeon that this ledgerno exists in */ 976. xchar 977. ledger_to_dnum(ledgerno) 978. xchar ledgerno; 979. { 980. register int i; 981. 982. /* find i such that (i->base + 1) <= ledgerno <= (i->base + i->count) */ 983. for (i = 0; i < n_dgns; i++) 984. if (dungeons[i].ledger_start < ledgerno && 985. ledgerno <= dungeons[i].ledger_start + dungeons[i].num_dunlevs) 986. return (xchar)i; 987. 988. panic("level number out of range [ledger_to_dnum(%d)]", (int)ledgerno); 989. /*NOT REACHED*/ 990. return (xchar)0; 991. } 992.
ledger_to_dlev[]
993. /* return the level of the dungeon this ledgerno exists in */ 994. xchar 995. ledger_to_dlev(ledgerno) 996. xchar ledgerno; 997. { 998. return((xchar)(ledgerno - dungeons[ledger_to_dnum(ledgerno)].ledger_start)); 999. } 1000. 1001. #endif /* OVL1 */
depth[]
1002. #ifdef OVL0 1003. 1004. /* returns the depth of a level, in floors below the surface */ 1005. /* (note levels in different dungeons can have the same depth). */ 1006. schar 1007. depth(lev) 1008. d_level *lev; 1009. { 1010. return((schar)( dungeons[lev->dnum].depth_start + lev->dlevel - 1)); 1011. } 1012.
on_level[]
1013. boolean 1014. on_level(lev1, lev2) /* are "lev1" and "lev2" actually the same? */ 1015. d_level *lev1, *lev2; 1016. { 1017. return((boolean)((lev1->dnum == lev2->dnum) && (lev1->dlevel == lev2->dlevel))); 1018. } 1019. 1020. #endif /* OVL0 */
Is_special[]
1021. #ifdef OVL1 1022. 1023. /* is this level referenced in the special level chain? */ 1024. s_level * 1025. Is_special(lev) 1026. d_level *lev; 1027. { 1028. s_level *levtmp; 1029. 1030. for (levtmp = sp_levchn; levtmp; levtmp = levtmp->next) 1031. if (on_level(lev, &levtmp->dlevel)) return(levtmp); 1032. 1033. return((s_level *)0); 1034. } 1035.
Is_branchlev[]
1036. /* 1037. * Is this a multi-dungeon branch level? If so, return a pointer to the 1038. * branch. Otherwise, return null. 1039. */ 1040. branch * 1041. Is_branchlev(lev) 1042. d_level *lev; 1043. { 1044. branch *curr; 1045. 1046. for (curr = branches; curr; curr = curr->next) { 1047. if (on_level(lev, &curr->end1) || on_level(lev, &curr->end2)) 1048. return curr; 1049. } 1050. return (branch *) 0; 1051. } 1052.
next_level[]
1053. /* goto the next level (or appropriate dungeon) */ 1054. void 1055. next_level(at_stairs) 1056. boolean at_stairs; 1057. { 1058. if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) { 1059. /* Taking a down dungeon branch. */ 1060. goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE); 1061. } else { 1062. /* Going down a stairs or jump in a trap door. */ 1063. d_level newlevel; 1064. 1065. newlevel.dnum = u.uz.dnum; 1066. newlevel.dlevel = u.uz.dlevel + 1; 1067. goto_level(&newlevel, at_stairs, !at_stairs, FALSE); 1068. } 1069. } 1070.
prev_level[]
1071. /* goto the previous level (or appropriate dungeon) */ 1072. void 1073. prev_level(at_stairs) 1074. boolean at_stairs; 1075. { 1076. if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) { 1077. /* Taking an up dungeon branch. */ 1078. /* KMH -- Upwards branches are okay if not level 1 */ 1079. /* (Just make sure it doesn't go above depth 1) */ 1080. if(!u.uz.dnum && u.uz.dlevel == 1 && !u.uhave.amulet) done(ESCAPED); 1081. else goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE); 1082. } else { 1083. /* Going up a stairs or rising through the ceiling. */ 1084. d_level newlevel; 1085. newlevel.dnum = u.uz.dnum; 1086. newlevel.dlevel = u.uz.dlevel - 1; 1087. goto_level(&newlevel, at_stairs, FALSE, FALSE); 1088. } 1089. } 1090.
u_on_newpos[]
1091. void 1092. u_on_newpos(x, y) 1093. int x, y; 1094. { 1095. u.ux = x; 1096. u.uy = y; 1097. #ifdef CLIPPING 1098. cliparound(u.ux, u.uy); 1099. #endif 1100. #ifdef STEED 1101. /* ridden steed always shares hero's location */ 1102. if (u.usteed) u.usteed->mx = u.ux, u.usteed->my = u.uy; 1103. #endif 1104. } 1105.
u_on_sstairs[]
1106. void 1107. u_on_sstairs() { /* place you on the special staircase */ 1108. 1109. if (sstairs.sx) { 1110. u_on_newpos(sstairs.sx, sstairs.sy); 1111. } else { 1112. /* code stolen from goto_level */ 1113. int trycnt = 0; 1114. xchar x, y; 1115. #ifdef DEBUG 1116. pline("u_on_sstairs: picking random spot"); 1117. #endif 1118. #define badspot(x,y) ((levl[x][y].typ != ROOM && levl[x][y].typ != CORR) || MON_AT(x, y)) 1119. do { 1120. x = rnd(COLNO-1); 1121. y = rn2(ROWNO); 1122. if (!badspot(x, y)) { 1123. u_on_newpos(x, y); 1124. return; 1125. } 1126. } while (++trycnt <= 500); 1127. panic("u_on_sstairs: could not relocate player!"); 1128. #undef badspot 1129. } 1130. } 1131.
u_on_upstairs[]
1132. void 1133. u_on_upstairs() /* place you on upstairs (or special equivalent) */ 1134. { 1135. if (xupstair) { 1136. u_on_newpos(xupstair, yupstair); 1137. } else 1138. u_on_sstairs(); 1139. } 1140.
u_on_dnstairs[]
1141. void 1142. u_on_dnstairs() /* place you on dnstairs (or special equivalent) */ 1143. { 1144. if (xdnstair) { 1145. u_on_newpos(xdnstair, ydnstair); 1146. } else 1147. u_on_sstairs(); 1148. } 1149.
On_stairs[]
1150. boolean 1151. On_stairs(x, y) 1152. xchar x, y; 1153. { 1154. return((boolean)((x == xupstair && y == yupstair) || 1155. (x == xdnstair && y == ydnstair) || 1156. (x == xdnladder && y == ydnladder) || 1157. (x == xupladder && y == yupladder) || 1158. (x == sstairs.sx && y == sstairs.sy))); 1159. } 1160.
Is_botlevel[]
1161. boolean 1162. Is_botlevel(lev) 1163. d_level *lev; 1164. { 1165. return((boolean)(lev->dlevel == dungeons[lev->dnum].num_dunlevs)); 1166. } 1167.
Can_dig_down[]
1168. boolean 1169. Can_dig_down(lev) 1170. d_level *lev; 1171. { 1172. return((boolean)(!level.flags.hardfloor 1173. && !Is_botlevel(lev) && !Invocation_lev(lev))); 1174. } 1175.
Can_fall_thru[]
1176. /* 1177. * Like Can_dig_down (above), but also allows falling through on the 1178. * stronghold level. Normally, the bottom level of a dungeon resists 1179. * both digging and falling. 1180. */ 1181. boolean 1182. Can_fall_thru(lev) 1183. d_level *lev; 1184. { 1185. return((boolean)(Can_dig_down(lev) || Is_stronghold(lev))); 1186. } 1187.
Can_rise_up[]
1188. /* 1189. * True if one can rise up a level (e.g. cursed gain level). 1190. * This happens on intermediate dungeon levels or on any top dungeon 1191. * level that has a stairwell style branch to the next higher dungeon. 1192. * Checks for amulets and such must be done elsewhere. 1193. */ 1194. boolean 1195. Can_rise_up(x, y, lev) 1196. int x, y; 1197. d_level *lev; 1198. { 1199. /* can't rise up from inside the top of the Wizard's tower */ 1200. /* KMH -- or in sokoban */ 1201. if (In_endgame(lev) || In_sokoban(lev) || 1202. (Is_wiz1_level(lev) && In_W_tower(x, y, lev))) 1203. return FALSE; 1204. return (boolean)(lev->dlevel > 1 || 1205. (dungeons[lev->dnum].entry_lev == 1 && ledger_no(lev) != 1 && 1206. sstairs.sx && sstairs.up)); 1207. } 1208.
get_level[]
1209. /* 1210. * It is expected that the second argument of get_level is a depth value, 1211. * either supplied by the user (teleport control) or randomly generated. 1212. * But more than one level can be at the same depth. If the target level 1213. * is "above" the present depth location, get_level must trace "up" from 1214. * the player's location (through the ancestors dungeons) the dungeon 1215. * within which the target level is located. With only one exception 1216. * which does not pass through this routine (see level_tele), teleporting 1217. * "down" is confined to the current dungeon. At present, level teleport 1218. * in dungeons that build up is confined within them. 1219. */ 1220. void 1221. get_level(newlevel, levnum) 1222. d_level *newlevel; 1223. int levnum; 1224. { 1225. branch *br; 1226. xchar dgn = u.uz.dnum; 1227. 1228. if (levnum <= 0) { 1229. /* can only currently happen in endgame */ 1230. levnum = u.uz.dlevel; 1231. } else if (levnum > dungeons[dgn].depth_start 1232. + dungeons[dgn].num_dunlevs - 1) { 1233. /* beyond end of dungeon, jump to last level */ 1234. levnum = dungeons[dgn].num_dunlevs; 1235. } else { 1236. /* The desired level is in this dungeon or a "higher" one. */ 1237. 1238. /* 1239. * Branch up the tree until we reach a dungeon that contains the 1240. * levnum. 1241. */ 1242. if (levnum < dungeons[dgn].depth_start) { 1243. 1244. do { 1245. /* 1246. * Find the parent dungeon of this dungeon. 1247. * 1248. * This assumes that end2 is always the "child" and it is 1249. * unique. 1250. */ 1251. for (br = branches; br; br = br->next) 1252. if (br->end2.dnum == dgn) break; 1253. if (!br) 1254. panic("get_level: can't find parent dungeon"); 1255. 1256. dgn = br->end1.dnum; 1257. } while (levnum < dungeons[dgn].depth_start); 1258. } 1259. 1260. /* We're within the same dungeon; calculate the level. */ 1261. levnum = levnum - dungeons[dgn].depth_start + 1; 1262. } 1263. 1264. newlevel->dnum = dgn; 1265. newlevel->dlevel = levnum; 1266. } 1267. 1268. #endif /* OVL1 */
In_quest[]
1269. #ifdef OVL0 1270. 1271. boolean 1272. In_quest(lev) /* are you in the quest dungeon? */ 1273. d_level *lev; 1274. { 1275. return((boolean)(lev->dnum == quest_dnum)); 1276. } 1277. 1278. #endif /* OVL0 */
In_mines[]
1279. #ifdef OVL1 1280. 1281. boolean 1282. In_mines(lev) /* are you in the mines dungeon? */ 1283. d_level *lev; 1284. { 1285. return((boolean)(lev->dnum == mines_dnum)); 1286. } 1287.
dungeon_branch[]
1288. /* 1289. * Return the branch for the given dungeon. 1290. * 1291. * This function assumes: 1292. * + This is not called with "Dungeons of Doom". 1293. * + There is only _one_ branch to a given dungeon. 1294. * + Field end2 is the "child" dungeon. 1295. */ 1296. branch * 1297. dungeon_branch(s) 1298. const char *s; 1299. { 1300. branch *br; 1301. xchar dnum; 1302. 1303. dnum = dname_to_dnum(s); 1304. 1305. /* Find the branch that connects to dungeon i's branch. */ 1306. for (br = branches; br; br = br->next) 1307. if (br->end2.dnum == dnum) break; 1308. 1309. if (!br) panic("dgn_entrance: can't find entrance to %s", s); 1310. 1311. return br; 1312. } 1313.
at_dgn_entrance[]
1314. /* 1315. * This returns true if the hero is on the same level as the entrance to 1316. * the named dungeon. 1317. * 1318. * Called from do.c and mklev.c. 1319. * 1320. * Assumes that end1 is always the "parent". 1321. */ 1322. boolean 1323. at_dgn_entrance(s) 1324. const char *s; 1325. { 1326. branch *br; 1327. 1328. br = dungeon_branch(s); 1329. return((boolean)(on_level(&u.uz, &br->end1) ? TRUE : FALSE)); 1330. } 1331.
In_V_tower[]
1332. boolean 1333. In_V_tower(lev) /* is `lev' part of Vlad's tower? */ 1334. d_level *lev; 1335. { 1336. return((boolean)(lev->dnum == tower_dnum)); 1337. } 1338.
On_W_tower_level[]
1339. boolean 1340. On_W_tower_level(lev) /* is `lev' a level containing the Wizard's tower? */ 1341. d_level *lev; 1342. { 1343. return (boolean)(Is_wiz1_level(lev) || 1344. Is_wiz2_level(lev) || 1345. Is_wiz3_level(lev)); 1346. } 1347.
In_W_tower[]
1348. boolean 1349. In_W_tower(x, y, lev) /* is <x,y> of `lev' inside the Wizard's tower? */ 1350. int x, y; 1351. d_level *lev; 1352. { 1353. if (!On_W_tower_level(lev)) return FALSE; 1354. /* 1355. * Both of the exclusion regions for arriving via level teleport 1356. * (from above or below) define the tower's boundary. 1357. * assert( updest.nIJ == dndest.nIJ for I={l|h},J={x|y} ); 1358. */ 1359. if (dndest.nlx > 0) 1360. return (boolean)within_bounded_area(x, y, dndest.nlx, dndest.nly, 1361. dndest.nhx, dndest.nhy); 1362. else 1363. impossible("No boundary for Wizard's Tower?"); 1364. return FALSE; 1365. } 1366. 1367. #endif /* OVL1 */
In_hell[]
1368. #ifdef OVL0 1369. 1370. boolean 1371. In_hell(lev) /* are you in one of the Hell levels? */ 1372. d_level *lev; 1373. { 1374. return((boolean)(dungeons[lev->dnum].flags.hellish)); 1375. } 1376. 1377. #endif /* OVL0 */
find_hell[]
1378. #ifdef OVL1 1379. 1380. void 1381. find_hell(lev) /* sets *lev to be the gateway to Gehennom... */ 1382. d_level *lev; 1383. { 1384. lev->dnum = valley_level.dnum; 1385. lev->dlevel = 1; 1386. } 1387.
goto_hell[]
1388. void 1389. goto_hell(at_stairs, falling) /* go directly to hell... */ 1390. boolean at_stairs, falling; 1391. { 1392. d_level lev; 1393. 1394. find_hell(&lev); 1395. goto_level(&lev, at_stairs, falling, FALSE); 1396. } 1397.
assign_level[]
1398. void 1399. assign_level(dest, src) /* equivalent to dest = source */ 1400. d_level *dest, *src; 1401. { 1402. dest->dnum = src->dnum; 1403. dest->dlevel = src->dlevel; 1404. } 1405.
assign_rnd_level[]
1406. void 1407. assign_rnd_level(dest, src, range) /* dest = src + rn1(range) */ 1408. d_level *dest, *src; 1409. int range; 1410. { 1411. dest->dnum = src->dnum; 1412. dest->dlevel = src->dlevel + ((range > 0) ? rnd(range) : -rnd(-range)) ; 1413. 1414. if(dest->dlevel > dunlevs_in_dungeon(dest)) 1415. dest->dlevel = dunlevs_in_dungeon(dest); 1416. else if(dest->dlevel < 1) 1417. dest->dlevel = 1; 1418. } 1419. 1420. #endif /* OVL1 */
induced_align[]
1421. #ifdef OVL0 1422. 1423. int 1424. induced_align(pct) 1425. int pct; 1426. { 1427. s_level *lev = Is_special(&u.uz); 1428. aligntyp al; 1429. 1430. if (lev && lev->flags.align) 1431. if(rn2(100) < pct) return(lev->flags.align); 1432. 1433. if(dungeons[u.uz.dnum].flags.align) 1434. if(rn2(100) < pct) return(dungeons[u.uz.dnum].flags.align); 1435. 1436. al = rn2(3) - 1; 1437. return(Align2amask(al)); 1438. } 1439. 1440. #endif /* OVL0 */
Invocation_lev[]
1441. #ifdef OVL1 1442. 1443. boolean 1444. Invocation_lev(lev) 1445. d_level *lev; 1446. { 1447. return((boolean)(In_hell(lev) && 1448. lev->dlevel == (dungeons[lev->dnum].num_dunlevs - 1))); 1449. } 1450.
level_difficulty[]
1451. /* use instead of depth() wherever a degree of difficulty is made 1452. * dependent on the location in the dungeon (eg. monster creation). 1453. */ 1454. xchar 1455. level_difficulty() 1456. { 1457. if (In_endgame(&u.uz)) 1458. return((xchar)(depth(&sanctum_level) + u.ulevel/2)); 1459. else 1460. if (u.uhave.amulet) 1461. return(deepest_lev_reached(FALSE)); 1462. else 1463. return((xchar) depth(&u.uz)); 1464. } 1465.
lev_by_name[]
1466. /* Take one word and try to match it to a level. 1467. * Recognized levels are as shown by print_dungeon(). 1468. */ 1469. schar 1470. lev_by_name(nam) 1471. const char *nam; 1472. { 1473. schar lev = 0; 1474. s_level *slev; 1475. d_level dlev; 1476. const char *p; 1477. int idx, idxtoo; 1478. char buf[BUFSZ]; 1479. 1480. /* allow strings like "the oracle level" to find "oracle" */ 1481. if (!strncmpi(nam, "the ", 4)) nam += 4; 1482. if ((p = strstri(nam, " level")) != 0 && p == eos((char*)nam) - 6) { 1483. nam = strcpy(buf, nam); 1484. *(eos(buf) - 6) = '\0'; 1485. } 1486. /* hell is the old name, and wouldn't match; gehennom would match its 1487. branch, yielding the castle level instead of the valley of the dead */ 1488. if (!strcmpi(nam, "gehennom") || !strcmpi(nam, "hell")) { 1489. if (In_V_tower(&u.uz)) nam = " to Vlad's tower"; /* branch to... */ 1490. else nam = "valley"; 1491. } 1492. 1493. if ((slev = find_level(nam)) != 0) { 1494. dlev = slev->dlevel; 1495. idx = ledger_no(&dlev); 1496. if ((dlev.dnum == u.uz.dnum || 1497. /* within same branch, or else main dungeon <-> gehennom */ 1498. (u.uz.dnum == valley_level.dnum && 1499. dlev.dnum == medusa_level.dnum) || 1500. (u.uz.dnum == medusa_level.dnum && 1501. dlev.dnum == valley_level.dnum)) && 1502. ( /* either wizard mode or else seen and not forgotten */ 1503. #ifdef WIZARD 1504. wizard || 1505. #endif 1506. (level_info[idx].flags & (FORGOTTEN|VISITED)) == VISITED)) { 1507. lev = depth(&slev->dlevel); 1508. } 1509. } else { /* not a specific level; try branch names */ 1510. idx = find_branch(nam, (struct proto_dungeon *)0); 1511. /* "<branch> to Xyzzy" */ 1512. if (idx < 0 && (p = strstri(nam, " to ")) != 0) 1513. idx = find_branch(p + 4, (struct proto_dungeon *)0); 1514. 1515. if (idx >= 0) { 1516. idxtoo = (idx >> 8) & 0x00FF; 1517. idx &= 0x00FF; 1518. if ( /* either wizard mode, or else _both_ sides of branch seen */ 1519. #ifdef WIZARD 1520. wizard || 1521. #endif 1522. ((level_info[idx].flags & (FORGOTTEN|VISITED)) == VISITED && 1523. (level_info[idxtoo].flags & (FORGOTTEN|VISITED)) == VISITED)) { 1524. if (ledger_to_dnum(idxtoo) == u.uz.dnum) idx = idxtoo; 1525. dlev.dnum = ledger_to_dnum(idx); 1526. dlev.dlevel = ledger_to_dlev(idx); 1527. lev = depth(&dlev); 1528. } 1529. } 1530. } 1531. return lev; 1532. } 1533.
br_string[]
1534. #ifdef WIZARD 1535. 1536. /* Convert a branch type to a string usable by print_dungeon(). */ 1537. STATIC_OVL const char * 1538. br_string(type) 1539. int type; 1540. { 1541. switch (type) { 1542. case BR_PORTAL: return "Portal"; 1543. case BR_NO_END1: return "Connection"; 1544. case BR_NO_END2: return "One way stair"; 1545. case BR_STAIR: return "Stair"; 1546. } 1547. return " (unknown)"; 1548. } 1549.
print_branch[]
1550. /* Print all child branches between the lower and upper bounds. */ 1551. STATIC_OVL void 1552. print_branch(win, dnum, lower_bound, upper_bound, bymenu, lchoices) 1553. winid win; 1554. int dnum; 1555. int lower_bound; 1556. int upper_bound; 1557. boolean bymenu; 1558. struct lchoice *lchoices; 1559. { 1560. branch *br; 1561. char buf[BUFSZ]; 1562. anything any; 1563. 1564. /* This assumes that end1 is the "parent". */ 1565. for (br = branches; br; br = br->next) { 1566. if (br->end1.dnum == dnum && lower_bound < br->end1.dlevel && 1567. br->end1.dlevel <= upper_bound) { 1568. Sprintf(buf," %s to %s: %d", 1569. br_string(br->type), 1570. dungeons[br->end2.dnum].dname, 1571. depth(&br->end1)); 1572. if (bymenu) { 1573. lchoices->lev[lchoices->idx] = br->end1.dlevel; 1574. lchoices->dgn[lchoices->idx] = br->end1.dnum; 1575. lchoices->playerlev[lchoices->idx] = depth(&br->end1); 1576. any.a_void = 0; 1577. any.a_int = lchoices->idx + 1; 1578. add_menu(win, NO_GLYPH, &any, lchoices->menuletter, 1579. 0, ATR_NONE, buf, MENU_UNSELECTED); 1580. if (lchoices->menuletter == 'z') lchoices->menuletter = 'A'; 1581. else lchoices->menuletter++; 1582. lchoices->idx++; 1583. } else 1584. putstr(win, 0, buf); 1585. } 1586. } 1587. } 1588.
print_dungeon[]
1589. /* Print available dungeon information. */ 1590. schar 1591. print_dungeon(bymenu, rlev, rdgn) 1592. boolean bymenu; 1593. schar *rlev; 1594. xchar *rdgn; 1595. { 1596. int i, last_level, nlev; 1597. char buf[BUFSZ]; 1598. boolean first; 1599. s_level *slev; 1600. dungeon *dptr; 1601. branch *br; 1602. anything any; 1603. struct lchoice lchoices; 1604. 1605. winid win = create_nhwindow(NHW_MENU); 1606. if (bymenu) { 1607. start_menu(win); 1608. lchoices.idx = 0; 1609. lchoices.menuletter = 'a'; 1610. } 1611. 1612. for (i = 0, dptr = dungeons; i < n_dgns; i++, dptr++) { 1613. nlev = dptr->num_dunlevs; 1614. if (nlev > 1) 1615. Sprintf(buf, "%s: levels %d to %d", dptr->dname, dptr->depth_start, 1616. dptr->depth_start + nlev - 1); 1617. else 1618. Sprintf(buf, "%s: level %d", dptr->dname, dptr->depth_start); 1619. 1620. /* Most entrances are uninteresting. */ 1621. if (dptr->entry_lev != 1) { 1622. if (dptr->entry_lev == nlev) 1623. Strcat(buf, ", entrance from below"); 1624. else 1625. Sprintf(eos(buf), ", entrance on %d", 1626. dptr->depth_start + dptr->entry_lev - 1); 1627. } 1628. if (bymenu) { 1629. any.a_void = 0; 1630. add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, buf, MENU_UNSELECTED); 1631. } else 1632. putstr(win, 0, buf); 1633. 1634. /* 1635. * Circle through the special levels to find levels that are in 1636. * this dungeon. 1637. */ 1638. for (slev = sp_levchn, last_level = 0; slev; slev = slev->next) { 1639. if (slev->dlevel.dnum != i) continue; 1640. 1641. /* print any branches before this level */ 1642. print_branch(win, i, last_level, slev->dlevel.dlevel, bymenu, &lchoices); 1643. 1644. Sprintf(buf, " %s: %d", slev->proto, depth(&slev->dlevel)); 1645. if (Is_stronghold(&slev->dlevel)) 1646. Sprintf(eos(buf), " (tune %s)", tune); 1647. if (bymenu) { 1648. /* If other floating branches are added, this will need to change */ 1649. if (i != knox_level.dnum) { 1650. lchoices.lev[lchoices.idx] = slev->dlevel.dlevel; 1651. lchoices.dgn[lchoices.idx] = i; 1652. } else { 1653. lchoices.lev[lchoices.idx] = depth(&slev->dlevel); 1654. lchoices.dgn[lchoices.idx] = 0; 1655. } 1656. lchoices.playerlev[lchoices.idx] = depth(&slev->dlevel); 1657. any.a_void = 0; 1658. any.a_int = lchoices.idx + 1; 1659. add_menu(win, NO_GLYPH, &any, lchoices.menuletter, 1660. 0, ATR_NONE, buf, MENU_UNSELECTED); 1661. if (lchoices.menuletter == 'z') lchoices.menuletter = 'A'; 1662. else lchoices.menuletter++; 1663. lchoices.idx++; 1664. } else 1665. putstr(win, 0, buf); 1666. 1667. last_level = slev->dlevel.dlevel; 1668. } 1669. /* print branches after the last special level */ 1670. print_branch(win, i, last_level, MAXLEVEL, bymenu, &lchoices); 1671. } 1672. 1673. /* Print out floating branches (if any). */ 1674. for (first = TRUE, br = branches; br; br = br->next) { 1675. if (br->end1.dnum == n_dgns) { 1676. if (first) { 1677. if (!bymenu) { 1678. putstr(win, 0, ""); 1679. putstr(win, 0, "Floating branches"); 1680. } 1681. first = FALSE; 1682. } 1683. Sprintf(buf, " %s to %s", 1684. br_string(br->type), dungeons[br->end2.dnum].dname); 1685. if (!bymenu) 1686. putstr(win, 0, buf); 1687. } 1688. } 1689. if (bymenu) { 1690. int n; 1691. menu_item *selected; 1692. int idx; 1693. 1694. end_menu(win, "Level teleport to where:"); 1695. n = select_menu(win, PICK_ONE, &selected); 1696. destroy_nhwindow(win); 1697. if (n > 0) { 1698. idx = selected[0].item.a_int - 1; 1699. free((genericptr_t)selected); 1700. if (rlev && rdgn) { 1701. *rlev = lchoices.lev[idx]; 1702. *rdgn = lchoices.dgn[idx]; 1703. return lchoices.playerlev[idx]; 1704. } 1705. } 1706. return 0; 1707. } 1708. 1709. /* I hate searching for the invocation pos while debugging. -dean */ 1710. if (Invocation_lev(&u.uz)) { 1711. putstr(win, 0, ""); 1712. Sprintf(buf, "Invocation position @ (%d,%d), hero @ (%d,%d)", 1713. inv_pos.x, inv_pos.y, u.ux, u.uy); 1714. putstr(win, 0, buf); 1715. } 1716. /* 1717. * The following is based on the assumption that the inter-level portals 1718. * created by the level compiler (not the dungeon compiler) only exist 1719. * one per level (currently true, of course). 1720. */ 1721. else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz) 1722. || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)) { 1723. struct trap *trap; 1724. for (trap = ftrap; trap; trap = trap->ntrap) 1725. if (trap->ttyp == MAGIC_PORTAL) break; 1726. 1727. putstr(win, 0, ""); 1728. if (trap) 1729. Sprintf(buf, "Portal @ (%d,%d), hero @ (%d,%d)", 1730. trap->tx, trap->ty, u.ux, u.uy); 1731. else 1732. Sprintf(buf, "No portal found."); 1733. putstr(win, 0, buf); 1734. } 1735. 1736. display_nhwindow(win, TRUE); 1737. destroy_nhwindow(win); 1738. return 0; 1739. } 1740. #endif /* WIZARD */ 1741. 1742. #endif /* OVL1 */ 1743. 1744. /*dungeon.c*/