#pragma once #include "engine/point.hpp" #include "engine/size.hpp" #include "utils/attributes.h" namespace devilution { template struct RectangleOf { PointOf position; SizeOf size; RectangleOf() = default; DVL_ALWAYS_INLINE constexpr RectangleOf(PointOf position, SizeOf size) : position(position) , size(size) { } /** * @brief Constructs a rectangle centered on the given point and including all tiles within the given radius. * * The resulting rectangle will be square with an odd size equal to 2*radius + 1. * * @param center center point of the target rectangle * @param radius a non-negative value indicating how many tiles to include around the center */ DVL_ALWAYS_INLINE explicit constexpr RectangleOf(PointOf center, SizeT radius) : position(center - DisplacementOf { radius }) , size(static_cast(2 * radius + 1)) { } /** * @brief Whether this rectangle contains the given point. * Works correctly even if the point uses a different underlying numeric type */ template DVL_ALWAYS_INLINE constexpr bool contains(PointOf point) const { return contains(point.x, point.y); } template constexpr bool contains(T x, T y) const { return x >= this->position.x && x < (this->position.x + this->size.width) && y >= this->position.y && y < (this->position.y + this->size.height); } /** * @brief Computes the center of this rectangle in integer coordinates. Values are truncated towards zero. */ constexpr PointOf Center() const { return position + DisplacementOf(size / 2); } /** * @brief Returns a rectangle with all sides shrunk according to the given displacement * * Effectively moves the left/right edges in by deltaX, and the top/bottom edges in by deltaY */ constexpr RectangleOf inset(DisplacementOf factor) const { return { position + factor, SizeOf(size.width - factor.deltaX * 2, size.height - factor.deltaY * 2) }; } }; using Rectangle = RectangleOf; } // namespace devilution