Handles the movement of a standard monster. * Return values: * 0: did not move, but can still attack and do other stuff; * 1: moved, possibly can attack; * 2: monster died; * 3: did not move, and can't do anything else either. */
| 1712 | * 3: did not move, and can't do anything else either. |
| 1713 | */ |
| 1714 | int |
| 1715 | m_move(struct monst *mtmp, int after) |
| 1716 | { |
| 1717 | int appr; |
| 1718 | coordxy ggx, ggy, nix, niy; |
| 1719 | xint16 chcnt; |
| 1720 | boolean can_tunnel = 0; |
| 1721 | boolean can_open = 0, can_unlock = 0 /*, doorbuster = 0 */; |
| 1722 | boolean getitems = FALSE; |
| 1723 | boolean avoid = FALSE; |
| 1724 | boolean better_with_displacing = FALSE; |
| 1725 | unsigned seenflgs; |
| 1726 | struct permonst *ptr; |
| 1727 | int chi, mmoved = MMOVE_NOTHING, /* not strictly nec.: chi >= 0 will do */ |
| 1728 | preferredrange_min = 0, preferredrange_max = 0; |
| 1729 | struct mfndposdata mfp; |
| 1730 | long flag; |
| 1731 | coordxy omx = mtmp->mx, omy = mtmp->my; |
| 1732 | |
| 1733 | if (mtmp->mtrapped) { |
| 1734 | int i = mintrap(mtmp, NO_TRAP_FLAGS); |
| 1735 | |
| 1736 | if (i == Trap_Killed_Mon) { |
| 1737 | newsym(mtmp->mx, mtmp->my); |
| 1738 | return MMOVE_DIED; |
| 1739 | } /* it died */ |
| 1740 | if (i == Trap_Caught_Mon) |
| 1741 | return MMOVE_NOTHING; /* still in trap, so didn't move */ |
| 1742 | } |
| 1743 | ptr = mtmp->data; /* mintrap() can change mtmp->data -dlc */ |
| 1744 | |
| 1745 | if (mtmp->meating) { |
| 1746 | mtmp->meating--; |
| 1747 | if (mtmp->meating <= 0) |
| 1748 | finish_meating(mtmp); |
| 1749 | return MMOVE_DONE; /* still eating */ |
| 1750 | } |
| 1751 | if (hides_under(ptr) && OBJ_AT(mtmp->mx, mtmp->my) |
| 1752 | && can_hide_under_obj(svl.level.objects[mtmp->mx][mtmp->my]) |
| 1753 | && rn2(10)) |
| 1754 | return MMOVE_NOTHING; /* do not leave hiding place */ |
| 1755 | |
| 1756 | /* set up pre-move visibility flags */ |
| 1757 | seenflgs = (canseemon(mtmp) ? 1 : 0) | (canspotmon(mtmp) ? 2 : 0); |
| 1758 | |
| 1759 | /* Where does 'mtmp' think you are? Not necessary if m_move() called |
| 1760 | from this file, but needed for other calls of m_move(). */ |
| 1761 | set_apparxy(mtmp); /* set mtmp->mux, mtmp->muy */ |
| 1762 | |
| 1763 | if (!Is_rogue_level(&u.uz)) |
| 1764 | can_tunnel = tunnels(ptr); |
| 1765 | can_open = !(nohands(ptr) || verysmall(ptr)); |
| 1766 | can_unlock = ((can_open && monhaskey(mtmp, TRUE)) |
| 1767 | || mtmp->iswiz || is_rider(ptr)); |
| 1768 | /* doorbuster = is_giant(ptr); */ |
| 1769 | if (mtmp->wormno) |
| 1770 | goto not_special; |
| 1771 | /* my dog gets special treatment */ |
no test coverage detected