Source:SLASH'EM 0.0.7E7F2/dungeon.c
Jump to navigation
Jump to search
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 [[Source:SLASH'EM 0.0.7E7F2/dungeon.c#line123]], for example.
Source code for vanilla NetHack is at Source code.
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
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*/