| 1890 | } |
| 1891 | |
| 1892 | staticfn boolean |
| 1893 | is_valid_jump_pos(coordxy x, coordxy y, int magic, boolean showmsg) |
| 1894 | { |
| 1895 | if (!magic && !(HJumping & ~INTRINSIC) && !EJumping && distu(x, y) != 5) { |
| 1896 | /* The Knight jumping restriction still applies when riding a |
| 1897 | * horse. After all, what shape is the knight piece in chess? |
| 1898 | */ |
| 1899 | if (showmsg) |
| 1900 | pline("Illegal move!"); |
| 1901 | return FALSE; |
| 1902 | } else if (distu(x, y) > (magic ? 6 + magic * 3 : 9)) { |
| 1903 | if (showmsg) |
| 1904 | pline("Too far!"); |
| 1905 | return FALSE; |
| 1906 | } else if (!isok(x, y)) { |
| 1907 | if (showmsg) |
| 1908 | You("cannot jump there!"); |
| 1909 | return FALSE; |
| 1910 | } else if (!cansee(x, y)) { |
| 1911 | if (showmsg) |
| 1912 | You("cannot see where to land!"); |
| 1913 | return FALSE; |
| 1914 | } else { |
| 1915 | coord uc, tc; |
| 1916 | struct rm *lev = &levl[u.ux][u.uy]; |
| 1917 | /* we want to categorize trajectory for use in determining |
| 1918 | passage through doorways: horizontal, vertical, or diagonal; |
| 1919 | since knight's jump and other irregular directions are |
| 1920 | possible, we flatten those out to simplify door checks */ |
| 1921 | int diag, traj; |
| 1922 | coordxy dx = x - u.ux, dy = y - u.uy, |
| 1923 | ax = abs(dx), ay = abs(dy); |
| 1924 | |
| 1925 | /* diag: any non-orthogonal destination classified as diagonal */ |
| 1926 | diag = (magic || Passes_walls || (!dx && !dy)) ? jAny |
| 1927 | : !dy ? jHorz : !dx ? jVert : jDiag; |
| 1928 | /* traj: flatten out the trajectory => some diagonals re-classified */ |
| 1929 | if (ax >= 2 * ay) |
| 1930 | ay = 0; |
| 1931 | else if (ay >= 2 * ax) |
| 1932 | ax = 0; |
| 1933 | traj = (magic || Passes_walls || (!ax && !ay)) ? jAny |
| 1934 | : !ay ? jHorz : !ax ? jVert : jDiag; |
| 1935 | /* walk_path doesn't process the starting spot; |
| 1936 | this is iffy: if you're starting on a closed door spot, |
| 1937 | you _can_ jump diagonally from doorway (without needing |
| 1938 | Passes_walls); that's intentional but is it correct? */ |
| 1939 | if (diag == jDiag && IS_DOOR(lev->typ) |
| 1940 | && (lev->doormask & D_ISOPEN) != 0 |
| 1941 | && (traj == jDiag |
| 1942 | || ((traj & jHorz) != 0) == (lev->horizontal != 0))) { |
| 1943 | if (showmsg) |
| 1944 | You_cant("jump diagonally out of a doorway."); |
| 1945 | return FALSE; |
| 1946 | } |
| 1947 | uc.x = u.ux, uc.y = u.uy; |
| 1948 | tc.x = x, tc.y = y; /* target */ |
| 1949 | if (!walk_path(&uc, &tc, check_jump, (genericptr_t) &traj)) { |