- Breaking wand of digging dug through rock which should be undiggable.
Checks assumed pits would never show up in solid rock.
- Breaking wand of digging near shop walls wouldn't anger the shopkeeper
Checks assumed pits would never show up in walls, also, added a special
case to pay_for_damage to handle the case where you're falling thru and
can't be asked to pay.
- Shop walls wouldn't be restored if there are pits in the way.
Checks assumed pits would never show up in walls.
- If there was a hole outside the shop, you could kick stuff out of the
door into the hole without shopkeeper noticing. Added the missing check.
adjust fruit name in potion juice messages if it has the form "foo of bar"
wielded camera passes harmlessly through shade
reading spellbooks while confused should allow tearing the book
+Breaking wand of digging dug through rock which should be undiggable.
+Breaking wand of digging near shop walls wouldn't anger the shopkeeper
+Shop walls wouldn't be restored if there were pits in the way.
+If there were a hole outside a shop, you could kick stuff out of the door
+ into the hole without the shopkeeper noticing.
Platform- and/or Interface-Specific Fixes
E void FDECL(after_shk_move, (struct monst *));
E boolean FDECL(is_fshk, (struct monst *));
E void FDECL(shopdig, (int));
-E void FDECL(pay_for_damage, (const char *));
+E void FDECL(pay_for_damage, (const char *,BOOLEAN_P));
E boolean FDECL(costly_spot, (XCHAR_P,XCHAR_P));
E struct obj *FDECL(shop_object, (XCHAR_P,XCHAR_P));
E void FDECL(price_quote, (struct obj *));
register struct monst *mon;
int dmg, damage;
boolean affects_objects;
+ boolean shop_damage = FALSE;
int expltype = EXPL_MAGICAL;
char confirm[QBUFSZ], the_wand[BUFSZ], buf[BUFSZ];
if (!isok(x,y)) continue;
if (obj->otyp == WAN_DIGGING) {
- if(dig_check(BY_OBJECT, FALSE, x, y))
+ if(dig_check(BY_OBJECT, FALSE, x, y)) {
+ if ((IS_WALL(levl[x][y].typ) || IS_DOOR(levl[x][y].typ)) &&
+ *in_rooms(x,y,SHOPBASE)) shop_damage = TRUE;
digactualhole(x, y, BY_OBJECT,
(rn2(obj->spe) < 3 || !Can_dig_down(&u.uz)) ?
PIT : HOLE);
+ }
continue;
} else if(obj->otyp == WAN_CREATE_MONSTER) {
/* u.ux,u.uy creates it near you--x,y might create it in rock */
}
}
+ /* Note: if player fell thru, this call is a no-op.
+ Damage is handled in digactualhole in that case */
+ if (shop_damage) pay_for_damage("dig into", FALSE);
+
if (obj->otyp == WAN_LIGHT)
litroom(TRUE, obj); /* only needs to be done once */
} else if (Is_waterlevel(&u.uz)) {
if(verbose) pline_The("water splashes and subsides.");
return(FALSE);
- } else if ((IS_WALL(levl[x][y].typ) &&
+ } else if ((IS_ROCK(levl[x][y].typ) && levl[x][y].typ != SDOOR &&
(levl[x][y].wall_info & W_NONDIGGABLE) != 0)
|| (ttmp &&
(ttmp->ttyp == MAGIC_PORTAL || !Can_dig_down(&u.uz)))) {
newsym(dpx, dpy);
if(digtxt && !digging.quiet) pline(digtxt); /* after newsym */
if(dmgtxt)
- pay_for_damage(dmgtxt);
+ pay_for_damage(dmgtxt, FALSE);
if(Is_earthlevel(&u.uz) && !rn2(3)) {
register struct monst *mtmp;
if(madeby_u) {
You("dig a pit in the %s.", surface_type);
- if (shopdoor) pay_for_damage("ruin");
+ if (shopdoor) pay_for_damage("ruin", FALSE);
} else if (!madeby_obj && canseemon(madeby))
pline("%s digs a pit in the %s.", Monnam(madeby), surface_type);
else if (cansee(x, y) && flags.verbose)
impact_drop((struct obj *)0, x, y, 0);
if (oldobjs != newobjs)
(void) pickup(1);
- if (shopdoor && madeby_u) pay_for_damage("ruin");
+ if (shopdoor && madeby_u) pay_for_damage("ruin", FALSE);
} else {
d_level newlevel;
if (*u.ushops && madeby_u)
shopdig(1); /* shk might snatch pack */
+ /* handle earlier damage, eg breaking wand of digging */
+ else if (!madeby_u) pay_for_damage("dig into", TRUE);
You("fall through...");
/* Earlier checks must ensure that the destination
spoteffects(FALSE);
}
} else {
- if (shopdoor && madeby_u) pay_for_damage("ruin");
+ if (shopdoor && madeby_u) pay_for_damage("ruin", FALSE);
if (newobjs)
impact_drop((struct obj *)0, x, y, 0);
if (mtmp) {
boolean nohole = !Can_dig_down(&u.uz);
if ((ttmp && (ttmp->ttyp == MAGIC_PORTAL || nohole)) ||
- (IS_WALL(lev->typ) && (lev->wall_info & W_NONDIGGABLE) != 0)) {
+ (IS_ROCK(lev->typ) && lev->typ != SDOOR &&
+ (lev->wall_info & W_NONDIGGABLE) != 0)) {
pline_The("%s here is too hard to dig in.", surface(u.ux,u.uy));
} else if (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) {
} /* while */
tmp_at(DISP_END,0); /* closing call */
if (shopdoor || shopwall)
- pay_for_damage(shopdoor ? "destroy" : "dig into");
+ pay_for_damage(shopdoor ? "destroy" : "dig into", FALSE);
return;
}
}
/* the object might have fallen down a hole */
- if (kickobj->where == OBJ_MIGRATING)
+ 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;
+ }
bhitroom = *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE);
if (costly && (!costly_spot(bhitpos.x, bhitpos.y) ||
unblock_point(x,y); /* vision */
if (shopdoor) {
add_damage(x, y, 400L);
- pay_for_damage("break");
+ pay_for_damage("break", FALSE);
}
if (in_town(x, y))
for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (shopdamage) {
pay_for_damage(adtyp == AD_FIRE ? "burn away" :
adtyp == AD_COLD ? "shatter" :
- adtyp == AD_DISN ? "disintegrate" : "destroy");
+ adtyp == AD_DISN ? "disintegrate" : "destroy",
+ FALSE);
}
/* explosions are noisy */
unblock_point(x, y); /* vision */
newsym(x, y);
if (digtxt) You(digtxt); /* after newsym */
- if (dmgtxt) pay_for_damage(dmgtxt);
+ if (dmgtxt) pay_for_damage(dmgtxt, FALSE);
(void) memset((genericptr_t)&digging, 0, sizeof digging);
return 0;
}
#endif /* KOPS */
void
-pay_for_damage(dmgstr)
+pay_for_damage(dmgstr, cant_mollify)
const char *dmgstr;
+boolean cant_mollify;
{
register struct monst *shkp = (struct monst *)0;
char shops_affected[5];
(void) mnearto(shkp, x, y, TRUE);
}
- if((um_dist(x, y, 1) && !uinshp) ||
+ if((um_dist(x, y, 1) && !uinshp) || cant_mollify ||
#ifndef GOLDOBJ
- (u.ugold + ESHK(shkp)->credit) < cost_of_damage
+ (u.ugold + ESHK(shkp)->credit) < cost_of_damage
#else
- (money_cnt(invent) + ESHK(shkp)->credit) < cost_of_damage
+ (money_cnt(invent) + ESHK(shkp)->credit) < cost_of_damage
#endif
|| !rn2(50)) {
if(um_dist(x, y, 1) && !uinshp) {
case TRAPDOOR:
lev = &levl[x][y];
if (*in_rooms(x, y, SHOPBASE) &&
- ((typ == HOLE || typ == TRAPDOOR) || IS_DOOR(lev->typ)))
+ ((typ == HOLE || typ == TRAPDOOR) ||
+ IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
add_damage(x, y, /* schedule repair */
- (IS_DOOR(lev->typ) && !flags.mon_moving) ? 200L : 0L);
+ ((IS_DOOR(lev->typ) || IS_WALL(lev->typ))
+ && !flags.mon_moving) ? 200L : 0L);
lev->doormask = 0; /* subsumes altarmask, icedpool... */
if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */
lev->typ = ROOM;
if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM) tmp_at(DISP_END, 0);
if(shopdoor)
- pay_for_damage("destroy");
+ pay_for_damage("destroy", FALSE);
return (struct monst *)0;
}
if (shopdamage)
pay_for_damage(abstype == ZT_FIRE ? "burn away" :
abstype == ZT_COLD ? "shatter" :
- abstype == ZT_DEATH ? "disintegrate" : "destroy");
+ abstype == ZT_DEATH ? "disintegrate" : "destroy", FALSE);
bhitpos = save_bhitpos;
}
#endif /*OVLB*/