Add get/setMetatileTiles array functions to API
This commit is contained in:
parent
6613318900
commit
ebd7af8846
2 changed files with 76 additions and 34 deletions
|
@ -127,7 +127,11 @@ public:
|
||||||
Q_INVOKABLE void setMetatileBehavior(int metatileId, int behavior);
|
Q_INVOKABLE void setMetatileBehavior(int metatileId, int behavior);
|
||||||
Q_INVOKABLE QJSValue getMetatileTile(int metatileId, int tileIndex);
|
Q_INVOKABLE QJSValue getMetatileTile(int metatileId, int tileIndex);
|
||||||
Q_INVOKABLE void setMetatileTile(int metatileId, int tileIndex, int tileId, bool xflip, bool yflip, int palette, bool forceRedraw = true);
|
Q_INVOKABLE void setMetatileTile(int metatileId, int tileIndex, int tileId, bool xflip, bool yflip, int palette, bool forceRedraw = true);
|
||||||
Q_INVOKABLE void setMetatileTile(int metatileId, int tileIndex, QJSValue obj, bool forceRedraw = true);
|
Q_INVOKABLE void setMetatileTile(int metatileId, int tileIndex, QJSValue tileObj, bool forceRedraw = true);
|
||||||
|
int calculateTileBounds(int * tileStart, int * tileEnd);
|
||||||
|
Q_INVOKABLE QJSValue getMetatileTiles(int metatileId, int tileStart = 0, int tileEnd = -1);
|
||||||
|
Q_INVOKABLE void setMetatileTiles(int metatileId, QJSValue tilesObj, int tileStart = 0, int tileEnd = -1, bool forceRedraw = true);
|
||||||
|
Q_INVOKABLE void setMetatileTiles(int metatileId, int tileId, bool xflip, bool yflip, int palette, int tileStart = 0, int tileEnd = -1, bool forceRedraw = true);
|
||||||
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -14,6 +14,14 @@ QJSValue MainWindow::getBlock(int x, int y) {
|
||||||
return Scripting::fromBlock(block);
|
return Scripting::fromBlock(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: "needsFullRedraw" is used when redrawing the map after
|
||||||
|
// changing a metatile's tiles via script. It is unnecessarily
|
||||||
|
// resource intensive. The map metatiles that need to be updated are
|
||||||
|
// not marked as changed, so they will not be redrawn if the cache
|
||||||
|
// isn't ignored. Ideally the setMetatileTiles functions would properly
|
||||||
|
// set each of the map spaces that use the modified metatile so that
|
||||||
|
// the cache could be used, though this would lkely still require a
|
||||||
|
// full read of the map and its border/connections.
|
||||||
void MainWindow::tryRedrawMapArea(bool forceRedraw) {
|
void MainWindow::tryRedrawMapArea(bool forceRedraw) {
|
||||||
if (!forceRedraw) return;
|
if (!forceRedraw) return;
|
||||||
|
|
||||||
|
@ -64,7 +72,7 @@ int MainWindow::getMetatileId(int x, int y) {
|
||||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return block.tile;
|
return block.metatileId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setMetatileId(int x, int y, int metatileId, bool forceRedraw, bool commitChanges) {
|
void MainWindow::setMetatileId(int x, int y, int metatileId, bool forceRedraw, bool commitChanges) {
|
||||||
|
@ -96,7 +104,7 @@ void MainWindow::setCollision(int x, int y, int collision, bool forceRedraw, boo
|
||||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->editor->map->setBlock(x, y, Block(block.tile, collision, block.elevation));
|
this->editor->map->setBlock(x, y, Block(block.metatileId, collision, block.elevation));
|
||||||
this->tryCommitMapChanges(commitChanges);
|
this->tryCommitMapChanges(commitChanges);
|
||||||
this->tryRedrawMapArea(forceRedraw);
|
this->tryRedrawMapArea(forceRedraw);
|
||||||
}
|
}
|
||||||
|
@ -118,7 +126,7 @@ void MainWindow::setElevation(int x, int y, int elevation, bool forceRedraw, boo
|
||||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->editor->map->setBlock(x, y, Block(block.tile, block.collision, elevation));
|
this->editor->map->setBlock(x, y, Block(block.metatileId, block.collision, elevation));
|
||||||
this->tryCommitMapChanges(commitChanges);
|
this->tryCommitMapChanges(commitChanges);
|
||||||
this->tryRedrawMapArea(forceRedraw);
|
this->tryRedrawMapArea(forceRedraw);
|
||||||
}
|
}
|
||||||
|
@ -667,44 +675,74 @@ void MainWindow::setMetatileBehavior(int metatileId, int behavior) {
|
||||||
this->saveMetatileAttributesByMetatileId(metatileId);
|
this->saveMetatileAttributesByMetatileId(metatileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJSValue MainWindow::getMetatileTile(int metatileId, int tileIndex) {
|
int MainWindow::calculateTileBounds(int * tileStart, int * tileEnd) {
|
||||||
Metatile * metatile = this->getMetatile(metatileId);
|
int maxNumTiles = projectConfig.getTripleLayerMetatilesEnabled() ? 12 : 8;
|
||||||
int maxTileIndex = projectConfig.getTripleLayerMetatilesEnabled() ? 12 : 8;
|
if (*tileEnd >= maxNumTiles || *tileEnd < 0)
|
||||||
if (!metatile || tileIndex >= maxTileIndex || tileIndex < 0)
|
*tileEnd = maxNumTiles - 1;
|
||||||
return QJSValue();
|
if (*tileStart >= maxNumTiles || *tileStart < 0)
|
||||||
return Scripting::fromTile(metatile->tiles[tileIndex]);
|
*tileStart = 0;
|
||||||
|
return 1 + (*tileEnd - *tileStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setMetatileTile(int metatileId, int tileIndex, int tileId, bool xflip, bool yflip, int palette, bool forceRedraw) {
|
QJSValue MainWindow::getMetatileTiles(int metatileId, int tileStart, int tileEnd) {
|
||||||
Metatile * metatile = this->getMetatile(metatileId);
|
Metatile * metatile = this->getMetatile(metatileId);
|
||||||
int maxTileIndex = projectConfig.getTripleLayerMetatilesEnabled() ? 12 : 8;
|
int numTiles = calculateTileBounds(&tileStart, &tileEnd);
|
||||||
if (!metatile || tileIndex >= maxTileIndex || tileIndex < 0)
|
if (!metatile || numTiles <= 0)
|
||||||
return;
|
return QJSValue();
|
||||||
Tile * tile = &metatile->tiles[tileIndex];
|
|
||||||
if (!tile) return;
|
QJSValue tiles = Scripting::getEngine()->newArray(numTiles);
|
||||||
if (tile->tile == tileId
|
for (int i = 0; i < numTiles; i++, tileStart++)
|
||||||
&& tile->xflip == xflip
|
tiles.setProperty(i, Scripting::fromTile(metatile->tiles[tileStart]));
|
||||||
&& tile->yflip == yflip
|
return tiles;
|
||||||
&& tile->palette == palette)
|
}
|
||||||
|
|
||||||
|
void MainWindow::setMetatileTiles(int metatileId, QJSValue tilesObj, int tileStart, int tileEnd, bool forceRedraw) {
|
||||||
|
Metatile * metatile = this->getMetatile(metatileId);
|
||||||
|
int numTiles = calculateTileBounds(&tileStart, &tileEnd);
|
||||||
|
if (!metatile || numTiles <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tile->tile = tileId;
|
// Write to metatile using as many of the given Tiles as possible
|
||||||
tile->xflip = xflip;
|
int numTileObjs = qMin(tilesObj.property("length").toInt(), numTiles);
|
||||||
tile->yflip = yflip;
|
int i = 0;
|
||||||
tile->palette = palette;
|
for (; i < numTileObjs; i++)
|
||||||
|
metatile->tiles[i] = Scripting::toTile(tilesObj.property(i));
|
||||||
|
|
||||||
|
// Fill remainder of specified length with empty Tiles
|
||||||
|
for (; i < numTiles; i++)
|
||||||
|
metatile->tiles[i] = Tile();
|
||||||
|
|
||||||
this->saveMetatilesByMetatileId(metatileId);
|
this->saveMetatilesByMetatileId(metatileId);
|
||||||
|
|
||||||
// TODO: Making tryRedrawMapArea do a full draw is unnecessarily expensive.
|
|
||||||
// The map metatiles that need to be updated are not changed by the above
|
|
||||||
// operation, so they will not be redrawn if the cache isn't ignored.
|
|
||||||
// Ideally setMetatileTile would properly set each of the map spaces that
|
|
||||||
// use this metatile so that the cache could be used, though this would
|
|
||||||
// likely still require a full read of the map and its border/connections.
|
|
||||||
this->needsFullRedraw = true;
|
this->needsFullRedraw = true;
|
||||||
this->tryRedrawMapArea(forceRedraw);
|
this->tryRedrawMapArea(forceRedraw);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setMetatileTile(int metatileId, int tileIndex, QJSValue obj, bool forceRedraw) {
|
void MainWindow::setMetatileTiles(int metatileId, int tileId, bool xflip, bool yflip, int palette, int tileStart, int tileEnd, bool forceRedraw) {
|
||||||
Tile tile = Scripting::toTile(obj);
|
Metatile * metatile = this->getMetatile(metatileId);
|
||||||
this->setMetatileTile(metatileId, tileIndex, tile.tile, tile.xflip, tile.yflip, tile.palette, forceRedraw);
|
int numTiles = calculateTileBounds(&tileStart, &tileEnd);
|
||||||
|
if (!metatile || numTiles <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Write to metatile using Tiles of the specified value
|
||||||
|
Tile tile = Tile(tileId, xflip, yflip, palette);
|
||||||
|
for (int i = 0; i < numTiles; i++)
|
||||||
|
metatile->tiles[i] = tile;
|
||||||
|
|
||||||
|
this->saveMetatilesByMetatileId(metatileId);
|
||||||
|
this->needsFullRedraw = true;
|
||||||
|
this->tryRedrawMapArea(forceRedraw);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJSValue MainWindow::getMetatileTile(int metatileId, int tileIndex) {
|
||||||
|
QJSValue tilesObj = this->getMetatileTiles(metatileId, tileIndex, tileIndex);
|
||||||
|
return tilesObj.property(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setMetatileTile(int metatileId, int tileIndex, int tileId, bool xflip, bool yflip, int palette, bool forceRedraw) {
|
||||||
|
this->setMetatileTiles(metatileId, tileId, xflip, yflip, palette, tileIndex, tileIndex, forceRedraw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setMetatileTile(int metatileId, int tileIndex, QJSValue tileObj, bool forceRedraw) {
|
||||||
|
Tile tile = Scripting::toTile(tileObj);
|
||||||
|
this->setMetatileTiles(metatileId, tile.tileId, tile.xflip, tile.yflip, tile.palette, tileIndex, tileIndex, forceRedraw);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue