| 159 | } |
| 160 | |
| 161 | void |
| 162 | breakchestlock(struct obj *box, boolean destroyit) |
| 163 | { |
| 164 | if (!destroyit) { /* bill for the box but not for its contents */ |
| 165 | struct obj *hide_contents = box->cobj; |
| 166 | |
| 167 | box->cobj = 0; |
| 168 | costly_alteration(box, COST_BRKLCK); |
| 169 | box->cobj = hide_contents; |
| 170 | box->olocked = 0; |
| 171 | box->obroken = 1; |
| 172 | box->lknown = 1; |
| 173 | } else { /* #force has destroyed this box (at <u.ux,u.uy>) */ |
| 174 | struct obj *otmp; |
| 175 | struct monst *shkp = (*u.ushops && costly_spot(u.ux, u.uy)) |
| 176 | ? shop_keeper(*u.ushops) |
| 177 | : 0; |
| 178 | boolean costly = (boolean) (shkp != 0), |
| 179 | peaceful_shk = costly && (boolean) shkp->mpeaceful; |
| 180 | long loss = 0L; |
| 181 | |
| 182 | pline("In fact, you've totally destroyed %s.", the(xname(box))); |
| 183 | /* Put the contents on ground at the hero's feet. */ |
| 184 | while ((otmp = box->cobj) != 0) { |
| 185 | obj_extract_self(otmp); |
| 186 | if (!rn2(3) || otmp->oclass == POTION_CLASS) { |
| 187 | chest_shatter_msg(otmp); |
| 188 | if (costly) |
| 189 | loss += stolen_value(otmp, u.ux, u.uy, peaceful_shk, |
| 190 | TRUE); |
| 191 | if (otmp->quan == 1L) { |
| 192 | obfree(otmp, (struct obj *) 0); |
| 193 | continue; |
| 194 | } |
| 195 | /* this works because we're sure to have at least 1 left; |
| 196 | otherwise it would fail since otmp is not in inventory */ |
| 197 | useup(otmp); |
| 198 | } |
| 199 | if (box->otyp == ICE_BOX && otmp->otyp == CORPSE) { |
| 200 | otmp->age = svm.moves - otmp->age; /* actual age */ |
| 201 | start_corpse_timeout(otmp); |
| 202 | } |
| 203 | place_object(otmp, u.ux, u.uy); |
| 204 | stackobj(otmp); |
| 205 | } |
| 206 | if (costly) |
| 207 | loss += stolen_value(box, u.ux, u.uy, peaceful_shk, TRUE); |
| 208 | if (loss) |
| 209 | You("owe %ld %s for objects destroyed.", loss, currency(loss)); |
| 210 | delobj(box); |
| 211 | } |
| 212 | } |
| 213 | |
| 214 | /* try to force a locked chest */ |
| 215 | staticfn int |
no test coverage detected