#pragma once #include #include #include // The coverage rules of a selection box (REQ-UI-MULTI-SELECT, REQ-BLD-DECONSTRUCT-BOX). // // The box is a rectangle in world coordinates — tiles as the unit, but fractional, // because the drag follows the mouse and is not snapped to the tile grid. The two // rules below are the whole of what "covered by the box" means; they live here so the // building query and the entity queries answer it identically. // // Both callers pass a normalized rectangle: neither rule normalizes on its own. // Whether the box overlaps the unit square of `tile` — the rule for anything that // occupies whole tiles (buildings, construction sites, defence station bodies). The // overlap must have area: a box that ends exactly on a tile boundary does not reach // into the tile beyond it. That matters because a click resolves as the unit square // of the tile it hit (GameWorldView::getBoxWorldRect), so its edges lie exactly on // tile boundaries — with the touching edges counted as coverage, such a box would // cover the whole 3x3 neighbourhood instead of the one tile clicked. inline bool boxCoversTile(const QRectF& worldBox, QPoint tile) { return worldBox.left() < static_cast(tile.x()) + 1.0 && worldBox.right() > static_cast(tile.x()) && worldBox.top() < static_cast(tile.y()) + 1.0 && worldBox.bottom() > static_cast(tile.y()); } // Whether the box contains `worldPos` — the rule for anything that has a position // rather than a footprint (ships, debris). Their centre is what the box must enclose, // so that what the rectangle visibly holds is what the drag selects. inline bool boxCoversPoint(const QRectF& worldBox, QVector2D worldPos) { return worldBox.contains(QPointF(worldPos.x(), worldPos.y())); }