container is kicked, dropped, thrown or otherwise impacted by player. * Assumes container is on floor. Checks contents for possible damage. */
| 409 | /* container is kicked, dropped, thrown or otherwise impacted by player. |
| 410 | * Assumes container is on floor. Checks contents for possible damage. */ |
| 411 | void |
| 412 | container_impact_dmg( |
| 413 | struct obj *obj, |
| 414 | coordxy x, /* coordinates where object was */ |
| 415 | coordxy y) /* before the impact, not after */ |
| 416 | { |
| 417 | struct monst *shkp; |
| 418 | struct obj *otmp, *otmp2; |
| 419 | long loss = 0L; |
| 420 | boolean costly, insider, frominv, wchange = FALSE; |
| 421 | |
| 422 | /* only consider normal containers */ |
| 423 | if (!Is_container(obj) || !Has_contents(obj) || Is_mbag(obj)) |
| 424 | return; |
| 425 | |
| 426 | costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) |
| 427 | && costly_spot(x, y)); |
| 428 | insider = (*u.ushops && inside_shop(u.ux, u.uy) |
| 429 | && *in_rooms(x, y, SHOPBASE) == *u.ushops); |
| 430 | /* if dropped or thrown, shop ownership flags are set on this obj */ |
| 431 | frominv = (obj != gk.kickedobj); |
| 432 | |
| 433 | for (otmp = obj->cobj; otmp; otmp = otmp2) { |
| 434 | const char *result = (char *) 0; |
| 435 | |
| 436 | otmp2 = otmp->nobj; |
| 437 | if (objects[otmp->otyp].oc_material == GLASS |
| 438 | && otmp->oclass != GEM_CLASS && !obj_resists(otmp, 33, 100)) { |
| 439 | result = "shatter"; |
| 440 | } else if (otmp->otyp == EGG && !rn2(3)) { |
| 441 | result = "cracking"; |
| 442 | } |
| 443 | if (result) { |
| 444 | if (otmp->otyp == MIRROR) |
| 445 | change_luck(-2); |
| 446 | |
| 447 | /* eggs laid by you. penalty is -1 per egg, max 5, |
| 448 | * but it's always exactly 1 that breaks */ |
| 449 | if (otmp->otyp == EGG && otmp->spe && ismnum(otmp->corpsenm)) |
| 450 | change_luck(-1); |
| 451 | if (otmp->otyp == EGG) { |
| 452 | Soundeffect(se_egg_cracking, 25); |
| 453 | } else { |
| 454 | Soundeffect(se_glass_shattering, 25); |
| 455 | } |
| 456 | You_hear("a muffled %s.", result); |
| 457 | if (costly) { |
| 458 | if (frominv && !otmp->unpaid) |
| 459 | otmp->no_charge = 1; |
| 460 | loss += |
| 461 | stolen_value(otmp, x, y, (boolean) shkp->mpeaceful, TRUE); |
| 462 | } |
| 463 | if (otmp->quan > 1L) { |
| 464 | useup(otmp); |
| 465 | } else { |
| 466 | obj_extract_self(otmp); |
| 467 | obfree(otmp, (struct obj *) 0); |
| 468 | } |
no test coverage detected