About: Source:NetHack 3.2.0/mkmaze.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 mkmaze.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/mkmaze.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.2.0/mkmaze.c
rdfs:comment
  • Below is the full text to mkmaze.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/mkmaze.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 mkmaze.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/mkmaze.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)mkmaze.c 3.2 95/09/06 */ 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 "sp_lev.h" 7. #include "lev.h" /* save & restore info */ 8. 9. /* from sp_lev.c, for fixup_special() */ 10. extern char *lev_message; 11. extern lev_region *lregions; 12. extern int num_lregions; 13. 14. static boolean FDECL(iswall,(int,int)); 15. static boolean FDECL(iswall_or_stone,(int,int)); 16. static boolean FDECL(is_solid,(int,int)); 17. static int FDECL(extend_spine, (int locale[3][3], int, int, int)); 18. static boolean FDECL(okay,(int,int,int)); 19. static void FDECL(maze0xy,(coord *)); 20. static boolean FDECL(put_lregion_here,(XCHAR_P,XCHAR_P,XCHAR_P, 21. XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P,BOOLEAN_P,d_level *)); 22. static void NDECL(fixup_special); 23. static void FDECL(move, (int *,int *,int)); 24. static void NDECL(setup_waterlevel); 25. static void NDECL(unsetup_waterlevel); 26. 27. #define OUT_OF_BOUNDS(x,y) ((x)<=0 || (y)<0 || (x)>COLNO-1 || (y)>ROWNO-1) 28. 29. static boolean 30. iswall(x,y) 31. int x,y; 32. { 33. if (OUT_OF_BOUNDS(x,y)) return FALSE; 34. return (IS_WALL(levl[x][y].typ) || IS_DOOR(levl[x][y].typ) 35. || levl[x][y].typ == SDOOR); 36. } 37. 38. static boolean 39. iswall_or_stone(x,y) 40. int x,y; 41. { 42. register int type; 43. 44. /* out of bounds = stone */ 45. if (OUT_OF_BOUNDS(x,y)) return TRUE; 46. 47. type = levl[x][y].typ; 48. return (type == STONE || IS_WALL(type) || IS_DOOR(type) || type == SDOOR); 49. } 50. 51. /* return TRUE if out of bounds, wall or rock */ 52. static boolean 53. is_solid(x,y) 54. int x, y; 55. { 56. return (OUT_OF_BOUNDS(x,y) || IS_STWALL(levl[x][y].typ)); 57. } 58. 59. 60. /* 61. * Return 1 (not TRUE - we're doing bit vectors here) if we want to extend 62. * a wall spine in the (dx,dy) direction. Return 0 otherwise. 63. * 64. * To extend a wall spine in that direction, first there must be a wall there. 65. * Then, extend a spine unless the current position is surrounded by walls 66. * in the direction given by (dx,dy). E.g. if 'x' is our location, 'W' 67. * a wall, '.' a room, 'a' anything (we don't care), and our direction is 68. * (0,1) - South or down - then: 69. * 70. * a a a 71. * W x W This would not extend a spine from x down 72. * W W W (a corridor of walls is formed). 73. * 74. * a a a 75. * W x W This would extend a spine from x down. 76. * . W W 77. */ 78. static int 79. extend_spine(locale, wall_there, dx, dy) 80. int locale[3][3]; 81. int wall_there, dx, dy; 82. { 83. int spine, nx, ny; 84. 85. nx = 1 + dx; 86. ny = 1 + dy; 87. 88. if (wall_there) { /* wall in that direction */ 89. if (dx) { 90. if (locale[ 1][0] && locale[ 1][2] && /* EW are wall/stone */ 91. locale[nx][0] && locale[nx][2]) { /* diag are wall/stone */ 92. spine = 0; 93. } else { 94. spine = 1; 95. } 96. } else { /* dy */ 97. if (locale[0][ 1] && locale[2][ 1] && /* NS are wall/stone */ 98. locale[0][ny] && locale[2][ny]) { /* diag are wall/stone */ 99. spine = 0; 100. } else { 101. spine = 1; 102. } 103. } 104. } else { 105. spine = 0; 106. } 107. 108. return spine; 109. } 110. 111. 112. /* 113. * Wall cleanup. This function has two purposes: (1) remove walls that 114. * are totally surrounded by stone - they are redundant. (2) correct 115. * the types so that they extend and connect to each other. 116. */ 117. void 118. wallification(x1, y1, x2, y2) 119. int x1, y1, x2, y2; 120. { 121. uchar type; 122. register int x,y; 123. struct rm *lev; 124. int bits; 125. int locale[3][3]; /* rock or wall status surrounding positions */ 126. /* 127. * Value 0 represents a free-standing wall. It could be anything, 128. * so even though this table says VWALL, we actually leave whatever 129. * typ was there alone. 130. */ 131. static xchar spine_array[16] = { 132. VWALL, HWALL, HWALL, HWALL, 133. VWALL, TRCORNER, TLCORNER, TDWALL, 134. VWALL, BRCORNER, BLCORNER, TUWALL, 135. VWALL, TLWALL, TRWALL, CROSSWALL 136. }; 137. 138. /* sanity check on incoming variables */ 139. if (x1<0 || x2>=COLNO || x1>x2 || y1<0 || y2>=ROWNO || y1>y2) 140. panic("wallification: bad bounds (%d,%d) to (%d,%d)",x1,y1,x2,y2); 141. 142. /* Step 1: change walls surrounded by rock to rock. */ 143. for(x = x1; x <= x2; x++) 144. for(y = y1; y <= y2; y++) { 145. lev = &levl[x][y]; 146. type = lev->typ; 147. if (IS_WALL(type) && type != DBWALL) { 148. if (is_solid(x-1,y-1) && 149. is_solid(x-1,y ) && 150. is_solid(x-1,y+1) && 151. is_solid(x, y-1) && 152. is_solid(x, y+1) && 153. is_solid(x+1,y-1) && 154. is_solid(x+1,y ) && 155. is_solid(x+1,y+1)) 156. lev->typ = STONE; 157. } 158. } 159. 160. /* 161. * Step 2: set the correct wall type. We can't combine steps 162. * 1 and 2 into a single sweep because we depend on knowing if 163. * the surrounding positions are stone. 164. */ 165. for(x = x1; x <= x2; x++) 166. for(y = y1; y <= y2; y++) { 167. lev = &levl[x][y]; 168. type = lev->typ; 169. if ( !(IS_WALL(type) && type != DBWALL)) continue; 170. 171. /* set the locations TRUE if rock or wall or out of bounds */ 172. locale[0][0] = iswall_or_stone(x-1,y-1); 173. locale[1][0] = iswall_or_stone( x,y-1); 174. locale[2][0] = iswall_or_stone(x+1,y-1); 175. 176. locale[0][1] = iswall_or_stone(x-1, y); 177. locale[2][1] = iswall_or_stone(x+1, y); 178. 179. locale[0][2] = iswall_or_stone(x-1,y+1); 180. locale[1][2] = iswall_or_stone( x,y+1); 181. locale[2][2] = iswall_or_stone(x+1,y+1); 182. 183. /* determine if wall should extend to each direction NSEW */ 184. bits = (extend_spine(locale, iswall(x,y-1), 0, -1) << 3) 185. | (extend_spine(locale, iswall(x,y+1), 0, 1) << 2) 186. | (extend_spine(locale, iswall(x+1,y), 1, 0) << 1) 187. | extend_spine(locale, iswall(x-1,y), -1, 0); 188. 189. /* don't change typ if wall is free-standing */ 190. if (bits) lev->typ = spine_array[bits]; 191. } 192. } 193. 194. static boolean 195. okay(x,y,dir) 196. int x,y; 197. register int dir; 198. { 199. move(&x,&y,dir); 200. move(&x,&y,dir); 201. if(x<3 || y<3 || x>x_maze_max || y>y_maze_max || levl[x][y].typ != 0) 202. return(FALSE); 203. return(TRUE); 204. } 205. 206. static void 207. maze0xy(cc) /* find random starting point for maze generation */ 208. coord *cc; 209. { 210. cc->x = 3 + 2*rn2((x_maze_max>>1) - 1); 211. cc->y = 3 + 2*rn2((y_maze_max>>1) - 1); 212. return; 213. } 214. 215. /* 216. * Bad if: 217. * pos is occupied OR 218. * pos is inside restricted region (lx,ly,hx,hy) OR 219. * NOT (pos is corridor and a maze level OR pos is a room OR pos is air) 220. */ 221. boolean 222. bad_location(x, y, lx, ly, hx, hy) 223. xchar x, y; 224. xchar lx, ly, hx, hy; 225. { 226. return((boolean)(occupied(x, y) || 227. within_bounded_area(x,y, lx,ly, hx,hy) || 228. !((levl[x][y].typ == CORR && level.flags.is_maze_lev) || 229. levl[x][y].typ == ROOM || levl[x][y].typ == AIR))); 230. } 231. 232. /* pick a location in area (lx, ly, hx, hy) but not in (nlx, nly, nhx, nhy) */ 233. /* and place something (based on rtype) in that region */ 234. void 235. place_lregion(lx, ly, hx, hy, nlx, nly, nhx, nhy, rtype, lev) 236. xchar lx, ly, hx, hy; 237. xchar nlx, nly, nhx, nhy; 238. xchar rtype; 239. d_level *lev; 240. { 241. int trycnt; 242. boolean oneshot; 243. xchar x, y; 244. 245. if(!lx) { /* default to whole level */ 246. /* 247. * if there are rooms and this a branch, let place_branch choose 248. * the branch location (to avoid putting branches in corridors). 249. */ 250. if(rtype == LR_BRANCH && nroom) { 251. place_branch(Is_branchlev(&u.uz), 0, 0); 252. return; 253. } 254. 255. lx = 1; hx = COLNO-1; 256. ly = 1; hy = ROWNO-1; 257. } 258. 259. /* first a probabilistic approach */ 260. 261. oneshot = (lx == hx && ly == hy); 262. for(trycnt = 0; trycnt < 100; trycnt ++) { 263. 264. x = rn1((hx - lx) + 1, lx); 265. y = rn1((hy - ly) + 1, ly); 266. 267. if (put_lregion_here(x,y,nlx,nly,nhx,nhy,rtype,oneshot,lev)) 268. return; 269. } 270. 271. /* then a deterministic one */ 272. 273. oneshot = TRUE; 274. for (x = lx; x <= hx; x++) 275. for (y = ly; y <= hy; y++) 276. if (put_lregion_here(x,y,nlx,nly,nhx,nhy,rtype,oneshot,lev)) 277. return; 278. 279. impossible("Couldn't place lregion type %d!", rtype); 280. } 281. 282. static boolean 283. put_lregion_here(x,y,nlx,nly,nhx,nhy,rtype,oneshot,lev) 284. xchar x, y; 285. xchar nlx, nly, nhx, nhy; 286. xchar rtype; 287. boolean oneshot; 288. d_level *lev; 289. { 290. if(oneshot) { 291. /* must make due with the only location possible */ 292. /* avoid failure due to a misplaced trap */ 293. /* it might still fail if there's a dungeon feature here */ 294. struct trap *t = t_at(x,y); 295. if (t) deltrap(t); 296. } 297. if(bad_location(x, y, nlx, nly, nhx, nhy)) return(FALSE); 298. switch (rtype) { 299. case LR_TELE: 300. case LR_UPTELE: 301. case LR_DOWNTELE: 302. /* "something" means the player in this case */ 303. if(MON_AT(x, y)) { 304. /* move the monster if no choice, or just try again */ 305. if(oneshot) rloc(m_at(x,y)); 306. else return(FALSE); 307. } 308. u_on_newpos(x, y); 309. break; 310. case LR_PORTAL: 311. mkportal(x, y, lev->dnum, lev->dlevel); 312. break; 313. case LR_DOWNSTAIR: 314. case LR_UPSTAIR: 315. mkstairs(x, y, (char)rtype, (struct mkroom *)0); 316. break; 317. case LR_BRANCH: 318. place_branch(Is_branchlev(&u.uz), x, y); 319. break; 320. } 321. return(TRUE); 322. } 323. 324. static boolean was_waterlevel; /* ugh... this shouldn't be needed */ 325. 326. /* this is special stuff that the level compiler cannot (yet) handle */ 327. static void 328. fixup_special() 329. { 330. register lev_region *r = lregions; 331. struct d_level lev; 332. register int x, y; 333. struct mkroom *croom; 334. boolean added_branch = FALSE; 335. 336. if (was_waterlevel) { 337. was_waterlevel = FALSE; 338. u.uinwater = 0; 339. unsetup_waterlevel(); 340. } else if (Is_waterlevel(&u.uz)) { 341. level.flags.hero_memory = 0; 342. was_waterlevel = TRUE; 343. /* water level is an odd beast - it has to be set up 344. before calling place_lregions etc. */ 345. setup_waterlevel(); 346. } 347. for(x = 0; x < num_lregions; x++, r++) { 348. switch(r->rtype) { 349. case LR_BRANCH: 350. added_branch = TRUE; 351. goto place_it; 352. 353. case LR_PORTAL: 354. if(*r->rname.str >= '0' && *r->rname.str <= '9') { 355. /* "chutes and ladders" */ 356. lev = u.uz; 357. lev.dlevel = atoi(r->rname.str); 358. } else { 359. s_level *sp = find_level(r->rname.str); 360. lev = sp->dlevel; 361. } 362. /* fall into... */ 363. 364. case LR_UPSTAIR: 365. case LR_DOWNSTAIR: 366. place_it: 367. place_lregion(r->inarea.x1, r->inarea.y1, 368. r->inarea.x2, r->inarea.y2, 369. r->delarea.x1, r->delarea.y1, 370. r->delarea.x2, r->delarea.y2, 371. r->rtype, &lev); 372. break; 373. 374. case LR_TELE: 375. case LR_UPTELE: 376. case LR_DOWNTELE: 377. /* save the region outlines for goto_level() */ 378. if(r->rtype == LR_TELE || r->rtype == LR_UPTELE) { 379. updest.lx = r->inarea.x1; updest.ly = r->inarea.y1; 380. updest.hx = r->inarea.x2; updest.hy = r->inarea.y2; 381. updest.nlx = r->delarea.x1; updest.nly = r->delarea.y1; 382. updest.nhx = r->delarea.x2; updest.nhy = r->delarea.y2; 383. } 384. if(r->rtype == LR_TELE || r->rtype == LR_DOWNTELE) { 385. dndest.lx = r->inarea.x1; dndest.ly = r->inarea.y1; 386. dndest.hx = r->inarea.x2; dndest.hy = r->inarea.y2; 387. dndest.nlx = r->delarea.x1; dndest.nly = r->delarea.y1; 388. dndest.nhx = r->delarea.x2; dndest.nhy = r->delarea.y2; 389. } 390. /* place_lregion gets called from goto_level() */ 391. break; 392. } 393. 394. if (r->rname.str) free((genericptr_t) r->rname.str), r->rname.str = 0; 395. } 396. 397. /* place dungeon branch if not placed above */ 398. if (!added_branch && Is_branchlev(&u.uz)) { 399. place_lregion(0,0,0,0,0,0,0,0,LR_BRANCH,(d_level *)0); 400. } 401. 402. /* Still need to add some stuff to level file */ 403. if (Is_medusa_level(&u.uz)) { 404. struct obj *otmp; 405. int tryct; 406. 407. croom = &rooms[0]; /* only one room on the medusa level */ 408. for (tryct = rnd(4); tryct; tryct--) { 409. x = somex(croom); y = somey(croom); 410. if (goodpos(x, y, (struct monst *)0, (struct permonst *)0)) { 411. otmp = mk_tt_object(STATUE, x, y); 412. while (otmp && (poly_when_stoned(&mons[otmp->corpsenm]) || 413. pm_resistance(&mons[otmp->corpsenm],MR_STONE))) { 414. otmp->corpsenm = rndmonnum(); 415. otmp->owt = weight(otmp); 416. } 417. } 418. } 419. 420. if (rn2(2)) 421. otmp = mk_tt_object(STATUE, somex(croom), somey(croom)); 422. else /* Medusa statues don't contain books */ 423. otmp = mkcorpstat(STATUE, (struct permonst *)0, 424. somex(croom), somey(croom), FALSE); 425. if (otmp) { 426. while (pm_resistance(&mons[otmp->corpsenm],MR_STONE) 427. || poly_when_stoned(&mons[otmp->corpsenm])) { 428. otmp->corpsenm = rndmonnum(); 429. otmp->owt = weight(otmp); 430. } 431. } 432. } else if(Is_wiz1_level(&u.uz)) { 433. croom = search_special(MORGUE); 434. 435. create_secret_door(croom, W_SOUTH|W_EAST|W_WEST); 436. } else if(Is_knox(&u.uz)) { 437. /* using an unfilled morgue for rm id */ 438. croom = search_special(MORGUE); 439. /* avoid inappropriate morgue-related messages */ 440. level.flags.graveyard = level.flags.has_morgue = FALSE; 441. croom->rtype = OROOM; /* perhaps it should be set to VAULT? */ 442. /* stock the main vault */ 443. for(x = croom->lx; x <= croom->hx; x++) 444. for(y = croom->ly; y <= croom->hy; y++) { 445. mkgold((long) rn1(300, 600), x, y); 446. if (!rn2(3) && !is_pool(x,y)) 447. (void)maketrap(x, y, rn2(3) ? LANDMINE : SPIKED_PIT); 448. } 449. } else if (Role_is('P') && In_quest(&u.uz)) { 450. /* less chance for undead corpses (lured from lower morgues) */ 451. level.flags.graveyard = TRUE; 452. } else if (Is_stronghold(&u.uz)) { 453. level.flags.graveyard = TRUE; 454. } else if(Is_sanctum(&u.uz)) { 455. croom = search_special(TEMPLE); 456. 457. create_secret_door(croom, W_ANY); 458. } else if(on_level(&u.uz, &orcus_level)) { 459. register struct monst *mtmp, *mtmp2; 460. 461. /* it's a ghost town, get rid of shopkeepers */ 462. for(mtmp = fmon; mtmp; mtmp = mtmp2) { 463. mtmp2 = mtmp->nmon; 464. if(mtmp->isshk) mongone(mtmp); 465. } 466. } 467. 468. if(lev_message) { 469. char *str, *nl; 470. for(str = lev_message; (nl = index(str, ' ')) != 0; str = nl+1) { 471. *nl = '\0'; 472. pline("%s", str); 473. } 474. if(*str) 475. pline("%s", str); 476. free((genericptr_t)lev_message); 477. lev_message = 0; 478. } 479. 480. if (lregions) 481. free((genericptr_t) lregions), lregions = 0; 482. num_lregions = 0; 483. } 484. 485. void 486. makemaz(s) 487. register const char *s; 488. { 489. int x,y; 490. char protofile[20]; 491. s_level *sp = Is_special(&u.uz); 492. coord mm; 493. 494. if(*s) { 495. if(sp && sp->rndlevs) Sprintf(protofile, "%s-%d", s, 496. rnd((int) sp->rndlevs)); 497. else Strcpy(protofile, s); 498. } else if(*(dungeons[u.uz.dnum].proto)) { 499. if(dunlevs_in_dungeon(&u.uz) > 1) { 500. if(sp && sp->rndlevs) 501. Sprintf(protofile, "%s%d-%d", dungeons[u.uz.dnum].proto, 502. dunlev(&u.uz), 503. rnd((int) sp->rndlevs)); 504. else Sprintf(protofile, "%s%d", dungeons[u.uz.dnum].proto, 505. dunlev(&u.uz)); 506. } else if(sp && sp->rndlevs) { 507. Sprintf(protofile, "%s-%d", dungeons[u.uz.dnum].proto, 508. rnd((int) sp->rndlevs)); 509. } else Strcpy(protofile, dungeons[u.uz.dnum].proto); 510. 511. } else Strcpy(protofile, ""); 512. 513. if(*protofile) { 514. Strcat(protofile, LEV_EXT); 515. if(load_special(protofile)) { 516. fixup_special(); 517. return; /* no mazification right now */ 518. } 519. impossible("Couldn't load \"%s\" - making a maze.", protofile); 520. } 521. 522. level.flags.is_maze_lev = TRUE; 523. 524. #ifndef WALLIFIED_MAZE 525. for(x = 2; x < x_maze_max; x++) 526. for(y = 2; y < y_maze_max; y++) 527. levl[x][y].typ = STONE; 528. #else 529. for(x = 2; x <= x_maze_max; x++) 530. for(y = 2; y <= y_maze_max; y++) 531. levl[x][y].typ = ((x % 2) && (y % 2)) ? STONE : HWALL; 532. #endif 533. 534. maze0xy(&mm); 535. walkfrom((int) mm.x, (int) mm.y); 536. /* put a boulder at the maze center */ 537. (void) mksobj_at(BOULDER, (int) mm.x, (int) mm.y, TRUE); 538. 539. #ifdef WALLIFIED_MAZE 540. wallification(2, 2, x_maze_max, y_maze_max); 541. #endif 542. mazexy(&mm); 543. mkstairs(mm.x, mm.y, 1, (struct mkroom *)0); /* up */ 544. if (!Invocation_lev(&u.uz)) { 545. mazexy(&mm); 546. mkstairs(mm.x, mm.y, 0, (struct mkroom *)0); /* down */ 547. } else { /* choose "vibrating square" location */ 548. #define x_maze_min 2 549. #define y_maze_min 2 550. /* 551. * Pick a position where the stairs down to Moloch's Sanctum 552. * level will ultimately be created. At that time, an area 553. * will be altered: walls removed, moat and traps generated, 554. * boulders destroyed. The position picked here must ensure 555. * that that invocation area won't extend off the map. 556. * 557. * We actually allow up to 2 squares around the usual edge of 558. * the area to get truncated; see mkinvokearea(mklev.c). 559. */ 560. #define INVPOS_X_MARGIN (6 - 2) 561. #define INVPOS_Y_MARGIN (5 - 2) 562. #define INVPOS_DISTANCE 11 563. int x_range = x_maze_max - x_maze_min - 2*INVPOS_X_MARGIN - 1, 564. y_range = y_maze_max - y_maze_min - 2*INVPOS_Y_MARGIN - 1; 565. 566. #ifdef DEBUG 567. if (x_range <= INVPOS_X_MARGIN || y_range <= INVPOS_Y_MARGIN || 568. (x_range * y_range) <= (INVPOS_DISTANCE * INVPOS_DISTANCE)) 569. panic("inv_pos: maze is too small! (%d x %d)", 570. x_maze_max, y_maze_max); 571. #endif 572. inv_pos.x = inv_pos.y = 0; /*{occupied() => invocation_pos()}*/ 573. do { 574. x = rn1(x_range, x_maze_min + INVPOS_X_MARGIN + 1); 575. y = rn1(y_range, y_maze_min + INVPOS_Y_MARGIN + 1); 576. /* we don't want it to be too near the stairs, nor 577. to be on a spot that's already in use (wall|trap) */ 578. } while (x == xupstair || y == yupstair || /*(direct line)*/ 579. abs(x - xupstair) == abs(y - yupstair) || 580. distmin(x, y, xupstair, yupstair) <= INVPOS_DISTANCE || 581. !SPACE_POS(levl[x][y].typ) || occupied(x, y)); 582. inv_pos.x = x; 583. inv_pos.y = y; 584. #undef INVPOS_X_MARGIN 585. #undef INVPOS_Y_MARGIN 586. #undef INVPOS_DISTANCE 587. #undef x_maze_min 588. #undef y_maze_min 589. } 590. 591. /* place branch stair or portal */ 592. place_branch(Is_branchlev(&u.uz), 0, 0); 593. 594. for(x = rn1(8,11); x; x--) { 595. mazexy(&mm); 596. (void) mkobj_at(rn2(2) ? GEM_CLASS : 0, mm.x, mm.y, TRUE); 597. } 598. for(x = rn1(10,2); x; x--) { 599. mazexy(&mm); 600. (void) mksobj_at(BOULDER, mm.x, mm.y, TRUE); 601. } 602. for (x = rn2(3); x; x--) { 603. mazexy(&mm); 604. (void) makemon(&mons[PM_MINOTAUR], mm.x, mm.y); 605. } 606. for(x = rn1(5,7); x; x--) { 607. mazexy(&mm); 608. (void) makemon((struct permonst *) 0, mm.x, mm.y); 609. } 610. for(x = rn1(6,7); x; x--) { 611. mazexy(&mm); 612. mkgold(0L,mm.x,mm.y); 613. } 614. for(x = rn1(6,7); x; x--) 615. mktrap(0,1,(struct mkroom *) 0, (coord*) 0); 616. } 617. 618. #ifdef MICRO 619. /* Make the mazewalk iterative by faking a stack. This is needed to 620. * ensure the mazewalk is successful in the limited stack space of 621. * the program. This iterative version uses the minimum amount of stack 622. * that is totally safe. 623. */ 624. void 625. walkfrom(x,y) 626. int x,y; 627. { 628. #define CELLS (ROWNO * COLNO) / 4 /* a maze cell is 4 squares */ 629. char mazex[CELLS + 1], mazey[CELLS + 1]; /* char's are OK */ 630. int q, a, dir, pos; 631. int dirs[4]; 632. 633. pos = 1; 634. mazex[pos] = (char) x; 635. mazey[pos] = (char) y; 636. while (pos) { 637. x = (int) mazex[pos]; 638. y = (int) mazey[pos]; 639. if(!IS_DOOR(levl[x][y].typ)) { 640. /* might still be on edge of MAP, so don't overwrite */ 641. #ifndef WALLIFIED_MAZE 642. levl[x][y].typ = CORR; 643. #else 644. levl[x][y].typ = ROOM; 645. #endif 646. levl[x][y].flags = 0; 647. } 648. q = 0; 649. for (a = 0; a < 4; a++) 650. if(okay(x, y, a)) dirs[q++]= a; 651. if (!q) 652. pos--; 653. else { 654. dir = dirs[rn2(q)]; 655. move(&x, &y, dir); 656. #ifndef WALLIFIED_MAZE 657. levl[x][y].typ = CORR; 658. #else 659. levl[x][y].typ = ROOM; 660. #endif 661. move(&x, &y, dir); 662. pos++; 663. if (pos > CELLS) 664. panic("Overflow in walkfrom"); 665. mazex[pos] = (char) x; 666. mazey[pos] = (char) y; 667. } 668. } 669. } 670. #else 671. 672. void 673. walkfrom(x,y) 674. int x,y; 675. { 676. register int q,a,dir; 677. int dirs[4]; 678. 679. if(!IS_DOOR(levl[x][y].typ)) { 680. /* might still be on edge of MAP, so don't overwrite */ 681. #ifndef WALLIFIED_MAZE 682. levl[x][y].typ = CORR; 683. #else 684. levl[x][y].typ = ROOM; 685. #endif 686. levl[x][y].flags = 0; 687. } 688. 689. while(1) { 690. q = 0; 691. for(a = 0; a < 4; a++) 692. if(okay(x,y,a)) dirs[q++]= a; 693. if(!q) return; 694. dir = dirs[rn2(q)]; 695. move(&x,&y,dir); 696. #ifndef WALLIFIED_MAZE 697. levl[x][y].typ = CORR; 698. #else 699. levl[x][y].typ = ROOM; 700. #endif 701. move(&x,&y,dir); 702. walkfrom(x,y); 703. } 704. } 705. #endif /* MICRO */ 706. 707. static void 708. move(x,y,dir) 709. register int *x, *y; 710. register int dir; 711. { 712. switch(dir){ 713. case 0: --(*y); break; 714. case 1: (*x)++; break; 715. case 2: (*y)++; break; 716. case 3: --(*x); break; 717. default: panic("move: bad direction"); 718. } 719. } 720. 721. void 722. mazexy(cc) /* find random point in generated corridors, 723. so we don't create items in moats, bunkers, or walls */ 724. coord *cc; 725. { 726. int cpt=0; 727. 728. do { 729. cc->x = 3 + 2*rn2((x_maze_max>>1) - 1); 730. cc->y = 3 + 2*rn2((y_maze_max>>1) - 1); 731. cpt++; 732. } while (cpt < 100 && levl[cc->x][cc->y].typ != 733. #ifdef WALLIFIED_MAZE 734. ROOM 735. #else 736. CORR 737. #endif 738. ); 739. if (cpt >= 100) { 740. register int x, y; 741. /* last try */ 742. for (x = 0; x < (x_maze_max>>1) - 1; x++) 743. for (y = 0; y < (y_maze_max>>1) - 1; y++) { 744. cc->x = 3 + 2 * x; 745. cc->y = 3 + 2 * y; 746. if (levl[cc->x][cc->y].typ == 747. #ifdef WALLIFIED_MAZE 748. ROOM 749. #else 750. CORR 751. #endif 752. ) return; 753. } 754. panic("mazexy: can't find a place!"); 755. } 756. return; 757. } 758. 759. void 760. bound_digging() 761. /* put a non-diggable boundary around the initial portion of a level map. 762. * assumes that no level will initially put things beyond the isok() range. 763. * 764. * we can't bound unconditionally on the last line with something in it, 765. * because that something might be a niche which was already reachable, 766. * so the boundary would be breached 767. * 768. * we can't bound unconditionally on one beyond the last line, because 769. * that provides a window of abuse for WALLIFIED_MAZE special levels 770. */ 771. { 772. register int x,y; 773. register unsigned typ; 774. register struct rm *lev; 775. boolean found, nonwall; 776. int xmin,xmax,ymin,ymax; 777. 778. if(Is_earthlevel(&u.uz)) return; /* everything diggable here */ 779. 780. found = nonwall = FALSE; 781. for(xmin=0; !found; xmin++) { 782. lev = &levl[xmin][0]; 783. for(y=0; y<=ROWNO-1; y++, lev++) { 784. typ = lev->typ; 785. if(typ != STONE) { 786. found = TRUE; 787. if(!IS_WALL(typ)) nonwall = TRUE; 788. } 789. } 790. } 791. xmin -= (nonwall || !level.flags.is_maze_lev) ? 2 : 1; 792. if (xmin < 0) xmin = 0; 793. 794. found = nonwall = FALSE; 795. for(xmax=COLNO-1; !found; xmax--) { 796. lev = &levl[xmax][0]; 797. for(y=0; y<=ROWNO-1; y++, lev++) { 798. typ = lev->typ; 799. if(typ != STONE) { 800. found = TRUE; 801. if(!IS_WALL(typ)) nonwall = TRUE; 802. } 803. } 804. } 805. xmax += (nonwall || !level.flags.is_maze_lev) ? 2 : 1; 806. if (xmax >= COLNO) xmax = COLNO-1; 807. 808. found = nonwall = FALSE; 809. for(ymin=0; !found; ymin++) { 810. lev = &levl[xmin][ymin]; 811. for(x=xmin; x<=xmax; x++, lev += ROWNO) { 812. typ = lev->typ; 813. if(typ != STONE) { 814. found = TRUE; 815. if(!IS_WALL(typ)) nonwall = TRUE; 816. } 817. } 818. } 819. ymin -= (nonwall || !level.flags.is_maze_lev) ? 2 : 1; 820. 821. found = nonwall = FALSE; 822. for(ymax=ROWNO-1; !found; ymax--) { 823. lev = &levl[xmin][ymax]; 824. for(x=xmin; x<=xmax; x++, lev += ROWNO) { 825. typ = lev->typ; 826. if(typ != STONE) { 827. found = TRUE; 828. if(!IS_WALL(typ)) nonwall = TRUE; 829. } 830. } 831. } 832. ymax += (nonwall || !level.flags.is_maze_lev) ? 2 : 1; 833. 834. for (x = 0; x < COLNO; x++) 835. for (y = 0; y < ROWNO; y++) 836. if (y <= ymin || y >= ymax || x <= xmin || x >= xmax) { 837. #ifdef DCC30_BUG 838. lev = &levl[x][y]; 839. lev->wall_info |= W_NONDIGGABLE; 840. #else 841. levl[x][y].wall_info |= W_NONDIGGABLE; 842. #endif 843. } 844. } 845. 846. void 847. mkportal(x, y, todnum, todlevel) 848. register xchar x, y, todnum, todlevel; 849. { 850. /* a portal "trap" must be matched by a */ 851. /* portal in the destination dungeon/dlevel */ 852. register struct trap *ttmp = maketrap(x, y, MAGIC_PORTAL); 853. 854. if (!ttmp) { 855. impossible("portal on top of portal??"); 856. return; 857. } 858. #ifdef DEBUG 859. pline("mkportal: at (%d,%d), to %s, level %d", 860. x, y, dungeons[todnum].dname, todlevel); 861. #endif 862. ttmp->dst.dnum = todnum; 863. ttmp->dst.dlevel = todlevel; 864. return; 865. } 866. 867. /* 868. * Special waterlevel stuff in endgame (TH). 869. * 870. * Some of these functions would probably logically belong to some 871. * other source files, but they are all so nicely encapsulated here. 872. */ 873. 874. /* to ease the work of debuggers at this stage */ 875. #define register 876. 877. struct container { 878. struct container *next; 879. xchar x, y; 880. short what; 881. genericptr_t list; 882. }; 883. #define CONS_OBJ 0 884. #define CONS_MON 1 885. #define CONS_HERO 2 886. #define CONS_TRAP 3 887. 888. static struct bubble { 889. xchar x, y; /* coordinates of the upper left corner */ 890. schar dx, dy; /* the general direction of the bubble's movement */ 891. uchar *bm; /* pointer to the bubble bit mask */ 892. struct bubble *prev, *next; /* need to traverse the list up and down */ 893. struct container *cons; 894. } *bbubbles, *ebubbles; 895. 896. static struct trap *wportal; 897. static int xmin, ymin, xmax, ymax; /* level boundaries */ 898. /* bubble movement boundaries */ 899. #define bxmin (xmin + 1) 900. #define bymin (ymin + 1) 901. #define bxmax (xmax - 1) 902. #define bymax (ymax - 1) 903. 904. static void NDECL(set_wportal); 905. static void FDECL(mk_bubble, (int,int,int)); 906. static void FDECL(mv_bubble, (struct bubble *,int,int,BOOLEAN_P)); 907. 908. void 909. movebubbles() 910. { 911. static boolean up; 912. register struct bubble *b; 913. register int x, y, i, j; 914. struct trap *btrap; 915. static const struct rm water_pos = 916. { cmap_to_glyph(S_water), WATER, 0, 0, 0, 0, 0, 0, 0 }; 917. 918. /* set up the portal the first time bubbles are moved */ 919. if (!wportal) set_wportal(); 920. 921. vision_recalc(2); 922. 923. /* 924. * Pick up everything inside of a bubble then fill all bubble 925. * locations. 926. */ 927. 928. for (b = up ? bbubbles : ebubbles; b; b = up ? b->next : b->prev) { 929. if (b->cons) panic("movebubbles: cons != null"); 930. for (i = 0, x = b->x; i < (int) b->bm[0]; i++, x++) 931. for (j = 0, y = b->y; j < (int) b->bm[1]; j++, y++) 932. if (b->bm[j + 2] & (1 << i)) { 933. if (!isok(x,y)) { 934. impossible("movebubbles: bad pos (%d,%d)", x,y); 935. continue; 936. } 937. 938. /* pick up objects, monsters, hero, and traps */ 939. if (OBJ_AT(x,y)) { 940. struct obj *olist = (struct obj *) 0, *otmp; 941. struct container *cons = (struct container *) 942. alloc(sizeof(struct container)); 943. 944. while ((otmp = level.objects[x][y]) != 0) { 945. remove_object(otmp); 946. otmp->ox = otmp->oy = 0; 947. otmp->nexthere = olist; 948. olist = otmp; 949. } 950. 951. cons->x = x; 952. cons->y = y; 953. cons->what = CONS_OBJ; 954. cons->list = (genericptr_t) olist; 955. cons->next = b->cons; 956. b->cons = cons; 957. } 958. if (MON_AT(x,y)) { 959. struct monst *mon = m_at(x,y); 960. struct container *cons = (struct container *) 961. alloc(sizeof(struct container)); 962. 963. cons->x = x; 964. cons->y = y; 965. cons->what = CONS_MON; 966. cons->list = (genericptr_t) mon; 967. 968. cons->next = b->cons; 969. b->cons = cons; 970. 971. if(mon->wormno) 972. remove_worm(mon); 973. else 974. remove_monster(x, y); 975. 976. newsym(x,y); /* clean up old position */ 977. mon->mx = mon->my = 0; 978. } 979. if (!u.uswallow && x == u.ux && y == u.uy) { 980. struct container *cons = (struct container *) 981. alloc(sizeof(struct container)); 982. 983. cons->x = x; 984. cons->y = y; 985. cons->what = CONS_HERO; 986. cons->list = (genericptr_t) 0; 987. 988. cons->next = b->cons; 989. b->cons = cons; 990. } 991. if ((btrap = t_at(x,y)) != 0) { 992. struct container *cons = (struct container *) 993. alloc(sizeof(struct container)); 994. 995. cons->x = x; 996. cons->y = y; 997. cons->what = CONS_TRAP; 998. cons->list = (genericptr_t) btrap; 999. 1000. cons->next = b->cons; 1001. b->cons = cons; 1002. } 1003. 1004. levl[x][y] = water_pos; 1005. block_point(x,y); 1006. } 1007. } 1008. 1009. /* 1010. * Every second time traverse down. This is because otherwise 1011. * all the junk that changes owners when bubbles overlap 1012. * would eventually end up in the last bubble in the chain. 1013. */ 1014. 1015. up = !up; 1016. for (b = up ? bbubbles : ebubbles; b; b = up ? b->next : b->prev) { 1017. register int rx = rn2(3), ry = rn2(3); 1018. 1019. mv_bubble(b,b->dx + 1 - (!b->dx ? rx : (rx ? 1 : 0)), 1020. b->dy + 1 - (!b->dy ? ry : (ry ? 1 : 0)), 1021. FALSE); 1022. } 1023. 1024. vision_full_recalc = 1; 1025. } 1026. 1027. /* when moving in water, possibly (1 in 3) alter the intended destination */ 1028. void 1029. water_friction() 1030. { 1031. register int x, y, dx, dy; 1032. register boolean eff = FALSE; 1033. 1034. if (is_swimmer(uasmon) && rn2(4)) 1035. return; /* natural swimmers have advantage */ 1036. 1037. if (u.dx && !rn2(!u.dy ? 3 : 6)) { /* 1/3 chance or half that */ 1038. /* cancel delta x and choose an arbitrary delta y value */ 1039. x = u.ux; 1040. do { 1041. dy = rn2(3) - 1; /* -1, 0, 1 */ 1042. y = u.uy + dy; 1043. } while (dy && (!isok(x,y) || !is_pool(x,y))); 1044. u.dx = 0; 1045. u.dy = dy; 1046. eff = TRUE; 1047. } else if (u.dy && !rn2(!u.dx ? 3 : 5)) { /* 1/3 or 1/5*(5/6) */ 1048. /* cancel delta y and choose an arbitrary delta x value */ 1049. y = u.uy; 1050. do { 1051. dx = rn2(3) - 1; /* -1 .. 1 */ 1052. x = u.ux + dx; 1053. } while (dx && (!isok(x,y) || !is_pool(x,y))); 1054. u.dy = 0; 1055. u.dx = dx; 1056. eff = TRUE; 1057. } 1058. if (eff) pline("Water turbulence affects your movements."); 1059. } 1060. 1061. void 1062. save_waterlevel(fd, mode) 1063. int fd, mode; 1064. { 1065. register struct bubble *b; 1066. 1067. if (!Is_waterlevel(&u.uz)) return; 1068. 1069. if (perform_bwrite(mode)) { 1070. int n = 0; 1071. for (b = bbubbles; b; b = b->next) ++n; 1072. bwrite(fd, (genericptr_t)&n, sizeof (int)); 1073. bwrite(fd, (genericptr_t)&xmin, sizeof (int)); 1074. bwrite(fd, (genericptr_t)&ymin, sizeof (int)); 1075. bwrite(fd, (genericptr_t)&xmax, sizeof (int)); 1076. bwrite(fd, (genericptr_t)&ymax, sizeof (int)); 1077. for (b = bbubbles; b; b = b->next) 1078. bwrite(fd, (genericptr_t)b, sizeof (struct bubble)); 1079. } 1080. if (release_data(mode)) 1081. unsetup_waterlevel(); 1082. } 1083. 1084. void 1085. restore_waterlevel(fd) 1086. register int fd; 1087. { 1088. register struct bubble *b = (struct bubble *)0, *btmp; 1089. register int i; 1090. int n; 1091. 1092. if (!Is_waterlevel(&u.uz)) return; 1093. 1094. set_wportal(); 1095. mread(fd,(genericptr_t)&n,sizeof(int)); 1096. mread(fd,(genericptr_t)&xmin,sizeof(int)); 1097. mread(fd,(genericptr_t)&ymin,sizeof(int)); 1098. mread(fd,(genericptr_t)&xmax,sizeof(int)); 1099. mread(fd,(genericptr_t)&ymax,sizeof(int)); 1100. for (i = 0; i < n; i++) { 1101. btmp = b; 1102. b = (struct bubble *)alloc(sizeof(struct bubble)); 1103. mread(fd,(genericptr_t)b,sizeof(struct bubble)); 1104. if (bbubbles) { 1105. btmp->next = b; 1106. b->prev = btmp; 1107. } else { 1108. bbubbles = b; 1109. b->prev = (struct bubble *)0; 1110. } 1111. mv_bubble(b,0,0,TRUE); 1112. } 1113. ebubbles = b; 1114. b->next = (struct bubble *)0; 1115. was_waterlevel = TRUE; 1116. } 1117. 1118. static void 1119. set_wportal() 1120. { 1121. /* there better be only one magic portal on water level... */ 1122. for (wportal = ftrap; wportal; wportal = wportal->ntrap) 1123. if (wportal->ttyp == MAGIC_PORTAL) return; 1124. impossible("set_wportal(): no portal!"); 1125. } 1126. 1127. static void 1128. setup_waterlevel() 1129. { 1130. register int x, y; 1131. register int xskip, yskip; 1132. register int water_glyph = cmap_to_glyph(S_water); 1133. 1134. /* ouch, hardcoded... */ 1135. 1136. xmin = 3; 1137. ymin = 1; 1138. xmax = 78; 1139. ymax = 20; 1140. 1141. /* set hero's memory to water */ 1142. 1143. for (x = xmin; x <= xmax; x++) 1144. for (y = ymin; y <= ymax; y++) 1145. levl[x][y].glyph = water_glyph; 1146. 1147. /* make bubbles */ 1148. 1149. xskip = 10 + rn2(10); 1150. yskip = 4 + rn2(4); 1151. for (x = bxmin; x <= bxmax; x += xskip) 1152. for (y = bymin; y <= bymax; y += yskip) 1153. mk_bubble(x,y,rn2(7)); 1154. } 1155. 1156. static void 1157. unsetup_waterlevel() 1158. { 1159. register struct bubble *b, *bb; 1160. 1161. /* free bubbles */ 1162. 1163. for (b = bbubbles; b; b = bb) { 1164. bb = b->next; 1165. free((genericptr_t)b); 1166. } 1167. bbubbles = ebubbles = (struct bubble *)0; 1168. } 1169. 1170. static void 1171. mk_bubble(x,y,n) 1172. register int x, y, n; 1173. { 1174. /* 1175. * These bit masks make visually pleasing bubbles on a normal aspect 1176. * 25x80 terminal, which naturally results in them being mathematically 1177. * anything but symmetric. For this reason they cannot be computed 1178. * in situ, either. The first two elements tell the dimensions of 1179. * the bubble's bounding box. 1180. */ 1181. static uchar 1182. bm2[] = {2,1,0x3}, 1183. bm3[] = {3,2,0x7,0x7}, 1184. bm4[] = {4,3,0x6,0xf,0x6}, 1185. bm5[] = {5,3,0xe,0x1f,0xe}, 1186. bm6[] = {6,4,0x1e,0x3f,0x3f,0x1e}, 1187. bm7[] = {7,4,0x3e,0x7f,0x7f,0x3e}, 1188. bm8[] = {8,4,0x7e,0xff,0xff,0x7e}, 1189. *bmask[] = {bm2,bm3,bm4,bm5,bm6,bm7,bm8}; 1190. 1191. register struct bubble *b; 1192. 1193. if (x >= bxmax || y >= bymax) return; 1194. if (n >= SIZE(bmask)) { 1195. impossible("n too large (mk_bubble)"); 1196. n = SIZE(bmask) - 1; 1197. } 1198. b = (struct bubble *)alloc(sizeof(struct bubble)); 1199. if ((x + (int) bmask[n][0] - 1) > bxmax) x = bxmax - bmask[n][0] + 1; 1200. if ((y + (int) bmask[n][1] - 1) > bymax) y = bymax - bmask[n][1] + 1; 1201. b->x = x; 1202. b->y = y; 1203. b->dx = 1 - rn2(3); 1204. b->dy = 1 - rn2(3); 1205. b->bm = bmask[n]; 1206. b->cons = 0; 1207. if (!bbubbles) bbubbles = b; 1208. if (ebubbles) { 1209. ebubbles->next = b; 1210. b->prev = ebubbles; 1211. } 1212. else 1213. b->prev = (struct bubble *)0; 1214. b->next = (struct bubble *)0; 1215. ebubbles = b; 1216. mv_bubble(b,0,0,TRUE); 1217. } 1218. 1219. /* 1220. * The player, the portal and all other objects and monsters 1221. * float along with their associated bubbles. Bubbles may overlap 1222. * freely, and the contents may get associated with other bubbles in 1223. * the process. Bubbles are "sticky", meaning that if the player is 1224. * in the immediate neighborhood of one, he/she may get sucked inside. 1225. * This property also makes leaving a bubble slightly difficult. 1226. */ 1227. static void 1228. mv_bubble(b,dx,dy,ini) 1229. register struct bubble *b; 1230. register int dx, dy; 1231. register boolean ini; 1232. { 1233. register int x, y, i, j, colli = 0; 1234. struct container *cons, *ctemp; 1235. 1236. /* move bubble */ 1237. if (dx < -1 || dx > 1 || dy < -1 || dy > 1) { 1238. /* pline("mv_bubble: dx = %d, dy = %d", dx, dy); */ 1239. dx = sgn(dx); 1240. dy = sgn(dy); 1241. } 1242. 1243. /* 1244. * collision with level borders? 1245. * 1 = horizontal border, 2 = vertical, 3 = corner 1246. */ 1247. if (b->x <= bxmin) colli |= 2; 1248. if (b->y <= bymin) colli |= 1; 1249. if ((int) (b->x + b->bm[0] - 1) >= bxmax) colli |= 2; 1250. if ((int) (b->y + b->bm[1] - 1) >= bymax) colli |= 1; 1251. 1252. if (b->x < bxmin) { 1253. pline("bubble xmin: x = %d, xmin = %d", b->x, bxmin); 1254. b->x = bxmin; 1255. } 1256. if (b->y < bymin) { 1257. pline("bubble ymin: y = %d, ymin = %d", b->y, bymin); 1258. b->y = bymin; 1259. } 1260. if ((int) (b->x + b->bm[0] - 1) > bxmax) { 1261. pline("bubble xmax: x = %d, xmax = %d", 1262. b->x + b->bm[0] - 1, bxmax); 1263. b->x = bxmax - b->bm[0] + 1; 1264. } 1265. if ((int) (b->y + b->bm[1] - 1) > bymax) { 1266. pline("bubble ymax: y = %d, ymax = %d", 1267. b->y + b->bm[1] - 1, bymax); 1268. b->y = bymax - b->bm[1] + 1; 1269. } 1270. 1271. /* bounce if we're trying to move off the border */ 1272. if (b->x == bxmin && dx < 0) dx = -dx; 1273. if (b->x + b->bm[0] - 1 == bxmax && dx > 0) dx = -dx; 1274. if (b->y == bymin && dy < 0) dy = -dy; 1275. if (b->y + b->bm[1] - 1 == bymax && dy > 0) dy = -dy; 1276. 1277. b->x += dx; 1278. b->y += dy; 1279. 1280. /* void positions inside bubble */ 1281. 1282. for (i = 0, x = b->x; i < (int) b->bm[0]; i++, x++) 1283. for (j = 0, y = b->y; j < (int) b->bm[1]; j++, y++) 1284. if (b->bm[j + 2] & (1 << i)) { 1285. levl[x][y].typ = AIR; 1286. levl[x][y].lit = 1; 1287. unblock_point(x,y); 1288. } 1289. 1290. /* replace contents of bubble */ 1291. for (cons = b->cons; cons; cons = ctemp) { 1292. ctemp = cons->next; 1293. cons->x += dx; 1294. cons->y += dy; 1295. 1296. switch(cons->what) { 1297. case CONS_OBJ: { 1298. struct obj *olist, *otmp; 1299. 1300. for (olist=(struct obj *)cons->list; olist; olist=otmp) { 1301. otmp = olist->nexthere; 1302. place_object(olist, cons->x, cons->y); 1303. } 1304. break; 1305. } 1306. 1307. case CONS_MON: { 1308. struct monst *mon = (struct monst *) cons->list; 1309. (void) mnearto(mon, cons->x, cons->y, TRUE); 1310. break; 1311. } 1312. 1313. case CONS_HERO: { 1314. int ux0 = u.ux, uy0 = u.uy; 1315. 1316. /* change u.ux0 and u.uy0? */ 1317. u.ux = cons->x; 1318. u.uy = cons->y; 1319. newsym(ux0, uy0); /* clean up old position */ 1320. 1321. if (MON_AT(cons->x, cons->y)) { 1322. mnexto(m_at(cons->x,cons->y)); 1323. } 1324. if (Punished) placebc(); /* do this for now */ 1325. break; 1326. } 1327. 1328. case CONS_TRAP: { 1329. struct trap *btrap = (struct trap *) cons->list; 1330. btrap->tx = cons->x; 1331. btrap->ty = cons->y; 1332. break; 1333. } 1334. 1335. default: 1336. impossible("mv_bubble: unknown bubble contents"); 1337. break; 1338. } 1339. free((genericptr_t)cons); 1340. } 1341. b->cons = 0; 1342. 1343. /* boing? */ 1344. 1345. switch (colli) { 1346. case 1: b->dy = -b->dy; break; 1347. case 3: b->dy = -b->dy; /* fall through */ 1348. case 2: b->dx = -b->dx; break; 1349. default: 1350. /* sometimes alter direction for fun anyway 1351. (higher probability for stationary bubbles) */ 1352. if (!ini && ((b->dx || b->dy) ? !rn2(20) : !rn2(5))) { 1353. b->dx = 1 - rn2(3); 1354. b->dy = 1 - rn2(3); 1355. } 1356. } 1357. } 1358. 1359. /*mkmaze.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