Blindfold removal fix
[slashemextended.git] / src / dig.c
blob32295c204139e14326429cbe64930caa02a454dd
1 /* SCCS Id: @(#)dig.c 3.4 2003/03/23 */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 #include "hack.h"
6 #include "edog.h"
7 /* #define DEBUG */ /* turn on for diagnostics */
9 #ifdef OVLB
11 static NEARDATA boolean did_dig_msg;
13 STATIC_DCL boolean rm_waslit(void);
14 STATIC_DCL void mkcavepos(XCHAR_P,XCHAR_P,int,BOOLEAN_P,BOOLEAN_P);
15 STATIC_DCL void mkcavearea(BOOLEAN_P);
16 STATIC_DCL int dig_typ(struct obj *,XCHAR_P,XCHAR_P);
17 STATIC_DCL int dig(void);
18 STATIC_DCL schar fillholetyp(int, int);
19 STATIC_DCL void dig_up_grave(void);
21 /* Indices returned by dig_typ() */
22 #define DIGTYP_UNDIGGABLE 0
23 #define DIGTYP_ROCK 1
24 #define DIGTYP_STATUE 2
25 #define DIGTYP_BOULDER 3
26 #define DIGTYP_DOOR 4
27 #define DIGTYP_TREE 5
28 #define DIGTYP_IRONBAR 6
29 #define DIGTYP_FIREAXE 7
30 /* keep d_action and d_target in sync!!! otherwise, CRASH with illegible backtrace "?? at 07f49320" or something --Amy */
32 STATIC_OVL boolean
33 rm_waslit()
35 register xchar x, y;
37 if(levl[u.ux][u.uy].typ == ROOM && levl[u.ux][u.uy].waslit)
38 return(TRUE);
39 for(x = u.ux-2; x < u.ux+3; x++)
40 for(y = u.uy-1; y < u.uy+2; y++)
41 if(isok(x,y) && levl[x][y].waslit) return(TRUE);
42 return(FALSE);
45 /* Change level topology. Messes with vision tables and ignores things like
46 * boulders in the name of a nice effect. Vision will get fixed up again
47 * immediately after the effect is complete.
49 STATIC_OVL void
50 mkcavepos(x, y, dist, waslit, rockit)
51 xchar x,y;
52 int dist;
53 boolean waslit, rockit;
55 register struct rm *lev;
57 if(!isok(x,y)) return;
58 lev = &levl[x][y];
60 if(rockit) {
61 register struct monst *mtmp;
63 if(IS_ROCK(lev->typ)) return;
64 if(t_at(x, y)) return; /* don't cover the portal */
65 if ((mtmp = m_at(x, y)) != 0) /* make sure crucial monsters survive */
66 if(!passes_walls(mtmp->data) && (!mtmp->egotype_wallwalk)) (void) rloc(mtmp, FALSE);
67 } else if(lev->typ == ROOM) return;
69 unblock_point(x,y); /* make sure vision knows this location is open */
70 if (!(levl[x][y].wall_info & W_HARDGROWTH)) levl[x][y].wall_info |= W_EASYGROWTH;
72 /* fake out saved state */
73 lev->seenv = 0;
74 lev->doormask = 0;
75 if(dist < 3) lev->lit = (rockit ? FALSE : TRUE);
76 if(waslit) lev->waslit = (rockit ? FALSE : TRUE);
77 lev->horizontal = FALSE;
78 viz_array[y][x] = (dist < 3 ) ?
79 (IN_SIGHT|COULD_SEE) : /* short-circuit vision recalc */
80 COULD_SEE;
81 lev->typ = (rockit ? STONE : ROOM);
82 if(dist >= 3)
83 impossible("mkcavepos called with dist %d", dist);
84 if(Blind)
85 feel_location(x, y);
86 else newsym(x,y);
89 STATIC_OVL void
90 mkcavearea(rockit)
91 register boolean rockit;
93 int dist;
94 xchar xmin = u.ux, xmax = u.ux;
95 xchar ymin = u.uy, ymax = u.uy;
96 register xchar i;
97 register boolean waslit = rm_waslit();
99 if(rockit) pline("Crash! The ceiling collapses around you!");
100 else pline("A mysterious force %s cave around you!",
101 (levl[u.ux][u.uy].typ == CORR) ? "creates a" : "extends the");
102 display_nhwindow(WIN_MESSAGE, TRUE);
104 for(dist = 1; dist <= 2; dist++) {
105 xmin--; xmax++;
107 /* top and bottom */
108 if(dist < 2) { /* the area is wider that it is high */
109 ymin--; ymax++;
110 for(i = xmin+1; i < xmax; i++) {
111 mkcavepos(i, ymin, dist, waslit, rockit);
112 mkcavepos(i, ymax, dist, waslit, rockit);
116 /* left and right */
117 for(i = ymin; i <= ymax; i++) {
118 mkcavepos(xmin, i, dist, waslit, rockit);
119 mkcavepos(xmax, i, dist, waslit, rockit);
122 flush_screen(1); /* make sure the new glyphs shows up */
123 delay_output();
126 if(!rockit && levl[u.ux][u.uy].typ == CORR) {
127 levl[u.ux][u.uy].typ = /*ROOM*/CORR;
128 if(waslit) levl[u.ux][u.uy].waslit = TRUE;
129 newsym(u.ux, u.uy); /* in case player is invisible */
132 vision_full_recalc = 1; /* everything changed */
135 /* When digging into location <x,y>, what are you actually digging into? */
136 STATIC_OVL int
137 dig_typ(otmp, x, y)
138 struct obj *otmp;
139 xchar x, y;
141 boolean ispick = is_pick(otmp);
142 boolean isantibar = is_antibar(otmp);
143 boolean issaber = is_lightsaber(otmp);
145 if (otmp->oartifact == ART_BREAK_EVERYTHING && Role_if(PM_FIREFIGHTER)) {
146 if (IS_IRONBAR(levl[x][y].typ) || IS_TREE(levl[x][y].typ) || IS_FARMLAND(levl[x][y].typ) || IS_MOUNTAIN(levl[x][y].typ)) {
148 return DIGTYP_FIREAXE;
152 return ((ispick
153 || issaber
154 ) && sobj_at(STATUE, x, y) ? DIGTYP_STATUE :
155 (isantibar && IS_IRONBAR(levl[x][y].typ)) ? DIGTYP_IRONBAR :
156 (ispick
157 || issaber
158 ) && sobj_at(BOULDER, x, y) ? DIGTYP_BOULDER :
159 closed_door(x, y) ? DIGTYP_DOOR :
160 IS_TREE(levl[x][y].typ) ?
161 (ispick ? DIGTYP_UNDIGGABLE : DIGTYP_TREE) :
162 (ispick
163 || issaber
164 ) && (IS_ROCK(levl[x][y].typ) || IS_WATERTUNNEL(levl[x][y].typ)) &&
165 (!level.flags.arboreal || IS_WALL(levl[x][y].typ)) ?
166 DIGTYP_ROCK : DIGTYP_UNDIGGABLE);
169 boolean
170 is_digging()
172 if (occupation == dig) {
173 return TRUE;
175 return FALSE;
178 #define BY_YOU (&youmonst)
179 #define BY_OBJECT ((struct monst *)0)
181 boolean
182 dig_check(madeby, verbose, x, y)
183 struct monst *madeby;
184 boolean verbose;
185 int x, y;
187 struct trap *ttmp = t_at(x, y);
188 const char *verb =
189 (madeby != BY_YOU || !uwep || is_pick(uwep)) ? "dig in" :
190 is_lightsaber(uwep) ? "cut" :
191 "chop";
193 if (On_stairs(x, y)) {
194 if (x == xdnladder || x == xupladder) {
195 if(verbose) pline_The("ladder resists your effort.");
196 } else if(verbose) pline_The("stairs are too hard to %s.", verb);
197 return(FALSE);
198 /* ALI - Artifact doors */
199 } else if (IS_DOOR(levl[x][y].typ) && artifact_door(x, y)) {
200 if(verbose) pline_The("%s here is too hard to dig in.",
201 surface(x,y));
202 return(FALSE);
203 } else if (IS_THRONE(levl[x][y].typ) && madeby != BY_OBJECT) {
204 if(verbose) pline_The("throne is too hard to break apart.");
205 return(FALSE);
206 } else if (IS_FARMLAND(levl[x][y].typ) && madeby != BY_OBJECT) {
207 if(verbose) pline("Farmland cannot be dug out.");
208 return(FALSE);
209 } else if (IS_MOUNTAIN(levl[x][y].typ) && madeby != BY_OBJECT) {
210 if(verbose) pline_The("mountain is too hard to dig into.");
211 return(FALSE);
212 } else if (IS_GRAVEWALL(levl[x][y].typ) && madeby != BY_OBJECT) {
213 if(verbose) pline_The("grave wall needs to be dug by moving into it.");
214 return(FALSE);
215 } else if (IS_ALTAR(levl[x][y].typ) && (madeby != BY_OBJECT ||
216 Is_astralevel(&u.uz) || Is_sanctum(&u.uz))) {
217 if(verbose) pline_The("altar is too hard to break apart.");
218 return(FALSE);
219 } else if (Is_airlevel(&u.uz)) {
220 if(verbose) You("cannot %s thin air.", verb);
221 return(FALSE);
222 } else if (Is_waterlevel(&u.uz)) {
223 if(verbose) pline_The("water splashes and subsides.");
224 return(FALSE);
225 } else if ((IS_ROCK(levl[x][y].typ) && levl[x][y].typ != SDOOR &&
226 ((levl[x][y].wall_info & W_NONDIGGABLE) != 0 && !(u.dynamitehack)) )
227 || (IS_FARMLAND(levl[x][y].typ)) || (IS_MOUNTAIN(levl[x][y].typ)) || (IS_GRAVEWALL(levl[x][y].typ))
228 || (ttmp &&
229 (ttmp->ttyp == MAGIC_PORTAL || ttmp->ttyp == HEEL_TRAP || ttmp->ttyp == ATTACKING_HEEL_TRAP || ttmp->ttyp == LOUDSPEAKER || ttmp->ttyp == KOP_CUBE || ttmp->ttyp == BOSS_SPAWNER || ttmp->ttyp == ARABELLA_SPEAKER || ttmp->ttyp == FART_TRAP || ttmp->ttyp == PERSISTENT_FART_TRAP || !Can_dig_down(&u.uz)))) {
230 if(verbose) pline_The("%s here is too hard to %s.",
231 surface(x,y), verb);
232 return(FALSE);
233 } else if (sobj_at(BOULDER, x, y)) {
234 if(verbose) There("isn't enough room to %s here.", verb);
235 return(FALSE);
236 } else if (madeby == BY_OBJECT &&
237 /* the block against existing traps is mainly to
238 prevent broken wands from turning holes into pits */
239 (ttmp || is_waterypool(x,y) || is_styxriver(x,y) || is_lava(x,y))) {
240 /* digging by player handles pools separately */
241 return FALSE;
243 return(TRUE);
246 STATIC_OVL int
247 dig()
249 register struct rm *lev;
250 register xchar dpx = digging.pos.x, dpy = digging.pos.y;
251 register boolean ispick = uwep && is_pick(uwep);
252 const char *verb =
253 (!uwep || is_pick(uwep)) ? "dig into" :
254 is_lightsaber(uwep) ? "cut through" :
255 "chop through";
256 int bonus;
258 lev = &levl[dpx][dpy];
259 /* perhaps a nymph stole your pick-axe while you were busy digging */
260 /* or perhaps you teleported away */
261 /* WAC allow lightsabers */
262 if (u.uswallow || !uwep || (!ispick &&
263 (!is_lightsaber(uwep) || (!uwep->lamplit && !Role_if(PM_SHADOW_JEDI)) ) &&
264 !is_axe(uwep) && !is_antibar(uwep)) ||
265 !on_level(&digging.level, &u.uz) ||
266 ((digging.down ? (dpx != u.ux || dpy != u.uy)
267 : (distu(dpx,dpy) > 2))))
268 return(0);
270 if (digging.down) {
271 if(!dig_check(BY_YOU, TRUE, u.ux, u.uy)) return(0);
272 } else { /* !digging.down */
273 if (IS_TREE(lev->typ) && !may_dig(dpx,dpy) &&
274 dig_typ(uwep, dpx, dpy) == DIGTYP_TREE) {
275 pline("This tree seems to be petrified.");
276 return(0);
278 /* ALI - Artifact doors */
279 if (IS_ROCK(lev->typ) && !may_dig(dpx,dpy) &&
280 dig_typ(uwep, dpx, dpy) == DIGTYP_ROCK ||
281 IS_DOOR(lev->typ) && artifact_door(dpx, dpy)) {
282 pline("This %s is too hard to %s.",
283 IS_DOOR(lev->typ) ? "door" : IS_MOUNTAIN(lev->typ) ? "mountain" : IS_FARMLAND(lev->typ) ? "farmland" : "wall", verb);
284 return(0);
287 if(Fumbling &&
288 /* Can't exactly miss holding a lightsaber to the wall */
289 !is_lightsaber(uwep) &&
290 !rn2(3)) {
291 switch(rn2(3)) {
292 case 0:
293 if(!welded(uwep)) {
294 You("fumble and drop your %s.", xname(uwep));
295 dropx(uwep);
296 } else {
297 if (u.usteed)
298 Your("%s %s and %s %s!",
299 xname(uwep),
300 otense(uwep, "bounce"), otense(uwep, "hit"),
301 mon_nam(u.usteed));
302 else
303 pline("Ouch! Your %s %s and %s you!",
304 xname(uwep),
305 otense(uwep, "bounce"), otense(uwep, "hit"));
306 set_wounded_legs(RIGHT_SIDE, HWounded_legs + 5 + rnd(5));
308 break;
309 case 1:
310 pline("Bang! You hit with the broad side of %s!",
311 the(xname(uwep)));
312 break;
313 default: Your("swing misses its mark.");
314 break;
316 return(0);
319 /* calculate digging effort */
320 bonus = 4 + rn2(5) + abon() + uwep->spe - greatest_erosionX(uwep) + increase_damage_bonus_value() + RngeBloodlust + (Drunken_boxing && Confusion) + (StrongDrunken_boxing && Confusion);
321 if (uarms && uarms->oartifact == ART_TEH_BASH_R) bonus += 2;
322 if (uarmh && uarmh->oartifact == ART_HELMET_OF_DIGGING) bonus += 5;
323 if (uarmg && itemhasappearance(uarmg, APP_DIGGER_GLOVES)) bonus += 5;
324 if (uwep && uwep->oartifact == ART_COPPERED_OFF_FROM_ME) bonus += 5;
325 if (uwep && uwep->oartifact == ART_STONEBITER) bonus += 5;
326 if (uwep && uwep->oartifact == ART_BREAK_OUT) bonus += 5;
327 if (uwep && uwep->oartifact == ART_MINE_OUT) bonus += 5;
328 if (uarmh && uarmh->oartifact == ART_THIRD_CAR) bonus += 10;
329 if (uwep && uwep->oartifact == ART_DIG__OF_COURSE) bonus += 5;
330 if (uwep && uwep->oartifact == ART_NOTHING_FOR_IT) bonus += 5;
331 if (uarm && uarm->oartifact == ART_CLANGFRIEND) bonus += 5;
332 if (uarmf && uarmf->oartifact == ART_GRAVY_HIDE) bonus += 5;
333 if (uarmc && uarmc->oartifact == ART_MINING_FOR_FUN_AND_PROFIT) bonus += 5;
334 if (tunnels(youmonst.data)) bonus += rn2(3); /* digging monsters really should have a bonus here --Amy */
335 if (needspick(youmonst.data)) bonus += rn2(3); /* and more so if they're dedicated miners (e.g. dwarf) */
336 if (!PlayerCannotUseSkills) {
338 if (uwep && is_lightsaber(uwep)) {
339 switch (P_SKILL(P_WEDI)) {
341 case P_BASIC: bonus += 5; break;
342 case P_SKILLED: bonus += 10; break;
343 case P_EXPERT: bonus += 14; break;
344 case P_MASTER: bonus += 17; break;
345 case P_GRAND_MASTER: bonus += 21; break;
346 case P_SUPREME_MASTER: bonus += 25; break;
347 default: break;
349 } else {
350 switch (P_SKILL(P_WEDI)) {
352 case P_BASIC: bonus += 3; break;
353 case P_SKILLED: bonus += 6; break;
354 case P_EXPERT: bonus += 10; break;
355 case P_MASTER: bonus += 13; break;
356 case P_GRAND_MASTER: bonus += 16; break;
357 case P_SUPREME_MASTER: bonus += 20; break;
358 default: break;
363 if (Race_if(PM_DWARF) || Role_if(PM_MIDGET) )
364 bonus *= 2;
365 if (Race_if(PM_IRAHA)) bonus *= rnd(3);
366 if (isfriday && bonus > 1) bonus /= 2;
368 if (uwep && uwep->oartifact == ART_ETERNALE_DELAY) bonus -= 5;
369 if (uwep && uwep->oartifact == ART_DE_SID && uwep->altmode) bonus += rnd(20);
371 if (uwep && uwep->otyp == SHOVEL && !(uwep->oartifact == ART_AFTERMINE) )
372 bonus -= rn2(Role_if(PM_UNDERTAKER) ? 5 : 20); /* digging with a shovel takes longer */
374 if (uwep && is_lightsaber(uwep) && !(uwep->oartifact == ART_DE_SID) ) /* Melting a hole takes longer */
375 bonus -= (uwep->lamplit && uwep->altmode) ? rn2(8) : rn2(20); /* but is faster if both blades are lit --Amy */
376 if (uwep && is_lightsaber(uwep) && !uwep->lamplit)
377 bonus -= rn2(200); /* and if the saber isn't lit (shadow jedi role), it takes like forever --Amy */
379 digging.effort += bonus;
381 if (digging.down) {
382 register struct trap *ttmp;
384 if (digging.effort > 250) {
385 (void) dighole(FALSE);
386 (void) memset((void *)&digging, 0, sizeof digging);
387 return(0); /* done with digging */
390 if (digging.effort <= 50 ||
391 is_lightsaber(uwep) ||
392 ((ttmp = t_at(dpx,dpy)) != 0 &&
393 (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT || ttmp->ttyp == GIANT_CHASM || ttmp->ttyp == SHIT_PIT || ttmp->ttyp == MANA_PIT || ttmp->ttyp == ANOXIC_PIT || ttmp->ttyp == HYPOXIC_PIT || ttmp->ttyp == ACID_PIT || ttmp->ttyp == SHAFT_TRAP || ttmp->ttyp == CURRENT_SHAFT ||
394 ttmp->ttyp == TRAPDOOR || ttmp->ttyp == HOLE)))
395 return(1);
397 if (IS_ALTAR(lev->typ)) {
398 altar_wrath(dpx, dpy);
399 angry_priest();
402 if (dighole(TRUE)) { /* make pit at <u.ux,u.uy> */
403 digging.level.dnum = 0;
404 digging.level.dlevel = -1;
406 return(0);
409 if (digging.effort > 100) {
410 register const char *digtxt, *dmgtxt = (const char*) 0;
411 register struct obj *obj;
412 register boolean shopedge = *in_rooms(dpx, dpy, SHOPBASE);
414 if (Role_if(PM_FIREFIGHTER) && uwep && uwep->oartifact == ART_BREAK_EVERYTHING && (IS_IRONBAR(lev->typ) || IS_TREE(lev->typ) || IS_FARMLAND(lev->typ) || IS_MOUNTAIN(lev->typ) ) ) {
415 lev->typ = ROOM;
416 digtxt = "You cleared away the obstructing terrain.";
417 } else if ((obj = sobj_at(STATUE, dpx, dpy)) != 0) {
418 if (break_statue(obj)) {
419 digtxt = "The statue shatters.";
420 if (uwep && is_lightsaber(uwep) && (uwep->lamplit || Role_if(PM_SHADOW_JEDI)) ) {
421 use_skill(P_WEDI, 1);
423 if (uwep && uwep->oartifact == ART_DIGSRU) {
424 use_skill(P_WEDI, 1);
426 } else
427 /* it was a statue trap; break_statue()
428 * printed a message and updated the screen
430 digtxt = (char *)0;
431 } else if ((obj = sobj_at(BOULDER, dpx, dpy)) != 0) {
432 struct obj *bobj;
434 fracture_rock(obj);
435 if ((bobj = sobj_at(BOULDER, dpx, dpy)) != 0) {
436 /* another boulder here, restack it to the top */
437 obj_extract_self(bobj);
438 place_object(bobj, dpx, dpy);
440 digtxt = "The boulder falls apart.";
441 if (uwep && is_lightsaber(uwep) && (uwep->lamplit || Role_if(PM_SHADOW_JEDI)) ) {
442 use_skill(P_WEDI, 1);
444 if (uwep && uwep->oartifact == ART_DIGSRU) {
445 use_skill(P_WEDI, 1);
447 } else if (lev->typ == STONE || lev->typ == WATERTUNNEL || lev->typ == SCORR || IS_IRONBAR(lev->typ) ||
448 IS_TREE(lev->typ)) {
449 if(Is_earthlevel(&u.uz)) {
450 if(uwep->blessed && !rn2(3)) {
451 mkcavearea(FALSE);
452 goto cleanup;
453 } else if((uwep->cursed && !rn2(4)) ||
454 (!uwep->blessed && !rn2(6))) {
455 mkcavearea(TRUE);
456 goto cleanup;
459 if (IS_TREE(lev->typ)) {
460 digtxt = "You cut down the tree.";
461 u.cnd_treechopamount++;
462 if (u.ualign.type == A_CHAOTIC) adjalign(1);
464 /* the tree squads do not want people who kill trees, and will aggressively chase them --Amy */
465 u.treesquadwantedlevel += (100 + rnd(u.cnd_treechopamount * 5));
466 if (Role_if(PM_BOSMER)) { /* you have angered Yavanna... */
467 You("violated the sanctity of the grove!");
468 adjalign(-10);
469 increasesincounter(1);
470 u.alignlim--;
471 u.treesquadwantedlevel += 1000;
474 lev->typ = ROOM;
475 if (!rn2(5)) wake_nearby(); /* felling a tree can make a loud noise, try it in real life! --Amy */
477 if (!rn2(5) && !(lev->looted & TREE_LOOTED) ) (void) rnd_treefruit_at(dpx, dpy);
479 if (uwep && is_lightsaber(uwep) && (uwep->lamplit || Role_if(PM_SHADOW_JEDI)) ) {
480 use_skill(P_WEDI, 1);
482 if (uwep && uwep->oartifact == ART_DIGSRU) {
483 use_skill(P_WEDI, 1);
486 if (!(lev->looted & TREE_SWARM) && !rn2(16)) {
487 int cnt = rnl(4) + 2;
488 int made = 0;
489 coord mm;
490 mm.x = dpx; mm.y = dpy;
492 if (!rn2(20)) {
494 while (cnt--) {
495 if (enexto(&mm, mm.x, mm.y, &mons[PM_WOOD_NYMPH]) &&
496 makemon(mkclass(S_NYMPH,0), mm.x, mm.y, MM_ANGRY))
497 made++;
499 wake_nearby(); /* make sure they're awake --Amy */
501 } else {
503 while (cnt--) {
504 if (enexto(&mm, mm.x, mm.y, &mons[PM_KILLER_BEE]) &&
505 makemon(beehivemon(), mm.x, mm.y, MM_ANGRY))
506 made++;
510 if ( made )
511 pline("You've attracted the tree's former occupants!");
512 else
513 You("smell stale honey.");
517 if (!rn2(50)) { /* summon the tree squad! --Amy */
519 coord cc, dd;
520 int cx,cy;
521 cx = rn2(COLNO);
522 cy = rn2(ROWNO);
523 int tsdamount = rnd(4);
524 if (!rn2(10)) tsdamount += rnd(8);
526 u.aggravation = 1;
527 reset_rndmonst(NON_PM);
529 while (tsdamount) {
531 int attempts = 0;
532 struct permonst *pm = 0;
533 tsdamount--;
534 if (!enexto(&dd, u.ux, u.uy, (struct permonst *)0) ) continue;
536 newbossTSD:
537 do {
538 pm = rndmonst();
539 attempts++;
540 if (attempts && (attempts % 10000 == 0)) u.mondiffhack++;
541 if (!rn2(2000)) reset_rndmonst(NON_PM);
543 } while ( (!pm || (pm && !(pm->msound == MS_TREESQUAD ))) && attempts < 50000);
545 if (!pm && rn2(50) ) {
546 attempts = 0;
547 goto newbossTSD;
549 if (pm && !(pm->msound == MS_TREESQUAD) && rn2(50) ) {
550 attempts = 0;
551 goto newbossTSD;
554 if (pm) (void) makemon(pm, cx, cy, MM_ANGRY|MM_FRENZIED|MM_XFRENZIED|MM_ADJACENTOK);
556 u.mondiffhack = 0;
560 u.aggravation = 0;
564 } else if (IS_WATERTUNNEL(lev->typ)) {
565 digtxt = "You smash the solid part of the tunnel apart. Now it's a moat!";
566 u.cnd_diggingamount++;
567 lev->typ = MOAT;
568 if (uwep && is_lightsaber(uwep) && (uwep->lamplit || Role_if(PM_SHADOW_JEDI)) ) {
569 use_skill(P_WEDI, 1);
571 if (uwep && uwep->oartifact == ART_DIGSRU) {
572 use_skill(P_WEDI, 1);
574 } else if (uwep && IS_IRONBAR(lev->typ) && is_antibar(uwep) ) {
576 digtxt = "You smash the bars to the ground.";
577 u.cnd_barbashamount++;
578 if (!rn2(100)) {
579 int attempts = 0;
580 int monstcnt;
581 monstcnt = 1 + rnd(3);
582 struct permonst *pm = 0;
584 if (Aggravate_monster) {
585 u.aggravation = 1;
586 reset_rndmonst(NON_PM);
589 newbossMETALMAFIA:
590 do {
591 pm = rndmonst();
592 attempts++;
593 if (attempts && (attempts % 10000 == 0)) u.mondiffhack++;
594 if (!rn2(2000)) reset_rndmonst(NON_PM);
596 } while ( (!pm || (pm && !(pm->msound == MS_METALMAFIA ))) && attempts < 50000);
598 if (!pm && rn2(50) ) {
599 attempts = 0;
600 goto newbossMETALMAFIA;
602 if (pm && !(pm->msound == MS_METALMAFIA) && rn2(50) ) {
603 attempts = 0;
604 goto newbossMETALMAFIA;
607 if (pm) (void) makemon(pm, 0, 0, MM_ANGRY);
609 u.mondiffhack = 0;
611 if (monstcnt > 0) {
612 monstcnt--;
613 if (monstcnt > 0) goto newbossMETALMAFIA;
616 u.aggravation = 0;
620 if (In_sokoban(&u.uz) && !playercancheatinsoko()) {
621 change_luck(-1);
622 pline("You cheater!");
623 if (evilfriday) u.ugangr++;
626 if (!issoviet || !rn2(10)) lev->typ = ROOM;
627 else {
628 pline("V sootvetstvii s tipom bloka l'da eto ne imeyet nikakogo smysla. I poetomu on ne rabotayet. Khar Khar Khar on on on bwar khar khar!");
629 digging.quiet = TRUE; /* suppress misleading message */
630 /* In Soviet Russia, iron bars are supposed to be nigh impenetrable. After all, someone's gotta keep all those
631 * capitalist prisoners at bay. Therefore, you can try to smash iron bars many times but only rarely it will
632 * work. Actually, it's supposed to be possible to cut through bars with a lightsaber instead according to
633 * Soviet, but seriously, fuck that shit, I'm not gonna bother coding that just for an obscure special mode
634 * that 99.9% of players won't use anyway because they don't understand russian. --Amy */
636 if (uwep->obrittle == 3 || uwep->obrittle2 == 3) {
637 Your("weapon was destroyed!");
638 useupall(uwep);
639 } else {
641 if (!rn2(2)) uwep->obrittle++;
642 else uwep->obrittle2++;
643 Your("weapon has taken damage from smashing the bars!");
645 /* it's intentional that the weapon cannot resist, because otherwise you could take one that
646 * is highly resistant to erosion or even immune to being destroyed and simply smash all bars
647 * in the entire dungeon, which isn't what we want --Amy */
649 if (!rn2(5)) mkobj_at(CHAIN_CLASS, dpx, dpy, FALSE, FALSE); /* maybe make a chain from the bars --Amy */
651 } else {
652 digtxt = "You succeed in cutting away some rock.";
653 u.cnd_diggingamount++;
654 lev->typ = CORR;
656 if (uwep && uwep->oartifact == ART_MFFAP && !rn2(20)) {
657 struct trap *extramine;
658 if (!t_at(dpx, dpy)) {
659 extramine = maketrap(dpx, dpy, LANDMINE, 0, FALSE);
660 if (extramine) {
661 extramine->tseen = TRUE;
662 extramine->hiddentrap = FALSE;
663 extramine->madeby_u = TRUE;
664 pline("CLICK! A mine has been set!");
669 if (uwep && is_lightsaber(uwep) && (uwep->lamplit || Role_if(PM_SHADOW_JEDI)) ) {
670 use_skill(P_WEDI, 1);
672 if (uwep && uwep->oartifact == ART_DIGSRU) {
673 use_skill(P_WEDI, 1);
676 } else if(IS_WALL(lev->typ)) {
677 if(shopedge) {
678 add_damage(dpx, dpy, 10L * ACURRSTR);
679 dmgtxt = "damage";
681 if (level.flags.is_maze_lev) {
682 lev->typ = /*ROOM*/CORR;
683 } else if (level.flags.is_cavernous_lev &&
684 !in_town(dpx, dpy)) {
685 lev->typ = CORR;
686 } else if (IS_WATERTUNNEL(lev->typ)) {
687 lev->typ = MOAT;
688 } else if (IS_DIGGABLEWALL(lev->typ)) {
689 lev->typ = CORR;
690 } else {
691 lev->typ = DOOR;
692 lev->doormask = D_NODOOR;
694 digtxt = "You make an opening in the wall.";
695 u.cnd_diggingamount++;
697 if (uwep && is_lightsaber(uwep) && (uwep->lamplit || Role_if(PM_SHADOW_JEDI)) ) {
698 use_skill(P_WEDI, 1);
700 if (uwep && uwep->oartifact == ART_DIGSRU) {
701 use_skill(P_WEDI, 1);
704 } else if(lev->typ == SDOOR) {
705 cvt_sdoor_to_door(lev); /* ->typ = DOOR */
706 digtxt = "You break through a secret door!";
707 if (uwep && is_lightsaber(uwep) && (uwep->lamplit || Role_if(PM_SHADOW_JEDI)) ) {
708 use_skill(P_WEDI, 1);
710 if (uwep && uwep->oartifact == ART_DIGSRU) {
711 use_skill(P_WEDI, 1);
713 if(!(lev->doormask & D_TRAPPED))
714 lev->doormask = D_BROKEN;
715 } else if(closed_door(dpx, dpy)) {
716 digtxt = "You break through the door.";
717 if (uwep && is_lightsaber(uwep) && (uwep->lamplit || Role_if(PM_SHADOW_JEDI)) ) {
718 use_skill(P_WEDI, 1);
720 if (uwep && uwep->oartifact == ART_DIGSRU) {
721 use_skill(P_WEDI, 1);
723 if(shopedge) {
724 add_damage(dpx, dpy, 400L);
725 dmgtxt = "break";
727 if(!(lev->doormask & D_TRAPPED))
728 lev->doormask = D_BROKEN;
729 } else return(0); /* statue or boulder got taken */
731 if(!does_block(dpx,dpy,&levl[dpx][dpy]))
732 unblock_point(dpx,dpy); /* vision: can see through */
733 if (!(levl[dpx][dpy].wall_info & W_HARDGROWTH)) levl[dpx][dpy].wall_info |= W_EASYGROWTH;
734 if(Blind)
735 feel_location(dpx, dpy);
736 else
737 newsym(dpx, dpy);
738 if(digtxt && !digging.quiet) pline("%s", digtxt); /* after newsym */
739 if(dmgtxt)
740 pay_for_damage(dmgtxt, FALSE);
742 if(Is_earthlevel(&u.uz) && !rn2(3)) {
743 register struct monst *mtmp;
745 switch(rn2(2)) {
746 case 0:
747 mtmp = makemon(&mons[PM_EARTH_ELEMENTAL],
748 dpx, dpy, NO_MM_FLAGS);
749 break;
750 default:
751 mtmp = makemon(&mons[PM_XORN],
752 dpx, dpy, NO_MM_FLAGS);
753 break;
755 if(mtmp) pline_The("debris reassembles and comes to life!");
757 if(IS_DOOR(lev->typ) && (lev->doormask & D_TRAPPED)) {
758 lev->doormask = D_NODOOR;
759 b_trapped("door", 0);
760 newsym(dpx, dpy);
762 cleanup:
763 digging.lastdigtime = moves;
764 digging.quiet = FALSE;
765 digging.level.dnum = 0;
766 digging.level.dlevel = -1;
767 return(0);
768 } else { /* not enough effort has been spent yet */
769 static const char *const d_target[8] = {
770 "", "rock", "statue", "boulder", "door", "tree", "bars", "obstruction"
772 int dig_target = dig_typ(uwep, dpx, dpy);
774 if (IS_WALL(lev->typ) || dig_target == DIGTYP_DOOR) {
775 if(*in_rooms(dpx, dpy, SHOPBASE)) {
776 pline("This %s seems too hard to %s.",
777 IS_DOOR(lev->typ) ? "door" : IS_MOUNTAIN(lev->typ) ? "mountain" : IS_FARMLAND(lev->typ) ? "farmland" : "wall", verb);
778 return(0);
780 } else if (!IS_ROCK(lev->typ) && !IS_WATERTUNNEL(lev->typ) && dig_target == DIGTYP_ROCK)
781 return(0); /* statue or boulder got taken */
782 if(!did_dig_msg) {
783 if (is_lightsaber(uwep)) You("burn steadily through %s.",
784 the(d_target[dig_target]));
785 else
786 You("hit the %s with all your might.",
787 d_target[dig_target]);
788 did_dig_msg = TRUE;
791 return(1);
794 /* When will hole be finished? Very rough indication used by shopkeeper. */
796 holetime()
798 if(occupation != dig || !*u.ushops) return(-1);
799 return ((250 - digging.effort) / 20);
802 /* Return typ of liquid to fill a hole with, or ROOM, if no liquid nearby */
803 STATIC_OVL
804 schar
805 fillholetyp(x,y)
806 int x, y;
808 register int x1, y1;
809 int lo_x = max(1,x-1), hi_x = min(x+1,COLNO-1),
810 lo_y = max(0,y-1), hi_y = min(y+1,ROWNO-1);
811 int pool_cnt = 0, moat_cnt = 0, lava_cnt = 0, urine_cnt = 0, styx_cnt = 0, shifting_cnt = 0;
813 for (x1 = lo_x; x1 <= hi_x; x1++)
814 for (y1 = lo_y; y1 <= hi_y; y1++)
815 if (levl[x1][y1].typ == POOL)
816 pool_cnt++;
817 else if (levl[x1][y1].typ == MOAT ||
818 (levl[x1][y1].typ == DRAWBRIDGE_UP &&
819 (levl[x1][y1].drawbridgemask & DB_UNDER) == DB_MOAT))
820 moat_cnt++;
821 else if (levl[x1][y1].typ == LAVAPOOL ||
822 (levl[x1][y1].typ == DRAWBRIDGE_UP &&
823 (levl[x1][y1].drawbridgemask & DB_UNDER) == DB_LAVA))
824 lava_cnt++;
825 else if (levl[x1][y1].typ == URINELAKE)
826 urine_cnt++;
827 else if (levl[x1][y1].typ == STYXRIVER)
828 styx_cnt++;
829 else if (levl[x1][y1].typ == SHIFTINGSAND)
830 shifting_cnt++;
831 pool_cnt /= 3; /* not as much liquid as the others */
833 if (lava_cnt > moat_cnt + pool_cnt && rn2(lava_cnt + 1))
834 return LAVAPOOL;
835 else if (moat_cnt > 0 && rn2(moat_cnt + 1))
836 return MOAT;
837 else if (pool_cnt > 0 && rn2(pool_cnt + 1))
838 return POOL;
839 else if (urine_cnt > 0 && rn2(urine_cnt + 1))
840 return URINELAKE;
841 else if (styx_cnt > 0 && rn2(styx_cnt + 1))
842 return STYXRIVER;
843 else if (shifting_cnt > 0 && rn2(shifting_cnt + 1))
844 return SHIFTINGSAND;
845 else
846 return ROOM;
849 void
850 digactualhole(x, y, madeby, ttyp)
851 register int x, y;
852 struct monst *madeby;
853 int ttyp;
855 struct obj *oldobjs, *newobjs;
856 register struct trap *ttmp;
857 char surface_type[BUFSZ];
858 struct rm *lev = &levl[x][y];
859 boolean shopdoor;
860 struct monst *mtmp = m_at(x, y); /* may be madeby */
861 boolean madeby_u = (madeby == BY_YOU);
862 boolean madeby_obj = (madeby == BY_OBJECT);
863 boolean at_u = (x == u.ux) && (y == u.uy);
864 boolean wont_fall = Levitation || Flying;
866 if (u.utrap && u.utraptype == TT_INFLOOR) u.utrap = 0;
868 /* these furniture checks were in dighole(), but wand
869 breaking bypasses that routine and calls us directly */
870 if (IS_FOUNTAIN(lev->typ)) {
871 dogushforth(FALSE);
872 SET_FOUNTAIN_WARNED(x,y); /* force dryup */
873 dryup(x, y, madeby_u);
874 return;
875 } else if (IS_SINK(lev->typ)) {
876 breaksink(x, y);
877 return;
878 } else if (IS_TOILET(lev->typ)) {
879 breaktoilet(u.ux,u.uy);
880 } else if (lev->typ == DRAWBRIDGE_DOWN ||
881 (is_drawbridge_wall(x, y) >= 0)) {
882 int bx = x, by = y;
883 /* if under the portcullis, the bridge is adjacent */
884 (void) find_drawbridge(&bx, &by);
885 destroy_drawbridge(bx, by);
886 return;
889 if (ttyp != PIT && !Can_dig_down(&u.uz)) {
890 impossible("digactualhole: can't dig %s on this level.",
891 defsyms[trap_to_defsym(ttyp)].explanation);
892 ttyp = PIT;
895 /* maketrap() might change it, also, in this situation,
896 surface() returns an inappropriate string for a grave */
897 if (IS_GRAVE(lev->typ))
898 strcpy(surface_type, "grave");
899 else
900 strcpy(surface_type, surface(x,y));
901 shopdoor = IS_DOOR(lev->typ) && *in_rooms(x, y, SHOPBASE);
902 oldobjs = level.objects[x][y];
903 ttmp = maketrap(x, y, ttyp, 0, FALSE);
904 if (!ttmp) return;
905 newobjs = level.objects[x][y];
906 ttmp->tseen = ((madeby_u || cansee(x,y)) && !ttmp->hiddentrap);
907 ttmp->madeby_u = madeby_u;
908 newsym(ttmp->tx,ttmp->ty);
910 if (ttyp == PIT) {
912 if(madeby_u) {
913 You("dig a pit in the %s.", surface_type);
914 u.cnd_diggingamount++;
915 if (shopdoor) pay_for_damage("ruin", FALSE);
916 } else if (!madeby_obj && canseemon(madeby))
917 pline("%s digs a pit in the %s.", Monnam(madeby), surface_type);
918 else if (cansee(x, y) && flags.verbose)
919 pline("A pit appears in the %s.", surface_type);
921 if(at_u) {
922 if (!wont_fall) {
923 if (!Passes_walls)
924 u.utrap = rn1(4,2);
925 u.utraptype = TT_PIT;
926 vision_full_recalc = 1; /* vision limits change */
927 } else
928 u.utrap = 0;
929 if (oldobjs != newobjs) /* something unearthed */
930 (void) pickup(1); /* detects pit */
931 } else if(mtmp) {
932 if(is_flyer(mtmp->data) || mtmp->egotype_flying || is_floater(mtmp->data)) {
933 if(canseemon(mtmp))
934 pline("%s %s over the pit.", Monnam(mtmp),
935 (is_flyer(mtmp->data)) ?
936 "flies" : "floats");
937 } else if(mtmp != madeby)
938 (void) mintrap(mtmp);
940 } else { /* was TRAPDOOR now a HOLE*/
942 if(madeby_u) {
943 You("dig a hole through the %s.", surface_type);
944 u.cnd_diggingamount++;
945 } else if(!madeby_obj && canseemon(madeby))
946 pline("%s digs a hole through the %s.",
947 Monnam(madeby), surface_type);
948 else if(cansee(x, y) && flags.verbose)
949 pline("A hole appears in the %s.", surface_type);
951 if (at_u) {
952 if (!u.ustuck && !wont_fall && !next_to_u()) {
953 You("are jerked back by your pet!");
954 wont_fall = TRUE;
957 /* Floor objects get a chance of falling down. The case where
958 * the hero does NOT fall down is treated here. The case
959 * where the hero does fall down is treated in goto_level().
961 if (u.ustuck || wont_fall) {
962 if (newobjs)
963 impact_drop((struct obj *)0, x, y, 0);
964 if (oldobjs != newobjs)
965 (void) pickup(1);
966 if (shopdoor && madeby_u) pay_for_damage("ruin", FALSE);
968 } else {
969 d_level newlevel;
970 const char *You_fall = "You fall through...";
972 if (*u.ushops && madeby_u)
973 shopdig(1); /* shk might snatch pack */
974 /* handle earlier damage, eg breaking wand of digging */
975 else if (!madeby_u) pay_for_damage("dig into", TRUE);
977 /* Earlier checks must ensure that the destination
978 * level exists and is in the present dungeon.
980 newlevel.dnum = u.uz.dnum;
981 newlevel.dlevel = u.uz.dlevel + 1;
982 /* Cope with holes caused by monster's actions -- ALI */
983 if (flags.mon_moving) {
984 schedule_goto(&newlevel, FALSE, TRUE, FALSE,
985 You_fall, (char *)0);
986 } else {
987 pline("%s", You_fall);
988 goto_level(&newlevel, FALSE, TRUE, FALSE);
989 /* messages for arriving in special rooms */
990 spoteffects(FALSE);
993 } else {
994 if (shopdoor && madeby_u) pay_for_damage("ruin", FALSE);
995 if (newobjs)
996 impact_drop((struct obj *)0, x, y, 0);
997 if (mtmp) {
998 /*[don't we need special sokoban handling here?]*/
999 if (is_flyer(mtmp->data) || mtmp->egotype_flying || is_floater(mtmp->data) ||
1000 mtmp->data == &mons[PM_WUMPUS] ||
1001 (mtmp->wormno && count_wsegs(mtmp) > 5) ||
1002 mtmp->data->msize >= MZ_HUGE) return;
1003 if (mtmp == u.ustuck) /* probably a vortex */
1004 return; /* temporary? kludge */
1006 if (teleport_pet(mtmp, FALSE)) {
1007 d_level tolevel;
1009 if (Is_stronghold(&u.uz)) {
1010 assign_level(&tolevel, &valley_level);
1011 } else if (Is_botlevel(&u.uz)) {
1012 if (canseemon(mtmp))
1013 pline("%s avoids the trap.", Monnam(mtmp));
1014 return;
1015 } else {
1016 get_level(&tolevel, depth(&u.uz) + 1);
1018 if (mtmp->isshk) make_angry_shk(mtmp, 0, 0);
1019 migrate_to_level(mtmp, ledger_no(&tolevel),
1020 MIGR_RANDOM, (coord *)0);
1027 /* return TRUE if digging succeeded, FALSE otherwise */
1028 boolean
1029 dighole(pit_only)
1030 boolean pit_only;
1032 register struct trap *ttmp = t_at(u.ux, u.uy);
1033 struct rm *lev = &levl[u.ux][u.uy];
1034 struct obj *boulder_here;
1035 schar typ;
1036 boolean nohole = !Can_dig_down(&u.uz);
1038 if ((ttmp && (ttmp->ttyp == MAGIC_PORTAL || ttmp->ttyp == HEEL_TRAP || ttmp->ttyp == ATTACKING_HEEL_TRAP || ttmp->ttyp == LOUDSPEAKER || ttmp->ttyp == KOP_CUBE || ttmp->ttyp == BOSS_SPAWNER || ttmp->ttyp == ARABELLA_SPEAKER || ttmp->ttyp == FART_TRAP || ttmp->ttyp == PERSISTENT_FART_TRAP || nohole)) ||
1039 In_minotaurmaze(&u.uz) ||
1040 /* ALI - artifact doors */
1041 IS_DOOR(levl[u.ux][u.uy].typ) && artifact_door(u.ux, u.uy) ||
1042 (IS_ROCK(lev->typ) && lev->typ != SDOOR &&
1043 (lev->wall_info & W_NONDIGGABLE) != 0)) {
1044 pline_The("%s here is too hard to dig in.", surface(u.ux,u.uy));
1046 } else if (is_waterypool(u.ux, u.uy) || is_styxriver(u.ux, u.uy) || is_lava(u.ux, u.uy)) {
1047 pline_The("%s sloshes furiously for a moment, then subsides.",
1048 is_lava(u.ux, u.uy) ? "lava" : "water");
1049 wake_nearby(); /* splashing */
1051 } else if (lev->typ == DRAWBRIDGE_DOWN ||
1052 (is_drawbridge_wall(u.ux, u.uy) >= 0)) {
1053 /* drawbridge_down is the platform crossing the moat when the
1054 bridge is extended; drawbridge_wall is the open "doorway" or
1055 closed "door" where the portcullis/mechanism is located */
1056 if (pit_only) {
1057 pline_The("drawbridge seems too hard to dig through.");
1058 return FALSE;
1059 } else if (IS_GRAVE(lev->typ)) {
1060 digactualhole(u.ux, u.uy, BY_YOU, PIT);
1061 dig_up_grave();
1062 return TRUE;
1063 } else {
1064 int x = u.ux, y = u.uy;
1065 /* if under the portcullis, the bridge is adjacent */
1066 (void) find_drawbridge(&x, &y);
1067 destroy_drawbridge(x, y);
1068 return TRUE;
1071 } else if ((boulder_here = sobj_at(BOULDER, u.ux, u.uy)) != 0) {
1072 if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT || ttmp->ttyp == SHIT_PIT || ttmp->ttyp == MANA_PIT || ttmp->ttyp == ANOXIC_PIT || ttmp->ttyp == HYPOXIC_PIT || ttmp->ttyp == ACID_PIT) &&
1073 rn2(2)) {
1074 pline_The("boulder settles into the pit.");
1075 ttmp->ttyp = PIT; /* crush spikes */
1076 } else if (ttmp && ttmp->ttyp == GIANT_CHASM) {
1077 pline("KADOOM! The boulder falls in!");
1078 } else {
1080 * digging makes a hole, but the boulder immediately
1081 * fills it. Final outcome: no hole, no boulder.
1083 pline("KADOOM! The boulder falls in!");
1084 (void) delfloortrap(ttmp);
1086 delobj(boulder_here);
1087 return TRUE;
1089 } else if (IS_GRAVE(lev->typ)) {
1090 dig_up_grave();
1091 digactualhole(u.ux, u.uy, BY_YOU, PIT);
1092 return TRUE;
1093 } else if (lev->typ == DRAWBRIDGE_UP) {
1094 /* must be floor or ice, other cases handled above */
1095 /* dig "pit" and let fluid flow in (if possible) */
1096 typ = fillholetyp(u.ux,u.uy);
1098 if (typ == ROOM) {
1100 * We can't dig a hole here since that will destroy
1101 * the drawbridge. The following is a cop-out. --dlc
1103 pline_The("%s here is too hard to dig in.",
1104 surface(u.ux, u.uy));
1105 return FALSE;
1108 lev->drawbridgemask &= ~DB_UNDER;
1109 lev->drawbridgemask |= (typ == LAVAPOOL) ? DB_LAVA : DB_MOAT;
1111 liquid_flow:
1112 if (ttmp) (void) delfloortrap(ttmp);
1113 /* if any objects were frozen here, they're released now */
1114 unearth_objs(u.ux, u.uy);
1116 pline("As you dig, the hole fills with %s!",
1117 typ == LAVAPOOL ? "lava" : typ == STYXRIVER ? "an icky green liquid" : typ == URINELAKE ? "urine" : typ == SHIFTINGSAND ? "quicksand" : "water");
1118 /* KMH, balance patch -- new intrinsic */
1119 if (!Levitation && !Flying && typ != STYXRIVER && typ != URINELAKE && typ != SHIFTINGSAND) {
1120 if (typ == LAVAPOOL)
1121 (void) lava_effects();
1122 else if (!Wwalking && !Race_if(PM_KORONST) && !Swimming)
1123 (void) drown();
1125 return TRUE;
1127 /* the following two are here for the wand of digging */
1128 } else if (IS_THRONE(lev->typ)) {
1129 pline_The("throne is too hard to break apart.");
1131 } else if (IS_FARMLAND(lev->typ)) {
1132 pline("Farmland cannot be dug out.");
1133 } else if (IS_MOUNTAIN(lev->typ)) {
1134 pline_The("mountain is too hard to dig into.");
1135 } else if (IS_GRAVEWALL(lev->typ)) {
1136 pline_The("grave wall needs to be dug by moving into it.");
1138 } else if (IS_ALTAR(lev->typ)) {
1139 pline_The("altar is too hard to break apart.");
1141 } else {
1142 typ = fillholetyp(u.ux,u.uy);
1144 if (typ != ROOM) {
1145 lev->typ = typ;
1146 goto liquid_flow;
1149 /* finally we get to make a hole */
1150 if (nohole || pit_only)
1151 digactualhole(u.ux, u.uy, BY_YOU, PIT);
1152 else
1153 digactualhole(u.ux, u.uy, BY_YOU, HOLE);
1155 return TRUE;
1158 return FALSE;
1161 STATIC_OVL void
1162 dig_up_grave()
1164 struct obj *otmp;
1166 /* Grave-robbing is frowned upon... */
1167 exercise(A_WIS, FALSE);
1168 if (uwep && uwep->oartifact == ART_JAPANESE_WOMEN) {
1169 adjalign(-5);
1170 increasesincounter(1);
1171 u.alignlim--;
1172 adjalign(-10);
1173 You("disturb the honorable dead!");
1175 if (u.twoweap && uswapwep && uswapwep->oartifact == ART_JAPANESE_WOMEN) {
1176 adjalign(-5);
1177 increasesincounter(1);
1178 u.alignlim--;
1179 adjalign(-10);
1180 You("disturb the honorable dead!");
1182 if (uwep && uwep->oartifact == ART_SAKUSHNIR) {
1183 adjalign(-5);
1184 increasesincounter(1);
1185 u.alignlim--;
1186 adjalign(-10);
1187 You("disturb the honorable dead!");
1189 if (u.twoweap && uswapwep && uswapwep->oartifact == ART_SAKUSHNIR) {
1190 adjalign(-5);
1191 increasesincounter(1);
1192 u.alignlim--;
1193 adjalign(-10);
1194 You("disturb the honorable dead!");
1196 if (Role_if(PM_ARCHEOLOGIST)) {
1197 adjalign(-sgn(u.ualign.type)*3);
1198 increasesincounter(1);
1199 u.alignlim--;
1200 adjalign(-5);
1201 You_feel("like a despicable grave-robber!");
1203 if (Role_if(PM_SAMURAI)) {
1204 adjalign(-sgn(u.ualign.type)*5); /* stiffer penalty */
1205 increasesincounter(1);
1206 u.alignlim--;
1207 adjalign(-10);
1208 You("disturb the honorable dead!");
1210 if (uwep && uwep->otyp == HONOR_KATANA) {
1211 adjalign(-sgn(u.ualign.type)*5); /* stiffer penalty */
1212 increasesincounter(1);
1213 u.alignlim--;
1214 adjalign(-10);
1215 You("disturb the honorable dead!");
1217 if (u.twoweap && uswapwep && uswapwep->otyp == HONOR_KATANA) {
1218 adjalign(-sgn(u.ualign.type)*5); /* stiffer penalty */
1219 increasesincounter(1);
1220 u.alignlim--;
1221 adjalign(-10);
1222 You("disturb the honorable dead!");
1224 if (u.ualign.type == A_LAWFUL) {
1225 adjalign(-sgn(u.ualign.type)*2);
1226 You("have violated the sanctity of this grave!");
1229 switch (rn2(5)) {
1230 case 0:
1231 case 1:
1232 You("unearth a corpse.");
1233 if (!!(otmp = mk_tt_object(CORPSE, u.ux, u.uy)))
1234 otmp->age -= 100; /* this is an *OLD* corpse */;
1235 break;
1236 case 2:
1237 if (!Blind) pline(FunnyHallu ? "Dude! The living dead!" :
1238 "The grave's owner is very upset!");
1240 if (Aggravate_monster) {
1241 u.aggravation = 1;
1242 reset_rndmonst(NON_PM);
1245 (void) makemon(mkclass(S_ZOMBIE,0), u.ux, u.uy, NO_MM_FLAGS);
1247 u.aggravation = 0;
1249 break;
1250 case 3:
1251 if (!Blind) pline(FunnyHallu ? "I want my mummy!" :
1252 "You've disturbed a tomb!");
1254 if (Aggravate_monster) {
1255 u.aggravation = 1;
1256 reset_rndmonst(NON_PM);
1259 (void) makemon(mkclass(S_MUMMY,0), u.ux, u.uy, NO_MM_FLAGS);
1261 u.aggravation = 0;
1263 break;
1264 default:
1265 /* No corpse */
1266 pline_The("grave seems unused. Strange....");
1267 break;
1269 levl[u.ux][u.uy].typ = ROOM;
1270 del_engr_at(u.ux, u.uy);
1271 newsym(u.ux,u.uy);
1272 return;
1276 use_pick_axe(obj)
1277 struct obj *obj;
1279 boolean ispick;
1280 boolean isantibar;
1281 char dirsyms[12];
1282 char qbuf[QBUFSZ];
1283 register char *dsp = dirsyms;
1284 register int rx, ry;
1285 int res = 0;
1286 register const char *sdp, *verb;
1288 if(iflags.num_pad) sdp = ndir; else sdp = sdir; /* DICE workaround */
1290 /* Check tool */
1291 if (obj != uwep) {
1292 if (!wield_tool(obj, "swing")) return 0;
1293 else res = 1;
1295 ispick = is_pick(obj);
1296 isantibar = is_antibar(obj);
1297 verb = ispick ? "dig" : isantibar ? "lash out" : "chop";
1299 if (u.utrap && u.utraptype == TT_WEB) {
1300 pline("%s you can't %s while entangled in a web.",
1301 /* res==0 => no prior message;
1302 res==1 => just got "You now wield a pick-axe." message */
1303 !res ? "Unfortunately," : "But", verb);
1304 if (flags.moreforced && !MessagesSuppressed) display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
1305 return res;
1308 if (u.utrap && u.utraptype == TT_GLUE) {
1309 pline("%s you can't %s while being held by the glue.",
1310 /* res==0 => no prior message;
1311 res==1 => just got "You now wield a pick-axe." message */
1312 !res ? "Unfortunately," : "But", verb);
1313 if (flags.moreforced && !MessagesSuppressed) display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
1314 return res;
1317 while(*sdp) {
1318 (void) movecmd(*sdp); /* sets u.dx and u.dy and u.dz */
1319 rx = u.ux + u.dx;
1320 ry = u.uy + u.dy;
1321 /* Include down even with axe, so we have at least one direction */
1322 if (u.dz > 0 ||
1323 (u.dz == 0 && isok(rx, ry) &&
1324 dig_typ(obj, rx, ry) != DIGTYP_UNDIGGABLE))
1325 *dsp++ = *sdp;
1326 sdp++;
1328 *dsp = 0;
1329 sprintf(qbuf, "In what direction do you want to %s? [%s]", verb, dirsyms);
1330 if(!getdir(qbuf))
1331 return(res);
1333 return (use_pick_axe2(obj));
1336 /* general dig through doors/etc. function
1337 * Handles pickaxes/lightsabers/axes
1338 * called from doforce and use_pick_axe
1341 /* MRKR: use_pick_axe() is split in two to allow autodig to bypass */
1342 /* the "In what direction do you want to dig?" query. */
1343 /* use_pick_axe2() uses the existing u.dx, u.dy and u.dz */
1345 int use_pick_axe2(obj)
1346 struct obj *obj;
1348 register int rx, ry;
1349 register struct rm *lev;
1350 int dig_target, digtyp;
1351 boolean ispick = is_pick(obj);
1352 const char *verbing = ispick ? "digging" :
1353 is_lightsaber(uwep) ? "cutting" :
1354 "chopping";
1356 /* 0 = pick, 1 = lightsaber, 2 = axe */
1357 digtyp = (is_pick(uwep) ? 0 :
1358 is_lightsaber(uwep) ? 1 :
1361 if (u.uswallow && attack(u.ustuck)) {
1362 ; /* return(1) */
1363 } else if (Underwater) {
1364 pline("Turbulence torpedoes your %s attempts.", verbing);
1365 } else if(u.dz < 0) {
1366 if(Levitation)
1367 if (digtyp == 1)
1368 pline_The("ceiling is too hard to cut through.");
1369 else
1370 You("don't have enough leverage.");
1371 else
1372 You_cant("reach the %s.",ceiling(u.ux,u.uy));
1373 } else if(!u.dx && !u.dy && !u.dz) {
1374 /* NOTREACHED for lightsabers/axes called from doforce */
1376 char buf[BUFSZ];
1377 int dam;
1379 dam = rnd(2) + dbon() + obj->spe;
1380 if (dam <= 0) dam = 1;
1381 if (obj->otyp == SEXY_LEATHER_PUMP) {
1382 if (ACURR(A_INT) >= 6) pline("Klock! You hit yourself with your sexy leather pump, producing a beautiful sound.");
1383 else pline("Klock! You hit yourself with your sexy leather pump, producing a hollow sound.");
1384 } else if (obj->otyp == BLOCK_HEELED_COMBAT_BOOT) You_feel("a wonderfully painful sensation as you hit yourself with your fleecy block-heeled combat boot.");
1385 else if (obj->otyp == TORPEDO) pline("You deal yourself a deep gash with your torpedo!");
1386 else if (obj->otyp == YATAGAN) pline("You terribly hurt yourself with your blade!");
1387 else if (obj->otyp == DIAMOND_SMASHER) pline("You see lots of little asterisks as the diamond club hits you!");
1388 else if (obj->otyp == HOMING_TORPEDO) pline("The torpedo strikes right into your vital organs!");
1389 else if (obj->otyp == RADIOACTIVE_DAGGER) pline("You irradiate yourself with your dagger!");
1390 else if (obj->otyp == IMPACT_STAFF) pline("Dock! You hit yourself with your staff!");
1391 else if (obj->otyp == BLOCK_HEELED_SANDAL) pline("Mmmmmmmm, the massive block heel hits your %s so wonderfully painfully!", body_part(HEAD));
1392 else if (obj->otyp == INKA_BOOT) pline("You come right as the lovely, soft boot heel hits you.");
1393 else if (obj->otyp == SEXY_MARY_JANE) pline("Wow, the area between your %s gets all wet as the fleecy-soft, massive block heel hits you!", makeplural(body_part(LEG)) );
1394 else if (obj->otyp == PROSTITUTE_SHOE) pline("You have an orgasm as you hit yourself with the incredibly female prostitute shoe.");
1395 else if (obj->otyp == SOFT_LADY_SHOE) pline("You feel wonderful intense pain as the incredibly soft lady shoe hits you.");
1396 else if (obj->otyp == STEEL_WHIP) {
1397 if (flags.female) You_feel("like a submissive girl as you whip yourself!");
1398 else pline("You enjoy the feeling of pain as the whip hits your bare skin!");
1400 else if (obj->otyp == HIGH_HEELED_SANDAL) pline("Ouch - you hit yourself with a massive high heel! It's very painful!");
1401 else if (obj->otyp == WEDGED_LITTLE_GIRL_SANDAL) pline("You hit yourself with a lovely wedge heel! Even though it looks very innocuous, you can definitely feel intense pain...");
1402 else if (obj->otyp == HUGGING_BOOT) pline("You bonk yourself with a thick winter boot - seems that this boot is made from a harder material than your %s...", body_part(HEAD));
1403 else You("hit yourself with %s.", yname(uwep));
1404 sprintf(buf, "%s own %s", uhis(),
1405 OBJ_NAME(objects[obj->otyp]));
1406 losehp(dam, buf, KILLED_BY);
1407 flags.botl=1;
1408 return(1);
1409 } else if(u.dz == 0) {
1410 if ((Stunned && !rn2(issoviet ? 1 : StrongStun_resist ? 20 : Stun_resist ? 8 : 2)) || (Confusion && !rn2(issoviet ? 2 : StrongConf_resist ? 200 : Conf_resist ? 40 : 8))) confdir();
1411 rx = u.ux + u.dx;
1412 ry = u.uy + u.dy;
1413 if(!isok(rx, ry)) {
1414 if (digtyp == 1) pline("Your %s bounces off harmlessly.",
1415 aobjnam(obj, (char *)0));
1416 else pline("Clash!");
1417 return(1);
1419 lev = &levl[rx][ry];
1420 if(MON_AT(rx, ry) && attack(m_at(rx, ry)))
1421 return(1);
1422 dig_target = dig_typ(obj, rx, ry);
1423 if (dig_target == DIGTYP_UNDIGGABLE) {
1424 /* ACCESSIBLE or POOL */
1425 struct trap *trap = t_at(rx, ry);
1427 if (trap && trap->ttyp == WEB) {
1428 if (!trap->tseen && !trap->hiddentrap) {
1429 seetrap(trap);
1430 There("is a spider web there!");
1432 Your("%s entangled in the web.",
1433 aobjnam(obj, "become"));
1434 /* you ought to be able to let go; tough luck */
1435 /* (maybe `move_into_trap()' would be better) */
1436 nomul(-d(2,2), "stuck in a spider web", TRUE);
1437 nomovemsg = "You pull free.";
1438 } else if (lev->typ == IRONBARS) {
1439 pline("Clang!");
1440 wake_nearby();
1441 } else if (IS_TREE(lev->typ))
1442 You("need an axe to cut down a tree.");
1443 else if (IS_FARMLAND(lev->typ))
1444 You("need to use the force to remove farmland.");
1445 else if (IS_MOUNTAIN(lev->typ))
1446 You("cannot dig out an entire mountain.");
1447 else if (IS_ROCK(lev->typ))
1448 You("need a pick to dig rock.");
1449 else if (!ispick && (sobj_at(STATUE, rx, ry) ||
1450 sobj_at(BOULDER, rx, ry))) {
1451 boolean vibrate = !rn2(3);
1452 pline("Sparks fly as you whack the %s.%s",
1453 sobj_at(STATUE, rx, ry) ? "statue" : "boulder",
1454 vibrate ? " The axe-handle vibrates violently!" : "");
1455 if (vibrate) losehp(2, "axing a hard object", KILLED_BY);
1457 else {
1458 You("swing your %s through thin air.", aobjnam(obj, (char *)0));
1459 if (FunnyHallu) pline("It creates erotic air current noises.");
1461 } else {
1462 static const char * const d_action[8][2] = {
1463 {"swinging","slicing the air"},
1464 {"digging","cutting through the wall"},
1465 {"chipping the statue","cutting the statue"},
1466 {"hitting the boulder","cutting through the boulder"},
1467 {"chopping at the door","burning through the door"},
1468 {"cutting the tree","razing the tree"},
1469 {"smashing the bars","breaking the bars"},
1470 {"smashing the obstruction","breaking the obstruction"}
1472 did_dig_msg = FALSE;
1473 digging.quiet = FALSE;
1474 if (digging.pos.x != rx || digging.pos.y != ry ||
1475 !on_level(&digging.level, &u.uz) || digging.down) {
1476 if (flags.autodig &&
1477 dig_target == DIGTYP_ROCK && !digging.down &&
1478 digging.pos.x == u.ux &&
1479 digging.pos.y == u.uy &&
1480 (moves <= digging.lastdigtime+2 &&
1481 moves >= digging.lastdigtime)) {
1482 /* avoid messages if repeated autodigging */
1483 did_dig_msg = TRUE;
1484 digging.quiet = TRUE;
1486 digging.down = digging.chew = FALSE;
1487 digging.warned = FALSE;
1488 digging.pos.x = rx;
1489 digging.pos.y = ry;
1490 assign_level(&digging.level, &u.uz);
1491 digging.effort = 0;
1492 if (!digging.quiet)
1493 You("start %s.", d_action[dig_target][digtyp == 1]);
1494 } else {
1495 You("%s %s.", digging.chew ? "begin" : "continue",
1496 d_action[dig_target][digtyp == 1]);
1497 digging.chew = FALSE;
1499 set_occupation(dig, verbing, 0);
1500 if (AutoDestruct || u.uprops[AUTO_DESTRUCT].extrinsic || (uarmf && uarmf->oartifact == ART_KHOR_S_REQUIRED_IDEA) || have_autodestructstone() || (uchain && uchain->oartifact == ART_SIYID) ) dig();
1502 } else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
1503 /* it must be air -- water checked above */
1504 You("swing your %s through thin air.", aobjnam(obj, (char *)0));
1505 if (FunnyHallu) pline("It creates erotic air current noises.");
1506 } else if (!can_reach_floor()) {
1507 You_cant("reach the %s.", surface(u.ux,u.uy));
1508 } else if (is_waterypool(u.ux, u.uy) || is_lava(u.ux, u.uy)) {
1509 /* Monsters which swim also happen not to be able to dig */
1510 You("cannot stay under%s long enough.",
1511 is_waterypool(u.ux, u.uy) ? "water" : " the lava");
1512 } else if (digtyp == 2) {
1513 Your("%s merely scratches the %s.",
1514 aobjnam(obj, (char *)0), surface(u.ux,u.uy));
1515 u_wipe_engr(3);
1516 } else {
1517 if (digging.pos.x != u.ux || digging.pos.y != u.uy ||
1518 !on_level(&digging.level, &u.uz) || !digging.down) {
1519 digging.chew = FALSE;
1520 digging.down = TRUE;
1521 digging.warned = FALSE;
1522 digging.pos.x = u.ux;
1523 digging.pos.y = u.uy;
1524 assign_level(&digging.level, &u.uz);
1525 digging.effort = 0;
1526 You("start %s downward.", verbing);
1527 if (*u.ushops) shopdig(0);
1528 } else
1529 You("continue %s downward.", verbing);
1530 did_dig_msg = FALSE;
1531 set_occupation(dig, verbing, 0);
1532 if (AutoDestruct || u.uprops[AUTO_DESTRUCT].extrinsic || (uarmf && uarmf->oartifact == ART_KHOR_S_REQUIRED_IDEA) || have_autodestructstone() || (uchain && uchain->oartifact == ART_SIYID) ) dig();
1534 return(1);
1538 * Town Watchmen frown on damage to the town walls, trees or fountains.
1539 * It's OK to dig holes in the ground, however.
1540 * If mtmp is assumed to be a watchman, a watchman is found if mtmp == 0
1541 * zap == TRUE if wand/spell of digging, FALSE otherwise (chewing)
1543 void
1544 watch_dig(mtmp, x, y, zap)
1545 struct monst *mtmp;
1546 xchar x, y;
1547 boolean zap;
1549 struct rm *lev = &levl[x][y];
1551 if (in_town(x, y) &&
1552 (closed_door(x, y) || lev->typ == SDOOR ||
1553 IS_WALL(lev->typ) || IS_FOUNTAIN(lev->typ) || IS_TREE(lev->typ))) {
1554 if (!mtmp) {
1555 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1556 if (DEADMONSTER(mtmp)) continue;
1557 if ((mtmp->data == &mons[PM_WATCHMAN] || mtmp->data == &mons[PM_WATCH_LIEUTENANT] || mtmp->data == &mons[PM_WATCH_LEADER] || mtmp->data == &mons[PM_WATCH_CAPTAIN]) &&
1558 mtmp->mcansee && m_canseeu(mtmp) &&
1559 couldsee(mtmp->mx, mtmp->my) && mtmp->mpeaceful)
1560 break;
1564 if (mtmp) {
1565 if(zap || digging.warned) {
1566 verbalize("Halt, vandal! You're under arrest!");
1567 (void) angry_guards(!(flags.soundok));
1568 } else {
1569 const char *str;
1571 if (IS_DOOR(lev->typ))
1572 str = "door";
1573 else if (IS_TREE(lev->typ))
1574 str = "tree";
1575 else if (IS_ROCK(lev->typ))
1576 str = "wall";
1577 else
1578 str = "fountain";
1579 verbalize("Hey, stop damaging that %s!", str);
1580 digging.warned = TRUE;
1582 if (is_digging())
1583 stop_occupation();
1588 #endif /* OVLB */
1589 #ifdef OVL0
1591 /* Return TRUE if monster died, FALSE otherwise. Called from m_move(). */
1592 boolean
1593 mdig_tunnel(mtmp)
1594 register struct monst *mtmp;
1596 register struct rm *here;
1597 int pile = rnd(24); /* nerf by Amy - if this is lower than 5, create a pile, used to be rnd(12) */
1599 here = &levl[mtmp->mx][mtmp->my];
1600 if (here->typ == SDOOR)
1601 cvt_sdoor_to_door(here); /* ->typ = DOOR */
1603 /* Eats away door if present & closed or locked */
1604 if (closed_door(mtmp->mx, mtmp->my)) {
1605 if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
1606 add_damage(mtmp->mx, mtmp->my, 0L);
1607 unblock_point(mtmp->mx, mtmp->my); /* vision */
1608 if (!(levl[mtmp->mx][mtmp->my].wall_info & W_HARDGROWTH)) levl[mtmp->mx][mtmp->my].wall_info |= W_EASYGROWTH;
1609 if (here->doormask & D_TRAPPED) {
1610 here->doormask = D_NODOOR;
1611 if (mb_trapped(mtmp)) { /* mtmp is killed */
1612 newsym(mtmp->mx, mtmp->my);
1613 return TRUE;
1615 } else {
1616 if (!rn2(3) && flags.verbose) /* not too often.. */
1617 You_feel("an unexpected draft.");
1618 here->doormask = D_BROKEN;
1620 newsym(mtmp->mx, mtmp->my);
1621 return FALSE;
1622 } else if ((!IS_ROCK(here->typ) && !IS_WATERTUNNEL(here->typ) && !IS_TREE(here->typ)) || IS_FARMLAND(here->typ) || IS_MOUNTAIN(here->typ) || IS_GRAVEWALL(here->typ)) /* no dig */
1623 return FALSE;
1625 /* Only rock, trees, and walls fall through to this point. */
1626 if ((here->wall_info & W_NONDIGGABLE) != 0) { /* This is not a bug. So let's get rid of the message. --Amy */
1627 /*impossible*//*pline("mdig_tunnel: %s at (%d,%d) is undiggable",
1628 (IS_WALL(here->typ) ? "wall" : IS_MOUNTAIN(here->typ) ? "mountain" : IS_FARMLAND(here->typ) ? "farmland" : "stone"),
1629 (int) mtmp->mx, (int) mtmp->my);*/
1630 return FALSE; /* still alive */
1633 if (IS_WALL(here->typ)) {
1635 u.cnd_monsterdigamount++;
1637 /* KMH -- Okay on arboreal levels (room walls are still stone) */
1638 if (flags.soundok && flags.verbose && !rn2(5)) {
1639 /* KMH -- Okay on arboreal levels (room walls are still stone) */
1640 You_hear("crashing rock.");
1641 if (PlayerHearsSoundEffects) pline(issoviet ? "Stena teper' ushla navsegda." : "Derrsch!");
1643 if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
1644 add_damage(mtmp->mx, mtmp->my, 0L);
1645 if (level.flags.is_maze_lev) {
1646 here->typ = ROOM;
1647 } else if (level.flags.is_cavernous_lev &&
1648 !in_town(mtmp->mx, mtmp->my)) {
1649 here->typ = CORR;
1650 } else if (IS_WATERTUNNEL(here->typ)) {
1651 here->typ = MOAT;
1652 } else if (IS_DIGGABLEWALL(here->typ)) {
1653 here->typ = CORR;
1654 } else {
1655 here->typ = DOOR;
1656 here->doormask = D_NODOOR;
1658 } else if (IS_TREE(here->typ)) {
1659 here->typ = ROOM;
1660 if (!rn2(50) && !(here->looted & TREE_LOOTED) && pile && pile < 5) /* it shouldn't be that easy to get tree fruits... --Amy */
1661 (void) rnd_treefruit_at(mtmp->mx, mtmp->my);
1662 } else if (IS_WATERTUNNEL(here->typ)) {
1663 u.cnd_monsterdigamount++;
1664 here->typ = MOAT;
1665 } else {
1666 u.cnd_monsterdigamount++;
1667 here->typ = CORR;
1668 if (!rn2(7) && pile && pile < 5) /* if you dig out rock yourself, you don't get boulders or rock either! --Amy */
1669 (void) mksobj_at((pile == 1) ? BOULDER : ROCK,
1670 mtmp->mx, mtmp->my, TRUE, FALSE, FALSE);
1672 newsym(mtmp->mx, mtmp->my);
1673 if (!sobj_at(BOULDER, mtmp->mx, mtmp->my))
1674 unblock_point(mtmp->mx, mtmp->my); /* vision */
1675 if (!(levl[mtmp->mx][mtmp->my].wall_info & W_HARDGROWTH)) levl[mtmp->mx][mtmp->my].wall_info |= W_EASYGROWTH;
1677 return FALSE;
1680 void
1681 stardigging()
1683 struct rm *room;
1684 struct monst *mtmp;
1685 register struct obj *otmp, *next_obj;
1686 int zx, zy, digdepth;
1687 boolean shopdoor, shopwall, maze_dig;
1689 int diggingiteration = 0;
1691 nextiteration:
1693 switch (diggingiteration) {
1695 case 0:
1696 u.dx = -1;
1697 u.dy = 0;
1698 break;
1699 case 1:
1700 u.dx = 1;
1701 u.dy = -1;
1702 break;
1703 case 2:
1704 u.dx = 1;
1705 u.dy = 0;
1706 break;
1707 case 3:
1708 u.dx = 1;
1709 u.dy = 1;
1710 break;
1711 case 4:
1712 u.dx = 0;
1713 u.dy = 1;
1714 break;
1715 case 5:
1716 u.dx = -1;
1717 u.dy = 1;
1718 break;
1719 case 6:
1720 u.dx = -1;
1721 u.dy = -1;
1722 break;
1723 case 7:
1724 u.dx = 0;
1725 u.dy = -1;
1726 break;
1730 /* normal case: digging across the level */
1731 shopdoor = shopwall = FALSE;
1732 maze_dig = level.flags.is_maze_lev && !Is_earthlevel(&u.uz);
1733 zx = u.ux + u.dx;
1734 zy = u.uy + u.dy;
1735 digdepth = rn1(18, 8);
1736 if (Race_if(PM_IRAHA)) digdepth *= 2;
1737 tmp_at(DISP_BEAM, cmap_to_glyph(S_digbeam));
1738 while (--digdepth >= 0) {
1739 if (!isok(zx,zy)) break;
1740 room = &levl[zx][zy];
1741 tmp_at(zx,zy);
1742 delay_output(); /* wait a little bit */
1744 /* WAC check for monster, boulder */
1745 if ((mtmp = m_at(zx, zy)) != 0) {
1746 if (made_of_rock(mtmp->data)) {
1747 You("gouge a hole in %s!", mon_nam(mtmp));
1748 mtmp->mhp /= 2;
1749 if (mtmp->mhp < 1) mtmp->mhp = 1;
1750 setmangry(mtmp);
1751 } else pline("%s is unaffected!", Monnam(mtmp));
1753 for(otmp = level.objects[zx][zy]; otmp; otmp = next_obj) {
1754 next_obj = otmp->nexthere;
1755 /* vaporize boulders */
1756 if (otmp->otyp == BOULDER) {
1757 delobj(otmp);
1758 /* A little Sokoban guilt... */
1759 if (In_sokoban(&u.uz) && !playercancheatinsoko()) {
1760 change_luck(-1);
1761 pline("You cheater!");
1762 if (evilfriday) u.ugangr++;
1764 unblock_point(zx, zy);
1765 newsym(zx, zy);
1766 pline_The("boulder is vaporized!");
1768 break;
1771 if (closed_door(zx, zy) || room->typ == SDOOR) {
1772 /* ALI - Artifact doors */
1773 if (artifact_door(zx, zy)) {
1774 if (cansee(zx, zy))
1775 pline_The("door glows then fades.");
1776 break;
1778 if (*in_rooms(zx,zy,SHOPBASE)) {
1779 add_damage(zx, zy, 400L);
1780 shopdoor = TRUE;
1782 if (room->typ == SDOOR)
1783 room->typ = DOOR;
1784 else if (cansee(zx, zy))
1785 pline_The("door is razed!");
1786 watch_dig((struct monst *)0, zx, zy, TRUE);
1787 room->doormask = D_NODOOR;
1788 unblock_point(zx,zy); /* vision */
1789 digdepth -= 2;
1790 if (issoviet && maze_dig) pline("Vy ne mozhete kopat'! Poskol'ku Sovetskiy Pyat' Lo nenavidit vashi kishki!");
1791 if (issoviet && maze_dig) break;
1792 } else if (maze_dig) {
1793 if (IS_WATERTUNNEL(room->typ)) {
1794 room->typ = MOAT;
1795 unblock_point(zx,zy); /* vision */
1796 digdepth -= 2; /* fix stupidity --Amy */
1797 if (issoviet) pline("Vy ne mozhete kopat'! Poskol'ku Sovetskiy Pyat' Lo nenavidit vashi kishki!");
1798 if (issoviet) break;
1800 } if (IS_WALL(room->typ) && !(IS_FARMLAND(room->typ)) && !(IS_MOUNTAIN(room->typ)) && !(IS_GRAVEWALL(room->typ)) ) {
1801 if (!(room->wall_info & W_NONDIGGABLE)) {
1802 if (*in_rooms(zx,zy,SHOPBASE)) {
1803 add_damage(zx, zy, 200L);
1804 shopwall = TRUE;
1806 room->typ = /*ROOM*/CORR;
1807 unblock_point(zx,zy); /* vision */
1808 if (!(levl[zx][zy].wall_info & W_HARDGROWTH)) levl[zx][zy].wall_info |= W_EASYGROWTH;
1809 digdepth -= 2; /* fix stupidity --Amy */
1810 if (issoviet) pline("Vy ne mozhete kopat'! Poskol'ku Sovetskiy Pyat' Lo nenavidit vashi kishki!");
1811 if (issoviet) break;
1812 } else if (!Blind) {
1813 pline_The("wall glows then fades.");
1814 break;
1816 } else if (IS_TREE(room->typ)) { /* check trees before stone */
1817 if (!(room->wall_info & W_NONDIGGABLE)) {
1818 room->typ = ROOM;
1819 unblock_point(zx,zy); /* vision */
1820 if (!(levl[zx][zy].wall_info & W_HARDGROWTH)) levl[zx][zy].wall_info |= W_EASYGROWTH;
1821 digdepth -= 2; /* fix stupidity --Amy */
1822 if (issoviet) pline("Vy ne mozhete kopat'! Poskol'ku Sovetskiy Pyat' Lo nenavidit vashi kishki!");
1823 if (issoviet) break;
1824 } else if (!Blind) {
1825 pline_The("tree shudders but is unharmed.");
1826 break;
1828 } else if (room->typ == STONE || room->typ == SCORR) {
1829 if (!(room->wall_info & W_NONDIGGABLE)) {
1830 room->typ = CORR;
1831 unblock_point(zx,zy); /* vision */
1832 if (!(levl[zx][zy].wall_info & W_HARDGROWTH)) levl[zx][zy].wall_info |= W_EASYGROWTH;
1833 digdepth--; /* fix stupidity --Amy */
1834 /* In Soviet Russia, digging has to be done one block at a time. Faster digging methods are capitalistic
1835 * and evil, so they're not allowed. I wonder how long until they decide to make mazes undiggable... --Amy */
1836 if (issoviet) pline("Vy ne mozhete kopat'! Poskol'ku Sovetskiy Pyat' Lo nenavidit vashi kishki!");
1837 if (issoviet) break;
1838 } else if (!Blind) {
1839 pline_The("rock glows then fades.");
1840 break;
1843 } else if (IS_ROCK(room->typ) || IS_WATERTUNNEL(room->typ)) {
1844 if (!may_dig(zx,zy)) break;
1845 if (IS_WALL(room->typ) || room->typ == SDOOR) {
1846 if (*in_rooms(zx,zy,SHOPBASE)) {
1847 add_damage(zx, zy, 200L);
1848 shopwall = TRUE;
1850 watch_dig((struct monst *)0, zx, zy, TRUE);
1851 if (level.flags.is_cavernous_lev && !in_town(zx, zy)) {
1852 room->typ = CORR;
1853 } else if (IS_WATERTUNNEL(room->typ)) {
1854 room->typ = MOAT;
1855 } else if (IS_DIGGABLEWALL(room->typ)) {
1856 room->typ = CORR;
1857 } else {
1858 room->typ = DOOR;
1859 room->doormask = D_NODOOR;
1861 digdepth -= 2;
1862 } else if (IS_TREE(room->typ)) {
1863 room->typ = ROOM;
1864 digdepth -= 2;
1865 } else if (IS_WATERTUNNEL(room->typ)) {
1866 room->typ = MOAT;
1867 digdepth -= 2;
1868 } else { /* IS_ROCK but not IS_WALL or SDOOR */
1869 room->typ = CORR;
1870 digdepth--;
1872 unblock_point(zx,zy); /* vision */
1873 if (!(levl[zx][zy].wall_info & W_HARDGROWTH)) levl[zx][zy].wall_info |= W_EASYGROWTH;
1875 zx += u.dx;
1876 zy += u.dy;
1877 } /* while */
1878 tmp_at(DISP_END,0); /* closing call */
1879 if (shopdoor || shopwall)
1880 pay_for_damage(shopdoor ? "destroy" : "dig into", FALSE);
1882 diggingiteration++;
1884 if (diggingiteration < 8) goto nextiteration;
1886 return;
1890 #endif /* OVL0 */
1891 #ifdef OVL3
1893 /* digging via wand zap or spell cast */
1894 void
1895 zap_dig(bigrange)
1896 boolean bigrange;
1898 struct rm *room;
1899 struct monst *mtmp;
1900 /* struct obj *otmp;*/
1901 register struct obj *otmp, *next_obj;
1902 int zx, zy, digdepth;
1903 boolean shopdoor, shopwall, maze_dig;
1905 * Original effect (approximately):
1906 * from CORR: dig until we pierce a wall
1907 * from ROOM: pierce wall and dig until we reach
1908 * an ACCESSIBLE place.
1909 * Currently: dig for digdepth positions;
1910 * also down on request of Lennart Augustsson.
1913 if (u.uswallow) {
1914 mtmp = u.ustuck;
1916 if (!is_whirly(mtmp->data)) {
1917 if (is_animal(mtmp->data))
1918 You("pierce %s %s wall!",
1919 s_suffix(mon_nam(mtmp)), mbodypart(mtmp, STOMACH));
1920 mtmp->mhp *= 4;
1921 mtmp->mhp /= 5; /* prevent easy Jubilex killing --Amy */
1922 if (bigrange) {
1923 mtmp->mhp *= 3;
1924 mtmp->mhp /= 5;
1926 if (mtmp->mhp < 1) mtmp->mhp = 1; /* fixes the bug where killing gray newts causes error messages */
1927 expels(mtmp, mtmp->data, !is_animal(mtmp->data));
1929 return;
1930 } /* swallowed */
1932 if (u.dz) {
1933 if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !Underwater) {
1934 if (u.dz < 0 || On_stairs(u.ux, u.uy)) {
1935 if (On_stairs(u.ux, u.uy))
1936 pline_The("beam bounces off the %s and hits the %s.",
1937 (u.ux == xdnladder || u.ux == xupladder) ?
1938 "ladder" : "stairs", ceiling(u.ux, u.uy));
1939 You("loosen a rock from the %s.", ceiling(u.ux, u.uy));
1940 pline("It falls on your %s!", body_part(HEAD));
1941 losehp(rnd((uarmh && is_hardmaterial(uarmh)) ? 2 : 6),
1942 "falling rock", KILLED_BY_AN);
1943 otmp = mksobj_at(ROCK, u.ux, u.uy, FALSE, FALSE, FALSE);
1944 if (otmp) {
1946 if(!rn2(8)) {
1947 otmp->spe = rne(2);
1948 if (rn2(2)) otmp->blessed = rn2(2);
1949 else blessorcurse(otmp, 3);
1950 } else if(!rn2(10)) {
1951 if (rn2(10)) curse(otmp);
1952 else blessorcurse(otmp, 3);
1953 otmp->spe = -rne(2);
1954 } else blessorcurse(otmp, 10);
1956 (void)xname(otmp); /* set dknown, maybe bknown */
1957 stackobj(otmp);
1959 newsym(u.ux, u.uy);
1960 } else {
1961 watch_dig((struct monst *)0, u.ux, u.uy, TRUE);
1962 (void) dighole(FALSE);
1965 return;
1966 } /* up or down */
1968 /* normal case: digging across the level */
1969 shopdoor = shopwall = FALSE;
1970 maze_dig = level.flags.is_maze_lev && !Is_earthlevel(&u.uz);
1971 zx = u.ux + u.dx;
1972 zy = u.uy + u.dy;
1973 digdepth = bigrange ? rn1(18, 8) : 1;
1974 if (Race_if(PM_IRAHA)) digdepth *= 2;
1975 tmp_at(DISP_BEAM, cmap_to_glyph(S_digbeam));
1976 while (--digdepth >= 0) {
1977 if (!isok(zx,zy)) break;
1978 room = &levl[zx][zy];
1979 tmp_at(zx,zy);
1980 delay_output(); /* wait a little bit */
1982 /* WAC check for monster, boulder */
1983 if ((mtmp = m_at(zx, zy)) != 0) {
1984 if (made_of_rock(mtmp->data)) {
1985 You("gouge a hole in %s!", mon_nam(mtmp));
1986 mtmp->mhp /= 2;
1987 if (mtmp->mhp < 1) mtmp->mhp = 1;
1988 setmangry(mtmp);
1989 } else pline("%s is unaffected!", Monnam(mtmp));
1991 for(otmp = level.objects[zx][zy]; otmp; otmp = next_obj) {
1992 next_obj = otmp->nexthere;
1993 /* vaporize boulders */
1994 if (otmp->otyp == BOULDER) {
1995 delobj(otmp);
1996 /* A little Sokoban guilt... */
1997 if (In_sokoban(&u.uz) && !playercancheatinsoko()) {
1998 change_luck(-1);
1999 pline("You cheater!");
2000 if (evilfriday) u.ugangr++;
2002 unblock_point(zx, zy);
2003 newsym(zx, zy);
2004 pline_The("boulder is vaporized!");
2006 break;
2009 if (closed_door(zx, zy) || room->typ == SDOOR) {
2010 /* ALI - Artifact doors */
2011 if (artifact_door(zx, zy)) {
2012 if (cansee(zx, zy))
2013 pline_The("door glows then fades.");
2014 break;
2016 if (*in_rooms(zx,zy,SHOPBASE)) {
2017 add_damage(zx, zy, 400L);
2018 shopdoor = TRUE;
2020 if (room->typ == SDOOR)
2021 room->typ = DOOR;
2022 else if (cansee(zx, zy))
2023 pline_The("door is razed!");
2024 watch_dig((struct monst *)0, zx, zy, TRUE);
2025 room->doormask = D_NODOOR;
2026 unblock_point(zx,zy); /* vision */
2027 digdepth -= 2;
2028 if (issoviet && maze_dig) pline("Vy ne mozhete kopat'! Poskol'ku Sovetskiy Pyat' Lo nenavidit vashi kishki!");
2029 if (issoviet && maze_dig) break;
2030 } else if (maze_dig) {
2031 if (IS_WATERTUNNEL(room->typ)) {
2032 room->typ = MOAT;
2033 unblock_point(zx,zy); /* vision */
2034 digdepth -= 2; /* fix stupidity --Amy */
2035 if (issoviet) pline("Vy ne mozhete kopat'! Poskol'ku Sovetskiy Pyat' Lo nenavidit vashi kishki!");
2036 if (issoviet) break;
2038 } if (IS_WALL(room->typ) && !(IS_FARMLAND(room->typ)) && !(IS_MOUNTAIN(room->typ)) && !(IS_GRAVEWALL(room->typ)) ) {
2039 if (!(room->wall_info & W_NONDIGGABLE)) {
2040 if (*in_rooms(zx,zy,SHOPBASE)) {
2041 add_damage(zx, zy, 200L);
2042 shopwall = TRUE;
2044 room->typ = /*ROOM*/CORR;
2045 unblock_point(zx,zy); /* vision */
2046 if (!(levl[zx][zy].wall_info & W_HARDGROWTH)) levl[zx][zy].wall_info |= W_EASYGROWTH;
2047 digdepth -= 2; /* fix stupidity --Amy */
2048 if (issoviet) pline("Vy ne mozhete kopat'! Poskol'ku Sovetskiy Pyat' Lo nenavidit vashi kishki!");
2049 if (issoviet) break;
2050 } else if (!Blind) {
2051 pline_The("wall glows then fades.");
2052 break;
2054 } else if (IS_TREE(room->typ)) { /* check trees before stone */
2055 if (!(room->wall_info & W_NONDIGGABLE)) {
2056 room->typ = ROOM;
2057 unblock_point(zx,zy); /* vision */
2058 if (!(levl[zx][zy].wall_info & W_HARDGROWTH)) levl[zx][zy].wall_info |= W_EASYGROWTH;
2059 digdepth -= 2; /* fix stupidity --Amy */
2060 if (issoviet) pline("Vy ne mozhete kopat'! Poskol'ku Sovetskiy Pyat' Lo nenavidit vashi kishki!");
2061 if (issoviet) break;
2062 } else if (!Blind) {
2063 pline_The("tree shudders but is unharmed.");
2064 break;
2066 } else if (room->typ == STONE || room->typ == SCORR) {
2067 if (!(room->wall_info & W_NONDIGGABLE)) {
2068 room->typ = CORR;
2069 unblock_point(zx,zy); /* vision */
2070 if (!(levl[zx][zy].wall_info & W_HARDGROWTH)) levl[zx][zy].wall_info |= W_EASYGROWTH;
2071 digdepth--; /* fix stupidity --Amy */
2072 /* In Soviet Russia, digging has to be done one block at a time. Faster digging methods are capitalistic
2073 * and evil, so they're not allowed. I wonder how long until they decide to make mazes undiggable... --Amy */
2074 if (issoviet) pline("Vy ne mozhete kopat'! Poskol'ku Sovetskiy Pyat' Lo nenavidit vashi kishki!");
2075 if (issoviet) break;
2076 } else if (!Blind) {
2077 pline_The("rock glows then fades.");
2078 break;
2081 } else if (IS_ROCK(room->typ) || IS_WATERTUNNEL(room->typ)) {
2082 if (!may_dig(zx,zy)) break;
2083 if (IS_WALL(room->typ) || room->typ == SDOOR) {
2084 if (*in_rooms(zx,zy,SHOPBASE)) {
2085 add_damage(zx, zy, 200L);
2086 shopwall = TRUE;
2088 watch_dig((struct monst *)0, zx, zy, TRUE);
2089 if (level.flags.is_cavernous_lev && !in_town(zx, zy)) {
2090 room->typ = CORR;
2091 } else if (IS_WATERTUNNEL(room->typ)) {
2092 room->typ = MOAT;
2093 } else if (IS_DIGGABLEWALL(room->typ)) {
2094 room->typ = CORR;
2095 } else {
2096 room->typ = DOOR;
2097 room->doormask = D_NODOOR;
2099 digdepth -= 2;
2100 } else if (IS_TREE(room->typ)) {
2101 room->typ = ROOM;
2102 digdepth -= 2;
2103 } else if (IS_WATERTUNNEL(room->typ)) {
2104 room->typ = MOAT;
2105 digdepth -= 2;
2106 } else { /* IS_ROCK but not IS_WALL or SDOOR */
2107 room->typ = CORR;
2108 digdepth--;
2110 unblock_point(zx,zy); /* vision */
2111 if (!(levl[zx][zy].wall_info & W_HARDGROWTH)) levl[zx][zy].wall_info |= W_EASYGROWTH;
2113 zx += u.dx;
2114 zy += u.dy;
2115 } /* while */
2116 tmp_at(DISP_END,0); /* closing call */
2117 if (shopdoor || shopwall)
2118 pay_for_damage(shopdoor ? "destroy" : "dig into", FALSE);
2119 return;
2122 /* move objects from fobj/nexthere lists to buriedobjlist, keeping position */
2123 /* information */
2124 struct obj *
2125 bury_an_obj(otmp)
2126 struct obj *otmp;
2128 struct obj *otmp2;
2129 boolean under_ice;
2131 #ifdef DEBUG
2132 pline("bury_an_obj: %s", xname(otmp));
2133 #endif
2134 if (otmp == uball)
2135 unpunish();
2136 /* after unpunish(), or might get deallocated chain */
2137 otmp2 = otmp->nexthere;
2139 * obj_resists(,0,0) prevents Rider corpses from being buried.
2140 * It also prevents The Amulet and invocation tools from being
2141 * buried. Since they can't be confined to bags and statues,
2142 * it makes sense that they can't be buried either, even though
2143 * the real reason there (direct accessibility when carried) is
2144 * completely different.
2146 if (otmp == uchain || obj_resists(otmp, 0, 0))
2147 return(otmp2);
2149 if (otmp->otyp == LEATHER_LEASH && otmp->leashmon != 0)
2150 o_unleash(otmp);
2152 if (otmp->otyp == INKA_LEASH && otmp->leashmon != 0)
2153 o_unleash(otmp);
2155 if (otmp->otyp == ADAMANT_LEASH && otmp->leashmon != 0)
2156 o_unleash(otmp);
2158 if (otmp == usaddle)
2159 dismount_steed(DISMOUNT_GENERIC);
2161 if (otmp->lamplit && otmp->otyp != POT_OIL)
2162 end_burn(otmp, TRUE);
2164 obj_extract_self(otmp);
2166 under_ice = is_ice(otmp->ox, otmp->oy);
2167 if (otmp->otyp == ROCK && !under_ice) {
2168 /* merges into burying material */
2169 obfree(otmp, (struct obj *)0);
2170 return(otmp2);
2173 * Start a rot on organic material. Not corpses -- they
2174 * are already handled.
2176 if (otmp->otyp == CORPSE) {
2177 ; /* should cancel timer if under_ice */
2178 } else if ((under_ice ? otmp->oclass == POTION_CLASS : is_organic(otmp))
2179 && !obj_resists(otmp, 5, 95)) {
2180 (void) start_timer((under_ice ? 0L : 250L) + (long)rnd(250),
2181 TIMER_OBJECT, ROT_ORGANIC, (void *)otmp);
2183 add_to_buried(otmp);
2184 return(otmp2);
2187 void
2188 bury_objs(x, y)
2189 int x, y;
2191 struct obj *otmp, *otmp2;
2193 #ifdef DEBUG
2194 if(level.objects[x][y] != (struct obj *)0)
2195 pline("bury_objs: at %d, %d", x, y);
2196 #endif
2197 for (otmp = level.objects[x][y]; otmp; otmp = otmp2)
2198 otmp2 = bury_an_obj(otmp);
2200 /* don't expect any engravings here, but just in case */
2201 del_engr_at(x, y);
2202 newsym(x, y);
2205 /* move objects from buriedobjlist to fobj/nexthere lists */
2206 void
2207 unearth_objs(x, y)
2208 int x, y;
2210 struct obj *otmp, *otmp2;
2212 #ifdef DEBUG
2213 pline("unearth_objs: at %d, %d", x, y);
2214 #endif
2215 for (otmp = level.buriedobjlist; otmp; otmp = otmp2) {
2216 otmp2 = otmp->nobj;
2217 if (otmp->ox == x && otmp->oy == y) {
2218 obj_extract_self(otmp);
2219 if (otmp->timed)
2220 (void) stop_timer(ROT_ORGANIC, (void *)otmp);
2221 place_object(otmp, x, y);
2222 stackobj(otmp);
2225 del_engr_at(x, y);
2226 newsym(x, y);
2230 * The organic material has rotted away while buried. As an expansion,
2231 * we could add add partial damage. A damage count is kept in the object
2232 * and every time we are called we increment the count and reschedule another
2233 * timeout. Eventually the object rots away.
2235 * This is used by buried objects other than corpses. When a container rots
2236 * away, any contents become newly buried objects.
2238 /* ARGSUSED */
2239 void
2240 rot_organic(arg, timeout)
2241 void * arg;
2242 long timeout; /* unused */
2244 #if defined(MAC_MPW)
2245 # pragma unused ( timeout )
2246 #endif
2247 struct obj *obj = (struct obj *) arg;
2249 /* nope, you do not get to retrieve the medical kit contents that way, you filthy exploit exploiter --Amy */
2250 if (obj && obj->otyp == MEDICAL_KIT && Has_contents(obj)) {
2251 delete_contents(obj);
2254 while (Has_contents(obj)) {
2255 /* We don't need to place contained object on the floor
2256 first, but we do need to update its map coordinates. */
2257 obj->cobj->ox = obj->ox, obj->cobj->oy = obj->oy;
2258 /* Everything which can be held in a container can also be
2259 buried, so bury_an_obj's use of obj_extract_self insures
2260 that Has_contents(obj) will eventually become false. */
2261 (void)bury_an_obj(obj->cobj);
2263 obj_extract_self(obj);
2264 obfree(obj, (struct obj *) 0);
2268 * Called when a corpse has rotted completely away.
2270 void
2271 rot_corpse(arg, timeout)
2272 void * arg;
2273 long timeout; /* unused */
2275 xchar x = 0, y = 0;
2276 struct obj *obj = (struct obj *) arg;
2277 boolean on_floor = obj->where == OBJ_FLOOR,
2278 in_minvent = obj->where == OBJ_MINVENT,
2279 in_invent = obj->where == OBJ_INVENT;
2281 if (on_floor) {
2282 x = obj->ox;
2283 y = obj->oy;
2284 } else if (in_minvent) {
2285 /* WAC unwield if wielded */
2286 if (MON_WEP(obj->ocarry) && MON_WEP(obj->ocarry) == obj) {
2287 obj->owornmask &= ~W_WEP;
2288 MON_NOWEP(obj->ocarry);
2290 } else if (in_invent) {
2291 if (flags.verbose) {
2292 char *cname = corpse_xname(obj, FALSE);
2293 Your("%s%s %s away%c",
2294 obj == uwep ? "wielded " : nul, cname,
2295 otense(obj, "rot"), obj == uwep ? '!' : '.');
2297 if (obj == uwep) {
2298 uwepgone(); /* now bare handed */
2299 stop_occupation();
2300 } else if (obj == uswapwep) {
2301 uswapwepgone();
2302 stop_occupation();
2303 } else if (obj == uquiver) {
2304 uqwepgone();
2305 stop_occupation();
2306 } else if (obj == uswapwep) {
2307 uswapwepgone();
2308 stop_occupation();
2309 } else if (obj == uquiver) {
2310 uqwepgone();
2311 stop_occupation();
2313 } else if (obj->where == OBJ_MINVENT && obj->owornmask) {
2314 if (obj == MON_WEP(obj->ocarry)) {
2315 setmnotwielded(obj->ocarry,obj);
2316 MON_NOWEP(obj->ocarry);
2319 rot_organic(arg, timeout);
2320 if (on_floor) newsym(x, y);
2321 else if (in_invent) update_inventory();
2324 #if 0
2325 void
2326 bury_monst(mtmp)
2327 struct monst *mtmp;
2329 #ifdef DEBUG
2330 pline("bury_monst: %s", mon_nam(mtmp));
2331 #endif
2332 if(canseemon(mtmp)) {
2333 if(is_flyer(mtmp->data) || mtmp->egotype_flying || is_floater(mtmp->data)) {
2334 pline_The("%s opens up, but %s is not swallowed!",
2335 surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
2336 return;
2337 } else
2338 pline_The("%s opens up and swallows %s!",
2339 surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
2342 mtmp->mburied = TRUE;
2343 wakeup(mtmp); /* at least give it a chance :-) */
2344 newsym(mtmp->mx, mtmp->my);
2347 void
2348 bury_you()
2350 #ifdef DEBUG
2351 pline("bury_you");
2352 #endif
2353 /* KMH, balance patch -- new intrinsic */
2354 if (!Levitation && !Flying) {
2355 if(u.uswallow)
2356 You_feel("a sensation like falling into a trap!");
2357 else
2358 pline_The("%s opens beneath you and you fall in!",
2359 surface(u.ux, u.uy));
2361 u.uburied = TRUE;
2362 if(!Strangled && !Breathless) Strangled = 11;
2363 under_ground(1);
2367 void
2368 unearth_you()
2370 #ifdef DEBUG
2371 pline("unearth_you");
2372 #endif
2373 u.uburied = FALSE;
2374 under_ground(0);
2375 if(!uamul || uamul->otyp != AMULET_OF_STRANGULATION)
2376 Strangled = 0;
2377 vision_recalc(0);
2380 void
2381 escape_tomb()
2383 #ifdef DEBUG
2384 pline("escape_tomb");
2385 #endif
2386 if ((Teleportation || can_teleport(youmonst.data)) &&
2387 (Teleport_control || rn2(3) < Luck+2)) {
2388 You("attempt a teleport spell.");
2389 (void) dotele_post(FALSE); /* calls unearth_you() */
2390 } else if(u.uburied) { /* still buried after 'port attempt */
2391 boolean good;
2393 if(amorphous(youmonst.data) || Passes_walls ||
2394 noncorporeal(youmonst.data) || unsolid(youmonst.data) || (uarmf && uarmf->oartifact == ART_STONEWALL_CHECKERBOARD_DIS) || (Race_if(PM_SCURRIER) && !Upolyd) ||
2395 (tunnels(youmonst.data) && !needspick(youmonst.data))) {
2397 You("%s up through the %s.",
2398 (tunnels(youmonst.data) && !needspick(youmonst.data)) ?
2399 "try to tunnel" : (uarmf && uarmf->oartifact == ART_STONEWALL_CHECKERBOARD_DIS) ? "try to tunnel" : (Race_if(PM_SCURRIER) && !Upolyd) ? "try to tunnel" : (amorphous(youmonst.data)) ?
2400 "ooze" : "phase", surface(u.ux, u.uy));
2402 if(tunnels(youmonst.data) && !needspick(youmonst.data))
2403 good = dighole(TRUE);
2404 else if (Race_if(PM_SCURRIER) && !Upolyd)
2405 good = dighole(TRUE);
2406 else if (uarmf && uarmf->oartifact == ART_STONEWALL_CHECKERBOARD_DIS)
2407 good = dighole(TRUE);
2408 else good = TRUE;
2409 if(good) unearth_you();
2414 void
2415 bury_obj(otmp)
2416 struct obj *otmp;
2419 #ifdef DEBUG
2420 pline("bury_obj");
2421 #endif
2422 if(cansee(otmp->ox, otmp->oy))
2423 pline_The("objects on the %s tumble into a hole!",
2424 surface(otmp->ox, otmp->oy));
2426 bury_objs(otmp->ox, otmp->oy);
2428 #endif
2430 #ifdef DEBUG
2432 wiz_debug_cmd() /* in this case, bury everything at your loc and around */
2434 int x, y;
2436 for (x = u.ux - 1; x <= u.ux + 1; x++)
2437 for (y = u.uy - 1; y <= u.uy + 1; y++)
2438 if (isok(x,y)) bury_objs(x,y);
2439 return 0;
2442 #endif /* DEBUG */
2443 #endif /* OVL3 */
2445 /*dig.c*/