diff -pruN slashem-0.0.7E7F1-official-release/include/extern.h slashem-0.0.7E7F1-bag_of_trick/include/extern.h --- slashem-0.0.7E7F1-official-release/include/extern.h 2005-07-02 09:24:44.000000000 +0200 +++ slashem-0.0.7E7F1-bag_of_trick/include/extern.h 2005-11-03 17:05:05.000000000 +0100 @@ -1025,7 +1025,7 @@ E void FDECL(mimic_hit_msg, (struct mons #ifdef GOLDOBJ E void FDECL(mkmonmoney, (struct monst *, long)); #endif -E void FDECL(bagotricks, (struct obj *)); +E int FDECL(bagotricks, (struct obj *)); E boolean FDECL(propagate, (int, BOOLEAN_P,BOOLEAN_P)); /* ### mapglyph.c ### */ diff -pruN slashem-0.0.7E7F1-official-release/src/apply.c slashem-0.0.7E7F1-bag_of_trick/src/apply.c --- slashem-0.0.7E7F1-official-release/src/apply.c 2005-07-02 09:24:44.000000000 +0200 +++ slashem-0.0.7E7F1-bag_of_trick/src/apply.c 2005-11-03 17:05:06.000000000 +0100 @@ -3454,7 +3454,7 @@ doapply() res = use_container(&obj, 1); break; case BAG_OF_TRICKS: - bagotricks(obj); + res = bagotricks(obj); break; case CAN_OF_GREASE: use_grease(obj); diff -pruN slashem-0.0.7E7F1-official-release/src/end.c slashem-0.0.7E7F1-bag_of_trick/src/end.c --- slashem-0.0.7E7F1-official-release/src/end.c 2005-07-02 09:24:44.000000000 +0200 +++ slashem-0.0.7E7F1-bag_of_trick/src/end.c 2005-11-03 17:05:06.000000000 +0100 @@ -981,8 +981,8 @@ boolean identified, all_containers; for (box = list; box; box = box->nobj) { if (Is_container(box) || box->otyp == STATUE) { - if (box->otyp == BAG_OF_TRICKS) { - continue; /* wrong type of container */ + if (box->otyp == BAG_OF_TRICKS && box->spe) { + continue; /* bag of tricks with charges can't contain anything */ } else if (box->cobj) { winid tmpwin = create_nhwindow(NHW_MENU); Sprintf(buf, "Contents of %s:", the(xname(box))); diff -pruN slashem-0.0.7E7F1-official-release/src/makemon.c slashem-0.0.7E7F1-bag_of_trick/src/makemon.c --- slashem-0.0.7E7F1-official-release/src/makemon.c 2005-07-02 09:24:44.000000000 +0200 +++ slashem-0.0.7E7F1-bag_of_trick/src/makemon.c 2005-11-03 17:05:06.000000000 +0100 @@ -2498,28 +2498,131 @@ assign_sym: mtmp->mappearance = appear; } -/* release a monster from a bag of tricks */ -void +/* Bag of Tricks now trickier ... nda 5/13/2003 */ +int bagotricks(bag) struct obj *bag; { if (!bag || bag->otyp != BAG_OF_TRICKS) { impossible("bad bag o' tricks"); } else if (bag->spe < 1) { - pline(nothing_happens); + return use_container(bag, 1); } else { - boolean gotone = FALSE; - int cnt = 1; + + boolean gotone = TRUE; + int cnt; + struct monst *mtmp; + struct obj *otmp; consume_obj_charge(bag, TRUE); - if (!rn2(23)) cnt += rn1(7, 1); - while (cnt-- > 0) { - if (makemon((struct permonst *)0, u.ux, u.uy, NO_MM_FLAGS)) - gotone = TRUE; + switch(rn2(20)) { + case 0: + case 1: + if(bag->recharged==0 && !bag->cursed) { + for(cnt=3;cnt>0 && (otmp = mkobj(RANDOM_CLASS,FALSE));cnt--) { + if(otmp->owt<100 && !objects[otmp->otyp].oc_big) + break; + obj_extract_self(otmp); + obfree(otmp, (struct obj *)0); + otmp = (struct obj*)0; + } + if(!otmp) { + pline_The("bag coughs nervously."); + break; + } + } else { + otmp = mksobj(IRON_CHAIN,FALSE,FALSE); + } + pline("%s spits %s out.", The(xname(bag)),something); + otmp = hold_another_object(otmp, "It slips away from you.", (char*)0, (char*)0); + break; + case 2: + pline_The("bag wriggles away from you!"); + dropx(bag); + break; + case 3: + nomul(-1*(rnd(4))); + if(Hallucination) { + You("start climbing into the bag."); + nomovemsg = "You give up your attempt to climb into the bag."; + } else { + pline("%s tries to pull you into the bag!",Something); + nomovemsg = "You manage to free yourself."; + } + break; + case 4: + if(Blind) + You_hear("a loud eructation."); + else + pline_The("bag belches out %s.", + Hallucination ? "the alphabet":"a noxious cloud"); + (void)create_gas_cloud(u.ux,u.uy,2,8); + break; + case 5: + if (Underwater) + pline_The("water around you vaporizes violently!"); + else { + pline_The("bag belches out a ball of flame!"); + burn_away_slime(); + } + explode(u.ux, u.uy, 11, rn2(4)+2,TOOL_CLASS, EXPL_FIERY); + break; + case 6: + pline_The("bag yells \"%s\".", Hallucination ? "!ooB":"Boo!"); + for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { + if (DEADMONSTER(mtmp)) continue; + if(cansee(mtmp->mx,mtmp->my)) { + if (! resist(mtmp, bag->oclass, 0, NOTELL)) + monflee(mtmp, 0, FALSE, FALSE); + } + } + if((ACURR(A_WIS)blessed) || bag->cursed) { + You("are startled into immobility."); + nomul(-1*rnd(3)); + nomovemsg = "You regain your composure."; + } + break; + case 7: + pline_The("bag develops a huge set of %s you!", + Hallucination ? "lips and kisses":"teeth and bites"); + cnt = rnd(10); + if (Half_physical_damage) cnt = (cnt+1) / 2; + losehp(cnt, Hallucination ? "amorous bag":"carnivorous bag", KILLED_BY_AN); + break; + case 8: + if(uwep || uswapwep) { + otmp = rn2(2) ? uwep : uswapwep; + if(!otmp) otmp = uwep ? uwep : uswapwep; + if(Blind) + pline("%s grabs %s away from you.", Something, yname(otmp)); + else + pline_The("bag sprouts a tongue and flicks %s %s.", + yname(otmp), + (Is_airlevel(&u.uz) || + Is_waterlevel(&u.uz) || + levl[u.ux][u.uy].typ < IRONBARS || + levl[u.ux][u.uy].typ >= ICE) ? + "away from you":"to the floor"); + dropx(otmp); + } else { + pline("%s licks your %s.", + Blind ? Something : "The bag sprouts a tongue and", + body_part(HAND)); + } + break; + default: + cnt = 1; + gotone = FALSE; + if (!rn2(23)) cnt += rn1(7, 1); + while (cnt-- > 0) { + if (makemon((struct permonst *)0, u.ux, u.uy, NO_MM_FLAGS)) + gotone = TRUE; + } } if (gotone) makeknown(BAG_OF_TRICKS); } + return 1; } #endif /* OVLB */ diff -pruN slashem-0.0.7E7F1-official-release/src/mkobj.c slashem-0.0.7E7F1-bag_of_trick/src/mkobj.c --- slashem-0.0.7E7F1-official-release/src/mkobj.c 2005-07-02 09:24:44.000000000 +0200 +++ slashem-0.0.7E7F1-bag_of_trick/src/mkobj.c 2005-11-03 17:12:57.000000000 +0100 @@ -596,7 +596,7 @@ boolean artif; break; case HORN_OF_PLENTY: case BAG_OF_TRICKS: - otmp->spe = rn1(20,10); + otmp->spe = rn1(30,15); break; case FIGURINE: { int tryct2 = 0; do diff -pruN slashem-0.0.7E7F1-official-release/src/pickup.c slashem-0.0.7E7F1-bag_of_trick/src/pickup.c --- slashem-0.0.7E7F1-official-release/src/pickup.c 2005-07-02 09:24:44.000000000 +0200 +++ slashem-0.0.7E7F1-bag_of_trick/src/pickup.c 2005-11-03 17:05:06.000000000 +0100 @@ -1564,13 +1564,14 @@ lootcont: pline("Hmmm, it seems to be locked."); continue; } - if (cobj->otyp == BAG_OF_TRICKS) { + if (cobj->otyp == BAG_OF_TRICKS && cobj->spe>0) { int tmp; You("carefully open the bag..."); - pline("It develops a huge set of teeth and bites you!"); + pline("It develops a huge set of %s you!", + Hallucination ? "lips and kisses":"teeth and bites"); tmp = rnd(10); if (Half_physical_damage) tmp = (tmp+1) / 2; - losehp(tmp, "carnivorous bag", KILLED_BY_AN); + losehp(tmp, Hallucination ? "amorous bag":"carnivorous bag", KILLED_BY_AN); makeknown(BAG_OF_TRICKS); timepassed = 1; continue; diff -pruN slashem-0.0.7E7F1-official-release/src/read.c slashem-0.0.7E7F1-bag_of_trick/src/read.c --- slashem-0.0.7E7F1-official-release/src/read.c 2005-07-02 09:24:44.000000000 +0200 +++ slashem-0.0.7E7F1-bag_of_trick/src/read.c 2005-11-03 17:20:57.000000000 +0100 @@ -579,8 +579,36 @@ int curse_bless; } else pline(nothing_happens); } break; - case HORN_OF_PLENTY: case BAG_OF_TRICKS: + /* if there are any objects inside the bag, devour them */ + if (!is_cursed) { + struct obj *curr, *otmp; + struct monst *shkp; + int lcnt = 0; + long loss = 0L; + + makeknown(BAG_OF_TRICKS); + for (curr = obj->cobj; curr; curr = otmp) { + otmp = curr->nobj; + obj_extract_self(curr); + lcnt++; + if (*u.ushops && (shkp = shop_keeper(*u.ushops)) != 0) { + if(curr->unpaid) + loss += stolen_value(curr, u.ux, u.uy, + (boolean)shkp->mpeaceful, TRUE, TRUE); + } + /* obfree() will free all contained objects */ + obfree(curr, (struct obj *) 0); + } + + if(lcnt) + You_hear("loud crunching sounds from inside %s.", yname(obj)); + if (lcnt && loss) + You("owe %ld %s for lost item%s.", + loss, currency(loss), lcnt > 1 ? "s" : ""); + } + /* fall through */ + case HORN_OF_PLENTY: case CAN_OF_GREASE: if (is_cursed) stripspe(obj); else if (is_blessed) {