* Polymorph the object to the given object ID. If the ID is STRANGE_OBJECT * then pick random object from the source's class (this is the standard * "polymorph" case). If ID is set to a specific object, inhibit fusing * n objects into 1. This could have been added as a flag, but currently * it is tied to not being the standard polymorph case. The new polymorphed * object replaces obj in it
| 1699 | * This should be safe to call for an object anywhere. |
| 1700 | */ |
| 1701 | struct obj * |
| 1702 | poly_obj(struct obj *obj, int id) |
| 1703 | { |
| 1704 | struct obj *otmp; |
| 1705 | coordxy ox = 0, oy = 0; |
| 1706 | long old_wornmask, new_wornmask = 0L; |
| 1707 | boolean can_merge = (id == STRANGE_OBJECT); |
| 1708 | int obj_location = obj->where; |
| 1709 | |
| 1710 | if (obj->otyp == BOULDER) |
| 1711 | sokoban_guilt(); |
| 1712 | if (id == STRANGE_OBJECT) { /* preserve symbol */ |
| 1713 | int try_limit = 3; |
| 1714 | unsigned magic_obj = objects[obj->otyp].oc_magic; |
| 1715 | |
| 1716 | if (obj->otyp == UNICORN_HORN && obj->degraded_horn) |
| 1717 | magic_obj = 0; |
| 1718 | /* Try up to 3 times to make the magic-or-not status of |
| 1719 | the new item the same as the old item. */ |
| 1720 | otmp = (struct obj *) 0; |
| 1721 | do { |
| 1722 | if (otmp) |
| 1723 | delobj(otmp); |
| 1724 | otmp = mkobj(obj->oclass, FALSE); |
| 1725 | } while (--try_limit > 0 |
| 1726 | && objects[otmp->otyp].oc_magic != magic_obj); |
| 1727 | } else { |
| 1728 | /* literally replace obj with this new thing */ |
| 1729 | otmp = mksobj(id, FALSE, FALSE); |
| 1730 | /* Actually more things use corpsenm but they polymorph differently */ |
| 1731 | #define USES_CORPSENM(typ) \ |
| 1732 | ((typ) == CORPSE || (typ) == STATUE || (typ) == FIGURINE) |
| 1733 | |
| 1734 | if (USES_CORPSENM(obj->otyp) && USES_CORPSENM(id)) |
| 1735 | set_corpsenm(otmp, obj->corpsenm); |
| 1736 | #undef USES_CORPSENM |
| 1737 | } |
| 1738 | |
| 1739 | /* preserve quantity */ |
| 1740 | otmp->quan = obj->quan; |
| 1741 | /* preserve the shopkeeper's (lack of) interest */ |
| 1742 | otmp->no_charge = obj->no_charge; |
| 1743 | /* preserve inventory letter if in inventory */ |
| 1744 | if (obj_location == OBJ_INVENT) |
| 1745 | otmp->invlet = obj->invlet; |
| 1746 | #ifdef MAIL_STRUCTURES |
| 1747 | /* You can't send yourself 100 mail messages and then |
| 1748 | * polymorph them into useful scrolls |
| 1749 | */ |
| 1750 | if (obj->otyp == SCR_MAIL) { |
| 1751 | otmp->otyp = SCR_MAIL; |
| 1752 | otmp->spe = 1; |
| 1753 | } |
| 1754 | #endif |
| 1755 | |
| 1756 | /* avoid abusing eggs laid by you */ |
| 1757 | if (obj->otyp == EGG && obj->spe) { |
| 1758 | int mnum, tryct = 100; |
no test coverage detected