NOTE: ship_object assumes otmp was FREED from fobj or invent. * is the point of drop. otmp is _not_ an resident: * otmp is either a kicked, dropped, or thrown object. */
| 1636 | * otmp is either a kicked, dropped, or thrown object. |
| 1637 | */ |
| 1638 | boolean |
| 1639 | ship_object(struct obj *otmp, coordxy x, coordxy y, boolean shop_floor_obj) |
| 1640 | { |
| 1641 | schar toloc; |
| 1642 | coordxy ox, oy; |
| 1643 | coord cc; |
| 1644 | struct obj *obj; |
| 1645 | struct trap *t; |
| 1646 | boolean nodrop, unpaid, container, impact = FALSE, chainthere = FALSE; |
| 1647 | long n = 0L; |
| 1648 | |
| 1649 | if (!otmp) |
| 1650 | return FALSE; |
| 1651 | if ((toloc = down_gate(x, y)) == MIGR_NOWHERE) |
| 1652 | return FALSE; |
| 1653 | drop_to(&cc, toloc, x, y); |
| 1654 | if (!cc.y) |
| 1655 | return FALSE; |
| 1656 | |
| 1657 | /* objects other than attached iron ball always fall down ladder, |
| 1658 | but have a chance of staying otherwise */ |
| 1659 | nodrop = (otmp == uball) || (otmp == uchain) |
| 1660 | || (toloc != MIGR_LADDER_UP && rn2(3)); |
| 1661 | |
| 1662 | container = Has_contents(otmp); |
| 1663 | unpaid = is_unpaid(otmp); |
| 1664 | |
| 1665 | if (OBJ_AT(x, y)) { |
| 1666 | for (obj = svl.level.objects[x][y]; obj; obj = obj->nexthere) { |
| 1667 | if (obj == uchain) |
| 1668 | chainthere = TRUE; |
| 1669 | else if (obj != otmp) |
| 1670 | n += obj->quan; |
| 1671 | } |
| 1672 | if (n) |
| 1673 | impact = TRUE; |
| 1674 | } |
| 1675 | /* boulders never fall through trap doors, but they might knock |
| 1676 | other things down before plugging the hole */ |
| 1677 | if (otmp->otyp == BOULDER && ((t = t_at(x, y)) != 0) |
| 1678 | && is_hole(t->ttyp)) { |
| 1679 | if (impact) |
| 1680 | impact_drop(otmp, x, y, 0); |
| 1681 | return FALSE; /* let caller finish the drop */ |
| 1682 | } |
| 1683 | |
| 1684 | if (cansee(x, y)) |
| 1685 | otransit_msg(otmp, nodrop, chainthere, n); |
| 1686 | |
| 1687 | if (nodrop) { |
| 1688 | if (impact) { |
| 1689 | impact_drop(otmp, x, y, 0); |
| 1690 | maybe_unhide_at(x, y); |
| 1691 | } |
| 1692 | return FALSE; |
| 1693 | } |
| 1694 | |
| 1695 | if (unpaid || shop_floor_obj) { |
no test coverage detected