E boolean FDECL(canletgo, (struct obj *,const char *));
E void FDECL(dropx, (struct obj *));
E void FDECL(dropy, (struct obj *));
+E void FDECL(dropz, (struct obj *,BOOLEAN_P));
E void FDECL(obj_no_longer_held, (struct obj *));
E int NDECL(doddrop);
E int NDECL(dodown);
/* ### dokick.c ### */
E boolean FDECL(ghitm, (struct monst *,struct obj *));
-E void FDECL(container_impact_dmg, (struct obj *));
+E void FDECL(container_impact_dmg, (struct obj *,XCHAR_P,XCHAR_P));
E int NDECL(dokick);
E boolean FDECL(ship_object, (struct obj *,XCHAR_P,XCHAR_P,BOOLEAN_P));
E void FDECL(obj_delivery, (BOOLEAN_P));
return(1);
}
-/* Called in several places - may produce output */
-/* eg ship_object() and dropy() -> sellobj() both produce output */
+/* dropx - take dropped item out of inventory;
+ called in several places - may produce output
+ (eg ship_object() and dropy() -> sellobj() both produce output) */
void
dropx(obj)
register struct obj *obj;
dropy(obj);
}
+/* dropy - put dropped object at its destination; called from lots of places */
void
dropy(obj)
-register struct obj *obj;
+struct obj *obj;
+{
+ dropz(obj, FALSE);
+}
+
+/* dropz - really put dropped object at its destination... */
+void
+dropz(obj, with_impact)
+struct obj *obj;
+boolean with_impact;
{
if (obj == uwep) setuwep((struct obj *)0);
if (obj == uquiver) setuqwep((struct obj *)0);
}
} else {
place_object(obj, u.ux, u.uy);
+ if (with_impact)
+ container_impact_dmg(obj, u.ux, u.uy);
if (obj == uball)
drop_ball(u.ux,u.uy);
else if (level.flags.has_shop)
/* container is kicked, dropped, thrown or otherwise impacted by player.
* Assumes container is on floor. Checks contents for possible damage. */
void
-container_impact_dmg(obj)
+container_impact_dmg(obj, x, y)
struct obj *obj;
+xchar x, y; /* coordinates where object was before the impact, not after */
{
struct monst *shkp;
struct obj *otmp, *otmp2;
long loss = 0L;
- boolean costly, insider;
- xchar x = obj->ox, y = obj->oy;
+ boolean costly, insider, frominv;
/* only consider normal containers */
- if (!Is_container(obj) || Is_mbag(obj)) return;
+ if (!Is_container(obj) || !Has_contents(obj) || Is_mbag(obj)) return;
costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) &&
costly_spot(x, y));
insider = (*u.ushops && inside_shop(u.ux, u.uy) &&
*in_rooms(x, y, SHOPBASE) == *u.ushops);
+ /* if dropped or thrown, shop ownership flags are set on this obj */
+ frominv = (obj != kickedobj);
for (otmp = obj->cobj; otmp; otmp = otmp2) {
const char *result = (char *)0;
if (otmp->otyp == EGG && otmp->spe && otmp->corpsenm >= LOW_PM)
change_luck(-1);
You_hear("a muffled %s.", result);
- if (costly)
+ if (costly) {
+ if (frominv && !otmp->unpaid) otmp->no_charge = 1;
loss += stolen_value(otmp, x, y,
(boolean)shkp->mpeaceful, TRUE);
- if (otmp->quan > 1L)
+ }
+ if (otmp->quan > 1L) {
useup(otmp);
- else {
+ } else {
obj_extract_self(otmp);
obfree(otmp, (struct obj *) 0);
}
+ /* contents of this container are no longer known */
+ obj->cknown = 0;
}
}
if (costly && loss) {
boolean otrp = kickedobj->otrapped;
if (range < 2) pline("THUD!");
- container_impact_dmg(kickedobj);
+ container_impact_dmg(kickedobj, x, y);
if (kickedobj->olocked) {
if (!rn2(5) || (martial() && !rn2(2))) {
You("break open the lock!");
if (hero_breaks(obj, u.ux, u.uy, TRUE)) return;
if (ship_object(obj, u.ux, u.uy, FALSE)) return;
- dropy(obj);
- if (!u.uswallow) container_impact_dmg(obj);
+ dropz(obj, TRUE);
}
/*
}
thrownobj = (struct obj*)0;
place_object(obj, bhitpos.x, bhitpos.y);
+ /* container contents might break;
+ do so before turning ownership of thrownobj over to shk
+ (container_impact_dmg handles item already owned by shop) */
+ if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ))
+ /* <x,y> is spot where you initiated throw, not bhitpos */
+ container_impact_dmg(obj, u.ux, u.uy);
+ /* charge for items thrown out of shop;
+ shk takes possession for items thrown into one */
if ((*u.ushops || obj->unpaid) && obj != uball)
check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE);
newsym(bhitpos.x,bhitpos.y);
if (obj_sheds_light(obj))
vision_full_recalc = 1;
- if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ))
- container_impact_dmg(obj);
}
}