/** * \brief Tests whether a point collides with the ground of the map. * * The ground is the terrain of the point. It is defined by the tiles and * by the presence of entities that may change it * (like dynamic tiles and destructible items). * * This method also returns true if the point is outside the map. * * \param layer Layer of the point. * \param x X of the point in pixels. * \param y Y of the point in pixels. * \param entity_to_check The entity to check (used to decide what grounds are * considered as obstacle). * \param [out] found_diagonal_wall \c true if the ground under this point was * a diagonal wall, unchanged otherwise. * Your algorithm may decide to check more points if there is a diagonal wall. * \return \c true if this point is on an obstacle. */ bool Map::test_collision_with_ground( int layer, int x, int y, const Entity& entity_to_check, bool& found_diagonal_wall) const { bool on_obstacle = false; int x_in_tile, y_in_tile; // If the point is outside the map, this is an obstacle. if (test_collision_with_border(x, y)) { return true; } // Get the ground property under this point. Ground ground = get_ground(layer, x, y); switch (ground) { case Ground::EMPTY: case Ground::TRAVERSABLE: case Ground::GRASS: case Ground::ICE: // The square is not an obstacle. on_obstacle = false; break; case Ground::WALL: // The square is entirely an obstacle. on_obstacle = true; break; case Ground::WALL_TOP_RIGHT: case Ground::WALL_TOP_RIGHT_WATER: // The upper right half of the square is an obstacle // so we have to test the position of the point in the square. x_in_tile = x & 7; y_in_tile = y & 7; on_obstacle = y_in_tile <= x_in_tile; found_diagonal_wall = true; break; case Ground::WALL_TOP_LEFT: case Ground::WALL_TOP_LEFT_WATER: // Same thing. x_in_tile = x & 7; y_in_tile = y & 7; on_obstacle = y_in_tile <= 7 - x_in_tile; found_diagonal_wall = true; break; case Ground::WALL_BOTTOM_LEFT: case Ground::WALL_BOTTOM_LEFT_WATER: x_in_tile = x & 7; y_in_tile = y & 7; on_obstacle = y_in_tile >= x_in_tile; found_diagonal_wall = true; break; case Ground::WALL_BOTTOM_RIGHT: case Ground::WALL_BOTTOM_RIGHT_WATER: x_in_tile = x & 7; y_in_tile = y & 7; on_obstacle = y_in_tile >= 7 - x_in_tile; found_diagonal_wall = true; break; case Ground::LOW_WALL: case Ground::SHALLOW_WATER: case Ground::DEEP_WATER: case Ground::HOLE: case Ground::LAVA: case Ground::PRICKLE: case Ground::LADDER: on_obstacle = entity_to_check.is_ground_obstacle(ground); break; } return on_obstacle; }
/** * \brief Returns the ground at the specified point. * * Static tiles and dynamic entities are all taken into account here. * * \param layer Layer of the point. * \param xy Coordinate of the point. * \return The ground at this place. */ Ground Map::get_ground(Layer layer, const Rectangle& xy) const { return get_ground(layer, xy.get_x(), xy.get_y()); }
/** * \brief Returns the ground at the specified point. * * Static tiles and dynamic entities are all taken into account here. * * \param layer Layer of the point. * \param xy Coordinate of the point. * \return The ground at this place. */ Ground Map::get_ground(int layer, const Point& xy) const { return get_ground(layer, xy.x, xy.y); }