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