Skip to content

Commit

Permalink
Fixed Automapping on infinite maps (#1692)
Browse files Browse the repository at this point in the history
This change enables Automapping rules to be used on infinite maps. The
rule maps themselves still can't be infinite maps.
  • Loading branch information
ketanhwr authored and bjorn committed Aug 27, 2017
1 parent 1a2930d commit e493426
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 31 deletions.
14 changes: 5 additions & 9 deletions src/libtiled/tilelayer.cpp
Expand Up @@ -197,20 +197,17 @@ void Tiled::TileLayer::setCell(int x, int y, const Cell &cell)

TileLayer *TileLayer::copy(const QRegion &region) const
{
const QRect bounds = region.boundingRect();
const QRect areaBounds = region.boundingRect();
const int offsetX = qMax(0, areaBounds.x() - bounds.x());
const int offsetY = qMax(0, areaBounds.y() - bounds.y());

TileLayer *copied = new TileLayer(QString(),
0, 0,
bounds.width(), bounds.height());
areaBounds.width(), areaBounds.height());

for (const QRect &rect : region.rects())
for (int x = rect.left(); x <= rect.right(); ++x)
for (int y = rect.top(); y <= rect.bottom(); ++y)
copied->setCell(x - areaBounds.x() + offsetX,
y - areaBounds.y() + offsetY,
copied->setCell(x - areaBounds.x(),
y - areaBounds.y(),
cellAt(x, y));

return copied;
Expand All @@ -235,7 +232,6 @@ void TileLayer::merge(const QPoint &pos, const TileLayer *layer)
void TileLayer::setCells(int x, int y, TileLayer *layer,
const QRegion &mask)
{
// Determine the overlapping area
QRegion area = QRect(x, y, layer->width(), layer->height());

if (!mask.isEmpty())
Expand Down Expand Up @@ -641,8 +637,8 @@ QRegion TileLayer::computeDiffRegion(const TileLayer *other) const

const int dx = other->x() - mX;
const int dy = other->y() - mY;
QRect r = QRect(0, 0, width(), height());
r &= QRect(dx, dy, other->width(), other->height());

const QRect r = bounds().united(other->bounds()).translated(-position());

for (int y = r.top(); y <= r.bottom(); ++y) {
for (int x = r.left(); x <= r.right(); ++x) {
Expand Down
28 changes: 11 additions & 17 deletions src/tiled/automapper.cpp
Expand Up @@ -690,19 +690,6 @@ static bool compareLayerTo(const TileLayer *setLayer,
bool matchListYes = false;
bool matchListNo = false;


if (!setLayer->contains(x + offset.x(), y + offset.y())) {
foreach (const TileLayer *comparedTileLayer, listYes) {
if (!comparedTileLayer->contains(x, y))
return false;

const Cell &c2 = comparedTileLayer->cellAt(x, y);
if (!c2.isEmpty())
return false;
}
continue;
}

const Cell &c1 = setLayer->cellAt(x + offset.x(),
y + offset.y());

Expand Down Expand Up @@ -809,11 +796,18 @@ void AutoMapper::copyTileRegion(const TileLayer *srcLayer, int srcX, int srcY,
int width, int height,
TileLayer *dstLayer, int dstX, int dstY)
{
const int startX = qMax(dstX, 0);
const int startY = qMax(dstY, 0);
int startX = dstX;
int startY = dstY;

int endX = dstX + width;
int endY = dstY + height;

const int endX = qMin(dstX + width, dstLayer->width());
const int endY = qMin(dstY + height, dstLayer->height());
if (!mMapWork->infinite()) {
startX = qMax(0, startX);
startY = qMax(0, startY);
endX = qMin(dstLayer->width(), endX);
endY = qMin(dstLayer->height(), endY);
}

const int offsetX = srcX - dstX;
const int offsetY = srcY - dstY;
Expand Down
4 changes: 2 additions & 2 deletions src/tiled/automapperwrapper.cpp
Expand Up @@ -63,7 +63,7 @@ AutoMapperWrapper::AutoMapperWrapper(MapDocument *mapDocument,
TileLayer *before = mLayersBefore.at(beforeIndex);
TileLayer *after = static_cast<TileLayer*>(map->layerAt(layerIndex));

if (before->drawMargins() != after->drawMargins())
if (before->drawMargins() != after->drawMargins() || before->bounds() != after->bounds())
emit mMapDocument->tileLayerDrawMarginsChanged(after);

// reduce memory usage by saving only diffs
Expand Down Expand Up @@ -115,7 +115,7 @@ void AutoMapperWrapper::redo()
void AutoMapperWrapper::patchLayer(int layerIndex, TileLayer *layer)
{
Map *map = mMapDocument->map();
QRect b = layer->bounds();
QRect b = layer->rect();

Q_ASSERT(map->layerAt(layerIndex)->asTileLayer());
TileLayer *t = static_cast<TileLayer*>(map->layerAt(layerIndex));
Expand Down
19 changes: 16 additions & 3 deletions src/tiled/automappingmanager.cpp
Expand Up @@ -52,10 +52,23 @@ void AutomappingManager::autoMap()
return;

Map *map = mMapDocument->map();
int w = map->width();
int h = map->height();

autoMapInternal(QRect(0, 0, w, h), nullptr);
QRect bounds;

if (map->infinite()) {
LayerIterator iterator(map);

while (Layer *layer = iterator.next()) {
if (TileLayer *tileLayer = dynamic_cast<TileLayer*>(layer))
bounds = bounds.united(tileLayer->bounds());
}
} else {
int w = map->width();
int h = map->height();
bounds = QRect(0, 0, w, h);
}

autoMapInternal(bounds, nullptr);
}

void AutomappingManager::autoMap(const QRegion &where, Layer *touchedLayer)
Expand Down

0 comments on commit e493426

Please sign in to comment.