Replace BORDER_DISTANCE with actual view distance

This commit is contained in:
GriffinR
2025-04-16 15:01:58 -04:00
parent db24687360
commit a6ec91724f
9 changed files with 54 additions and 42 deletions

View File

@@ -22,10 +22,6 @@
#define MAX_BORDER_WIDTH 255
#define MAX_BORDER_HEIGHT 255
// Number of metatiles to draw out from edge of map. Could allow modification of this in the future.
// porymap will reflect changes to it, but the value is hard-coded in the projects at the moment
#define BORDER_DISTANCE 7
class LayoutPixmapItem;
class CollisionPixmapItem;
class BorderMetatilesPixmapItem;

View File

@@ -98,6 +98,7 @@ public:
int getBorderHeight() const { return border_height; }
int getBorderDrawWidth() const;
int getBorderDrawHeight() const;
QRect getVisibleRect() const;
bool isWithinBounds(int x, int y) const;
bool isWithinBounds(const QRect &rect) const;

View File

@@ -256,6 +256,8 @@ public:
static QString getDynamicMapDefineName();
static QString getDynamicMapName();
static QString getEmptySpeciesName();
static QSize getViewDistance();
static QSize getMetatileViewDistance();
static int getNumTilesPrimary() { return num_tiles_primary; }
static int getNumTilesTotal() { return num_tiles_total; }
static int getNumMetatilesPrimary() { return num_metatiles_primary; }

View File

@@ -22,10 +22,10 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override {
if (!(*enabled)) return;
painter->setPen(this->color);
painter->drawRect(this->rect().x() - 2, this->rect().y() - 2, this->rect().width() + 3, this->rect().height() + 3);
painter->setPen(QColor(0, 0, 0));
painter->drawRect(this->rect().x() - 3, this->rect().y() - 3, this->rect().width() + 5, this->rect().height() + 5);
painter->drawRect(this->rect().x() - 1, this->rect().y() - 1, this->rect().width() + 1, this->rect().height() + 1);
painter->drawRect(this->rect() + QMargins(1,1,1,1)); // Fill
painter->setPen(Qt::black);
painter->drawRect(this->rect() + QMargins(2,2,2,2)); // Outer border
painter->drawRect(this->rect()); // Inner border
}
void updateLocation(int x, int y);
bool *enabled;

View File

@@ -83,16 +83,17 @@ QRect Map::getConnectionRect(const QString &direction, Layout * fromLayout) cons
int x = 0, y = 0;
int w = getWidth(), h = getHeight();
QSize viewDistance = Project::getMetatileViewDistance();
if (direction == "up") {
h = qMin(h, BORDER_DISTANCE);
h = qMin(h, viewDistance.height());
y = getHeight() - h;
} else if (direction == "down") {
h = qMin(h, BORDER_DISTANCE);
h = qMin(h, viewDistance.height());
} else if (direction == "left") {
w = qMin(w, BORDER_DISTANCE);
w = qMin(w, viewDistance.width());
x = getWidth() - w;
} else if (direction == "right") {
w = qMin(w, BORDER_DISTANCE);
w = qMin(w, viewDistance.width());
} else if (MapConnection::isDiving(direction)) {
if (fromLayout) {
w = qMin(w, fromLayout->getWidth());

View File

@@ -64,16 +64,18 @@ bool Layout::isWithinBorderBounds(int x, int y) const {
}
int Layout::getBorderDrawWidth() const {
return getBorderDrawDistance(border_width, BORDER_DISTANCE);
return getBorderDrawDistance(border_width, Project::getMetatileViewDistance().width());
}
int Layout::getBorderDrawHeight() const {
return getBorderDrawDistance(border_height, BORDER_DISTANCE);
return getBorderDrawDistance(border_height, Project::getMetatileViewDistance().height());
}
// We need to draw sufficient border blocks to fill the area that gets loaded around the player in-game (BORDER_DISTANCE).
// Note that this is not the same as the player's view distance.
// The result will be some multiple of the input dimension, because we only draw the border in increments of its full width/height.
// Calculate the distance away from the layout's edge that we need to start drawing border blocks.
// We need to fulfill two requirements here:
// - We should draw enough to fill the player's in-game view
// - The value should be some multiple of the border's dimension
// (otherwise the border won't be positioned the same as it would in-game).
int Layout::getBorderDrawDistance(int dimension, qreal minimum) {
if (dimension >= minimum)
return dimension;
@@ -82,6 +84,14 @@ int Layout::getBorderDrawDistance(int dimension, qreal minimum) {
return dimension * qCeil(minimum / qMax(dimension, 1));
}
// Get a rectangle that represents (in pixels) the layout's map area and the visible area of its border.
QRect Layout::getVisibleRect() const {
QRect area = QRect(0, 0, this->width * 16, this->height * 16);
QSize viewDistance = Project::getMetatileViewDistance() * 16;
area += QMargins(viewDistance.width(), viewDistance.height(), viewDistance.width(), viewDistance.height());
return area;
}
bool Layout::getBlock(int x, int y, Block *out) {
if (isWithinBounds(x, y)) {
int i = y * getWidth() + x;

View File

@@ -1572,14 +1572,8 @@ void Editor::displayMapMetatiles() {
map_item->draw(true);
scene->addItem(map_item);
int tw = 16;
int th = 16;
scene->setSceneRect(
-BORDER_DISTANCE * tw,
-BORDER_DISTANCE * th,
map_item->pixmap().width() + BORDER_DISTANCE * 2 * tw,
map_item->pixmap().height() + BORDER_DISTANCE * 2 * th
);
// Scene rect is the map plus a margin that gives enough space to scroll and see the edge of the player view rectangle.
scene->setSceneRect(this->layout->getVisibleRect() + QMargins(3,3,3,3));
}
void Editor::clearMapMovementPermissions() {
@@ -1772,18 +1766,13 @@ void Editor::clearConnectionMask() {
}
}
// Hides connected map tiles that cannot be seen from the current map (beyond BORDER_DISTANCE).
// Hides connected map tiles that cannot be seen from the current map
void Editor::maskNonVisibleConnectionTiles() {
clearConnectionMask();
QPainterPath mask;
mask.addRect(scene->itemsBoundingRect().toRect());
mask.addRect(
-BORDER_DISTANCE * 16,
-BORDER_DISTANCE * 16,
(layout->getWidth() + BORDER_DISTANCE * 2) * 16,
(layout->getHeight() + BORDER_DISTANCE * 2) * 16
);
mask.addRect(layout->getVisibleRect());
// Mask the tiles with the current theme's background color.
QPen pen(ui->graphicsView_Map->palette().color(QPalette::Active, QPalette::Base));
@@ -1805,13 +1794,11 @@ void Editor::clearMapBorder() {
void Editor::displayMapBorder() {
clearMapBorder();
int borderWidth = this->layout->getBorderWidth();
int borderHeight = this->layout->getBorderHeight();
int borderHorzDist = this->layout->getBorderDrawWidth();
int borderVertDist = this->layout->getBorderDrawHeight();
QPixmap pixmap = this->layout->renderBorder();
for (int y = -borderVertDist; y < this->layout->getHeight() + borderVertDist; y += borderHeight)
for (int x = -borderHorzDist; x < this->layout->getWidth() + borderHorzDist; x += borderWidth) {
for (int y = -borderVertDist; y < this->layout->getHeight() + borderVertDist; y += this->layout->getBorderHeight())
for (int x = -borderHorzDist; x < this->layout->getWidth() + borderHorzDist; x += this->layout->getBorderWidth()) {
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
item->setX(x * 16);
item->setY(y * 16);

View File

@@ -3235,6 +3235,21 @@ QString Project::getEmptySpeciesName() {
return projectConfig.getIdentifier(ProjectIdentifier::define_species_prefix) + projectConfig.getIdentifier(ProjectIdentifier::define_species_empty);
}
// Get the distance in pixels that the player is able to see from the space they're standing on.
// For the default size of the view area (i.e. the full 240x160 GBA screen) this is 112x72.
QSize Project::getViewDistance() {
return ((projectConfig.playerViewSize) - QSize(16,16)) / 2;
}
// Get the distance in metatiles that the player is able to see from the space they're standing on, rounded up.
// For the default size of the view area (i.e. the full 240x160 GBA screen) this is 7x5 metatiles.
QSize Project::getMetatileViewDistance() {
QSize viewDistance = getViewDistance();
viewDistance.setWidth(qCeil(viewDistance.width() / 16.0));
viewDistance.setHeight(qCeil(viewDistance.height() / 16.0));
return viewDistance;
}
// If the provided filepath is an absolute path to an existing file, return filepath.
// If not, and the provided filepath is a relative path from the project dir to an existing file, return the relative path.
// Otherwise return empty string.

View File

@@ -606,9 +606,11 @@ QPixmap MapImageExporter::getFormattedMapPixmap() {
QMargins MapImageExporter::getMargins(const Map *map) {
QMargins margins;
if (m_settings.showBorder) {
// The border may technically extend beyond BORDER_DISTANCE, but when the border is painted
// we will be limiting it to the visible sight range.
margins = QMargins(BORDER_DISTANCE, BORDER_DISTANCE, BORDER_DISTANCE, BORDER_DISTANCE) * 16;
// When we render map borders we render them in full increments of the border dimensions.
// This means for large border dimensions the painted area of the border may extend well beyond the area the player can see.
// When we call paintBorder we will clip the painting to this visible area, so we only need to consider the visible area here.
QSize viewDistance = m_project->getMetatileViewDistance() * 16;
margins = QMargins(viewDistance.width(), viewDistance.height(), viewDistance.width(), viewDistance.height());
} else if (map && connectionsEnabled()) {
for (const auto &connection : map->getConnections()) {
const QString dir = connection->direction();
@@ -649,10 +651,8 @@ void MapImageExporter::paintBorder(QPainter *painter, Layout *layout) {
layout->renderBorder(true);
// Clip parts of the border that would be beyond player visibility.
QRect visibleArea(0, 0, layout->getWidth() * 16, layout->getHeight() * 16);
visibleArea += (QMargins(BORDER_DISTANCE, BORDER_DISTANCE, BORDER_DISTANCE, BORDER_DISTANCE) * 16);
painter->save();
painter->setClipRect(visibleArea);
painter->setClipRect(layout->getVisibleRect());
int borderHorzDist = layout->getBorderDrawWidth();
int borderVertDist = layout->getBorderDrawHeight();