| 967 | } |
| 968 | |
| 969 | void compute(const ProjectilePath &path) |
| 970 | { |
| 971 | hit_type = Impassable; |
| 972 | collision_step = goal_step = goal_z_step = 1000000; |
| 973 | collision_z_step = 0; |
| 974 | |
| 975 | goal_distance = point_distance(path.origin - path.goal); |
| 976 | |
| 977 | int step = 0; |
| 978 | df::coord prev_pos = path.origin; |
| 979 | |
| 980 | for (;;) { |
| 981 | df::coord cur_pos = path[++step]; |
| 982 | if (cur_pos == prev_pos) |
| 983 | break; |
| 984 | |
| 985 | if (cur_pos.z == path.goal.z) |
| 986 | { |
| 987 | goal_z_step = std::min(step, goal_z_step); |
| 988 | if (cur_pos == path.goal) |
| 989 | goal_step = step; |
| 990 | } |
| 991 | |
| 992 | if (!Maps::isValidTilePos(cur_pos)) |
| 993 | { |
| 994 | hit_type = PathMetrics::MapEdge; |
| 995 | break; |
| 996 | } |
| 997 | |
| 998 | if (!isPassableTile(cur_pos)) |
| 999 | { |
| 1000 | if (isTreeTile(cur_pos)) |
| 1001 | { |
| 1002 | // The projectile code has a bug where it will |
| 1003 | // hit a tree on the same tick as a Z level change. |
| 1004 | if (cur_pos.z != prev_pos.z) |
| 1005 | { |
| 1006 | hit_type = Tree; |
| 1007 | break; |
| 1008 | } |
| 1009 | } |
| 1010 | else |
| 1011 | { |
| 1012 | hit_type = Impassable; |
| 1013 | break; |
| 1014 | } |
| 1015 | } |
| 1016 | |
| 1017 | if (cur_pos.z != prev_pos.z) |
| 1018 | { |
| 1019 | int top_z = std::max(prev_pos.z, cur_pos.z); |
| 1020 | auto ptile = Maps::getTileType(cur_pos.x, cur_pos.y, top_z); |
| 1021 | |
| 1022 | if (ptile && !LowPassable(*ptile)) |
| 1023 | { |
| 1024 | hit_type = (cur_pos.z > prev_pos.z ? Ceiling : Floor); |
| 1025 | break; |
| 1026 | } |
nothing calls this directly
no test coverage detected