dungeon_obj.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. /* =============================================================================
  2. * PROGRAM: ularn
  3. * FILENAME: dungeon_obj.c
  4. *
  5. * DESCRIPTION:
  6. * This module contains functions for handling the effects of static objects
  7. * in the dungeon.
  8. * (ie. Objects that cannot be picked up such as stairs, fountains etc.)
  9. *
  10. * =============================================================================
  11. * EXPORTED VARIABLES
  12. *
  13. * None
  14. *
  15. * =============================================================================
  16. * EXPORTED FUNCTIONS
  17. *
  18. * oopendoor - processes the player opening a closed door
  19. * oaltar - processes player stepping onto an alter
  20. * othrone - processes player stepping onto a throne
  21. * odeadthrone - processes player stepping onto a dead throne
  22. * ofountain - processes player stepping onto a fountain
  23. * ostairs - processes player stepping onto the stairs (up or down)
  24. * oteleport - processes player stepping onto a teleport trap, and all other
  25. * reasons for teleporting the player
  26. * opit - processes player stepping onto a pit
  27. * oelevator - processes player stepping onto an elevator
  28. * ostatue - processes player stepping onto a statue
  29. * omirror - processes player stepping onto a mirror
  30. *
  31. * =============================================================================
  32. */
  33. #include "dungeon_obj.h"
  34. #include "header.h"
  35. #include "itm.h"
  36. #include "monster.h"
  37. #include "player.h"
  38. #include "potion.h"
  39. #include "scores.h"
  40. #include "ularn_game.h"
  41. #include "ularn_win.h"
  42. /* =============================================================================
  43. * Local functions
  44. */
  45. /* =============================================================================
  46. * FUNCTION: ohear
  47. *
  48. * DESCRIPTION:
  49. * Function to cast a +3 protection on the player from an altar.
  50. *
  51. * PARAMETERS:
  52. *
  53. * None.
  54. *
  55. * RETURN VALUE:
  56. *
  57. * None.
  58. */
  59. static void ohear(void) {
  60. Print("\nYou have been heard!");
  61. if (c[ALTPRO] == 0)
  62. c[MOREDEFENSES] += ALTAR_PRO_BOOST;
  63. c[ALTPRO] += 800; /* protection field */
  64. recalc();
  65. UpdateEffects();
  66. }
  67. /* =============================================================================
  68. * FUNCTION: fch
  69. *
  70. * DESCRIPTION:
  71. * Changes a players ability by 1 for ofountain effects.
  72. *
  73. * PARAMETERS:
  74. *
  75. * how : The direction the attribute is to be changed.
  76. * x < 0 => down
  77. * x > 0 => up
  78. *
  79. * x : A pointer to the attribute value to change.
  80. *
  81. * RETURN VALUE:
  82. *
  83. * None.
  84. */
  85. static void fch(int how, long *x) {
  86. if (how < 0) {
  87. if (*x > 3) {
  88. Print(" went down by one!");
  89. --(*x);
  90. } else
  91. Print(" remained unchanged!");
  92. } else {
  93. Print(" went up by one!");
  94. (*x)++;
  95. }
  96. UpdateStatus();
  97. }
  98. /* =============================================================================
  99. * FUNCTION: fntchange
  100. *
  101. * DESCRIPTION:
  102. * Function to change player attributes for fountain based effects.
  103. *
  104. * PARAMETERS:
  105. *
  106. * how : The size and direction of the change.
  107. * how > 0 => raised
  108. * how < 0 => lowered
  109. *
  110. * RETURN VALUE:
  111. *
  112. * None.
  113. */
  114. static void fntchange(int how) {
  115. long j;
  116. Printc('\n');
  117. switch (rnd(9)) {
  118. case 1:
  119. Print("Your strength");
  120. fch(how, &c[STRENGTH]);
  121. break;
  122. case 2:
  123. Print("Your intelligence");
  124. fch(how, &c[INTELLIGENCE]);
  125. break;
  126. case 3:
  127. Print("Your wisdom");
  128. fch(how, &c[WISDOM]);
  129. break;
  130. case 4:
  131. Print("Your constitution");
  132. fch(how, &c[CONSTITUTION]);
  133. break;
  134. case 5:
  135. Print("Your dexterity");
  136. fch(how, &c[DEXTERITY]);
  137. break;
  138. case 6:
  139. Print("Your charm");
  140. fch(how, &c[CHARISMA]);
  141. break;
  142. case 7:
  143. j = rnd(level + 1);
  144. if (how < 0) {
  145. Printf("You lose %d hit point%s!", (long)j, plural(j));
  146. losemhp((int)j);
  147. } else {
  148. Printf("You gain %d hit point%s!", (long)j, plural(j));
  149. raisemhp((int)j);
  150. }
  151. UpdateStatus();
  152. break;
  153. case 8:
  154. j = rnd(level + 1);
  155. if (how > 0) {
  156. Printf("You just gained %d spell%s!", (long)j, plural(j));
  157. raisemspells((int)j);
  158. } else {
  159. Printf("You just lost %d spell%s!", (long)j, plural(j));
  160. losemspells((int)j);
  161. }
  162. UpdateStatus();
  163. break;
  164. case 9:
  165. j = 5 * rnd((level + 1) * (level + 1));
  166. if (how < 0) {
  167. Printf("You just lost %d experience point%s!", (long)j, plural(j));
  168. loseexperience((long)j);
  169. } else {
  170. Printf("You just gained %d experience point%s!", (long)j, plural(j));
  171. raiseexperience((long)j);
  172. }
  173. break;
  174. }
  175. }
  176. /* =============================================================================
  177. * FUNCTION: obottomless
  178. *
  179. * DESCRIPTION:
  180. * Processes the player falling into a bottomless pit.
  181. *
  182. * PARAMETERS:
  183. *
  184. * None.
  185. *
  186. * RETURN VALUE:
  187. *
  188. * None.
  189. */
  190. static void obottomless(void) {
  191. Print("\nYou fell into a pit leading straight to HELL!");
  192. UlarnBeep();
  193. nap(3000);
  194. died(DIED_FELL_INTO_BOTTOMLESS_PIT, 0);
  195. }
  196. /* =============================================================================
  197. * Exported functions
  198. */
  199. /* =============================================================================
  200. * FUNCTION: oopendoor
  201. */
  202. void oopendoor(int x, int y) {
  203. if (item[x][y] != OCLOSEDDOOR)
  204. return;
  205. if (rnd(11) < 7) {
  206. /*
  207. * Failed to open the door
  208. * See if something nasty happened instead
  209. */
  210. switch (iarg[x][y]) {
  211. case 6:
  212. c[AGGRAVATE] += rnd(400);
  213. break;
  214. case 7:
  215. case 8:
  216. Print("\nYou are jolted by an electric shock!");
  217. losehp(DIED_ELECTRIC_SHOCK, rnd(20));
  218. UpdateStatus();
  219. break;
  220. case 9:
  221. Print("\nYou suddenly feel weaker!");
  222. if (c[STRENGTH] > 3)
  223. c[STRENGTH]--;
  224. UpdateStatus();
  225. break;
  226. default:
  227. break;
  228. }
  229. /* Now the trap has been triggered, clear the trap */
  230. iarg[x][y] = 0;
  231. } else {
  232. item[x][y] = OOPENDOOR;
  233. show1cell(x, y);
  234. }
  235. }
  236. /* =============================================================================
  237. * FUNCTION: oaltar
  238. */
  239. void oaltar(void) {
  240. long k;
  241. int p;
  242. int ans;
  243. int redo;
  244. do {
  245. redo = 0;
  246. ans = get_prompt_input(
  247. "\nDo you (p) pray (d) desecrate, or (i) ignore it? ", "pdi\033", 1);
  248. switch (ans) {
  249. case 'p':
  250. Print(" pray");
  251. ans = get_prompt_input("\nDo you (m) give money or (j) just pray? ", "mj",
  252. 1);
  253. switch (ans) {
  254. case 'j':
  255. p = rund(100);
  256. if (p < 12)
  257. createmonster(makemonst(level + 2));
  258. else if (p < 17)
  259. enchweapon(ENCH_ALTAR);
  260. else if (p < 22)
  261. enchantarmor(ENCH_ALTAR);
  262. else if (p < 27)
  263. ohear();
  264. else
  265. Print("\nNothing happens.");
  266. break;
  267. case 'm':
  268. Print("\nHow much do you donate? ");
  269. k = get_num_input(c[GOLD]);
  270. if (k < 0)
  271. redo = 1;
  272. else if (c[GOLD] < k) {
  273. Print(" You don't have that much!");
  274. nap(1001);
  275. redo = 1;
  276. } else {
  277. /*
  278. * Remove gold from player
  279. */
  280. c[GOLD] -= k;
  281. if ((k < (c[GOLD] / 10)) && (rnd(60) < 30) && !wizard) {
  282. /*
  283. * Player offers < 1/11% of gold insults the gods 50% of the time.
  284. * Insulted gods send a demon prince to punish the player.
  285. */
  286. Print(
  287. " Cheapskate! The Gods are insulted by such a tiny offering!");
  288. forget();
  289. createmonster(DEMONPRINCE);
  290. c[AGGRAVATE] += 1500;
  291. /* God takes more gold anyway */
  292. c[GOLD] -= k;
  293. } else if (((k < (c[GOLD] + k) / 10) || (k < rnd(50))) && !wizard) {
  294. /*
  295. * Player offers more than 1/11, but less than 1/10 of gold.
  296. * God has a chance of sending a monster to encourage the player
  297. * to be more generous based on how far below 50 gold the
  298. * amount doneted is.
  299. */
  300. createmonster(makemonst(level + 2));
  301. c[AGGRAVATE] += 500;
  302. /* God takes more gold anyway */
  303. c[GOLD] -= k;
  304. } else {
  305. /*
  306. * Player was reasonably generous, so give a blessing
  307. */
  308. p = rund(16);
  309. if (p < 4)
  310. Print(" Thank you.");
  311. else if (p < 6) {
  312. enchantarmor(ENCH_ALTAR);
  313. enchantarmor(ENCH_ALTAR);
  314. } else if (p < 8) {
  315. enchweapon(ENCH_ALTAR);
  316. enchweapon(ENCH_ALTAR);
  317. } else
  318. ohear();
  319. }
  320. UpdateStatus();
  321. }
  322. break;
  323. default:
  324. break;
  325. } /* end while switch : case j or m */
  326. break;
  327. case 'd':
  328. Print(" desecrate");
  329. if (rnd(100) < 60) {
  330. createmonster(makemonst(level + 3) + 8);
  331. c[AGGRAVATE] += 2500;
  332. } else if (rnd(100) < 5)
  333. raiselevel();
  334. else if (rnd(101) < 30) {
  335. Print("\nThe altar crumbles into a pile of dust before your eyes.");
  336. forget();
  337. } else
  338. Print("\nNothing happens.");
  339. UpdateStatus();
  340. break;
  341. case 'i':
  342. case ESC:
  343. Print(" ignore");
  344. if (rnd(100) < 30) {
  345. createmonster(makemonst(level + 2));
  346. c[AGGRAVATE] += rnd(450);
  347. } else {
  348. Print("\nNothing happens.");
  349. nomove = 1; /* XXX trn */
  350. }
  351. break;
  352. } /* end while switch: pray, des, ignore */
  353. } while (redo);
  354. }
  355. /* =============================================================================
  356. * FUNCTION: othrone
  357. */
  358. void othrone(int arg) {
  359. int i, k;
  360. int ans;
  361. ans = get_prompt_input(
  362. "\nDo you (p) pry off jewels, (s) sit down, or (i) ignore it? ",
  363. "psi\033", 1);
  364. switch (ans) {
  365. case 'p':
  366. Print(" pry off");
  367. k = rnd(101);
  368. if (k < 25) {
  369. for (i = 0; i < rnd(4); i++) {
  370. creategem(); /*gems pop off the throne*/
  371. }
  372. item[playerx][playery] = ODEADTHRONE;
  373. } else if ((k < 40) && (arg == 0)) {
  374. createmonster(GNOMEKING);
  375. item[playerx][playery] = OTHRONE2;
  376. } else
  377. Print("\nNothing happens.");
  378. break;
  379. case 's':
  380. Print(" sit down");
  381. k = rnd(101);
  382. if ((k < 30) && (arg == 0)) {
  383. createmonster(GNOMEKING);
  384. item[playerx][playery] = OTHRONE2;
  385. } else if (k < 35) {
  386. Print("\nZaaaappp! You've been teleported!\n");
  387. UlarnBeep();
  388. oteleport(0);
  389. } else
  390. Print("\nNothing happens.");
  391. break;
  392. case 'i':
  393. case ESC:
  394. Print(" ignore");
  395. break;
  396. ;
  397. }
  398. }
  399. /* =============================================================================
  400. * FUNCTION: odeadthrone
  401. */
  402. void odeadthrone(void) {
  403. int k;
  404. int ans;
  405. ans = get_prompt_input("\nDo you (s) sit down, or (i) ignore it? ", "si\033",
  406. 1);
  407. switch (ans) {
  408. case 's':
  409. Print(" sit down");
  410. k = rnd(101);
  411. if (k < 5)
  412. raiselevel();
  413. else if (k < 25) {
  414. Print("\nZaaaappp! You've been teleported!\n");
  415. UlarnBeep();
  416. oteleport(0);
  417. } else
  418. Print("\nNothing happens.");
  419. break;
  420. case 'i':
  421. case ESC:
  422. Print(" ignore");
  423. ;
  424. break;
  425. }
  426. }
  427. /* =============================================================================
  428. * FUNCTION: ofountain
  429. */
  430. void ofountain(void) {
  431. int x;
  432. int ans;
  433. ans = get_prompt_input(
  434. "\nDo you (d) drink, (w) wash yourself, or (i) ignore it? ", "dwi\033",
  435. 1);
  436. switch (ans) {
  437. case 'd':
  438. Print("drink");
  439. if (rnd(1501) < 4) {
  440. Print("\nOH MY GOD!! You have caught the *dreadful sleep*!");
  441. UlarnBeep();
  442. nap(3000);
  443. died(DIED_DREADFUL_SLEEP, 0);
  444. return;
  445. } else {
  446. x = rnd(100);
  447. if (x == 1)
  448. raiselevel();
  449. else if (x < 11) {
  450. x = rnd((level << 2) + 2);
  451. Printf("\nBleah! The water tasted like stale gatorade! You lose %d "
  452. "hit point%s!",
  453. (long)x, plural(x));
  454. losehp(DIED_DRANK_POISONOUS_WATER, x);
  455. UpdateStatus();
  456. } else if (x < 14) {
  457. c[HALFDAM] += 200 + rnd(200);
  458. Print("\nThe water makes you vomit.");
  459. } else if (x < 17) {
  460. /* Same effect as giant strength */
  461. Print("\n You now have incredible bulging muscles!");
  462. if (c[GIANTSTR] == 0)
  463. c[STREXTRA] += PGIANTSTR_BOOST;
  464. c[GIANTSTR] += 700;
  465. UpdateEffects();
  466. } else if (x < 45)
  467. Print("\nNothing seems to have happened.");
  468. else if (rnd(3) != 2) {
  469. fntchange(1); /*change char levels upward*/
  470. } else {
  471. fntchange(-1); /*change char levels downward*/
  472. }
  473. if (rnd(12) < 3) {
  474. Print("\nThe fountains bubbling slowly quietens.");
  475. /* dead fountain */
  476. item[playerx][playery] = ODEADFOUNTAIN;
  477. }
  478. }
  479. break;
  480. case 'i':
  481. case ESC:
  482. Print(" ignore");
  483. break;
  484. case 'w':
  485. Print("wash yourself.");
  486. if (rnd(100) < 11) {
  487. x = rnd((level << 2) + 2);
  488. Printf("\nThe water burns like acid! You lose %d hit point%s!", (long)x,
  489. plural(x));
  490. losehp(DIED_DRANK_POISONOUS_WATER, x);
  491. UpdateStatus();
  492. } else if (rnd(100) < 29) {
  493. Print("\nYou are now clean.");
  494. if (c[ITCHING])
  495. /*
  496. * Managed to get rid of the itching powder, so set it so the
  497. * next call to regen will cancel the effect.
  498. */
  499. c[ITCHING] = 1;
  500. } else if (rnd(100) < 31)
  501. Print("\nThis water needs soap -- the dirt didn't come off.");
  502. else if (rnd(100) < 34)
  503. createmonster(WATERLORD);
  504. else
  505. Print("\nNothing seems to have happened.");
  506. break;
  507. }
  508. }
  509. /* =============================================================================
  510. * FUNCTION: ostairs
  511. */
  512. void ostairs(int dir) {
  513. int x, y;
  514. int ans;
  515. Print("\nDo you (s) stay here or ");
  516. if (dir > 0)
  517. Print("(u) go up? ");
  518. else
  519. Print("(d) go down? ");
  520. ans = get_prompt_input("", "sudi\033", 1);
  521. switch (ans) {
  522. case ESC:
  523. case 's':
  524. case 'i':
  525. Print("stay here.");
  526. return;
  527. case 'u':
  528. Print("go up.");
  529. if (dir < 0)
  530. Print("\nThe stairs don't go up!");
  531. else {
  532. /* not on V1 */
  533. if ((level >= 2) && (level != (DBOTTOM + 1))) {
  534. newcavelevel(level - 1);
  535. for (x = 0; x < MAXX; x++) {
  536. for (y = 0; y < MAXY; y++) {
  537. if (item[x][y] == OSTAIRSDOWN) {
  538. playerx = (char)x;
  539. playery = (char)y;
  540. x = MAXX;
  541. y = MAXY;
  542. }
  543. }
  544. }
  545. if (mitem[playerx][playery].mon != MONST_NONE)
  546. /*
  547. * A monster is on the stairs, so find an empty position for the
  548. * player.
  549. */
  550. positionplayer();
  551. draws(0, MAXX, 0, MAXY);
  552. UpdateStatusAndEffects();
  553. } else
  554. Print("\nThe stairs lead to a dead end!");
  555. }
  556. break;
  557. case 'd':
  558. Print("go down.");
  559. if (dir > 0)
  560. Print("\nThe stairs don't go down!");
  561. else {
  562. /* not on dungeon bottom or V5 */
  563. if ((level != 0) && (level != DBOTTOM) && (level != VBOTTOM)) {
  564. newcavelevel(level + 1);
  565. for (x = 0; x < MAXX; x++) {
  566. for (y = 0; y < MAXY; y++) {
  567. if (item[x][y] == OSTAIRSUP) {
  568. playerx = (char)x;
  569. playery = (char)y;
  570. x = MAXX;
  571. y = MAXY;
  572. }
  573. }
  574. }
  575. if (mitem[playerx][playery].mon != MONST_NONE)
  576. /*
  577. * A monster is on the stairs, so find an empty position for the
  578. * player.
  579. */
  580. positionplayer();
  581. draws(0, MAXX, 0, MAXY);
  582. UpdateStatusAndEffects();
  583. } else
  584. Print("\nThe stairs lead to a dead end!");
  585. }
  586. break;
  587. default:
  588. break;
  589. }
  590. }
  591. /* =============================================================================
  592. * FUNCTION: oteleport
  593. */
  594. void oteleport(int err) {
  595. int tmp;
  596. if (err) {
  597. if (rnd(151) < 3) {
  598. /* stuck in a rock if the player can't walk through walls */
  599. if (c[WTW] == 0) {
  600. died(DIED_TRAPPED_IN_SOLID_ROCK, 0);
  601. return;
  602. }
  603. }
  604. }
  605. /* show ?? on bottomline if been teleported */
  606. if (!wizard)
  607. c[TELEFLAG] = 1;
  608. if (level == 0)
  609. tmp = 0;
  610. else if (level <= DBOTTOM) {
  611. /* in dungeon */
  612. tmp = rnd(5) + level - 3;
  613. if (tmp > DBOTTOM)
  614. tmp = DBOTTOM;
  615. if (tmp < 0)
  616. tmp = 0;
  617. } else {
  618. /* in volcano */
  619. tmp = rnd(4) + level - 2;
  620. if (tmp >= VBOTTOM)
  621. tmp = VBOTTOM;
  622. if (tmp < DBOTTOM + 1)
  623. /* back to surface */
  624. tmp = 0;
  625. }
  626. playerx = (char)rnd(MAXX - 2);
  627. playery = (char)rnd(MAXY - 2);
  628. if (level != tmp)
  629. newcavelevel(tmp);
  630. else
  631. positionplayer();
  632. draws(0, MAXX, 0, MAXY);
  633. UpdateStatusAndEffects();
  634. }
  635. /* =============================================================================
  636. * FUNCTION: opit
  637. */
  638. void opit(void) {
  639. int i;
  640. if (rnd(101) > 81)
  641. return;
  642. if ((rnd(70) > (9 * c[DEXTERITY] - packweight())) || (rnd(101) < 5)) {
  643. /* Never fall into a pit if the player has a wand of wonder */
  644. if (player_has_item(OWWAND)) {
  645. Print("\nYou float right over the pit.");
  646. return;
  647. }
  648. if (level == DBOTTOM || level == VBOTTOM)
  649. /* Pits on the bottom of the dungeon or volcano are bottomless */
  650. obottomless();
  651. else {
  652. if (rnd(101) < 20) {
  653. i = 0;
  654. Print("\nYou fell ino a pit! A poor monster cushions your fall!\n");
  655. } else {
  656. i = rnd(level * 3 + 3);
  657. if (i > c[HP])
  658. i = c[HP];
  659. Printf("\nYou fell into a pit! You suffer %d hit point%s damage.",
  660. (long)i, plural(i));
  661. }
  662. losehp(DIED_FELL_INTO_PIT, i);
  663. nap(2000);
  664. newcavelevel(level + 1);
  665. draws(0, MAXX, 0, MAXY);
  666. }
  667. }
  668. }
  669. /* =============================================================================
  670. * FUNCTION: oelevator
  671. */
  672. void oelevator(int dir) {
  673. int new_level;
  674. if (dir == 1) {
  675. /* going up */
  676. if (level == 0) {
  677. Print(",\nunfortunately, it is out of order.");
  678. return;
  679. }
  680. playerx = (char)rnd(MAXX - 2);
  681. playery = (char)rnd(MAXY - 2);
  682. nap(2000);
  683. if (level <= DBOTTOM)
  684. /* In dungeon */
  685. newcavelevel(rund(level));
  686. else {
  687. /* In volcano */
  688. new_level = DBOTTOM + rund(level - DBOTTOM);
  689. if (new_level == DBOTTOM)
  690. new_level = 0;
  691. newcavelevel(new_level);
  692. }
  693. } else {
  694. /* going down */
  695. if ((level == DBOTTOM) || (level == VBOTTOM)) {
  696. nap(2000);
  697. Print("\nand it leads straight to HELL!");
  698. UlarnBeep();
  699. nap(3000);
  700. died(DIED_ELEVATOR_TO_HELL, 0);
  701. return;
  702. }
  703. playerx = (char)rnd(MAXX - 2);
  704. playery = (char)rnd(MAXY - 2);
  705. nap(2000);
  706. if (level < DBOTTOM)
  707. /* In dungeon */
  708. newcavelevel(level + rnd(DBOTTOM - level));
  709. else
  710. /* in volcano */
  711. newcavelevel(level + rnd(VBOTTOM - level));
  712. }
  713. draws(0, MAXX, 0, MAXY);
  714. UpdateStatusAndEffects();
  715. }
  716. /* =============================================================================
  717. * FUNCTION: ostatue
  718. */
  719. void ostatue(void) {} /* nothing happens when you move on a statue */
  720. /* =============================================================================
  721. * FUNCTION: omirror
  722. */
  723. void omirror(void) {} /* nothing happens when you move on a mirror */