passive fire effects can damage attackers weapons
wielded bow shouldn't affect outcome of kicked arrows
ranged polearm hit can divide puddings and can use confuse monster effect
+charge for kicked shop-owned food if it gets used up taming a monster
+give better feedback when thrown shop-owned food gets used up taming a monster
Platform- and/or Interface-Specific Fixes
-/* SCCS Id: @(#)dogmove.c 3.5 2006/08/16 */
+/* SCCS Id: @(#)dogmove.c 3.5 2007/03/26 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
int
dog_eat(mtmp, obj, x, y, devour)
register struct monst *mtmp;
-register struct obj * obj;
+register struct obj *obj; /* if unpaid, then thrown or kicked by hero */
int x, y;
boolean devour;
{
register struct edog *edog = EDOG(mtmp);
- boolean poly = FALSE, grow = FALSE, heal = FALSE;
+ boolean poly = FALSE, grow = FALSE, heal = FALSE, deadmimic;
int nutrit;
- boolean deadmimic = FALSE;
+ long oprice;
+ char objnambuf[BUFSZ];
+ objnambuf[0] = '\0';
if(edog->hungrytime < monstermoves)
edog->hungrytime = monstermoves;
nutrit = dog_nutrition(mtmp, obj);
newsym(x, y);
newsym(mtmp->mx, mtmp->my);
}
+
+ /* food items are eaten one at a time; entire stack for other stuff */
+ if (obj->quan > 1L && obj->oclass == FOOD_CLASS)
+ obj = splitobj(obj, 1L);
+ if (obj->unpaid) iflags.suppress_price++;
if (is_pool(x, y) && !Underwater) {
/* Don't print obj */
/* TODO: Reveal presence of sea monster (especially sharks) */
sight locations should not. */
if (cansee(x, y) || cansee(mtmp->mx, mtmp->my))
pline("%s %s %s.", mon_visible(mtmp) ? noit_Monnam(mtmp) : "It",
- devour ? "devours" : "eats",
- (obj->oclass == FOOD_CLASS) ?
- singular(obj, doname) : doname(obj));
+ devour ? "devours" : "eats", doname(obj));
+ if (obj->unpaid) {
+ Strcpy(objnambuf, xname(obj));
+ iflags.suppress_price--;
+ }
/* It's a reward if it's DOGFOOD and the player dropped/threw it. */
/* We know the player had it if invlet is set -dlc */
if(dogfood(mtmp,obj) == DOGFOOD && obj->invlet)
#endif
if (mtmp->data == &mons[PM_RUST_MONSTER] && obj->oerodeproof) {
/* The object's rustproofing is gone now */
+ if (obj->unpaid) costly_alteration(obj, COST_DEGRD);
obj->oerodeproof = 0;
mtmp->mstun = 1;
if (canseemon(mtmp) && flags.verbose) {
}
} else if (obj == uball) {
unpunish();
- delobj(obj);
- } else if (obj == uchain)
+ delobj(obj); /* we assume this can't be unpaid */
+ } else if (obj == uchain) {
unpunish();
- else if (obj->quan > 1L && obj->oclass == FOOD_CLASS) {
- obj->quan--;
- obj->owt = weight(obj);
- } else
+ } else {
+ if (obj->unpaid) {
+ /* edible item owned by shop has been thrown or kicked
+ by hero and caught by tame or food-tameable monst */
+ oprice = unpaid_cost(obj, TRUE);
+ pline("That %s will cost you %ld %s.",
+ objnambuf, oprice, currency(oprice));
+ /* delobj->obfree will handle actual shop billing update */
+ }
delobj(obj);
+ }
if (poly) {
(void) newcham(mtmp, (struct permonst *)0, FALSE,
xchar x, y;
{
int range;
- register struct monst *mon, *shkp;
+ struct monst *mon, *shkp = 0;
struct trap *trap;
char bhitroom;
boolean costly, isgold, slide = FALSE;
if(!ZAP_POS(levl[x+u.dx][y+u.dy].typ) || closed_door(x+u.dx, y+u.dy))
range = 1;
- costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) &&
- costly_spot(x, y));
+ costly = (!(kickobj->no_charge && !Has_contents(kickobj)) &&
+ (shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0 &&
+ costly_spot(x, y));
isgold = (kickobj->oclass == COIN_CLASS);
if (IS_ROCK(levl[x][y].typ) || closed_door(x, y)) {
pline("Whee! %s %s across the %s.", Doname2(kickobj),
otense(kickobj, "slide"), surface(x,y));
+ if (costly && !isgold) addtobill(kickobj, FALSE, FALSE, TRUE);
obj_extract_self(kickobj);
(void) snuff_candle(kickobj);
newsym(x, y);
return(1);
}
- /* the object might have fallen down a hole */
- if (kickobj->where == OBJ_MIGRATING) {
- if (costly) {
- if(isgold)
- costly_gold(x, y, kickobj->quan);
- else (void)stolen_value(kickobj, x, y,
- (boolean)shkp->mpeaceful, FALSE);
- }
- return 1;
- }
+ /* the object might have fallen down a hole;
+ ship_object() will have taken care of shop billing */
+ if (kickobj->where == OBJ_MIGRATING) return 1;
bhitroom = *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE);
if (costly && (!costly_spot(bhitpos.x, bhitpos.y) ||
}
if(flooreffects(kickobj,bhitpos.x,bhitpos.y,"fall")) return(1);
+ if (kickobj->unpaid) subfrombill(kickobj, shkp);
place_object(kickobj, bhitpos.x, bhitpos.y);
stackobj(kickobj);
newsym(kickobj->ox, kickobj->oy);
return(1);
}
+/* cause of death if kicking kills kicker */
STATIC_OVL char *
kickstr(buf)
char *buf;
otmp->no_charge = 0;
}
- if (otmp == uwep) setuwep((struct obj *)0);
- if (otmp == uquiver) setuqwep((struct obj *)0);
- if (otmp == uswapwep) setuswapwep((struct obj *)0);
+ if (otmp->owornmask) remove_worn_item(otmp, TRUE);
/* some things break rather than ship */
if (breaktest(otmp)) {
if (cansee(bhitpos.x, bhitpos.y))
pline("%s snatches up %s.",
Monnam(mon), the(xname(obj)));
- if(*u.ushops)
+ if (*u.ushops || obj->unpaid)
check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE);
(void) mpickobj(mon, obj); /* may merge and free obj */
thrownobj = (struct obj*)0;
}
thrownobj = (struct obj*)0;
place_object(obj, bhitpos.x, bhitpos.y);
- if(*u.ushops && obj != uball)
+ if ((*u.ushops || obj->unpaid) && obj != uball)
check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE);
stackobj(obj);
(void) encumber_msg();
} else {
/* angry leader caught it and isn't returning it */
+ if (*u.ushops || obj->unpaid) /* not very likely... */
+ check_shop_obj(obj, mon->mx, mon->my, FALSE);
(void) mpickobj(mon, obj);
}
return 1; /* caller doesn't need to place it */
broken = 0;
if (broken) {
- if (*u.ushops)
+ if (*u.ushops || obj->unpaid)
check_shop_obj(obj, bhitpos.x,bhitpos.y, TRUE);
obfree(obj, (struct obj *)0);
return 1;
}
}
Strcat(buf,acceptgift);
- if(*u.ushops) check_shop_obj(obj, mon->mx, mon->my, TRUE);
+ if (*u.ushops || obj->unpaid)
+ check_shop_obj(obj, mon->mx, mon->my, TRUE);
(void) mpickobj(mon, obj); /* may merge and free obj */
ret = 1;
}
if (hero_caused) {
- if (from_invent) {
- if (*u.ushops)
- check_shop_obj(obj, x, y, TRUE);
+ if (from_invent || obj->unpaid) {
+ if (*u.ushops || obj->unpaid)
+ check_shop_obj(obj, x, y, TRUE);
} else if (!obj->no_charge && costly_spot(x, y)) {
/* it is assumed that the obj is a floor-object */
char *o_shop = in_rooms(x, y, SHOPBASE);