Scatter bag of holding contents instead of deleting them
Losing all of your items in one go is really frustrating. If you blow up your bag of holding, make the contents scatter around instead of outright deleting them. This will destroy fragile objects.
This commit is contained in:
@@ -128,6 +128,7 @@ revival via undead turning of corpse carried by hero said "your <mon> corpse
|
|||||||
comes alive" even when revived monster was undead
|
comes alive" even when revived monster was undead
|
||||||
prevent searching or waiting next to a hostile monster - override with 'm'
|
prevent searching or waiting next to a hostile monster - override with 'm'
|
||||||
allow random mimics to show up mimicing more furniture than just stairs
|
allow random mimics to show up mimicing more furniture than just stairs
|
||||||
|
scatter exploding bag of holding contents instead of outright deleting them
|
||||||
|
|
||||||
|
|
||||||
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
||||||
|
|||||||
47
src/pickup.c
47
src/pickup.c
@@ -32,11 +32,12 @@ static int FDECL(lift_object, (struct obj *, struct obj *, long *,
|
|||||||
BOOLEAN_P));
|
BOOLEAN_P));
|
||||||
static boolean FDECL(mbag_explodes, (struct obj *, int));
|
static boolean FDECL(mbag_explodes, (struct obj *, int));
|
||||||
static boolean NDECL(is_boh_item_gone);
|
static boolean NDECL(is_boh_item_gone);
|
||||||
static long FDECL(boh_loss, (struct obj *container, int));
|
static void FDECL(do_boh_explosion, (struct obj *, BOOLEAN_P));
|
||||||
|
static long FDECL(boh_loss, (struct obj *, int));
|
||||||
static int FDECL(in_container, (struct obj *));
|
static int FDECL(in_container, (struct obj *));
|
||||||
static int FDECL(out_container, (struct obj *));
|
static int FDECL(out_container, (struct obj *));
|
||||||
static void FDECL(removed_from_icebox, (struct obj *));
|
static void FDECL(removed_from_icebox, (struct obj *));
|
||||||
static long FDECL(mbag_item_gone, (int, struct obj *));
|
static long FDECL(mbag_item_gone, (int, struct obj *, BOOLEAN_P));
|
||||||
static void FDECL(explain_container_prompt, (BOOLEAN_P));
|
static void FDECL(explain_container_prompt, (BOOLEAN_P));
|
||||||
static int FDECL(traditional_loot, (BOOLEAN_P));
|
static int FDECL(traditional_loot, (BOOLEAN_P));
|
||||||
static int FDECL(menu_loot, (int, BOOLEAN_P));
|
static int FDECL(menu_loot, (int, BOOLEAN_P));
|
||||||
@@ -2219,6 +2220,28 @@ is_boh_item_gone()
|
|||||||
return (boolean) (!rn2(13));
|
return (boolean) (!rn2(13));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Scatter most of Bag of holding contents around.
|
||||||
|
Some items will be destroyed with the same chance as looting a cursed bag.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
do_boh_explosion(boh, on_floor)
|
||||||
|
struct obj *boh;
|
||||||
|
boolean on_floor;
|
||||||
|
{
|
||||||
|
struct obj *otmp, *nobj;
|
||||||
|
|
||||||
|
for (otmp = boh->cobj; otmp; otmp = nobj) {
|
||||||
|
nobj = otmp->nobj;
|
||||||
|
if (is_boh_item_gone()) {
|
||||||
|
obj_extract_self(otmp);
|
||||||
|
mbag_item_gone(!on_floor, otmp, TRUE);
|
||||||
|
} else {
|
||||||
|
otmp->ox = u.ux, otmp->oy = u.uy;
|
||||||
|
(void) scatter(u.ux, u.uy, 4, MAY_HIT | MAY_DESTROY, otmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static long
|
static long
|
||||||
boh_loss(container, held)
|
boh_loss(container, held)
|
||||||
struct obj *container;
|
struct obj *container;
|
||||||
@@ -2233,7 +2256,7 @@ int held;
|
|||||||
otmp = curr->nobj;
|
otmp = curr->nobj;
|
||||||
if (is_boh_item_gone()) {
|
if (is_boh_item_gone()) {
|
||||||
obj_extract_self(curr);
|
obj_extract_self(curr);
|
||||||
loss += mbag_item_gone(held, curr);
|
loss += mbag_item_gone(held, curr, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return loss;
|
return loss;
|
||||||
@@ -2365,7 +2388,8 @@ register struct obj *obj;
|
|||||||
so that useupf() doesn't double bill */
|
so that useupf() doesn't double bill */
|
||||||
g.current_container->no_charge = save_no_charge.no_charge;
|
g.current_container->no_charge = save_no_charge.no_charge;
|
||||||
}
|
}
|
||||||
delete_contents(g.current_container);
|
do_boh_explosion(g.current_container, floor_container);
|
||||||
|
|
||||||
if (!floor_container)
|
if (!floor_container)
|
||||||
useup(g.current_container);
|
useup(g.current_container);
|
||||||
else if (obj_here(g.current_container, u.ux, u.uy))
|
else if (obj_here(g.current_container, u.ux, u.uy))
|
||||||
@@ -2481,17 +2505,20 @@ struct obj *obj;
|
|||||||
|
|
||||||
/* an object inside a cursed bag of holding is being destroyed */
|
/* an object inside a cursed bag of holding is being destroyed */
|
||||||
static long
|
static long
|
||||||
mbag_item_gone(held, item)
|
mbag_item_gone(held, item, silent)
|
||||||
int held;
|
int held;
|
||||||
struct obj *item;
|
struct obj *item;
|
||||||
|
boolean silent;
|
||||||
{
|
{
|
||||||
struct monst *shkp;
|
struct monst *shkp;
|
||||||
long loss = 0L;
|
long loss = 0L;
|
||||||
|
|
||||||
if (item->dknown)
|
if (!silent) {
|
||||||
pline("%s %s vanished!", Doname2(item), otense(item, "have"));
|
if (item->dknown)
|
||||||
else
|
pline("%s %s vanished!", Doname2(item), otense(item, "have"));
|
||||||
You("%s %s disappear!", Blind ? "notice" : "see", doname(item));
|
else
|
||||||
|
You("%s %s disappear!", Blind ? "notice" : "see", doname(item));
|
||||||
|
}
|
||||||
|
|
||||||
if (*u.ushops && (shkp = shop_keeper(*u.ushops)) != 0) {
|
if (*u.ushops && (shkp = shop_keeper(*u.ushops)) != 0) {
|
||||||
if (held ? (boolean) item->unpaid : costly_spot(u.ux, u.uy))
|
if (held ? (boolean) item->unpaid : costly_spot(u.ux, u.uy))
|
||||||
@@ -3348,7 +3375,7 @@ struct obj *box; /* or bag */
|
|||||||
if (box->otyp == ICE_BOX) {
|
if (box->otyp == ICE_BOX) {
|
||||||
removed_from_icebox(otmp); /* resume rotting for corpse */
|
removed_from_icebox(otmp); /* resume rotting for corpse */
|
||||||
} else if (cursed_mbag && is_boh_item_gone()) {
|
} else if (cursed_mbag && is_boh_item_gone()) {
|
||||||
loss += mbag_item_gone(held, otmp);
|
loss += mbag_item_gone(held, otmp, FALSE);
|
||||||
/* abbreviated drop format is no longer appropriate */
|
/* abbreviated drop format is no longer appropriate */
|
||||||
terse = FALSE;
|
terse = FALSE;
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user