About: Source:NetHack 3.4.0/dungeon.c   Sponge Permalink

An Entity of Type : owl:Thing, within Data Space : 134.155.108.49:8890 associated with source dataset(s)

Below is the full text to dungeon.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.0/dungeon.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code

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