Source:SLASH'EM 0.0.7E7F2/teleport.c
Jump to navigation
Jump to search
Below is the full text to teleport.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[Source:SLASH'EM 0.0.7E7F2/teleport.c#line123]], for example.
Source code for vanilla NetHack is at Source code.
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)teleport.c 3.4 2003/08/11 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. 7. STATIC_DCL boolean FDECL(tele_jump_ok, (int,int,int,int)); 8. STATIC_DCL boolean FDECL(teleok, (int,int,BOOLEAN_P)); 9. STATIC_DCL void NDECL(vault_tele); 10. STATIC_DCL boolean FDECL(rloc_pos_ok, (int,int,struct monst *)); 11. STATIC_DCL void FDECL(mvault_tele, (struct monst *)); 12. 13. /* 14. * Is (x, y) a bad position of mtmp? If mtmp is NULL, then is (x, y) bad 15. * for an object? 16. * 17. * Caller is responsible for checking (x, y) with isok() if required. 18. * 19. * Returns: -1: Inaccessible, 0: Good pos, 1: Temporally inacessible 20. */ 21. static int 22. badpos(x, y, mtmp, gpflags) 23. int x, y; 24. struct monst *mtmp; 25. unsigned gpflags; 26. { 27. int is_badpos = 0, pool; 28. struct permonst *mdat = NULL; 29. boolean ignorewater = ((gpflags & MM_IGNOREWATER) != 0); 30. struct monst *mtmp2; 31. 32. /* in many cases, we're trying to create a new monster, which 33. * can't go on top of the player or any existing monster. 34. * however, occasionally we are relocating engravings or objects, 35. * which could be co-located and thus get restricted a bit too much. 36. * oh well. 37. */ 38. if (mtmp != &youmonst && x == u.ux && y == u.uy 39. #ifdef STEED 40. && (!u.usteed || mtmp != u.usteed) 41. #endif 42. ) 43. is_badpos = 1; 44. 45. if (mtmp) { 46. mtmp2 = m_at(x,y); 47. 48. /* Be careful with long worms. A monster may be placed back in 49. * its own location. Normally, if m_at() returns the same monster 50. * that we're trying to place, the monster is being placed in its 51. * own location. However, that is not correct for worm segments, 52. * because all the segments of the worm return the same m_at(). 53. * Actually we overdo the check a little bit--a worm can't be placed 54. * in its own location, period. If we just checked for mtmp->mx 55. * != x || mtmp->my != y, we'd miss the case where we're called 56. * to place the worm segment and the worm's head is at x,y. 57. */ 58. if (mtmp2 && (mtmp2 != mtmp || mtmp->wormno)) 59. is_badpos = 1; 60. 61. mdat = mtmp->data; 62. pool = is_pool(x,y); 63. if (mdat->mlet == S_EEL && !pool && rn2(13) && !ignorewater) 64. is_badpos = 1; 65. 66. if (pool && !ignorewater) { 67. if (mtmp == &youmonst) 68. return (HLevitation || Flying || Wwalking || 69. Swimming || Amphibious) ? is_badpos : -1; 70. else return (is_flyer(mdat) || is_swimmer(mdat) || 71. is_clinger(mdat)) ? is_badpos : -1; 72. } else if (is_lava(x,y)) { 73. if (mtmp == &youmonst) 74. return HLevitation ? is_badpos : -1; 75. else 76. return (is_flyer(mdat) || likes_lava(mdat)) ? 77. is_badpos : -1; 78. } 79. if (passes_walls(mdat) && may_passwall(x,y)) return is_badpos; 80. } 81. if (!ACCESSIBLE(levl[x][y].typ)) { 82. if (!(is_pool(x,y) && ignorewater)) return -1; 83. } 84. 85. if (closed_door(x, y) && (!mdat || !amorphous(mdat))) 86. return mdat && (nohands(mdat) || verysmall(mdat)) ? -1 : 1; 87. if (sobj_at(BOULDER, x, y) && (!mdat || !throws_rocks(mdat))) 88. return mdat ? -1 : 1; 89. return is_badpos; 90. } 91. 92. /* 93. * Is (x,y) a good position of mtmp? If mtmp is NULL, then is (x,y) good 94. * for an object? 95. * 96. * This function will only look at mtmp->mdat, so makemon, mplayer, etc can 97. * call it to generate new monster positions with fake monster structures. 98. */ 99. boolean 100. goodpos(x, y, mtmp, gpflags) 101. int x,y; 102. struct monst *mtmp; 103. unsigned gpflags; 104. { 105. if (!isok(x, y)) return FALSE; 106. 107. return !badpos(x, y, mtmp, gpflags); 108. } 109. 110. /* 111. * "entity next to" 112. * 113. * Attempt to find a good place for the given monster type in the closest 114. * position to (xx,yy). Do so in successive square rings around (xx,yy). 115. * If there is more than one valid positon in the ring, choose one randomly. 116. * Return TRUE and the position chosen when successful, FALSE otherwise. 117. */ 118. boolean 119. enexto(cc, xx, yy, mdat) 120. coord *cc; 121. register xchar xx, yy; 122. struct permonst *mdat; 123. { 124. return enexto_core(cc, xx, yy, mdat, 0); 125. } 126. 127. boolean 128. enexto_core(cc, xx, yy, mdat, entflags) 129. coord *cc; 130. register xchar xx, yy; 131. struct permonst *mdat; 132. unsigned entflags; 133. { 134. #define MAX_GOOD 15 135. coord good[MAX_GOOD], *good_ptr; 136. int x, y, range, i; 137. int xmin, xmax, ymin, ymax; 138. struct monst fakemon; /* dummy monster */ 139. 140. if (!mdat) { 141. #ifdef DEBUG 142. pline("enexto() called with mdat==0"); 143. #endif 144. /* default to player's original monster type */ 145. mdat = &mons[u.umonster]; 146. } 147. fakemon.data = mdat; /* set up for goodpos */ 148. good_ptr = good; 149. range = 1; 150. /* 151. * Walk around the border of the square with center (xx,yy) and 152. * radius range. Stop when we find at least one valid position. 153. */ 154. do { 155. xmin = max(1, xx-range); 156. xmax = min(COLNO-1, xx+range); 157. ymin = max(0, yy-range); 158. ymax = min(ROWNO-1, yy+range); 159. 160. for (x = xmin; x <= xmax; x++) 161. if (goodpos(x, ymin, &fakemon, entflags)) { 162. good_ptr->x = x; 163. good_ptr->y = ymin ; 164. /* beware of accessing beyond segment boundaries.. */ 165. if (good_ptr++ == &good[MAX_GOOD-1]) goto full; 166. } 167. for (x = xmin; x <= xmax; x++) 168. if (goodpos(x, ymax, &fakemon, entflags)) { 169. good_ptr->x = x; 170. good_ptr->y = ymax ; 171. /* beware of accessing beyond segment boundaries.. */ 172. if (good_ptr++ == &good[MAX_GOOD-1]) goto full; 173. } 174. for (y = ymin+1; y < ymax; y++) 175. if (goodpos(xmin, y, &fakemon, entflags)) { 176. good_ptr->x = xmin; 177. good_ptr-> y = y ; 178. /* beware of accessing beyond segment boundaries.. */ 179. if (good_ptr++ == &good[MAX_GOOD-1]) goto full; 180. } 181. for (y = ymin+1; y < ymax; y++) 182. if (goodpos(xmax, y, &fakemon, entflags)) { 183. good_ptr->x = xmax; 184. good_ptr->y = y ; 185. /* beware of accessing beyond segment boundaries.. */ 186. if (good_ptr++ == &good[MAX_GOOD-1]) goto full; 187. } 188. range++; 189. 190. /* return if we've grown too big (nothing is valid) */ 191. if (range > ROWNO && range > COLNO) return FALSE; 192. } while (good_ptr == good); 193. 194. full: 195. i = rn2((int)(good_ptr - good)); 196. cc->x = good[i].x; 197. cc->y = good[i].y; 198. return TRUE; 199. } 200. 201. /* 202. * "entity path to" 203. * 204. * Attempt to find nc good places for the given monster type with the shortest 205. * path to (xx,yy). Where there is more than one valid set of positions, one 206. * will be chosen at random. Return the number of positions found. 207. * Warning: This routine is much slower than enexto and should be used 208. * with caution. 209. */ 210. 211. #define EPATHTO_UNSEEN 0x0 212. #define EPATHTO_INACCESSIBLE 0x1 213. #define EPATHTO_DONE 0x2 214. #define EPATHTO_TAIL(n) (0x3 + ((n) & 1)) 215. 216. #define EPATHTO_XY(x,y) (((y) + 1) * COLNO + (x)) 217. #define EPATHTO_Y(xy) ((xy) / COLNO - 1) 218. #define EPATHTO_X(xy) ((xy) % COLNO) 219. 220. #ifdef DEBUG 221. coord epathto_debug_cc[100]; 222. #endif 223. 224. int 225. epathto(cc, nc, xx, yy, mdat) 226. coord *cc; 227. int nc; 228. register xchar xx, yy; 229. struct permonst *mdat; 230. { 231. int i, j, dir, ndirs, xy, x, y, r; 232. int path_len, postype; 233. int first_col, last_col; 234. int nd, n; 235. unsigned char *map; 236. static const int dirs[8] = 237. /* N, S, E, W, NW, NE, SE, SW */ 238. { -COLNO, COLNO, 1, -1, -COLNO-1, -COLNO+1, COLNO+1, COLNO-1}; 239. struct monst fakemon; /* dummy monster */ 240. fakemon.data = mdat; /* set up for badpos */ 241. map = (unsigned char *)alloc(COLNO * (ROWNO + 2)); 242. (void) memset((genericptr_t)map, EPATHTO_INACCESSIBLE, COLNO * (ROWNO + 2)); 243. for(i = 1; i < COLNO; i++) 244. for(j = 0; j < ROWNO; j++) 245. map[EPATHTO_XY(i, j)] = EPATHTO_UNSEEN; 246. map[EPATHTO_XY(xx, yy)] = EPATHTO_TAIL(0); 247. if (badpos(xx, yy, &fakemon, 0) == 0) { 248. cc[0].x = xx; 249. cc[0].y = yy; 250. nd = n = 1; 251. } 252. else 253. nd = n = 0; 254. for(path_len = 0; nd < nc; path_len++) 255. { 256. first_col = max(1, xx - path_len); 257. last_col = min(COLNO - 1, xx + path_len); 258. for(j = max(0, yy - path_len); j <= min(ROWNO - 1, yy + path_len); j++) 259. for(i = first_col; i <= last_col; i++) 260. if (map[EPATHTO_XY(i, j)] == EPATHTO_TAIL(path_len)) { 261. map[EPATHTO_XY(i, j)] = EPATHTO_DONE; 262. ndirs = mdat == &mons[PM_GRID_BUG] ? 4 : 8; 263. for(dir = 0; dir < ndirs; dir++) { 264. xy = EPATHTO_XY(i, j) + dirs[dir]; 265. if (map[xy] == EPATHTO_UNSEEN) { 266. x = EPATHTO_X(xy); 267. y = EPATHTO_Y(xy); 268. postype = badpos(x, y, &fakemon, 0); 269. map[xy] = postype < 0 ? EPATHTO_INACCESSIBLE : 270. EPATHTO_TAIL(path_len + 1); 271. if (postype == 0) { 272. if (n < nc) 273. { 274. cc[n].x = x; 275. cc[n].y = y; 276. } 277. else if (rn2(n - nd + 1) < nc - nd) 278. { 279. r = rn2(nc - nd) + nd; 280. cc[r].x = x; 281. cc[r].y = y; 282. } 283. ++n; 284. } 285. } 286. } 287. } 288. if (nd == n) 289. break; /* No more positions */ 290. else 291. nd = n; 292. } 293. if (nd > nc) 294. nd = nc; 295. #ifdef DEBUG 296. if (cc == epathto_debug_cc) 297. { 298. winid win; 299. int glyph; 300. char row[COLNO+1]; 301. 302. win = create_nhwindow(NHW_TEXT); 303. putstr(win, 0, ""); 304. for (y = 0; y < ROWNO; y++) { 305. for (x = 1; x < COLNO; x++) { 306. xy = EPATHTO_XY(x, y); 307. if (map[xy] == EPATHTO_INACCESSIBLE) { 308. glyph = back_to_glyph(x, y); 309. row[x] = showsyms[glyph_to_cmap(glyph)]; 310. } 311. else 312. row[x] = ' '; 313. } 314. for (i = 0; i < nd; i++) 315. if (cc[i].y == y) 316. row[cc[i].x] = i < 10 ? '0' + i : 317. i < 36 ? 'a' + i - 10 : 318. i < 62 ? 'A' + i - 36 : 319. '?'; 320. /* remove trailing spaces */ 321. for (x = COLNO-1; x >= 1; x--) 322. if (row[x] != ' ') break; 323. row[x+1] = '\0'; 324. 325. putstr(win, 0, &row[1]); 326. } 327. display_nhwindow(win, TRUE); 328. destroy_nhwindow(win); 329. } 330. #endif 331. 332. free((genericptr_t)map); 333. return nd; 334. } 335. 336. /* 337. * func should return 1 if the location should be counted as inaccessible 338. * (path won't continue through this point) or 0 if it is accessible. 339. */ 340. 341. void 342. xpathto(r, xx, yy, func, data) 343. int r; 344. register xchar xx, yy; 345. int (*func)(genericptr_t, int, int); 346. genericptr_t data; 347. { 348. int i, j, dir, xy, x, y; 349. int path_len, postype; 350. int first_col, last_col; 351. int nd, n; 352. unsigned char *map; 353. static const int dirs[8] = 354. /* N, S, E, W, NW, NE, SE, SW */ 355. { -COLNO, COLNO, 1, -1, -COLNO-1, -COLNO+1, COLNO+1, COLNO-1}; 356. map = (unsigned char *)alloc(COLNO * (ROWNO + 2)); 357. (void) memset((genericptr_t)map, EPATHTO_INACCESSIBLE, COLNO * (ROWNO + 2)); 358. for(i = 1; i < COLNO; i++) 359. for(j = 0; j < ROWNO; j++) 360. map[EPATHTO_XY(i, j)] = EPATHTO_UNSEEN; 361. map[EPATHTO_XY(xx, yy)] = EPATHTO_TAIL(0); 362. if (func(data, xx, yy) == 0) 363. nd = n = 1; 364. else 365. nd = n = 0; 366. for(path_len = 0; path_len < r; path_len++) 367. { 368. first_col = max(1, xx - path_len); 369. last_col = min(COLNO - 1, xx + path_len); 370. for(j = max(0, yy - path_len); j <= min(ROWNO - 1, yy + path_len); j++) 371. for(i = first_col; i <= last_col; i++) 372. if (map[EPATHTO_XY(i, j)] == EPATHTO_TAIL(path_len)) { 373. map[EPATHTO_XY(i, j)] = EPATHTO_DONE; 374. for(dir = 0; dir < 8; dir++) { 375. xy = EPATHTO_XY(i, j) + dirs[dir]; 376. if (map[xy] == EPATHTO_UNSEEN) { 377. x = EPATHTO_X(xy); 378. y = EPATHTO_Y(xy); 379. postype = func(data, x, y); 380. map[xy] = postype ? EPATHTO_INACCESSIBLE : 381. EPATHTO_TAIL(path_len + 1); 382. if (postype == 0) 383. ++n; 384. } 385. } 386. } 387. if (nd == n) 388. break; /* No more positions */ 389. else 390. nd = n; 391. } 392. free((genericptr_t)map); 393. } 394. 395. #ifdef DEBUG 396. void 397. wiz_debug_cmd() /* in this case, run epathto on arbitary monster & goal */ 398. { 399. struct permonst *ptr; 400. int mndx, i; 401. coord cc; 402. char buf[BUFSIZ]; 403. for(i = 0; ; i++) { 404. if(i >= 5) { 405. pline(thats_enough_tries); 406. return; 407. } 408. getlin("What monster do you want to test? [type the name]", buf); 409. 410. mndx = name_to_mon(buf); 411. if (mndx == NON_PM) { 412. pline("Such creatures do not exist in this world."); 413. continue; 414. } 415. ptr = &mons[mndx]; 416. pline("Which position do you want to aim for?"); 417. cc.x = u.ux; 418. cc.y = u.uy; 419. if (getpos(&cc, TRUE, "the goal position") < 0) 420. return; /* abort */ 421. epathto(epathto_debug_cc, SIZE(epathto_debug_cc), cc.x, cc.y, ptr); 422. break; 423. } 424. } 425. #endif /* DEBUG */ 426. 427. /* 428. * Check for restricted areas present in some special levels. (This might 429. * need to be augmented to allow deliberate passage in wizard mode, but 430. * only for explicitly chosen destinations.) 431. */ 432. STATIC_OVL boolean 433. tele_jump_ok(x1, y1, x2, y2) 434. int x1, y1, x2, y2; 435. { 436. if (dndest.nlx > 0) { 437. /* if inside a restricted region, can't teleport outside */ 438. if (within_bounded_area(x1, y1, dndest.nlx, dndest.nly, 439. dndest.nhx, dndest.nhy) && 440. !within_bounded_area(x2, y2, dndest.nlx, dndest.nly, 441. dndest.nhx, dndest.nhy)) 442. # ifdef WIZARD 443. if (!wizard) 444. # endif /* WIZARD */ 445. return FALSE; 446. /* and if outside, can't teleport inside */ 447. if (!within_bounded_area(x1, y1, dndest.nlx, dndest.nly, 448. dndest.nhx, dndest.nhy) && 449. within_bounded_area(x2, y2, dndest.nlx, dndest.nly, 450. dndest.nhx, dndest.nhy)) 451. # ifdef WIZARD 452. if (!wizard) 453. # endif /* WIZARD */ 454. return FALSE; 455. } 456. if (updest.nlx > 0) { /* ditto */ 457. if (within_bounded_area(x1, y1, updest.nlx, updest.nly, 458. updest.nhx, updest.nhy) && 459. !within_bounded_area(x2, y2, updest.nlx, updest.nly, 460. updest.nhx, updest.nhy)) 461. # ifdef WIZARD 462. if (!wizard) 463. # endif /* WIZARD */ 464. return FALSE; 465. if (!within_bounded_area(x1, y1, updest.nlx, updest.nly, 466. updest.nhx, updest.nhy) && 467. within_bounded_area(x2, y2, updest.nlx, updest.nly, 468. updest.nhx, updest.nhy)) 469. # ifdef WIZARD 470. if (!wizard) 471. # endif /* WIZARD */ 472. return FALSE; 473. } 474. return TRUE; 475. } 476. 477. STATIC_OVL boolean 478. teleok(x, y, trapok) 479. register int x, y; 480. boolean trapok; 481. { 482. if (!trapok && t_at(x, y)) return FALSE; 483. if (!goodpos(x, y, &youmonst, 0)) return FALSE; 484. if (!tele_jump_ok(u.ux, u.uy, x, y)) return FALSE; 485. if (!in_out_region(x, y)) return FALSE; 486. return TRUE; 487. } 488. 489. void 490. teleds(nux, nuy, allow_drag) 491. register int nux,nuy; 492. boolean allow_drag; 493. { 494. boolean ball_active = (Punished && uball->where != OBJ_FREE), 495. ball_still_in_range = FALSE; 496. 497. /* If they have to move the ball, then drag if allow_drag is true; 498. * otherwise they are teleporting, so unplacebc(). 499. * If they don't have to move the ball, then always "drag" whether or 500. * not allow_drag is true, because we are calling that function, not 501. * to drag, but to move the chain. *However* there are some dumb 502. * special cases: 503. * 0 0 504. * _X move east -----> X_ 505. * @ @ 506. * These are permissible if teleporting, but not if dragging. As a 507. * result, drag_ball() needs to know about allow_drag and might end 508. * up dragging the ball anyway. Also, drag_ball() might find that 509. * dragging the ball is completely impossible (ball in range but there's 510. * rock in the way), in which case it teleports the ball on its own. 511. */ 512. if (ball_active) { 513. if (!carried(uball) && distmin(nux, nuy, uball->ox, uball->oy) <= 2) 514. ball_still_in_range = TRUE; /* don't have to move the ball */ 515. else { 516. /* have to move the ball */ 517. if (!allow_drag || distmin(u.ux, u.uy, nux, nuy) > 1) { 518. /* we should not have dist > 1 and allow_drag at the same 519. * time, but just in case, we must then revert to teleport. 520. */ 521. allow_drag = FALSE; 522. unplacebc(); 523. } 524. } 525. } 526. u.utrap = 0; 527. setustuck(0); 528. u.ux0 = u.ux; 529. u.uy0 = u.uy; 530. 531. if (hides_under(youmonst.data)) 532. u.uundetected = OBJ_AT(nux, nuy); 533. else if (youmonst.data->mlet == S_EEL) 534. u.uundetected = is_pool(nux, nuy); 535. else { 536. u.uundetected = 0; 537. /* mimics stop being unnoticed */ 538. if (youmonst.data->mlet == S_MIMIC) 539. youmonst.m_ap_type = M_AP_NOTHING; 540. } 541. 542. if (u.uswallow) { 543. u.uswldtim = u.uswallow = 0; 544. if (Punished && !ball_active) { 545. /* ensure ball placement, like unstuck */ 546. ball_active = TRUE; 547. allow_drag = FALSE; 548. } 549. docrt(); 550. } 551. if (ball_active) { 552. if (ball_still_in_range || allow_drag) { 553. int bc_control; 554. xchar ballx, bally, chainx, chainy; 555. boolean cause_delay; 556. 557. if (drag_ball(nux, nuy, &bc_control, &ballx, &bally, 558. &chainx, &chainy, &cause_delay, allow_drag)) 559. move_bc(0, bc_control, ballx, bally, chainx, chainy); 560. } 561. } 562. /* must set u.ux, u.uy after drag_ball(), which may need to know 563. the old position if allow_drag is true... */ 564. u.ux = nux; 565. u.uy = nuy; 566. fill_pit(u.ux0, u.uy0); 567. if (ball_active) { 568. if (!ball_still_in_range && !allow_drag) 569. placebc(); 570. } 571. initrack(); /* teleports mess up tracking monsters without this */ 572. update_player_regions(); 573. #ifdef STEED 574. /* Move your steed, too */ 575. if (u.usteed) { 576. u.usteed->mx = nux; 577. u.usteed->my = nuy; 578. } 579. #endif 580. 581. /* 582. * Make sure the hero disappears from the old location. This will 583. * not happen if she is teleported within sight of her previous 584. * location. Force a full vision recalculation because the hero 585. * is now in a new location. 586. */ 587. newsym(u.ux0,u.uy0); 588. see_monsters(); 589. vision_full_recalc = 1; 590. nomul(0); 591. vision_recalc(0); /* vision before effects */ 592. spoteffects(TRUE); 593. invocation_message(); 594. } 595. 596. boolean 597. safe_teleds(allow_drag) 598. boolean allow_drag; 599. { 600. register int nux, nuy, tcnt = 0; 601. 602. do { 603. nux = rnd(COLNO-1); 604. nuy = rn2(ROWNO); 605. } while (!teleok(nux, nuy, (boolean)(tcnt > 200)) && ++tcnt <= 400); 606. 607. if (tcnt <= 400) { 608. teleds(nux, nuy, allow_drag); 609. return TRUE; 610. } else 611. return FALSE; 612. } 613. 614. STATIC_OVL void 615. vault_tele() 616. { 617. register struct mkroom *croom = search_special(VAULT); 618. coord c; 619. 620. if (croom && somexy(croom, &c) && teleok(c.x,c.y,FALSE)) { 621. teleds(c.x,c.y,FALSE); 622. return; 623. } 624. tele(); 625. } 626. 627. boolean 628. teleport_pet(mtmp, force_it) 629. register struct monst *mtmp; 630. boolean force_it; 631. { 632. register struct obj *otmp; 633. 634. #ifdef STEED 635. if (mtmp == u.usteed) 636. return (FALSE); 637. #endif 638. 639. if (mtmp->mleashed) { 640. otmp = get_mleash(mtmp); 641. if (!otmp) { 642. impossible("%s is leashed, without a leash.", Monnam(mtmp)); 643. goto release_it; 644. } 645. if (otmp->cursed && !force_it) { 646. yelp(mtmp); 647. return FALSE; 648. } else { 649. Your("leash goes slack."); 650. release_it: 651. m_unleash(mtmp, FALSE); 652. return TRUE; 653. } 654. } 655. return TRUE; 656. } 657. 658. void 659. tele() 660. { 661. coord cc; 662. 663. /* Disable teleportation in stronghold && Vlad's Tower */ 664. if (level.flags.noteleport) { 665. #ifdef WIZARD 666. if (!wizard) { 667. #endif 668. pline("A mysterious force prevents you from teleporting!"); 669. return; 670. #ifdef WIZARD 671. } 672. #endif 673. } 674. 675. /* don't show trap if "Sorry..." */ 676. if (!Blinded) make_blinded(0L,FALSE); 677. 678. if 679. #ifdef WIZARD 680. ( 681. #endif 682. (u.uhave.amulet || On_W_tower_level(&u.uz) 683. #ifdef STEED 684. || (u.usteed && mon_has_amulet(u.usteed)) 685. #endif 686. ) 687. #ifdef WIZARD 688. && (!wizard) ) 689. #endif 690. { 691. You_feel("disoriented for a moment."); 692. return; 693. } 694. if ((Teleport_control && !Stunned) 695. #ifdef WIZARD 696. || wizard 697. #endif 698. ) { 699. if (unconscious()) { 700. pline("Being unconscious, you cannot control your teleport."); 701. } else { 702. #ifdef STEED 703. char buf[BUFSZ]; 704. if (u.usteed) Sprintf(buf," and %s", mon_nam(u.usteed)); 705. #endif 706. pline("To what position do you%s want to be teleported?", 707. #ifdef STEED 708. u.usteed ? buf : 709. #endif 710. ""); 711. cc.x = u.ux; 712. cc.y = u.uy; 713. if (getpos(&cc, TRUE, "the desired position") < 0) 714. return; /* abort */ 715. /* possible extensions: introduce a small error if 716. magic power is low; allow transfer to solid rock */ 717. if (teleok(cc.x, cc.y, FALSE)) { 718. teleds(cc.x, cc.y, FALSE); 719. return; 720. } 721. pline("Sorry..."); 722. } 723. } 724. 725. (void) safe_teleds(FALSE); 726. } 727. 728. int 729. dotele() 730. { 731. struct trap *trap; 732. 733. trap = t_at(u.ux, u.uy); 734. if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP)) 735. trap = 0; 736. 737. if (trap) { 738. if (trap->once) { 739. pline("This is a vault teleport, usable once only."); 740. if (yn("Jump in?") == 'n') 741. trap = 0; 742. else { 743. deltrap(trap); 744. newsym(u.ux, u.uy); 745. } 746. } 747. if (trap) 748. You("%s onto the teleportation trap.", 749. locomotion(youmonst.data, "jump")); 750. } 751. if (!trap) { 752. boolean castit = FALSE; 753. register int sp_no = 0, energy = 0; 754. 755. if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12) 756. && !can_teleport(youmonst.data))) { 757. /* Try to use teleport away spell. */ 758. if (objects[SPE_TELEPORT_AWAY].oc_name_known && !Confusion) 759. for (sp_no = 0; sp_no < MAXSPELL; sp_no++) 760. if (spl_book[sp_no].sp_id == SPE_TELEPORT_AWAY) { 761. castit = TRUE; 762. break; 763. } 764. #ifdef WIZARD 765. if (!wizard) { 766. #endif 767. if (!castit) { 768. if (!Teleportation) 769. You("don't know that spell."); 770. else You("are not able to teleport at will."); 771. return(0); 772. } 773. #ifdef WIZARD 774. } 775. #endif 776. } 777. 778. if (u.uhunger <= 10 || ACURR(A_STR) < 6) { 779. #ifdef WIZARD 780. if (!wizard) { 781. #endif 782. You("lack the strength %s.", 783. castit ? "for a teleport spell" : "to teleport"); 784. return 1; 785. #ifdef WIZARD 786. } 787. #endif 788. } 789. 790. energy = objects[SPE_TELEPORT_AWAY].oc_level * 5; 791. if (u.uen <= energy) { 792. #ifdef WIZARD 793. if (wizard) 794. energy = u.uen; 795. else 796. #endif 797. { 798. You("lack the energy %s.", 799. castit ? "for a teleport spell" : "to teleport"); 800. return 1; 801. } 802. } 803. 804. if (check_capacity( 805. "Your concentration falters from carrying so much.")) 806. return 1; 807. 808. if (castit) { 809. exercise(A_WIS, TRUE); 810. if (spelleffects(sp_no, TRUE)) 811. return(1); 812. else 813. #ifdef WIZARD 814. if (!wizard) 815. #endif 816. return(0); 817. } else { 818. u.uen -= energy; 819. flags.botl = 1; 820. } 821. } 822. 823. if (next_to_u()) { 824. if (trap && trap->once) vault_tele(); 825. else tele(); 826. (void) next_to_u(); 827. } else { 828. You(shudder_for_moment); 829. return(0); 830. } 831. if (!trap) morehungry(10); 832. return(1); 833. } 834. 835. void 836. level_tele() 837. { 838. register int newlev; 839. d_level newlevel; 840. const char *escape_by_flying = 0; /* when surviving dest of -N */ 841. char buf[BUFSZ]; 842. boolean force_dest = FALSE; 843. 844. if ((u.uhave.amulet || In_endgame(&u.uz) || In_sokoban(&u.uz) 845. #ifdef STEED 846. || (u.usteed && mon_has_amulet(u.usteed)) 847. #endif 848. ) 849. #ifdef WIZARD 850. && !wizard 851. #endif 852. ) { 853. You_feel("very disoriented for a moment."); 854. return; 855. } 856. if ((Teleport_control && !Stunned) 857. #ifdef WIZARD 858. || wizard 859. #endif 860. ) { 861. char qbuf[BUFSZ]; 862. int trycnt = 0; 863. 864. Strcpy(qbuf, "To what level do you want to teleport?"); 865. do { 866. if (++trycnt == 2) { 867. #ifdef WIZARD 868. if (wizard) Strcat(qbuf, " [type a number or ? for a menu]"); 869. else 870. #endif 871. Strcat(qbuf, " [type a number]"); 872. } 873. getlin(qbuf, buf); 874. if (!strcmp(buf,"\033")) { /* cancelled */ 875. if (Confusion && rnl(5)) { 876. pline("Oops..."); 877. goto random_levtport; 878. } 879. return; 880. } else if (!strcmp(buf,"*")) { 881. goto random_levtport; 882. } else if (Confusion && rnl(5)) { 883. pline("Oops..."); 884. goto random_levtport; 885. } 886. #ifdef WIZARD 887. if (wizard && !strcmp(buf,"?")) { 888. schar destlev = 0; 889. xchar destdnum = 0; 890. 891. if ((newlev = (int)print_dungeon(TRUE, &destlev, &destdnum))) { 892. newlevel.dnum = destdnum; 893. newlevel.dlevel = destlev; 894. if (In_endgame(&newlevel) && !In_endgame(&u.uz)) { 895. Sprintf(buf, 896. "Destination is earth level"); 897. if (!u.uhave.amulet) { 898. struct obj *obj; 899. obj = mksobj(AMULET_OF_YENDOR, 900. TRUE, FALSE); 901. if (obj) { 902. obj = addinv(obj); 903. Strcat(buf, " with the amulet"); 904. } 905. } 906. assign_level(&newlevel, &earth_level); 907. pline("%s.", buf); 908. } 909. force_dest = TRUE; 910. } else return; 911. } else 912. #endif 913. if ((newlev = lev_by_name(buf)) == 0) { 914. #ifdef WIZARD 915. s_level *slev; 916. 917. /* if you're using wizard mode, you shouldn't really need 918. * the game to interpret things like `mine town level' */ 919. if (wizard && (slev = find_level(buf))) { 920. schedule_goto(&slev->dlevel, FALSE, FALSE, 0, 921. (char *)0, (char *)0); 922. return; 923. } 924. #endif 925. newlev = atoi(buf); 926. } 927. } while (!newlev && !digit(buf[0]) && 928. (buf[0] != '-' || !digit(buf[1])) && 929. trycnt < 10); 930. 931. /* no dungeon escape via this route */ 932. if (newlev == 0) { 933. if (trycnt >= 10) 934. goto random_levtport; 935. if (ynq("Go to Nowhere. Are you sure?") != 'y') return; 936. You("%s in agony as your body begins to warp...", 937. is_silent(youmonst.data) ? "writhe" : "scream"); 938. display_nhwindow(WIN_MESSAGE, FALSE); 939. You("cease to exist."); 940. if (invent) Your("possessions land on the %s with a thud.", 941. surface(u.ux, u.uy)); 942. killer_format = NO_KILLER_PREFIX; 943. killer = "committed suicide"; 944. done(DIED); 945. pline("An energized cloud of dust begins to coalesce."); 946. Your("body rematerializes%s.", invent ? 947. ", and you gather up all your possessions" : ""); 948. return; 949. } 950. 951. /* if in Knox and the requested level > 0, stay put. 952. * we let negative values requests fall into the "heaven" loop. 953. * [ALI] Add other single level dungeons entered via portal. 954. */ 955. if ((Is_knox(&u.uz) || 956. #ifdef BLACKMARKET 957. Is_blackmarket(&u.uz) || 958. #endif 959. Is_aligned_quest(&u.uz)) && newlev > 0) { 960. You(shudder_for_moment); 961. return; 962. } 963. /* if in Quest, the player sees "Home 1", etc., on the status 964. * line, instead of the logical depth of the level. controlled 965. * level teleport request is likely to be relativized to the 966. * status line, and consequently it should be incremented to 967. * the value of the logical depth of the target level. 968. * 969. * we let negative values requests fall into the "heaven" loop. 970. */ 971. if (In_quest(&u.uz) && newlev > 0) 972. newlev = newlev + dungeons[u.uz.dnum].depth_start - 1; 973. } else { /* involuntary level tele */ 974. random_levtport: 975. newlev = random_teleport_level(); 976. if (newlev == depth(&u.uz)) { 977. You(shudder_for_moment); 978. return; 979. } 980. } 981. 982. if (!next_to_u()) { 983. You(shudder_for_moment); 984. return; 985. } 986. #ifdef WIZARD 987. if (In_endgame(&u.uz)) { /* must already be wizard */ 988. int llimit = dunlevs_in_dungeon(&u.uz); 989. 990. if (newlev >= 0 || newlev <= -llimit) { 991. You_cant("get there from here."); 992. return; 993. } 994. newlevel.dnum = u.uz.dnum; 995. newlevel.dlevel = llimit + newlev; 996. schedule_goto(&newlevel, FALSE, FALSE, 0, (char *)0, (char *)0); 997. return; 998. } 999. #endif 1000. killer = 0; /* still alive, so far... */ 1001. 1002. if (newlev < 0 && !force_dest) { 1003. if (*u.ushops0) { 1004. /* take unpaid inventory items off of shop bills */ 1005. in_mklev = TRUE; /* suppress map update */ 1006. u_left_shop(u.ushops0, TRUE); 1007. /* you're now effectively out of the shop */ 1008. *u.ushops0 = *u.ushops = '\0'; 1009. in_mklev = FALSE; 1010. } 1011. if (newlev <= -10) { 1012. You("arrive in heaven."); 1013. verbalize("Thou art early, but we'll admit thee."); 1014. killer_format = NO_KILLER_PREFIX; 1015. killer = "went to heaven prematurely"; 1016. } else if (newlev == -9) { 1017. You_feel("deliriously happy. "); 1018. pline("(In fact, you're on Cloud 9!) "); 1019. display_nhwindow(WIN_MESSAGE, FALSE); 1020. } else 1021. You("are now high above the clouds..."); 1022. 1023. if (killer) { 1024. ; /* arrival in heaven is pending */ 1025. } else if (Levitation) { 1026. escape_by_flying = "float gently down to earth"; 1027. } else if (Flying) { 1028. escape_by_flying = "fly down to the ground"; 1029. } else { 1030. pline("Unfortunately, you don't know how to fly."); 1031. You("plummet a few thousand feet to your death."); 1032. Sprintf(buf, 1033. "teleported out of the dungeon and fell to %s death", 1034. uhis()); 1035. killer = buf; 1036. killer_format = NO_KILLER_PREFIX; 1037. } 1038. } 1039. 1040. if (killer) { /* the chosen destination was not survivable */ 1041. d_level lsav; 1042. 1043. /* set specific death location; this also suppresses bones */ 1044. lsav = u.uz; /* save current level, see below */ 1045. u.uz.dnum = 0; /* main dungeon */ 1046. u.uz.dlevel = (newlev <= -10) ? -10 : 0; /* heaven or surface */ 1047. done(DIED); 1048. /* can only get here via life-saving (or declining to die in 1049. explore|debug mode); the hero has now left the dungeon... */ 1050. escape_by_flying = "find yourself back on the surface"; 1051. u.uz = lsav; /* restore u.uz so escape code works */ 1052. } 1053. 1054. /* calls done(ESCAPED) if newlevel==0 */ 1055. if (escape_by_flying) { 1056. You("%s.", escape_by_flying); 1057. newlevel.dnum = 0; /* specify main dungeon */ 1058. newlevel.dlevel = 0; /* escape the dungeon */ 1059. /* [dlevel used to be set to 1, but it doesn't make sense to 1060. teleport out of the dungeon and float or fly down to the 1061. surface but then actually arrive back inside the dungeon] */ 1062. } else if (u.uz.dnum == medusa_level.dnum && 1063. newlev >= dungeons[u.uz.dnum].depth_start + 1064. dunlevs_in_dungeon(&u.uz)) { 1065. #ifdef WIZARD 1066. if (!(wizard && force_dest)) 1067. #endif 1068. find_hell(&newlevel); 1069. } else { 1070. /* if invocation did not yet occur, teleporting into 1071. * the last level of Gehennom is forbidden. 1072. */ 1073. #ifdef WIZARD 1074. if (!wizard) 1075. #endif 1076. if (Inhell && !u.uevent.invoked && 1077. newlev >= (dungeons[u.uz.dnum].depth_start + 1078. dunlevs_in_dungeon(&u.uz) - 1)) { 1079. # ifdef WIZARD 1080. if (!wizard) 1081. { 1082. # endif /* WIZARD */ 1083. newlev = dungeons[u.uz.dnum].depth_start + 1084. dunlevs_in_dungeon(&u.uz) - 2; 1085. pline("Sorry..."); 1086. # ifdef WIZARD 1087. } 1088. # endif /* WIZARD */ 1089. 1090. } 1091. /* no teleporting out of quest dungeon */ 1092. if 1093. # ifdef WIZARD 1094. ((!wizard) && 1095. # endif /* WIZARD */ 1096. (In_quest(&u.uz) && newlev < depth(&qstart_level)) 1097. # ifdef WIZARD 1098. ) 1099. # endif /* WIZARD */ 1100. newlev = depth(&qstart_level); 1101. /* the player thinks of levels purely in logical terms, so 1102. * we must translate newlev to a number relative to the 1103. * current dungeon. 1104. */ 1105. #ifdef WIZARD 1106. if (!(wizard && force_dest)) 1107. #endif 1108. get_level(&newlevel, newlev); 1109. } 1110. schedule_goto(&newlevel, FALSE, FALSE, 0, (char *)0, (char *)0); 1111. /* in case player just read a scroll and is about to be asked to 1112. call it something, we can't defer until the end of the turn */ 1113. if (u.utotype && !flags.mon_moving) deferred_goto(); 1114. } 1115. 1116. void 1117. domagicportal(ttmp) 1118. register struct trap *ttmp; 1119. { 1120. struct d_level target_level; 1121. 1122. if (!next_to_u()) { 1123. You(shudder_for_moment); 1124. return; 1125. } 1126. 1127. /* if landed from another portal, do nothing */ 1128. /* problem: level teleport landing escapes the check */ 1129. if (!on_level(&u.uz, &u.uz0)) return; 1130. 1131. You("activated a magic portal!"); 1132. 1133. /* prevent the poor shnook, whose amulet was stolen while in 1134. * the endgame, from accidently triggering the portal to the 1135. * next level, and thus losing the game 1136. */ 1137. if (In_endgame(&u.uz) && !u.uhave.amulet) { 1138. You_feel("dizzy for a moment, but nothing happens..."); 1139. return; 1140. } 1141. 1142. target_level = ttmp->dst; 1143. schedule_goto(&target_level, FALSE, FALSE, 1, 1144. "You feel dizzy for a moment, but the sensation passes.", 1145. (char *)0); 1146. } 1147. 1148. void 1149. tele_trap(trap) 1150. struct trap *trap; 1151. { 1152. if (In_endgame(&u.uz) || Antimagic) { 1153. if (Antimagic) 1154. shieldeff(u.ux, u.uy); 1155. You_feel("a wrenching sensation."); 1156. } else if (!next_to_u()) { 1157. You(shudder_for_moment); 1158. } else if (trap->once) { 1159. deltrap(trap); 1160. newsym(u.ux,u.uy); /* get rid of trap symbol */ 1161. vault_tele(); 1162. } else 1163. tele(); 1164. } 1165. 1166. void 1167. level_tele_trap(trap) 1168. struct trap *trap; 1169. { 1170. You("%s onto a level teleport trap!", 1171. Levitation ? (const char *)"float" : 1172. locomotion(youmonst.data, "step")); 1173. if (Antimagic) { 1174. shieldeff(u.ux, u.uy); 1175. } 1176. if (Antimagic || In_endgame(&u.uz)) { 1177. You_feel("a wrenching sensation."); 1178. return; 1179. } 1180. if (!Blind) 1181. You("are momentarily blinded by a flash of light."); 1182. else 1183. You("are momentarily disoriented."); 1184. deltrap(trap); 1185. newsym(u.ux,u.uy); /* get rid of trap symbol */ 1186. level_tele(); 1187. } 1188. 1189. /* check whether monster can arrive at location <x,y> via Tport (or fall) */ 1190. STATIC_OVL boolean 1191. rloc_pos_ok(x, y, mtmp) 1192. register int x, y; /* coordinates of candidate location */ 1193. struct monst *mtmp; 1194. { 1195. register int xx, yy; 1196. 1197. if (!goodpos(x, y, mtmp, 0)) return FALSE; 1198. /* 1199. * Check for restricted areas present in some special levels. 1200. * 1201. * `xx' is current column; if 0, then `yy' will contain flag bits 1202. * rather than row: bit #0 set => moving upwards; bit #1 set => 1203. * inside the Wizard's tower. 1204. */ 1205. xx = mtmp->mx; 1206. yy = mtmp->my; 1207. if (!xx) { 1208. /* no current location (migrating monster arrival) */ 1209. if (dndest.nlx && On_W_tower_level(&u.uz)) 1210. return ((yy & 2) != 0) ^ /* inside xor not within */ 1211. !within_bounded_area(x, y, dndest.nlx, dndest.nly, 1212. dndest.nhx, dndest.nhy); 1213. if (updest.lx && (yy & 1) != 0) /* moving up */ 1214. return (within_bounded_area(x, y, updest.lx, updest.ly, 1215. updest.hx, updest.hy) && 1216. (!updest.nlx || 1217. !within_bounded_area(x, y, updest.nlx, updest.nly, 1218. updest.nhx, updest.nhy))); 1219. if (dndest.lx && (yy & 1) == 0) /* moving down */ 1220. return (within_bounded_area(x, y, dndest.lx, dndest.ly, 1221. dndest.hx, dndest.hy) && 1222. (!dndest.nlx || 1223. !within_bounded_area(x, y, dndest.nlx, dndest.nly, 1224. dndest.nhx, dndest.nhy))); 1225. } else { 1226. /* current location is <xx,yy> */ 1227. if (!tele_jump_ok(xx, yy, x, y)) return FALSE; 1228. } 1229. /* <x,y> is ok */ 1230. return TRUE; 1231. } 1232. 1233. /* 1234. * rloc_to() 1235. * 1236. * Pulls a monster from its current position and places a monster at 1237. * a new x and y. If oldx is 0, then the monster was not in the levels.monsters 1238. * array. However, if oldx is 0, oldy may still have a value because mtmp is a 1239. * migrating_mon. Worm tails are always placed randomly around the head of 1240. * the worm. 1241. */ 1242. void 1243. rloc_to(mtmp, x, y) 1244. struct monst *mtmp; 1245. register int x, y; 1246. { 1247. register int oldx = mtmp->mx, oldy = mtmp->my; 1248. boolean resident_shk = mtmp->isshk && inhishop(mtmp); 1249. 1250. if (x == mtmp->mx && y == mtmp->my) /* that was easy */ 1251. return; 1252. 1253. if (oldx) { /* "pick up" monster */ 1254. if (mtmp->wormno) 1255. remove_worm(mtmp); 1256. else { 1257. remove_monster(oldx, oldy); 1258. newsym(oldx, oldy); /* update old location */ 1259. } 1260. } 1261. 1262. place_monster(mtmp, x, y); /* put monster down */ 1263. update_monster_region(mtmp); 1264. 1265. if (mtmp->wormno) /* now put down tail */ 1266. place_worm_tail_randomly(mtmp, x, y); 1267. 1268. if (u.ustuck == mtmp) { 1269. if (u.uswallow) { 1270. u.ux = x; 1271. u.uy = y; 1272. docrt(); 1273. } else setustuck(0); 1274. } 1275. 1276. newsym(x, y); /* update new location */ 1277. set_apparxy(mtmp); /* orient monster */ 1278. 1279. /* shopkeepers will only teleport if you zap them with a wand of 1280. teleportation or if they've been transformed into a jumpy monster; 1281. the latter only happens if you've attacked them with polymorph */ 1282. if (resident_shk && !inhishop(mtmp)) make_angry_shk(mtmp, oldx, oldy); 1283. } 1284. 1285. /* place a monster at a random location, typically due to teleport */ 1286. /* return TRUE if successful, FALSE if not */ 1287. boolean 1288. rloc(mtmp, suppress_impossible) 1289. struct monst *mtmp; /* mx==0 implies migrating monster arrival */ 1290. boolean suppress_impossible; 1291. { 1292. register int x, y, trycount; 1293. 1294. #ifdef STEED 1295. if (mtmp == u.usteed) { 1296. tele(); 1297. return TRUE; 1298. } 1299. #endif 1300. 1301. if (mtmp->iswiz && mtmp->mx) { /* Wizard, not just arriving */ 1302. if (!In_W_tower(u.ux, u.uy, &u.uz)) 1303. x = xupstair, y = yupstair; 1304. else if (!xdnladder) /* bottom level of tower */ 1305. x = xupladder, y = yupladder; 1306. else 1307. x = xdnladder, y = ydnladder; 1308. /* if the wiz teleports away to heal, try the up staircase, 1309. to block the player's escaping before he's healed 1310. (deliberately use `goodpos' rather than `rloc_pos_ok' here) */ 1311. if (goodpos(x, y, mtmp, 0)) 1312. goto found_xy; 1313. } 1314. 1315. trycount = 0; 1316. do { 1317. x = rn1(COLNO-3,2); 1318. y = rn2(ROWNO); 1319. if ((trycount < 500) ? rloc_pos_ok(x, y, mtmp) 1320. : goodpos(x, y, mtmp, 0)) 1321. goto found_xy; 1322. } while (++trycount < 1000); 1323. 1324. /* last ditch attempt to find a good place */ 1325. for (x = 2; x < COLNO - 1; x++) 1326. for (y = 0; y < ROWNO; y++) 1327. if (goodpos(x, y, mtmp, 0)) 1328. goto found_xy; 1329. 1330. /* level either full of monsters or somehow faulty */ 1331. if (!suppress_impossible) 1332. impossible("rloc(): couldn't relocate monster"); 1333. return FALSE; 1334. 1335. found_xy: 1336. rloc_to(mtmp, x, y); 1337. return TRUE; 1338. } 1339. 1340. STATIC_OVL void 1341. mvault_tele(mtmp) 1342. struct monst *mtmp; 1343. { 1344. register struct mkroom *croom = search_special(VAULT); 1345. coord c; 1346. 1347. if (croom && somexy(croom, &c) && 1348. goodpos(c.x, c.y, mtmp, 0)) { 1349. rloc_to(mtmp, c.x, c.y); 1350. return; 1351. } 1352. (void) rloc(mtmp, FALSE); 1353. } 1354. 1355. boolean 1356. tele_restrict(mon) 1357. struct monst *mon; 1358. { 1359. if (level.flags.noteleport) { 1360. if (canseemon(mon)) 1361. pline("A mysterious force prevents %s from teleporting!", 1362. mon_nam(mon)); 1363. return TRUE; 1364. } 1365. return FALSE; 1366. } 1367. 1368. void 1369. mtele_trap(mtmp, trap, in_sight) 1370. struct monst *mtmp; 1371. struct trap *trap; 1372. int in_sight; 1373. { 1374. char *monname; 1375. 1376. if (tele_restrict(mtmp)) return; 1377. if (teleport_pet(mtmp, FALSE)) { 1378. /* save name with pre-movement visibility */ 1379. monname = Monnam(mtmp); 1380. 1381. /* Note: don't remove the trap if a vault. Other- 1382. * wise the monster will be stuck there, since 1383. * the guard isn't going to come for it... 1384. */ 1385. if (trap->once) mvault_tele(mtmp); 1386. else (void) rloc(mtmp, FALSE); 1387. 1388. if (in_sight) { 1389. if (canseemon(mtmp)) 1390. pline("%s seems disoriented.", monname); 1391. else 1392. pline("%s suddenly disappears!", monname); 1393. seetrap(trap); 1394. } 1395. } 1396. } 1397. 1398. /* return 0 if still on level, 3 if not */ 1399. int 1400. mlevel_tele_trap(mtmp, trap, force_it, in_sight) 1401. struct monst *mtmp; 1402. struct trap *trap; 1403. boolean force_it; 1404. int in_sight; 1405. { 1406. int tt = trap->ttyp; 1407. struct permonst *mptr = mtmp->data; 1408. 1409. if (mtmp == u.ustuck) /* probably a vortex */ 1410. return 0; /* temporary? kludge */ 1411. if (teleport_pet(mtmp, force_it)) { 1412. d_level tolevel; 1413. int migrate_typ = MIGR_RANDOM; 1414. 1415. if ((tt == HOLE || tt == TRAPDOOR)) { 1416. if (Is_stronghold(&u.uz)) { 1417. assign_level(&tolevel, &valley_level); 1418. } else if (Is_botlevel(&u.uz)) { 1419. if (in_sight && trap->tseen) 1420. pline("%s avoids the %s.", Monnam(mtmp), 1421. (tt == HOLE) ? "hole" : "trap"); 1422. return 0; 1423. } else { 1424. get_level(&tolevel, depth(&u.uz) + 1); 1425. } 1426. } else if (tt == MAGIC_PORTAL) { 1427. if (In_endgame(&u.uz) && 1428. (mon_has_amulet(mtmp) || is_home_elemental(mptr))) { 1429. if (in_sight && mptr->mlet != S_ELEMENTAL) { 1430. pline("%s seems to shimmer for a moment.", 1431. Monnam(mtmp)); 1432. seetrap(trap); 1433. } 1434. return 0; 1435. } 1436. #ifdef BLACKMARKET 1437. else if (mtmp->mtame && 1438. (Is_blackmarket(&trap->dst) || Is_blackmarket(&u.uz))) { 1439. if (in_sight) { 1440. pline("%s seems to shimmer for a moment.", 1441. Monnam(mtmp)); 1442. seetrap(trap); 1443. } 1444. return 0; 1445. } 1446. #endif /* BLACKMARKET */ 1447. else { 1448. assign_level(&tolevel, &trap->dst); 1449. migrate_typ = MIGR_PORTAL; 1450. } 1451. } else { /* (tt == LEVEL_TELEP) */ 1452. int nlev; 1453. 1454. if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) { 1455. if (in_sight) 1456. pline("%s seems very disoriented for a moment.", 1457. Monnam(mtmp)); 1458. return 0; 1459. } 1460. nlev = random_teleport_level(); 1461. if (nlev == depth(&u.uz)) { 1462. if (in_sight) 1463. pline("%s shudders for a moment.", Monnam(mtmp)); 1464. return 0; 1465. } 1466. get_level(&tolevel, nlev); 1467. } 1468. 1469. if (in_sight) { 1470. pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp)); 1471. seetrap(trap); 1472. } 1473. migrate_to_level(mtmp, ledger_no(&tolevel), 1474. migrate_typ, (coord *)0); 1475. return 3; /* no longer on this level */ 1476. } 1477. return 0; 1478. } 1479. 1480. 1481. void 1482. rloco(obj) 1483. register struct obj *obj; 1484. { 1485. register xchar tx, ty, otx, oty; 1486. boolean restricted_fall; 1487. int try_limit = 4000; 1488. 1489. if (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm])) { 1490. if (revive_corpse(obj, FALSE)) return; 1491. } 1492. 1493. obj_extract_self(obj); 1494. otx = obj->ox; 1495. oty = obj->oy; 1496. restricted_fall = (otx == 0 && dndest.lx); 1497. do { 1498. tx = rn1(COLNO-3,2); 1499. ty = rn2(ROWNO); 1500. if (!--try_limit) break; 1501. } while (!goodpos(tx, ty, (struct monst *)0, 0) || 1502. /* bug: this lacks provision for handling the Wizard's tower */ 1503. (restricted_fall && 1504. (!within_bounded_area(tx, ty, dndest.lx, dndest.ly, 1505. dndest.hx, dndest.hy) || 1506. (dndest.nlx && 1507. within_bounded_area(tx, ty, dndest.nlx, dndest.nly, 1508. dndest.nhx, dndest.nhy))))); 1509. 1510. if (flooreffects(obj, tx, ty, "fall")) { 1511. return; 1512. } else if (otx == 0 && oty == 0) { 1513. ; /* fell through a trap door; no update of old loc needed */ 1514. } else { 1515. if (costly_spot(otx, oty) 1516. && (!costly_spot(tx, ty) || 1517. !index(in_rooms(tx, ty, 0), *in_rooms(otx, oty, 0)))) { 1518. if (costly_spot(u.ux, u.uy) && 1519. index(u.urooms, *in_rooms(otx, oty, 0))) 1520. addtobill(obj, FALSE, FALSE, FALSE); 1521. else (void)stolen_value(obj, otx, oty, FALSE, FALSE, FALSE); 1522. } 1523. newsym(otx, oty); /* update old location */ 1524. } 1525. place_object(obj, tx, ty); 1526. newsym(tx, ty); 1527. } 1528. 1529. /* Returns an absolute depth */ 1530. int 1531. random_teleport_level() 1532. { 1533. int nlev, max_depth, min_depth, 1534. cur_depth = (int)depth(&u.uz); 1535. 1536. if (!rn2(5) || Is_knox(&u.uz) || 1537. #ifdef BLACKMARKET 1538. Is_blackmarket(&u.uz) || 1539. #endif 1540. Is_aligned_quest(&u.uz)) 1541. return cur_depth; 1542. 1543. /* What I really want to do is as follows: 1544. * -- If in a dungeon that goes down, the new level is to be restricted 1545. * to [top of parent, bottom of current dungeon] 1546. * -- If in a dungeon that goes up, the new level is to be restricted 1547. * to [top of current dungeon, bottom of parent] 1548. * -- If in a quest dungeon or similar dungeon entered by portals, 1549. * the new level is to be restricted to [top of current dungeon, 1550. * bottom of current dungeon] 1551. * The current behavior is not as sophisticated as that ideal, but is 1552. * still better what we used to do, which was like this for players 1553. * but different for monsters for no obvious reason. Currently, we 1554. * must explicitly check for special dungeons. We check for Knox 1555. * above; endgame is handled in the caller due to its different 1556. * message ("disoriented"). 1557. * --KAA 1558. * [ALI] Also check for Sam's blackmarket and the three aligned quests 1559. * above. 1560. * 3.4.2: explicitly handle quest here too, to fix the problem of 1561. * monsters sometimes level teleporting out of it into main dungeon. 1562. * Also prevent monsters reaching the Sanctum prior to invocation. 1563. */ 1564. min_depth = In_quest(&u.uz) ? dungeons[u.uz.dnum].depth_start : 1; 1565. max_depth = dunlevs_in_dungeon(&u.uz) + 1566. (dungeons[u.uz.dnum].depth_start - 1); 1567. /* can't reach the Sanctum if the invocation hasn't been performed */ 1568. if (Inhell && !u.uevent.invoked) max_depth -= 1; 1569. 1570. /* Get a random value relative to the current dungeon */ 1571. /* Range is 1 to current+3, current not counting */ 1572. nlev = rn2(cur_depth + 3 - min_depth) + min_depth; 1573. if (nlev >= cur_depth) nlev++; 1574. 1575. if (nlev > max_depth) { 1576. nlev = max_depth; 1577. /* teleport up if already on bottom */ 1578. if (Is_botlevel(&u.uz)) nlev -= rnd(3); 1579. } 1580. if (nlev < min_depth) { 1581. nlev = min_depth; 1582. if (nlev == cur_depth) { 1583. nlev += rnd(3); 1584. if (nlev > max_depth) 1585. nlev = max_depth; 1586. } 1587. } 1588. return nlev; 1589. } 1590. 1591. /* you teleport a monster (via wand, spell, or poly'd q.mechanic attack); 1592. return false iff the attempt fails */ 1593. boolean 1594. u_teleport_mon(mtmp, give_feedback) 1595. struct monst *mtmp; 1596. boolean give_feedback; 1597. { 1598. coord cc; 1599. 1600. if (mtmp->ispriest && *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) { 1601. if (give_feedback) 1602. pline("%s resists your magic!", Monnam(mtmp)); 1603. return FALSE; 1604. } else if (level.flags.noteleport && u.uswallow && mtmp == u.ustuck) { 1605. if (give_feedback) 1606. You("are no longer inside %s!", mon_nam(mtmp)); 1607. unstuck(mtmp); 1608. rloc(mtmp, FALSE); 1609. } else if (is_rider(mtmp->data) && rn2(13) && 1610. enexto(&cc, u.ux, u.uy, mtmp->data)) 1611. rloc_to(mtmp, cc.x, cc.y); 1612. else { 1613. #ifdef WIZARD 1614. if (wizard && Teleport_control) 1615. { 1616. /* 1617. * [ALI] This code will only allow monsters to be 1618. * teleported to positions acceptable to rloc_pos_ok(). 1619. * We could use goodpos() which would allow more 1620. * locations but, in my view, is less informative. 1621. */ 1622. xchar omx, omy; 1623. pline("To what position do you want %s to be teleported?", 1624. mon_nam(mtmp)); 1625. cc.x = omx = mtmp->mx; 1626. cc.y = omy = mtmp->my; 1627. if (getpos(&cc, TRUE, "the desired position") < 0) 1628. rloc(mtmp, FALSE); /* abort */ 1629. else if (rloc_pos_ok(cc.x, cc.y, mtmp)) { 1630. rloc_to(mtmp, cc.x, cc.y); 1631. /* As rloc() ... */ 1632. if (mtmp->isshk && !inhishop(mtmp)) 1633. make_angry_shk(mtmp, omx, omy); 1634. } else { 1635. pline("Sorry..."); 1636. rloc(mtmp, FALSE); 1637. } 1638. } else 1639. #endif /* WIZARD */ 1640. rloc(mtmp, FALSE); 1641. } 1642. return TRUE; 1643. } 1644. /*teleport.c*/