* Single step for the hero flying through the air from jumping, flying, * etc. Called from hurtle() and jump() via walk_path(). We expect the * argument to be a pointer to an integer -- the range -- which is * used in the calculation of points off if we hit something. * * Bumping into monsters won't cause damage but will wake them and make * them angry. Auto-pickup isn't done, since you d
| 770 | * o let jumps go over boulders |
| 771 | */ |
| 772 | boolean |
| 773 | hurtle_step(genericptr_t arg, coordxy x, coordxy y) |
| 774 | { |
| 775 | coordxy ox, oy; |
| 776 | int *range = (int *) arg; |
| 777 | struct obj *obj; |
| 778 | struct monst *mon; |
| 779 | boolean may_pass = TRUE, via_jumping, stopping_short; |
| 780 | struct trap *ttmp; |
| 781 | struct rm *lev; |
| 782 | int ltyp, dmg = 0; |
| 783 | |
| 784 | if (!isok(x, y)) { |
| 785 | You_feel("the spirits holding you back."); |
| 786 | return FALSE; |
| 787 | } else if (!in_out_region(x, y)) { |
| 788 | return FALSE; |
| 789 | } else if (*range == 0) { |
| 790 | return FALSE; /* previous step wants to stop now */ |
| 791 | } |
| 792 | via_jumping = (EWwalking & I_SPECIAL) != 0L; |
| 793 | stopping_short = (via_jumping && *range < 2); |
| 794 | lev = &levl[x][y]; |
| 795 | ltyp = lev->typ; |
| 796 | |
| 797 | if (!Passes_walls || !(may_pass = may_passwall(x, y))) { |
| 798 | const char *why = NULL; |
| 799 | boolean diagonal = (u.ux - x) != 0 && (u.uy - y) != 0, |
| 800 | open_door = IS_DOOR(ltyp) && (lev->doormask & D_ISOPEN) != 0, |
| 801 | odoor_diag = open_door && diagonal; |
| 802 | |
| 803 | if (IS_OBSTRUCTED(levl[x][y].typ) |
| 804 | || closed_door(x, y) || odoor_diag) { |
| 805 | why = IS_TREE(ltyp) ? "bumping into a tree" |
| 806 | : IS_OBSTRUCTED(ltyp) ? "bumping into a wall" |
| 807 | : odoor_diag ? "bumping into a door frame" |
| 808 | : "bumping into a closed door"; |
| 809 | if (odoor_diag) |
| 810 | You("hit the door frame!"); |
| 811 | pline("Ouch!"); |
| 812 | } else if (ltyp == IRONBARS) { |
| 813 | why = "crashing into iron bars"; |
| 814 | You("crash into some iron bars. Ouch!"); |
| 815 | } else if ((obj = sobj_at(BOULDER, x, y)) != 0) { |
| 816 | why = "bumping into a boulder"; |
| 817 | You("bump into a %s. Ouch!", xname(obj)); |
| 818 | } else if (!may_pass) { |
| 819 | /* did we hit a no-dig non-wall position? */ |
| 820 | why = "touching the edge of the universe"; |
| 821 | You("smack into something!"); |
| 822 | } else if (diagonal |
| 823 | && bad_rock(gy.youmonst.data, u.ux, y) |
| 824 | && bad_rock(gy.youmonst.data, x, u.uy)) { |
| 825 | boolean too_much = (gi.invent |
| 826 | && (inv_weight() + weight_cap() > WT_TOOMUCH_DIAGONAL)); |
| 827 | |
| 828 | if (bigmonst(gy.youmonst.data) || too_much) { |
| 829 | why = "wedging into a narrow crevice"; |
no test coverage detected