About: Source:NetHack 3.3.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.3.0. To link to a particular line, write [[NetHack 3.3.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.3.0/dungeon.c
rdfs:comment
  • Below is the full text to dungeon.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.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.3.0. To link to a particular line, write [[NetHack 3.3.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.3 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) ((((long)(bp)->end1.dnum * (MAXLEVEL+1) + (long)(bp)->end1.dlevel) * (MAXDUNGEON+1) * (MAXLEVEL+1)) + ((long)(bp)->end2.dnum * (MAXLEVEL+1) + (long)(bp)->end2.dlevel)) 384. 385. /* 386. * Insert the new branch into the correct place in the branch list. 387. */ 388. prev = (branch *) 0; 389. prev_val = -1; 390. new_val = branch_val(new_branch); 391. for (curr = branches; curr; 392. prev_val = curr_val, prev = curr, curr = curr->next) { 393. curr_val = branch_val(curr); 394. if (prev_val < new_val && new_val <= curr_val) break; 395. } 396. if (prev) { 397. new_branch->next = curr; 398. prev->next = new_branch; 399. } else { 400. new_branch->next = branches; 401. branches = new_branch; 402. } 403. } 404. 405. /* Add a dungeon branch to the branch list. */ 406. STATIC_OVL branch * 407. add_branch(dgn, child_entry_level, pd) 408. int dgn; 409. int child_entry_level; 410. struct proto_dungeon *pd; 411. { 412. static int branch_id = 0; 413. int branch_num; 414. branch *new_branch; 415. 416. branch_num = find_branch(dungeons[dgn].dname,pd); 417. new_branch = (branch *) alloc(sizeof(branch)); 418. new_branch->next = (branch *) 0; 419. new_branch->id = branch_id++; 420. new_branch->type = correct_branch_type(&pd->tmpbranch[branch_num]); 421. new_branch->end1.dnum = parent_dnum(dungeons[dgn].dname, pd); 422. new_branch->end1.dlevel = parent_dlevel(dungeons[dgn].dname, pd); 423. new_branch->end2.dnum = dgn; 424. new_branch->end2.dlevel = child_entry_level; 425. new_branch->end1_up = pd->tmpbranch[branch_num].up ? TRUE : FALSE; 426. 427. insert_branch(new_branch, FALSE); 428. return new_branch; 429. } 430. 431. /* 432. * Add new level to special level chain. Insert it in level order with the 433. * other levels in this dungeon. This assumes that we are never given a 434. * level that has a dungeon number less than the dungeon number of the 435. * last entry. 436. */ 437. STATIC_OVL void 438. add_level(new_lev) 439. s_level *new_lev; 440. { 441. s_level *prev, *curr; 442. 443. prev = (s_level *) 0; 444. for (curr = sp_levchn; curr; curr = curr->next) { 445. if (curr->dlevel.dnum == new_lev->dlevel.dnum && 446. curr->dlevel.dlevel > new_lev->dlevel.dlevel) 447. break; 448. prev = curr; 449. } 450. if (!prev) { 451. new_lev->next = sp_levchn; 452. sp_levchn = new_lev; 453. } else { 454. new_lev->next = curr; 455. prev->next = new_lev; 456. } 457. } 458. 459. STATIC_OVL void 460. init_level(dgn, proto_index, pd) 461. int dgn, proto_index; 462. struct proto_dungeon *pd; 463. { 464. s_level *new_level; 465. struct tmplevel *tlevel = &pd->tmplevel[proto_index]; 466. 467. pd->final_lev[proto_index] = (s_level *) 0; /* no "real" level */ 468. #ifdef WIZARD 469. if (!wizard) 470. #endif 471. if (tlevel->chance <= rn2(100)) return; 472. 473. pd->final_lev[proto_index] = new_level = 474. (s_level *) alloc(sizeof(s_level)); 475. /* load new level with data */ 476. Strcpy(new_level->proto, tlevel->name); 477. new_level->boneid = tlevel->boneschar; 478. new_level->dlevel.dnum = dgn; 479. new_level->dlevel.dlevel = 0; /* for now */ 480. 481. new_level->flags.town = !!(tlevel->flags & TOWN); 482. new_level->flags.hellish = !!(tlevel->flags & HELLISH); 483. new_level->flags.maze_like = !!(tlevel->flags & MAZELIKE); 484. new_level->flags.rogue_like = !!(tlevel->flags & ROGUELIKE); 485. new_level->flags.align = ((tlevel->flags & D_ALIGN_MASK) >> 4); 486. 487. new_level->rndlevs = tlevel->rndlevs; 488. new_level->next = (s_level *) 0; 489. } 490. 491. STATIC_OVL int 492. possible_places(idx, map, pd) 493. int idx; /* prototype index */ 494. boolean *map; /* array MAXLEVEL+1 in length */ 495. struct proto_dungeon *pd; 496. { 497. int i, start, count; 498. s_level *lev = pd->final_lev[idx]; 499. 500. /* init level possibilities */ 501. for (i = 0; i <= MAXLEVEL; i++) map[i] = FALSE; 502. 503. /* get base and range and set those entried to true */ 504. count = level_range(lev->dlevel.dnum, pd->tmplevel[idx].lev.base, 505. pd->tmplevel[idx].lev.rand, 506. pd->tmplevel[idx].chain, 507. pd, &start); 508. for (i = start; i < start+count; i++) 509. map[i] = TRUE; 510. 511. /* mark off already placed levels */ 512. for (i = pd->start; i < idx; i++) { 513. if (pd->final_lev[i] && map[pd->final_lev[i]->dlevel.dlevel]) { 514. map[pd->final_lev[i]->dlevel.dlevel] = FALSE; 515. --count; 516. } 517. } 518. 519. return count; 520. } 521. 522. /* Pick the nth TRUE entry in the given boolean array. */ 523. STATIC_OVL xchar 524. pick_level(map, nth) 525. boolean *map; /* an array MAXLEVEL+1 in size */ 526. int nth; 527. { 528. int i; 529. for (i = 1; i <= MAXLEVEL; i++) 530. if (map[i] && !nth--) return (xchar) i; 531. panic("pick_level: ran out of valid levels"); 532. return 0; 533. } 534. 535. #ifdef DDEBUG 536. static void FDECL(indent,(int)); 537. 538. static void 539. indent(d) 540. int d; 541. { 542. while (d-- > 0) fputs(" ", stderr); 543. } 544. #endif 545. 546. /* 547. * Place a level. First, find the possible places on a dungeon map 548. * template. Next pick one. Then try to place the next level. If 549. * sucessful, we're done. Otherwise, try another (and another) until 550. * all possible places have been tried. If all possible places have 551. * been exausted, return false. 552. */ 553. STATIC_OVL boolean 554. place_level(proto_index, pd) 555. int proto_index; 556. struct proto_dungeon *pd; 557. { 558. boolean map[MAXLEVEL+1]; /* valid levels are 1..MAXLEVEL inclusive */ 559. s_level *lev; 560. int npossible; 561. #ifdef DDEBUG 562. int i; 563. #endif 564. 565. if (proto_index == pd->n_levs) return TRUE; /* at end of proto levels */ 566. 567. lev = pd->final_lev[proto_index]; 568. 569. /* No level created for this prototype, goto next. */ 570. if (!lev) return place_level(proto_index+1, pd); 571. 572. npossible = possible_places(proto_index, map, pd); 573. 574. for (; npossible; --npossible) { 575. lev->dlevel.dlevel = pick_level(map, rn2(npossible)); 576. #ifdef DDEBUG 577. indent(proto_index-pd->start); 578. fprintf(stderr,"%s: trying %d [ ", lev->proto, lev->dlevel.dlevel); 579. for (i = 1; i <= MAXLEVEL; i++) 580. if (map[i]) fprintf(stderr,"%d ", i); 581. fprintf(stderr,"] "); 582. #endif 583. if (place_level(proto_index+1, pd)) return TRUE; 584. map[lev->dlevel.dlevel] = FALSE; /* this choice didn't work */ 585. } 586. #ifdef DDEBUG 587. indent(proto_index-pd->start); 588. fprintf(stderr,"%s: failed ", lev->proto); 589. #endif 590. return FALSE; 591. } 592. 593. 594. struct level_map { 595. const char *lev_name; 596. d_level *lev_spec; 597. } level_map[] = { 598. { "air", &air_level }, 599. { "asmodeus", &asmodeus_level }, 600. { "astral", &astral_level }, 601. { "baalz", &baalzebub_level }, 602. { "bigroom", &bigroom_level }, 603. { "castle", &stronghold_level }, 604. { "earth", &earth_level }, 605. { "fakewiz1", &portal_level }, 606. { "fire", &fire_level }, 607. { "juiblex", &juiblex_level }, 608. { "knox", &knox_level }, 609. { "medusa", &medusa_level }, 610. { "oracle", &oracle_level }, 611. { "orcus", &orcus_level }, 612. #ifdef REINCARNATION 613. { "rogue", &rogue_level }, 614. #endif 615. { "sanctum", &sanctum_level }, 616. { "valley", &valley_level }, 617. { "water", &water_level }, 618. { "wizard1", &wiz1_level }, 619. { "wizard2", &wiz2_level }, 620. { "wizard3", &wiz3_level }, 621. { X_START, &qstart_level }, 622. { X_LOCATE, &qlocate_level }, 623. { X_GOAL, &nemesis_level }, 624. { "", (d_level *)0 } 625. }; 626. 627. void 628. init_dungeons() /* initialize the "dungeon" structs */ 629. { 630. dlb *dgn_file; 631. register int i, cl = 0, cb = 0; 632. register s_level *x; 633. struct proto_dungeon pd; 634. struct level_map *lev_map; 635. struct version_info vers_info; 636. 637. pd.n_levs = pd.n_brs = 0; 638. 639. dgn_file = dlb_fopen(DUNGEON_FILE, RDBMODE); 640. if (!dgn_file) 641. panic("Cannot open dungeon description file \"%s\"!", DUNGEON_FILE); 642. 643. /* validate the data's version against the program's version */ 644. Fread((genericptr_t) &vers_info, sizeof vers_info, 1, dgn_file); 645. if (!check_version(&vers_info, DUNGEON_FILE, TRUE)) 646. panic("Dungeon description not valid."); 647. 648. /* 649. * Read in each dungeon and transfer the results to the internal 650. * dungeon arrays. 651. */ 652. sp_levchn = (s_level *) 0; 653. Fread((genericptr_t)&n_dgns, sizeof(int), 1, dgn_file); 654. if (n_dgns >= MAXDUNGEON) 655. panic("init_dungeons: too many dungeons"); 656. 657. for (i = 0; i < n_dgns; i++) { 658. Fread((genericptr_t)&pd.tmpdungeon[i], 659. sizeof(struct tmpdungeon), 1, dgn_file); 660. #ifdef WIZARD 661. if(!wizard) 662. #endif 663. if(pd.tmpdungeon[i].chance && (pd.tmpdungeon[i].chance <= rn2(100))) { 664. int j; 665. 666. /* skip over any levels or branches */ 667. for(j = 0; j < pd.tmpdungeon[i].levels; j++) 668. Fread((genericptr_t)&pd.tmplevel[cl], sizeof(struct tmplevel), 669. 1, dgn_file); 670. 671. for(j = 0; j < pd.tmpdungeon[i].branches; j++) 672. Fread((genericptr_t)&pd.tmpbranch[cb], 673. sizeof(struct tmpbranch), 1, dgn_file); 674. n_dgns--; i--; 675. continue; 676. } 677. 678. Strcpy(dungeons[i].dname, pd.tmpdungeon[i].name); 679. Strcpy(dungeons[i].proto, pd.tmpdungeon[i].protoname); 680. dungeons[i].boneid = pd.tmpdungeon[i].boneschar; 681. 682. if(pd.tmpdungeon[i].lev.rand) 683. dungeons[i].num_dunlevs = (xchar)rn1(pd.tmpdungeon[i].lev.rand, 684. pd.tmpdungeon[i].lev.base); 685. else dungeons[i].num_dunlevs = (xchar)pd.tmpdungeon[i].lev.base; 686. 687. if(!i) { 688. dungeons[i].ledger_start = 0; 689. dungeons[i].depth_start = 1; 690. dungeons[i].dunlev_ureached = 1; 691. } else { 692. dungeons[i].ledger_start = dungeons[i-1].ledger_start + 693. dungeons[i-1].num_dunlevs; 694. dungeons[i].dunlev_ureached = 0; 695. } 696. 697. dungeons[i].flags.hellish = !!(pd.tmpdungeon[i].flags & HELLISH); 698. dungeons[i].flags.maze_like = !!(pd.tmpdungeon[i].flags & MAZELIKE); 699. dungeons[i].flags.rogue_like = !!(pd.tmpdungeon[i].flags & ROGUELIKE); 700. dungeons[i].flags.align = ((pd.tmpdungeon[i].flags & D_ALIGN_MASK) >> 4); 701. /* 702. * Set the entry level for this dungeon. The pd.tmpdungeon entry 703. * value means: 704. * < 0 from bottom (-1 == bottom level) 705. * 0 default (top) 706. * > 0 actual level (1 = top) 707. * 708. * Note that the entry_lev field in the dungeon structure is 709. * redundant. It is used only here and in print_dungeon(). 710. */ 711. if (pd.tmpdungeon[i].entry_lev < 0) { 712. dungeons[i].entry_lev = dungeons[i].num_dunlevs + 713. pd.tmpdungeon[i].entry_lev + 1; 714. if (dungeons[i].entry_lev <= 0) dungeons[i].entry_lev = 1; 715. } else if (pd.tmpdungeon[i].entry_lev > 0) { 716. dungeons[i].entry_lev = pd.tmpdungeon[i].entry_lev; 717. if (dungeons[i].entry_lev > dungeons[i].num_dunlevs) 718. dungeons[i].entry_lev = pd.tmpdungeon[i].entry_lev; 719. } else { /* default */ 720. dungeons[i].entry_lev = 1; /* defaults to top level */ 721. } 722. 723. if (i) { /* set depth */ 724. branch *br; 725. schar from_depth; 726. boolean from_up; 727. 728. br = add_branch(i, dungeons[i].entry_lev, &pd); 729. 730. /* Get the depth of the connecting end. */ 731. if (br->end1.dnum == i) { 732. from_depth = depth(&br->end2); 733. from_up = !br->end1_up; 734. } else { 735. from_depth = depth(&br->end1); 736. from_up = br->end1_up; 737. } 738. 739. /* 740. * Calculate the depth of the top of the dungeon via 741. * its branch. First, the depth of the entry point: 742. * 743. * depth of branch from "parent" dungeon 744. * + -1 or 1 depending on a up or down stair or 745. * 0 if portal 746. * 747. * Followed by the depth of the top of the dungeon: 748. * 749. * - (entry depth - 1) 750. * 751. * We'll say that portals stay on the same depth. 752. */ 753. dungeons[i].depth_start = from_depth 754. + (br->type == BR_PORTAL ? 0 : 755. (from_up ? -1 : 1)) 756. - (dungeons[i].entry_lev - 1); 757. } 758. 759. /* this is redundant - it should have been flagged by dgn_comp */ 760. if(dungeons[i].num_dunlevs > MAXLEVEL) 761. dungeons[i].num_dunlevs = MAXLEVEL; 762. 763. pd.start = pd.n_levs; /* save starting point */ 764. pd.n_levs += pd.tmpdungeon[i].levels; 765. if (pd.n_levs > LEV_LIMIT) 766. panic("init_dungeon: too many special levels"); 767. /* 768. * Read in the prototype special levels. Don't add generated 769. * special levels until they are all placed. 770. */ 771. for(; cl < pd.n_levs; cl++) { 772. Fread((genericptr_t)&pd.tmplevel[cl], 773. sizeof(struct tmplevel), 1, dgn_file); 774. init_level(i, cl, &pd); 775. } 776. /* 777. * Recursively place the generated levels for this dungeon. This 778. * routine will attempt all possible combinations before giving 779. * up. 780. */ 781. if (!place_level(pd.start, &pd)) 782. panic("init_dungeon: couldn't place levels"); 783. #ifdef DDEBUG 784. fprintf(stderr, "--- end of dungeon %d --- ", i); 785. fflush(stderr); 786. getchar(); 787. #endif 788. for (; pd.start < pd.n_levs; pd.start++) 789. if (pd.final_lev[pd.start]) add_level(pd.final_lev[pd.start]); 790. 791. 792. pd.n_brs += pd.tmpdungeon[i].branches; 793. if (pd.n_brs > BRANCH_LIMIT) 794. panic("init_dungeon: too many branches"); 795. for(; cb < pd.n_brs; cb++) 796. Fread((genericptr_t)&pd.tmpbranch[cb], 797. sizeof(struct tmpbranch), 1, dgn_file); 798. } 799. (void) dlb_fclose(dgn_file); 800. 801. for (i = 0; i < 5; i++) tune[i] = 'A' + rn2(7); 802. tune[5] = 0; 803. 804. /* 805. * Find most of the special levels and dungeons so we can access their 806. * locations quickly. 807. */ 808. for (lev_map = level_map; lev_map->lev_name[0]; lev_map++) { 809. x = find_level(lev_map->lev_name); 810. if (x) { 811. assign_level(lev_map->lev_spec, &x->dlevel); 812. if (!strncmp(lev_map->lev_name, "x-", 2)) { 813. /* This is where the name substitution on the 814. * levels of the quest dungeon occur. 815. */ 816. Sprintf(x->proto, "%s%s", urole.filecode, &lev_map->lev_name[1]); 817. } else if (lev_map->lev_spec == &knox_level) { 818. branch *br; 819. /* 820. * Kludge to allow floating Knox entrance. We 821. * specify a floating entrance by the fact that 822. * its entrance (end1) has a bogus dnum, namely 823. * n_dgns. 824. */ 825. for (br = branches; br; br = br->next) 826. if (on_level(&br->end2, &knox_level)) break; 827. 828. if (br) br->end1.dnum = n_dgns; 829. /* adjust the branch's position on the list */ 830. insert_branch(br, TRUE); 831. } 832. } 833. } 834. /* 835. * I hate hardwiring these names. :-( 836. */ 837. quest_dnum = dname_to_dnum("The Quest"); 838. sokoban_dnum = dname_to_dnum("Sokoban"); 839. mines_dnum = dname_to_dnum("The Gnomish Mines"); 840. tower_dnum = dname_to_dnum("Vlad's Tower"); 841. 842. /* one special fixup for dummy surface level */ 843. if ((x = find_level("dummy")) != 0) { 844. i = x->dlevel.dnum; 845. /* the code above puts earth one level above dungeon level #1, 846. making the dummy level overlay level 1; but the whole reason 847. for having the dummy level is to make earth have depth -1 848. instead of 0, so adjust the start point to shift endgame up */ 849. if (dunlevs_in_dungeon(&x->dlevel) > 1 - dungeons[i].depth_start) 850. dungeons[i].depth_start -= 1; 851. /* TO DO: strip "dummy" out all the way here, 852. so that it's hidden from feedback. */ 853. } 854. 855. #ifdef DEBUG 856. dumpit(); 857. #endif 858. } 859. 860. xchar 861. dunlev(lev) /* return the level number for lev in *this* dungeon */ 862. d_level *lev; 863. { 864. return(lev->dlevel); 865. } 866. 867. xchar 868. dunlevs_in_dungeon(lev) /* return the lowest level number for *this* dungeon*/ 869. d_level *lev; 870. { 871. return(dungeons[lev->dnum].num_dunlevs); 872. } 873. 874. xchar 875. deepest_lev_reached(noquest) /* return the lowest level explored in the game*/ 876. boolean noquest; 877. { 878. /* this function is used for three purposes: to provide a factor 879. * of difficulty in monster generation; to provide a factor of 880. * difficulty in experience calculations (botl.c and end.c); and 881. * to insert the deepest level reached in the game in the topten 882. * display. the 'noquest' arg switch is required for the latter. 883. * 884. * from the player's point of view, going into the Quest is _not_ 885. * going deeper into the dungeon -- it is going back "home", where 886. * the dungeon starts at level 1. given the setup in dungeon.def, 887. * the depth of the Quest (thought of as starting at level 1) is 888. * never lower than the level of entry into the Quest, so we exclude 889. * the Quest from the topten "deepest level reached" display 890. * calculation. _However_ the Quest is a difficult dungeon, so we 891. * include it in the factor of difficulty calculations. 892. */ 893. register int i; 894. d_level tmp; 895. register schar ret = 0; 896. 897. for(i = 0; i < n_dgns; i++) { 898. if((tmp.dlevel = dungeons[i].dunlev_ureached) == 0) continue; 899. if(!strcmp(dungeons[i].dname, "The Quest") && noquest) continue; 900. 901. tmp.dnum = i; 902. if(depth(&tmp) > ret) ret = depth(&tmp); 903. } 904. return((xchar) ret); 905. } 906. 907. /* return a bookkeeping level number for purpose of comparisons and 908. * save/restore */ 909. xchar 910. ledger_no(lev) 911. d_level *lev; 912. { 913. return((xchar)(lev->dlevel + dungeons[lev->dnum].ledger_start)); 914. } 915. 916. /* 917. * The last level in the bookkeeping list of level is the bottom of the last 918. * dungeon in the dungeons[] array. 919. * 920. * Maxledgerno() -- which is the max number of levels in the bookkeeping 921. * list, should not be confused with dunlevs_in_dungeon(lev) -- which 922. * returns the max number of levels in lev's dungeon, and both should 923. * not be confused with deepest_lev_reached() -- which returns the lowest 924. * depth visited by the player. 925. */ 926. xchar 927. maxledgerno() 928. { 929. return (xchar) (dungeons[n_dgns-1].ledger_start + 930. dungeons[n_dgns-1].num_dunlevs); 931. } 932. 933. /* return the dungeon that this ledgerno exists in */ 934. xchar 935. ledger_to_dnum(ledgerno) 936. xchar ledgerno; 937. { 938. register int i; 939. 940. /* find i such that (i->base + 1) <= ledgerno <= (i->base + i->count) */ 941. for (i = 0; i < n_dgns; i++) 942. if (dungeons[i].ledger_start < ledgerno && 943. ledgerno <= dungeons[i].ledger_start + dungeons[i].num_dunlevs) 944. return (xchar)i; 945. 946. panic("level number out of range [ledger_to_dnum(%d)]", (int)ledgerno); 947. /*NOT REACHED*/ 948. return (xchar)0; 949. } 950. 951. /* return the level of the dungeon this ledgerno exists in */ 952. xchar 953. ledger_to_dlev(ledgerno) 954. xchar ledgerno; 955. { 956. return((xchar)(ledgerno - dungeons[ledger_to_dnum(ledgerno)].ledger_start)); 957. } 958. 959. #endif /* OVL1 */ 960. #ifdef OVL0 961. 962. /* returns the depth of a level, in floors below the surface */ 963. /* (note levels in different dungeons can have the same depth). */ 964. schar 965. depth(lev) 966. d_level *lev; 967. { 968. return((schar)( dungeons[lev->dnum].depth_start + lev->dlevel - 1)); 969. } 970. 971. boolean 972. on_level(lev1, lev2) /* are "lev1" and "lev2" actually the same? */ 973. d_level *lev1, *lev2; 974. { 975. return((boolean)((lev1->dnum == lev2->dnum) && (lev1->dlevel == lev2->dlevel))); 976. } 977. 978. #endif /* OVL0 */ 979. #ifdef OVL1 980. 981. /* is this level referenced in the special level chain? */ 982. s_level * 983. Is_special(lev) 984. d_level *lev; 985. { 986. s_level *levtmp; 987. 988. for (levtmp = sp_levchn; levtmp; levtmp = levtmp->next) 989. if (on_level(lev, &levtmp->dlevel)) return(levtmp); 990. 991. return((s_level *)0); 992. } 993. 994. /* 995. * Is this a multi-dungeon branch level? If so, return a pointer to the 996. * branch. Otherwise, return null. 997. */ 998. branch * 999. Is_branchlev(lev) 1000. d_level *lev; 1001. { 1002. branch *curr; 1003. 1004. for (curr = branches; curr; curr = curr->next) { 1005. if (on_level(lev, &curr->end1) || on_level(lev, &curr->end2)) 1006. return curr; 1007. } 1008. return (branch *) 0; 1009. } 1010. 1011. /* goto the next level (or appropriate dungeon) */ 1012. void 1013. next_level(at_stairs) 1014. boolean at_stairs; 1015. { 1016. if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) { 1017. /* Taking a down dungeon branch. */ 1018. goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE); 1019. } else { 1020. /* Going down a stairs or jump in a trap door. */ 1021. d_level newlevel; 1022. 1023. newlevel.dnum = u.uz.dnum; 1024. newlevel.dlevel = u.uz.dlevel + 1; 1025. goto_level(&newlevel, at_stairs, !at_stairs, FALSE); 1026. } 1027. } 1028. 1029. /* goto the previous level (or appropriate dungeon) */ 1030. void 1031. prev_level(at_stairs) 1032. boolean at_stairs; 1033. { 1034. if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) { 1035. /* Taking an up dungeon branch. */ 1036. /* KMH -- Upwards branches are okay if not level 1 */ 1037. /* (Just make sure it doesn't go above depth 1) */ 1038. if(!u.uz.dnum && u.uz.dlevel == 1 && !u.uhave.amulet) done(ESCAPED); 1039. else goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE); 1040. } else { 1041. /* Going up a stairs or rising through the ceiling. */ 1042. d_level newlevel; 1043. newlevel.dnum = u.uz.dnum; 1044. newlevel.dlevel = u.uz.dlevel - 1; 1045. goto_level(&newlevel, at_stairs, FALSE, FALSE); 1046. } 1047. } 1048. 1049. void 1050. u_on_newpos(x, y) 1051. int x, y; 1052. { 1053. u.ux = x; 1054. u.uy = y; 1055. #ifdef CLIPPING 1056. cliparound(u.ux, u.uy); 1057. #endif 1058. #ifdef STEED 1059. /* ridden steed always shares hero's location */ 1060. if (u.usteed) u.usteed->mx = u.ux, u.usteed->my = u.uy; 1061. #endif 1062. } 1063. 1064. void 1065. u_on_sstairs() { /* place you on the special staircase */ 1066. 1067. if (sstairs.sx) { 1068. u_on_newpos(sstairs.sx, sstairs.sy); 1069. } else { 1070. /* code stolen from goto_level */ 1071. int trycnt = 0; 1072. xchar x, y; 1073. #ifdef DEBUG 1074. pline("u_on_sstairs: picking random spot"); 1075. #endif 1076. #define badspot(x,y) ((levl[x][y].typ != ROOM && levl[x][y].typ != CORR) || MON_AT(x, y)) 1077. do { 1078. x = rnd(COLNO-1); 1079. y = rn2(ROWNO); 1080. if (!badspot(x, y)) { 1081. u_on_newpos(x, y); 1082. return; 1083. } 1084. } while (++trycnt <= 500); 1085. panic("u_on_sstairs: could not relocate player!"); 1086. #undef badspot 1087. } 1088. } 1089. 1090. void 1091. u_on_upstairs() /* place you on upstairs (or special equivalent) */ 1092. { 1093. if (xupstair) { 1094. u_on_newpos(xupstair, yupstair); 1095. } else 1096. u_on_sstairs(); 1097. } 1098. 1099. void 1100. u_on_dnstairs() /* place you on dnstairs (or special equivalent) */ 1101. { 1102. if (xdnstair) { 1103. u_on_newpos(xdnstair, ydnstair); 1104. } else 1105. u_on_sstairs(); 1106. } 1107. 1108. boolean 1109. On_stairs(x, y) 1110. xchar x, y; 1111. { 1112. return((boolean)((x == xupstair && y == yupstair) || 1113. (x == xdnstair && y == ydnstair) || 1114. (x == xdnladder && y == ydnladder) || 1115. (x == xupladder && y == yupladder) || 1116. (x == sstairs.sx && y == sstairs.sy))); 1117. } 1118. 1119. boolean 1120. Is_botlevel(lev) 1121. d_level *lev; 1122. { 1123. return((boolean)(lev->dlevel == dungeons[lev->dnum].num_dunlevs)); 1124. } 1125. 1126. boolean 1127. Can_dig_down(lev) 1128. d_level *lev; 1129. { 1130. return((boolean)(!level.flags.hardfloor 1131. && !Is_botlevel(lev) && !Invocation_lev(lev))); 1132. } 1133. 1134. /* 1135. * Like Can_dig_down (above), but also allows falling through on the 1136. * stronghold level. Normally, the bottom level of a dungeon resists 1137. * both digging and falling. 1138. */ 1139. boolean 1140. Can_fall_thru(lev) 1141. d_level *lev; 1142. { 1143. return((boolean)(Can_dig_down(lev) || Is_stronghold(lev))); 1144. } 1145. 1146. /* 1147. * True if one can rise up a level (e.g. cursed gain level). 1148. * This happens on intermediate dungeon levels or on any top dungeon 1149. * level that has a stairwell style branch to the next higher dungeon. 1150. * Checks for amulets and such must be done elsewhere. 1151. */ 1152. boolean 1153. Can_rise_up(x, y, lev) 1154. int x, y; 1155. d_level *lev; 1156. { 1157. /* can't rise up from inside the top of the Wizard's tower */ 1158. /* KMH -- or in sokoban */ 1159. if (In_endgame(lev) || In_sokoban(lev) || 1160. (Is_wiz1_level(lev) && In_W_tower(x, y, lev))) 1161. return FALSE; 1162. return (boolean)(lev->dlevel > 1 || 1163. (dungeons[lev->dnum].entry_lev == 1 && ledger_no(lev) != 1 && 1164. sstairs.sx && sstairs.up)); 1165. } 1166. 1167. /* 1168. * It is expected that the second argument of get_level is a depth value, 1169. * either supplied by the user (teleport control) or randomly generated. 1170. * But more than one level can be at the same depth. If the target level 1171. * is "above" the present depth location, get_level must trace "up" from 1172. * the player's location (through the ancestors dungeons) the dungeon 1173. * within which the target level is located. With only one exception 1174. * which does not pass through this routine (see level_tele), teleporting 1175. * "down" is confined to the current dungeon. At present, level teleport 1176. * in dungeons that build up is confined within them. 1177. */ 1178. void 1179. get_level(newlevel, levnum) 1180. d_level *newlevel; 1181. int levnum; 1182. { 1183. branch *br; 1184. xchar dgn = u.uz.dnum; 1185. 1186. if (levnum <= 0) { 1187. /* can only currently happen in endgame */ 1188. levnum = u.uz.dlevel; 1189. } else if (levnum > dungeons[dgn].depth_start 1190. + dungeons[dgn].num_dunlevs - 1) { 1191. /* beyond end of dungeon, jump to last level */ 1192. levnum = dungeons[dgn].num_dunlevs; 1193. } else { 1194. /* The desired level is in this dungeon or a "higher" one. */ 1195. 1196. /* 1197. * Branch up the tree until we reach a dungeon that contains the 1198. * levnum. 1199. */ 1200. if (levnum < dungeons[dgn].depth_start) { 1201. 1202. do { 1203. /* 1204. * Find the parent dungeon of this dungeon. 1205. * 1206. * This assumes that end2 is always the "child" and it is 1207. * unique. 1208. */ 1209. for (br = branches; br; br = br->next) 1210. if (br->end2.dnum == dgn) break; 1211. if (!br) 1212. panic("get_level: can't find parent dungeon"); 1213. 1214. dgn = br->end1.dnum; 1215. } while (levnum < dungeons[dgn].depth_start); 1216. } 1217. 1218. /* We're within the same dungeon; calculate the level. */ 1219. levnum = levnum - dungeons[dgn].depth_start + 1; 1220. } 1221. 1222. newlevel->dnum = dgn; 1223. newlevel->dlevel = levnum; 1224. } 1225. 1226. #endif /* OVL1 */ 1227. #ifdef OVL0 1228. 1229. boolean 1230. In_quest(lev) /* are you in the quest dungeon? */ 1231. d_level *lev; 1232. { 1233. return((boolean)(lev->dnum == quest_dnum)); 1234. } 1235. 1236. #endif /* OVL0 */ 1237. #ifdef OVL1 1238. 1239. boolean 1240. In_mines(lev) /* are you in the mines dungeon? */ 1241. d_level *lev; 1242. { 1243. return((boolean)(lev->dnum == mines_dnum)); 1244. } 1245. 1246. /* 1247. * Return the branch for the given dungeon. 1248. * 1249. * This function assumes: 1250. * + This is not called with "Dungeons of Doom". 1251. * + There is only _one_ branch to a given dungeon. 1252. * + Field end2 is the "child" dungeon. 1253. */ 1254. branch * 1255. dungeon_branch(s) 1256. const char *s; 1257. { 1258. branch *br; 1259. xchar dnum; 1260. 1261. dnum = dname_to_dnum(s); 1262. 1263. /* Find the branch that connects to dungeon i's branch. */ 1264. for (br = branches; br; br = br->next) 1265. if (br->end2.dnum == dnum) break; 1266. 1267. if (!br) panic("dgn_entrance: can't find entrance to %s", s); 1268. 1269. return br; 1270. } 1271. 1272. /* 1273. * This returns true if the hero is on the same level as the entrance to 1274. * the named dungeon. 1275. * 1276. * Called from do.c and mklev.c. 1277. * 1278. * Assumes that end1 is always the "parent". 1279. */ 1280. boolean 1281. at_dgn_entrance(s) 1282. const char *s; 1283. { 1284. branch *br; 1285. 1286. br = dungeon_branch(s); 1287. return((boolean)(on_level(&u.uz, &br->end1) ? TRUE : FALSE)); 1288. } 1289. 1290. boolean 1291. In_V_tower(lev) /* is `lev' part of Vlad's tower? */ 1292. d_level *lev; 1293. { 1294. return((boolean)(lev->dnum == tower_dnum)); 1295. } 1296. 1297. boolean 1298. On_W_tower_level(lev) /* is `lev' a level containing the Wizard's tower? */ 1299. d_level *lev; 1300. { 1301. return (boolean)(Is_wiz1_level(lev) || 1302. Is_wiz2_level(lev) || 1303. Is_wiz3_level(lev)); 1304. } 1305. 1306. boolean 1307. In_W_tower(x, y, lev) /* is of `lev' inside the Wizard's tower? */ 1308. int x, y; 1309. d_level *lev; 1310. { 1311. if (!On_W_tower_level(lev)) return FALSE; 1312. /* 1313. * Both of the exclusion regions for arriving via level teleport 1314. * (from above or below) define the tower's boundary. 1315. * assert( updest.nIJ == dndest.nIJ for I={l|h},J={x|y} ); 1316. */ 1317. if (dndest.nlx > 0) 1318. return (boolean)within_bounded_area(x, y, dndest.nlx, dndest.nly, 1319. dndest.nhx, dndest.nhy); 1320. else 1321. impossible("No boundary for Wizard's Tower?"); 1322. return FALSE; 1323. } 1324. 1325. #endif /* OVL1 */ 1326. #ifdef OVL0 1327. 1328. boolean 1329. In_hell(lev) /* are you in one of the Hell levels? */ 1330. d_level *lev; 1331. { 1332. return((boolean)(dungeons[lev->dnum].flags.hellish)); 1333. } 1334. 1335. #endif /* OVL0 */ 1336. #ifdef OVL1 1337. 1338. void 1339. find_hell(lev) /* sets *lev to be the gateway to Gehennom... */ 1340. d_level *lev; 1341. { 1342. lev->dnum = valley_level.dnum; 1343. lev->dlevel = 1; 1344. } 1345. 1346. void 1347. goto_hell(at_stairs, falling) /* go directly to hell... */ 1348. boolean at_stairs, falling; 1349. { 1350. d_level lev; 1351. 1352. find_hell(&lev); 1353. goto_level(&lev, at_stairs, falling, FALSE); 1354. } 1355. 1356. void 1357. assign_level(dest, src) /* equivalent to dest = source */ 1358. d_level *dest, *src; 1359. { 1360. dest->dnum = src->dnum; 1361. dest->dlevel = src->dlevel; 1362. } 1363. 1364. void 1365. assign_rnd_level(dest, src, range) /* dest = src + rn1(range) */ 1366. d_level *dest, *src; 1367. int range; 1368. { 1369. dest->dnum = src->dnum; 1370. dest->dlevel = src->dlevel + ((range > 0) ? rnd(range) : -rnd(-range)) ; 1371. 1372. if(dest->dlevel > dunlevs_in_dungeon(dest)) 1373. dest->dlevel = dunlevs_in_dungeon(dest); 1374. else if(dest->dlevel < 1) 1375. dest->dlevel = 1; 1376. } 1377. 1378. #endif /* OVL1 */ 1379. #ifdef OVL0 1380. 1381. int 1382. induced_align(pct) 1383. int pct; 1384. { 1385. s_level *lev = Is_special(&u.uz); 1386. aligntyp al; 1387. 1388. if (lev && lev->flags.align) 1389. if(rn2(100) < pct) return(lev->flags.align); 1390. 1391. if(dungeons[u.uz.dnum].flags.align) 1392. if(rn2(100) < pct) return(dungeons[u.uz.dnum].flags.align); 1393. 1394. al = rn2(3) - 1; 1395. return(Align2amask(al)); 1396. } 1397. 1398. #endif /* OVL0 */ 1399. #ifdef OVL1 1400. 1401. boolean 1402. Invocation_lev(lev) 1403. d_level *lev; 1404. { 1405. return((boolean)(In_hell(lev) && 1406. lev->dlevel == (dungeons[lev->dnum].num_dunlevs - 1))); 1407. } 1408. 1409. /* use instead of depth() wherever a degree of difficulty is made 1410. * dependent on the location in the dungeon (eg. monster creation). 1411. */ 1412. xchar 1413. level_difficulty() 1414. { 1415. if (In_endgame(&u.uz)) 1416. return((xchar)(depth(&sanctum_level) + u.ulevel/2)); 1417. else 1418. if (u.uhave.amulet) 1419. return(deepest_lev_reached(FALSE)); 1420. else 1421. return((xchar) depth(&u.uz)); 1422. } 1423. 1424. /* Take one word and try to match it to a level. 1425. * Recognized levels are as shown by print_dungeon(). 1426. */ 1427. schar 1428. lev_by_name(nam) 1429. const char *nam; 1430. { 1431. schar lev = 0; 1432. s_level *slev; 1433. d_level dlev; 1434. const char *p; 1435. int idx, idxtoo; 1436. char buf[BUFSZ]; 1437. 1438. /* allow strings like "the oracle level" to find "oracle" */ 1439. if (!strncmpi(nam, "the ", 4)) nam += 4; 1440. if ((p = strstri(nam, " level")) != 0 && p == eos((char*)nam) - 6) { 1441. nam = strcpy(buf, nam); 1442. *(eos(buf) - 6) = '\0'; 1443. } 1444. /* hell is the old name, and wouldn't match; gehennom would match its 1445. branch, yielding the castle level instead of the valley of the dead */ 1446. if (!strcmpi(nam, "gehennom") || !strcmpi(nam, "hell")) { 1447. if (In_V_tower(&u.uz)) nam = " to Vlad's tower"; /* branch to... */ 1448. else nam = "valley"; 1449. } 1450. 1451. if ((slev = find_level(nam)) != 0) { 1452. dlev = slev->dlevel; 1453. idx = ledger_no(&dlev); 1454. if ((dlev.dnum == u.uz.dnum || 1455. /* within same branch, or else main dungeon <-> gehennom */ 1456. (u.uz.dnum == valley_level.dnum && 1457. dlev.dnum == medusa_level.dnum) || 1458. (u.uz.dnum == medusa_level.dnum && 1459. dlev.dnum == valley_level.dnum)) && 1460. ( /* either wizard mode or else seen and not forgotten */ 1461. #ifdef WIZARD 1462. wizard || 1463. #endif 1464. (level_info[idx].flags & (FORGOTTEN|VISITED)) == VISITED)) { 1465. lev = depth(&slev->dlevel); 1466. } 1467. } else { /* not a specific level; try branch names */ 1468. idx = find_branch(nam, (struct proto_dungeon *)0); 1469. /* " to Xyzzy" */ 1470. if (idx < 0 && (p = strstri(nam, " to ")) != 0) 1471. idx = find_branch(p + 4, (struct proto_dungeon *)0); 1472. 1473. if (idx >= 0) { 1474. idxtoo = (idx >> 8) & 0x00FF; 1475. idx &= 0x00FF; 1476. if ( /* either wizard mode, or else _both_ sides of branch seen */ 1477. #ifdef WIZARD 1478. wizard || 1479. #endif 1480. ((level_info[idx].flags & (FORGOTTEN|VISITED)) == VISITED && 1481. (level_info[idxtoo].flags & (FORGOTTEN|VISITED)) == VISITED)) { 1482. if (ledger_to_dnum(idxtoo) == u.uz.dnum) idx = idxtoo; 1483. dlev.dnum = ledger_to_dnum(idx); 1484. dlev.dlevel = ledger_to_dlev(idx); 1485. lev = depth(&dlev); 1486. } 1487. } 1488. } 1489. return lev; 1490. } 1491. 1492. 1493. #ifdef WIZARD 1494. 1495. /* Convert a branch type to a string usable by print_dungeon(). */ 1496. STATIC_OVL const char * 1497. br_string(type) 1498. int type; 1499. { 1500. switch (type) { 1501. case BR_PORTAL: return "Portal"; 1502. case BR_NO_END1: return "Connection"; 1503. case BR_NO_END2: return "One way stair"; 1504. case BR_STAIR: return "Stair"; 1505. } 1506. return " (unknown)"; 1507. } 1508. 1509. /* Print all child branches between the lower and upper bounds. */ 1510. STATIC_OVL void 1511. print_branch(win, dnum, lower_bound, upper_bound) 1512. winid win; 1513. int dnum; 1514. int lower_bound; 1515. int upper_bound; 1516. { 1517. branch *br; 1518. char buf[BUFSZ]; 1519. 1520. /* This assumes that end1 is the "parent". */ 1521. for (br = branches; br; br = br->next) { 1522. if (br->end1.dnum == dnum && lower_bound < br->end1.dlevel && 1523. br->end1.dlevel <= upper_bound) { 1524. Sprintf(buf," %s to %s: %d", 1525. br_string(br->type), 1526. dungeons[br->end2.dnum].dname, 1527. depth(&br->end1)); 1528. putstr(win, 0, buf); 1529. } 1530. } 1531. } 1532. 1533. /* Print available dungeon information. */ 1534. void 1535. print_dungeon() 1536. { 1537. int i, last_level, nlev; 1538. char buf[BUFSZ]; 1539. boolean first; 1540. s_level *slev; 1541. dungeon *dptr; 1542. branch *br; 1543. winid win = create_nhwindow(NHW_MENU); 1544. 1545. for (i = 0, dptr = dungeons; i < n_dgns; i++, dptr++) { 1546. nlev = dptr->num_dunlevs; 1547. if (nlev > 1) 1548. Sprintf(buf, "%s: levels %d to %d", dptr->dname, dptr->depth_start, 1549. dptr->depth_start + nlev - 1); 1550. else 1551. Sprintf(buf, "%s: level %d", dptr->dname, dptr->depth_start); 1552. 1553. /* Most entrances are uninteresting. */ 1554. if (dptr->entry_lev != 1) { 1555. if (dptr->entry_lev == nlev) 1556. Strcat(buf, ", entrance from below"); 1557. else 1558. Sprintf(eos(buf), ", entrance on %d", 1559. dptr->depth_start + dptr->entry_lev - 1); 1560. } 1561. putstr(win, 0, buf); 1562. 1563. /* 1564. * Circle through the special levels to find levels that are in 1565. * this dungeon. 1566. */ 1567. for (slev = sp_levchn, last_level = 0; slev; slev = slev->next) { 1568. if (slev->dlevel.dnum != i) continue; 1569. 1570. /* print any branches before this level */ 1571. print_branch(win, i, last_level, slev->dlevel.dlevel); 1572. 1573. Sprintf(buf, " %s: %d", slev->proto, depth(&slev->dlevel)); 1574. if (Is_stronghold(&slev->dlevel)) 1575. Sprintf(eos(buf), " (tune %s)", tune); 1576. putstr(win, 0, buf); 1577. 1578. last_level = slev->dlevel.dlevel; 1579. } 1580. /* print branches after the last special level */ 1581. print_branch(win, i, last_level, MAXLEVEL); 1582. } 1583. 1584. /* Print out floating branches (if any). */ 1585. for (first = TRUE, br = branches; br; br = br->next) { 1586. if (br->end1.dnum == n_dgns) { 1587. if (first) { 1588. putstr(win, 0, ""); 1589. putstr(win, 0, "Floating branches"); 1590. first = FALSE; 1591. } 1592. Sprintf(buf, " %s to %s", 1593. br_string(br->type), dungeons[br->end2.dnum].dname); 1594. putstr(win, 0, buf); 1595. } 1596. } 1597. 1598. /* I hate searching for the invocation pos while debugging. -dean */ 1599. if (Invocation_lev(&u.uz)) { 1600. putstr(win, 0, ""); 1601. Sprintf(buf, "Invocation position @ (%d,%d), hero @ (%d,%d)", 1602. inv_pos.x, inv_pos.y, u.ux, u.uy); 1603. putstr(win, 0, buf); 1604. } 1605. /* 1606. * The following is based on the assumption that the inter-level portals 1607. * created by the level compiler (not the dungeon compiler) only exist 1608. * one per level (currently true, of course). 1609. */ 1610. else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz) 1611. || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)) { 1612. struct trap *trap; 1613. for (trap = ftrap; trap; trap = trap->ntrap) 1614. if (trap->ttyp == MAGIC_PORTAL) break; 1615. 1616. putstr(win, 0, ""); 1617. if (trap) 1618. Sprintf(buf, "Portal @ (%d,%d), hero @ (%d,%d)", 1619. trap->tx, trap->ty, u.ux, u.uy); 1620. else 1621. Sprintf(buf, "No portal found."); 1622. putstr(win, 0, buf); 1623. } 1624. 1625. display_nhwindow(win, TRUE); 1626. destroy_nhwindow(win); 1627. } 1628. #endif /* WIZARD */ 1629. 1630. #endif /* OVL1 */ 1631. 1632. /*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