diff -Naur nethack-3.4.0/src/apply.c nethack-hole/src/apply.c --- nethack-3.4.0/src/apply.c Wed Jul 17 13:15:52 2002 +++ nethack-hole/src/apply.c Tue Jul 23 16:03:47 2002 @@ -1988,7 +1988,25 @@ reset_trapset(); return; } - ttyp = (otmp->otyp == LAND_MINE) ? LANDMINE : BEAR_TRAP; + + + switch (otmp->otyp) { + case LAND_MINE: + ttyp = LANDMINE; + break; + case BEARTRAP: + ttyp = BEAR_TRAP; + break; + case PORTABLE_HOLE: + if (Can_dig_down(&u.uz)) { + ttyp = HOLE; + } + else { + ttyp = PIT; + } + break; + } + if (otmp == trapinfo.tobj && u.ux == trapinfo.tx && u.uy == trapinfo.ty) { You("resume setting %s %s.", @@ -1999,20 +2017,28 @@ } trapinfo.tobj = otmp; trapinfo.tx = u.ux, trapinfo.ty = u.uy; - tmp = ACURR(A_DEX); - trapinfo.time_needed = (tmp > 17) ? 2 : (tmp > 12) ? 3 : + if (otmp->otyp == PORTABLE_HOLE) { + trapinfo.time_needed = 1; + set_trap(); + if (*u.ushops && ttyp == HOLE) shopdig(0); + } + else { + tmp = ACURR(A_DEX); + trapinfo.time_needed = (tmp > 17) ? 2 : (tmp > 12) ? 3 : (tmp > 7) ? 4 : 5; - if (Blind) trapinfo.time_needed *= 2; - tmp = ACURR(A_STR); - if (ttyp == BEAR_TRAP && tmp < 18) + + if (Blind) trapinfo.time_needed *= 2; + tmp = ACURR(A_STR); + if (ttyp == BEAR_TRAP && tmp < 18) trapinfo.time_needed += (tmp > 12) ? 1 : (tmp > 7) ? 2 : 4; - /*[fumbling and/or confusion and/or cursed object check(s) - should be incorporated here instead of in set_trap]*/ + /*[fumbling and/or confusion and/or cursed object check(s) + should be incorporated here instead of in set_trap]*/ - You("begin setting %s %s.", - shk_your(buf, otmp), - defsyms[trap_to_defsym(what_trap(ttyp))].explanation); - set_occupation(set_trap, occutext, 0); + You("begin setting %s %s.", + shk_your(buf, otmp), + defsyms[trap_to_defsym(what_trap(ttyp))].explanation); + set_occupation(set_trap, occutext, 0); + } return; } @@ -2033,7 +2059,18 @@ if (--trapinfo.time_needed > 0) return 1; /* still busy */ - ttyp = (otmp->otyp == LAND_MINE) ? LANDMINE : BEAR_TRAP; + switch (otmp->otyp) { + case LAND_MINE: + ttyp = LANDMINE; + break; + case BEARTRAP: + ttyp = BEAR_TRAP; + break; + case PORTABLE_HOLE: + ttyp = HOLE; + break; + } + ttmp = maketrap(u.ux, u.uy, ttyp); if (ttmp) { ttmp->tseen = 1; @@ -2811,6 +2848,7 @@ break; case LAND_MINE: case BEARTRAP: + case PORTABLE_HOLE: use_trap(obj); break; case FLINT: diff -Naur nethack-3.4.0/src/do.c nethack-hole/src/do.c --- nethack-3.4.0/src/do.c Wed Jul 17 13:15:52 2002 +++ nethack-hole/src/do.c Mon Jul 22 19:20:42 2002 @@ -767,9 +767,12 @@ return(0); } - if (trap) + if (trap) { You("%s %s.", locomotion(youmonst.data, "jump"), - trap->ttyp == HOLE ? "down the hole" : "through the trap door"); + trap->ttyp == HOLE ? + "down the hole" : "through the trap door"); + if (*u.ushops) shopdig(1); + } if (trap && Is_stronghold(&u.uz)) { goto_hell(TRUE, TRUE); diff -Naur nethack-3.4.0/src/objects.c nethack-hole/src/objects.c --- nethack-3.4.0/src/objects.c Wed Jul 17 13:15:52 2002 +++ nethack-hole/src/objects.c Mon Jul 22 19:20:42 2002 @@ -625,6 +625,8 @@ /* traps */ TOOL("land mine",(char *)0, 1, 0, 0, 0, 0,300, 180, IRON, CLR_RED), TOOL("beartrap", (char *)0, 1, 0, 0, 0, 0,200, 60, IRON, HI_METAL), +TOOL("portable hole", (char *)0, + 1, 0, 0, 0, 0, 20, 60, PLASTIC, CLR_BLACK), /* instruments */ TOOL("tin whistle", "whistle", 0, 0, 0, 0, 100, 3, 10, METAL, HI_METAL), TOOL("magic whistle", "whistle",0, 0, 1, 0, 30, 3, 10, METAL, HI_METAL), diff -Naur nethack-3.4.0/src/pickup.c nethack-hole/src/pickup.c --- nethack-3.4.0/src/pickup.c Wed Jul 17 13:15:52 2002 +++ nethack-hole/src/pickup.c Wed Jul 24 13:06:25 2002 @@ -1642,6 +1642,10 @@ obj->spe <= 0) return FALSE; + if (obj->otyp == PORTABLE_HOLE) { + return TRUE; + } + /* odds: 1/1, 2/2, 3/4, 4/8, 5/16, 6/32, 7/64, 8/128, 9/128, 10/128,... */ if ((Is_mbag(obj) || obj->otyp == WAN_CANCELLATION) && (rn2(1 << (depthin > 7 ? 7 : depthin)) <= depthin)) @@ -1799,6 +1803,83 @@ (void) add_to_container(current_container, obj); current_container->owt = weight(current_container); } + + if (obj->otyp == PORTABLE_HOLE) { + struct obj *otmp, *onext; + int pass; + + pline("There is a hole in %s!", yname(current_container)); + + /* MRKR: Two passes, so the hole you put in falls out last */ + /* rather than first. */ + + for (pass = 1; pass <= 2; pass++) { + for (otmp = current_container->cobj; otmp; otmp = onext) { + onext = otmp->nobj; + + /* + * Objects have a 50% chance of falling out. + * Except the hole itself, which is guarenteed to + * fall out, on the second pass, after everything else. + */ + + if (pass == 1 && (otmp->otyp == PORTABLE_HOLE || rn2(2))) + continue; + if (pass == 2 && otmp->otyp != PORTABLE_HOLE) + continue; + + pline("%s %s out.", Doname2(otmp), otense(otmp, "fall")); + obj_extract_self(otmp); + + if (Icebox && otmp->otyp != OIL_LAMP + && otmp->otyp != BRASS_LANTERN + && !Is_candle(otmp)) { + otmp->age = monstermoves - otmp->age; /* actual age */ + if (otmp->otyp == CORPSE) + start_corpse_timeout(otmp); + } + + if (carried(current_container)) { + if (u.uswallow || !ship_object(otmp, u.ux, u.uy, FALSE)) + dropy(otmp); + } + else { + /* Code duplicated from dropy() with simplifications: */ + /* - No selling of dropped objects. */ + /* - No need to worry if otmp == uball */ + /* (You can't put uball in a container.) */ + + xchar x = current_container->ox; + xchar y = current_container->oy; + + if (!u.uswallow && + (ship_object(otmp, x, y, costly_spot(x,y))) + || flooreffects(otmp, x, y, "drop")) continue; + + if(u.uswallow) { + boolean could_petrify; + could_petrify = otmp->otyp == CORPSE && + touch_petrifies(&mons[otmp->corpsenm]); + (void) mpickobj(u.ustuck,otmp); + if (could_petrify && is_animal(u.ustuck->data)) { + minstapetrify(u.ustuck, TRUE); + /* Don't leave a cockatrice corpse */ + /* available in a statue */ + if (!u.uswallow) delobj(otmp); + } + } else { + place_object(otmp, x, y); + stackobj(otmp); + if(Blind && Levitation) + map_object(otmp, 0); + newsym(x, y); /* remap location */ + } + } + } + } + current_container->owt = weight(current_container); + } + if (is_gold) bot(); /* update gold piece count immediately */ return(current_container ? 1 : -1); diff -Naur nethack-3.4.0/src/trap.c nethack-hole/src/trap.c --- nethack-3.4.0/src/trap.c Wed Jul 17 13:15:52 2002 +++ nethack-hole/src/trap.c Wed Jul 24 13:14:45 2002 @@ -10,11 +10,12 @@ STATIC_DCL void NDECL(domagictrap); STATIC_DCL boolean FDECL(emergency_disrobe,(boolean *)); STATIC_DCL int FDECL(untrap_prob, (struct trap *ttmp)); -STATIC_DCL void FDECL(cnv_trap_obj, (int, int, struct trap *)); +STATIC_DCL void FDECL(cnv_trap_obj, (int, int, struct trap *, boolean)); STATIC_DCL void FDECL(move_into_trap, (struct trap *)); STATIC_DCL int FDECL(try_disarm, (struct trap *,BOOLEAN_P)); STATIC_DCL void FDECL(reward_untrap, (struct trap *, struct monst *)); STATIC_DCL int FDECL(disarm_holdingtrap, (struct trap *)); +STATIC_DCL int FDECL(disarm_hole, (struct trap *)); STATIC_DCL int FDECL(disarm_landmine, (struct trap *)); STATIC_DCL int FDECL(disarm_squeaky_board, (struct trap *)); STATIC_DCL int FDECL(disarm_shooting_trap, (struct trap *, int)); @@ -2714,10 +2715,11 @@ /* Replace trap with object(s). Helge Hafting */ STATIC_OVL void -cnv_trap_obj(otyp, cnt, ttmp) +cnv_trap_obj(otyp, cnt, ttmp, toinv) int otyp; int cnt; struct trap *ttmp; +boolean toinv; { struct obj *otmp = mksobj(otyp, TRUE, FALSE); otmp->quan=cnt; @@ -2725,12 +2727,20 @@ /* Only dart traps are capable of being poisonous */ if (otyp != DART) otmp->opoisoned = 0; - place_object(otmp, ttmp->tx, ttmp->ty); - /* Sell your own traps only... */ - if (ttmp->madeby_u) sellobj(otmp, ttmp->tx, ttmp->ty); - stackobj(otmp); - newsym(ttmp->tx, ttmp->ty); + + /* delete the trap first, in case we drop otmp */ deltrap(ttmp); + if (toinv) { + hold_another_object(otmp, "You drop %s!", + doname(otmp), (const char *)0); + } + else { + place_object(otmp, ttmp->tx, ttmp->ty); + /* Sell your own traps only... */ + if (ttmp->madeby_u) sellobj(otmp, ttmp->tx, ttmp->ty); + stackobj(otmp); + newsym(ttmp->tx, ttmp->ty); + } } /* while attempting to disarm an adjacent trap, we've fallen into it */ @@ -2884,7 +2894,7 @@ } else { if (ttmp->ttyp == BEAR_TRAP) { You("disarm %s bear trap.", the_your[ttmp->madeby_u]); - cnv_trap_obj(BEARTRAP, 1, ttmp); + cnv_trap_obj(BEARTRAP, 1, ttmp, 0); } else /* if (ttmp->ttyp == WEB) */ { You("succeed in removing %s web.", the_your[ttmp->madeby_u]); deltrap(ttmp); @@ -2895,6 +2905,18 @@ } STATIC_OVL int +disarm_hole(ttmp) /* Malcolm Ryan, from idea by Jerome Plut */ +struct trap *ttmp; +{ + int fails = try_disarm(ttmp, FALSE); + + if (fails < 2) return fails; + You("peel %s hole off the floor.", the_your[ttmp->madeby_u]); + cnv_trap_obj(PORTABLE_HOLE, 1, ttmp, 1); + return 1; +} + +STATIC_OVL int disarm_landmine(ttmp) /* Helge Hafting */ struct trap *ttmp; { @@ -2902,7 +2924,7 @@ if (fails < 2) return fails; You("disarm %s land mine.", the_your[ttmp->madeby_u]); - cnv_trap_obj(LAND_MINE, 1, ttmp); + cnv_trap_obj(LAND_MINE, 1, ttmp, 0); return 1; } @@ -2954,7 +2976,7 @@ if (fails < 2) return fails; You("disarm %s trap.", the_your[ttmp->madeby_u]); - cnv_trap_obj(otyp, 50-rnl(50), ttmp); + cnv_trap_obj(otyp, 50-rnl(50), ttmp, 0); return 1; } @@ -3119,6 +3141,14 @@ return 0; } return help_monster_out(mtmp, ttmp); + case HOLE: + /* MRKR: Only makes sense while tripping... */ + /* or if you are Wily Coyote. */ + if ((Hallucination || u.umonnum == PM_COYOTE) + && !In_sokoban(&u.uz)) { + return disarm_hole(ttmp); + } + /* fall through */ default: You("cannot disable %s trap.", (u.dx || u.dy) ? "that" : "this"); return 0;