A modified bhit() for monsters. Based on bhit() in zap.c. Unlike * buzz(), bhit() doesn't take into account the possibility of a monster * zapping you, so we need a special function for it. (Unless someone wants * to merge the two functions...) */
| 1731 | * to merge the two functions...) |
| 1732 | */ |
| 1733 | staticfn void |
| 1734 | mbhit( |
| 1735 | struct monst *mon, /* monster shooting the wand */ |
| 1736 | int range, /* direction and range */ |
| 1737 | int (*fhitm)(MONST_P, OBJ_P), /* must be non-Null */ |
| 1738 | int (*fhito)(OBJ_P, OBJ_P), /* fns called when mon/obj hit */ |
| 1739 | struct obj *obj) /* 2nd arg to fhitm/fhito */ |
| 1740 | { |
| 1741 | struct monst *mtmp; |
| 1742 | uchar ltyp; |
| 1743 | int ddx, ddy, otyp = obj->otyp; |
| 1744 | |
| 1745 | gb.bhitpos.x = mon->mx; |
| 1746 | gb.bhitpos.y = mon->my; |
| 1747 | ddx = sgn(mon->mux - mon->mx); |
| 1748 | ddy = sgn(mon->muy - mon->my); |
| 1749 | |
| 1750 | while (range-- > 0) { |
| 1751 | coordxy x, y, dbx, dby; |
| 1752 | |
| 1753 | gb.bhitpos.x += ddx; |
| 1754 | gb.bhitpos.y += ddy; |
| 1755 | x = gb.bhitpos.x; |
| 1756 | y = gb.bhitpos.y; |
| 1757 | |
| 1758 | if (!isok(x, y)) { |
| 1759 | gb.bhitpos.x -= ddx; |
| 1760 | gb.bhitpos.y -= ddy; |
| 1761 | break; |
| 1762 | } |
| 1763 | if (u_at(gb.bhitpos.x, gb.bhitpos.y)) { |
| 1764 | (*fhitm)(&gy.youmonst, obj); |
| 1765 | range -= 3; |
| 1766 | } else if ((mtmp = m_at(gb.bhitpos.x, gb.bhitpos.y)) != 0) { |
| 1767 | if (cansee(gb.bhitpos.x, gb.bhitpos.y) && !canspotmon(mtmp)) |
| 1768 | map_invisible(gb.bhitpos.x, gb.bhitpos.y); |
| 1769 | (*fhitm)(mtmp, obj); |
| 1770 | range -= 3; |
| 1771 | } |
| 1772 | if (fhito_loc(obj, gb.bhitpos.x, gb.bhitpos.y, fhito)) |
| 1773 | range--; |
| 1774 | ltyp = levl[gb.bhitpos.x][gb.bhitpos.y].typ; |
| 1775 | dbx = x, dby = y; |
| 1776 | if (otyp == WAN_STRIKING |
| 1777 | /* if levl[x][y].typ is DRAWBRIDGE_UP then the zap is passing |
| 1778 | over the moat in front of a closed drawbridge and doesn't |
| 1779 | hit any part of the bridge's mechanism (yet; it might be |
| 1780 | about to hit the closed portcullis on the next iteration) */ |
| 1781 | && ltyp != DRAWBRIDGE_UP && find_drawbridge(&dbx, &dby)) { |
| 1782 | /* this might kill mon and destroy obj but they'll remain |
| 1783 | accessible; (*fhitm)() and (*fhito)() use obj for zap type */ |
| 1784 | destroy_drawbridge(dbx, dby); |
| 1785 | } else if (IS_DOOR(ltyp) || ltyp == SDOOR) { |
| 1786 | switch (otyp) { |
| 1787 | /* note: monsters don't use opening or locking magic |
| 1788 | at present, but keep these as placeholders */ |
| 1789 | case WAN_OPENING: |
| 1790 | case WAN_LOCKING: |
no test coverage detected