Merge pull request #455 from GriffinRichards/api-border

Add map border to the scripting API
This commit is contained in:
Marcus Huderle 2022-09-03 12:48:35 -05:00 committed by GitHub
commit a5136849b8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 331 additions and 34 deletions

View file

@ -118,6 +118,15 @@ Callbacks
:param object prevBlock: the block's state before it was modified. The object's shape is ``{metatileId, collision, elevation, rawValue}``
:param object newBlock: the block's new state after it was modified. The object's shape is ``{metatileId, collision, elevation, rawValue}``
.. js:function:: onBorderMetatileChanged(x, y, prevMetatileId, newMetatileId)
Called when a border metatile is changed.
:param number x: x coordinate of the block
:param number y: y coordinate of the block
:param number prevMetatileId: the metatile id of the border block before it was modified
:param number newMetatileId: the metatile id of the border block after it was modified
.. js:function:: onBlockHoverChanged(x, y)
Called when the mouse enters a new map block.
@ -138,6 +147,15 @@ Callbacks
:param number newWidth: the width of the map after the change
:param number newHeight: the height of the map after the change
.. js:function:: onBorderResized(oldWidth, oldHeight, newWidth, newHeight)
Called when the dimensions of the border are changed.
:param number oldWidth: the width of the border before the change
:param number oldHeight: the height of the border before the change
:param number newWidth: the width of the border after the change
:param number newHeight: the height of the border after the change
.. js:function:: onMapShifted(xDelta, yDelta)
Called when the map is updated by use of the Map Shift tool.
@ -165,6 +183,12 @@ Callbacks
:param number oldTab: the index of the previously selected tab
:param number newTab: the index of the newly selected tab
.. js:function:: onBorderVisibilityToggled(visible)
Called when the visibility of the border and connecting maps is toggled on or off.
:param boolean visible: whether the border is now visible
Functions
~~~~~~~~~
@ -213,6 +237,24 @@ The following functions are related to editing the map's blocks or retrieving in
:param boolean forceRedraw: Force the map view to refresh. Defaults to ``true``. Redrawing the map view is expensive, so set to ``false`` when making many consecutive map edits, and then redraw the map once using ``map.redraw()``.
:param boolean commitChanges: Commit the changes to the map's edit/undo history. Defaults to ``true``. When making many related map edits, it can be useful to set this to ``false``, and then commit all of them together with ``map.commit()``.
.. js:function:: map.getBorderMetatileId(x, y)
Gets the metatile id of a block in the border of the currently-opened map.
:param number x: x coordinate of the block
:param number y: y coordinate of the block
:returns number: the metatile id of the block
.. js:function:: map.setBorderMetatileId(x, y, metatileId, forceRedraw = true, commitChanges = true)
Sets the metatile id of a block in the border of the currently-opened map.
:param number x: x coordinate of the block
:param number y: y coordinate of the block
:param number metatileId: the metatile id of the block
:param boolean forceRedraw: Force the map view to refresh. Defaults to ``true``. Redrawing the map view is expensive, so set to ``false`` when making many consecutive map edits, and then redraw the map once using ``map.redraw()``.
:param boolean commitChanges: Commit the changes to the map's edit/undo history. Defaults to ``true``. When making many related map edits, it can be useful to set this to ``false``, and then commit all of them together with ``map.commit()``.
.. js:function:: map.getCollision(x, y)
Gets the collision of a block in the currently-opened map. (``0`` = passable, ``1`` = impassable)
@ -323,6 +365,24 @@ The following functions are related to editing the map's blocks or retrieving in
:returns number: the height of the map
.. js:function:: map.getBorderDimensions()
Gets the dimensions of the border of the currently-opened map.
:returns {width, height}: the dimensions of the border
.. js:function:: map.getBorderWidth()
Gets the width of the border of the currently-opened map.
:returns number: the width of the border
.. js:function:: map.getBorderHeight()
Gets the height of the border of the currently-opened map.
:returns number: the height of the border
.. js:function:: map.setDimensions(width, height)
Sets the dimensions of the currently-opened map.
@ -342,6 +402,25 @@ The following functions are related to editing the map's blocks or retrieving in
:param number height: height in blocks
.. js:function:: map.setBorderDimensions(width, height)
Sets the dimensions of the border of the currently-opened map. If the config setting ``use_custom_border_size`` is set to ``0`` then this does nothing.
:param number width: width in blocks
:param number height: height in blocks
.. js:function:: map.setBorderWidth(width)
Sets the width of the border of the currently-opened map. If the config setting ``use_custom_border_size`` is set to ``0`` then this does nothing.
:param number width: width in blocks
.. js:function:: map.setBorderHeight(height)
Sets the height of the border of the currently-opened map. If the config setting ``use_custom_border_size`` is set to ``0`` then this does nothing.
:param number height: height in blocks
.. js:function:: map.redraw()
Redraws the entire map area. Useful when delaying map redraws using ``forceRedraw = false`` in certain map editing functions.

View file

@ -343,12 +343,14 @@ public:
/// Implements a command to commit map edits from the scripting API.
/// The scripting api can edit metatiles and map dimensions.
/// The scripting api can edit map/border blocks and dimensions.
class ScriptEditMap : public QUndoCommand {
public:
ScriptEditMap(Map *map,
QSize oldMapDimensions, QSize newMapDimensions,
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
QSize oldBorderDimensions, QSize newBorderDimensions,
const Blockdata &oldBorder, const Blockdata &newBorder,
QUndoCommand *parent = nullptr);
void undo() override;
@ -363,10 +365,18 @@ private:
Blockdata newMetatiles;
Blockdata oldMetatiles;
Blockdata newBorder;
Blockdata oldBorder;
int oldMapWidth;
int oldMapHeight;
int newMapWidth;
int newMapHeight;
int oldBorderWidth;
int oldBorderHeight;
int newBorderWidth;
int newBorderHeight;
};
#endif // EDITCOMMANDS_H

View file

@ -17,6 +17,10 @@
#define DEFAULT_BORDER_WIDTH 2
#define DEFAULT_BORDER_HEIGHT 2
// Maximum based only on data type (u8) of map border width/height
#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
@ -82,6 +86,9 @@ public:
bool getBlock(int x, int y, Block *out);
void setBlock(int x, int y, Block block, bool enableScriptCallback = false);
void setBlockdata(Blockdata blockdata);
uint16_t getBorderMetatileId(int x, int y);
void setBorderMetatileId(int x, int y, uint16_t metatileId, bool enableScriptCallback = false);
void setBorderBlockData(Blockdata blockdata);
void floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
void _floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
void magicFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
@ -96,6 +103,7 @@ public:
void cacheBorder();
bool hasUnsavedChanges();
bool isWithinBounds(int x, int y);
bool isWithinBorderBounds(int x, int y);
// for memory management
QVector<Event *> ownedEvents;

View file

@ -33,8 +33,10 @@ public:
Blockdata cached_border;
struct {
Blockdata blocks;
QSize dimensions;
} lastCommitMapBlocks; // to track map changes
QSize mapDimensions;
Blockdata border;
QSize borderDimensions;
} lastCommitBlocks; // to track map changes
int getWidth();
int getHeight();

View file

@ -88,7 +88,7 @@ public:
void setSelectedConnectionFromMap(QString mapName);
void updatePrimaryTileset(QString tilesetLabel, bool forceLoad = false);
void updateSecondaryTileset(QString tilesetLabel, bool forceLoad = false);
void toggleBorderVisibility(bool visible);
void toggleBorderVisibility(bool visible, bool enableScriptCallback = true);
void updateCustomMapHeaderValues(QTableWidget *);
void configureEncounterJSON(QWidget *);
Tileset *getCurrentMapPrimaryTileset();
@ -158,6 +158,7 @@ public slots:
void openScript(const QString &scriptLabel) const;
void openProjectInTextEditor() const;
void maskNonVisibleConnectionTiles();
void onBorderMetatilesChanged();
private:
void setConnectionItemsVisible(bool);
@ -192,7 +193,6 @@ private slots:
void onConnectionItemSelected(ConnectionPixmapItem* connectionItem);
void onConnectionItemDoubleClicked(ConnectionPixmapItem* connectionItem);
void onConnectionDirectionChanged(QString newDirection);
void onBorderMetatilesChanged();
void onHoveredMovementPermissionChanged(uint16_t, uint16_t);
void onHoveredMovementPermissionCleared();
void onHoveredMetatileSelectionChanged(uint16_t);

View file

@ -50,6 +50,8 @@ public:
Q_INVOKABLE void setBlocksFromSelection(int x, int y, bool forceRedraw = true, bool commitChanges = true);
Q_INVOKABLE int getMetatileId(int x, int y);
Q_INVOKABLE void setMetatileId(int x, int y, int metatileId, bool forceRedraw = true, bool commitChanges = true);
Q_INVOKABLE int getBorderMetatileId(int x, int y);
Q_INVOKABLE void setBorderMetatileId(int x, int y, int metatileId, bool forceRedraw = true, bool commitChanges = true);
Q_INVOKABLE int getCollision(int x, int y);
Q_INVOKABLE void setCollision(int x, int y, int collision, bool forceRedraw = true, bool commitChanges = true);
Q_INVOKABLE int getElevation(int x, int y);
@ -64,9 +66,15 @@ public:
Q_INVOKABLE QJSValue getDimensions();
Q_INVOKABLE int getWidth();
Q_INVOKABLE int getHeight();
Q_INVOKABLE QJSValue getBorderDimensions();
Q_INVOKABLE int getBorderWidth();
Q_INVOKABLE int getBorderHeight();
Q_INVOKABLE void setDimensions(int width, int height);
Q_INVOKABLE void setWidth(int width);
Q_INVOKABLE void setHeight(int height);
Q_INVOKABLE void setBorderDimensions(int width, int height);
Q_INVOKABLE void setBorderWidth(int width);
Q_INVOKABLE void setBorderHeight(int height);
Q_INVOKABLE void clearOverlay(int layer = 0);
Q_INVOKABLE void clearOverlays();
Q_INVOKABLE void hideOverlay(int layer = 0);

View file

@ -12,14 +12,17 @@ enum CallbackType {
OnProjectOpened,
OnProjectClosed,
OnBlockChanged,
OnBorderMetatileChanged,
OnBlockHoverChanged,
OnBlockHoverCleared,
OnMapOpened,
OnMapResized,
OnBorderResized,
OnMapShifted,
OnTilesetUpdated,
OnMainTabChanged,
OnMapViewTabChanged,
OnBorderVisibilityToggled,
};
class Scripting
@ -41,14 +44,17 @@ public:
static void cb_ProjectOpened(QString projectPath);
static void cb_ProjectClosed(QString projectPath);
static void cb_MetatileChanged(int x, int y, Block prevBlock, Block newBlock);
static void cb_BorderMetatileChanged(int x, int y, uint16_t prevMetatileId, uint16_t newMetatileId);
static void cb_BlockHoverChanged(int x, int y);
static void cb_BlockHoverCleared();
static void cb_MapOpened(QString mapName);
static void cb_MapResized(int oldWidth, int oldHeight, int newWidth, int newHeight);
static void cb_BorderResized(int oldWidth, int oldHeight, int newWidth, int newHeight);
static void cb_MapShifted(int xDelta, int yDelta);
static void cb_TilesetUpdated(QString tilesetName);
static void cb_MainTabChanged(int oldTab, int newTab);
static void cb_MapViewTabChanged(int oldTab, int newTab);
static void cb_BorderVisibilityToggled(bool visible);
static bool tryErrorJS(QJSValue js);
private:

View file

@ -49,7 +49,7 @@ void PaintMetatile::redo() {
map->setBlockdata(newMetatiles);
map->layout->lastCommitMapBlocks.blocks = map->layout->blockdata;
map->layout->lastCommitBlocks.blocks = map->layout->blockdata;
renderMapBlocks(map);
}
@ -59,7 +59,7 @@ void PaintMetatile::undo() {
map->setBlockdata(oldMetatiles);
map->layout->lastCommitMapBlocks.blocks = map->layout->blockdata;
map->layout->lastCommitBlocks.blocks = map->layout->blockdata;
renderMapBlocks(map);
@ -101,7 +101,9 @@ void PaintBorder::redo() {
if (!map) return;
map->layout->border = newBorder;
map->setBorderBlockData(newBorder);
map->layout->lastCommitBlocks.border = map->layout->border;
map->borderItem->draw();
}
@ -109,7 +111,9 @@ void PaintBorder::redo() {
void PaintBorder::undo() {
if (!map) return;
map->layout->border = oldBorder;
map->setBorderBlockData(oldBorder);
map->layout->lastCommitBlocks.border = map->layout->border;
map->borderItem->draw();
@ -139,7 +143,7 @@ void ShiftMetatiles::redo() {
map->setBlockdata(newMetatiles);
map->layout->lastCommitMapBlocks.blocks = map->layout->blockdata;
map->layout->lastCommitBlocks.blocks = map->layout->blockdata;
renderMapBlocks(map, true);
}
@ -149,7 +153,7 @@ void ShiftMetatiles::undo() {
map->setBlockdata(oldMetatiles);
map->layout->lastCommitMapBlocks.blocks = map->layout->blockdata;
map->layout->lastCommitBlocks.blocks = map->layout->blockdata;
renderMapBlocks(map, true);
@ -213,7 +217,8 @@ void ResizeMap::redo() {
map->layout->border = newBorder;
map->setBorderDimensions(newBorderWidth, newBorderHeight, false);
map->layout->lastCommitMapBlocks.dimensions = QSize(map->getWidth(), map->getHeight());
map->layout->lastCommitBlocks.mapDimensions = QSize(map->getWidth(), map->getHeight());
map->layout->lastCommitBlocks.borderDimensions = QSize(map->getBorderWidth(), map->getBorderHeight());
map->mapNeedsRedrawing();
}
@ -227,7 +232,8 @@ void ResizeMap::undo() {
map->layout->border = oldBorder;
map->setBorderDimensions(oldBorderWidth, oldBorderHeight, false);
map->layout->lastCommitMapBlocks.dimensions = QSize(map->getWidth(), map->getHeight());
map->layout->lastCommitBlocks.mapDimensions = QSize(map->getWidth(), map->getHeight());
map->layout->lastCommitBlocks.borderDimensions = QSize(map->getBorderWidth(), map->getBorderHeight());
map->mapNeedsRedrawing();
@ -484,6 +490,8 @@ int EventPaste::id() const {
ScriptEditMap::ScriptEditMap(Map *map,
QSize oldMapDimensions, QSize newMapDimensions,
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
QSize oldBorderDimensions, QSize newBorderDimensions,
const Blockdata &oldBorder, const Blockdata &newBorder,
QUndoCommand *parent) : QUndoCommand(parent) {
setText("Script Edit Map");
@ -496,6 +504,14 @@ ScriptEditMap::ScriptEditMap(Map *map,
this->oldMapHeight = oldMapDimensions.height();
this->newMapWidth = newMapDimensions.width();
this->newMapHeight = newMapDimensions.height();
this->oldBorder = oldBorder;
this->newBorder = newBorder;
this->oldBorderWidth = oldBorderDimensions.width();
this->oldBorderHeight = oldBorderDimensions.height();
this->newBorderWidth = newBorderDimensions.width();
this->newBorderHeight = newBorderDimensions.height();
}
void ScriptEditMap::redo() {
@ -510,10 +526,19 @@ void ScriptEditMap::redo() {
map->setBlockdata(newMetatiles);
}
map->layout->lastCommitMapBlocks.blocks = newMetatiles;
map->layout->lastCommitMapBlocks.dimensions = QSize(newMapWidth, newMapHeight);
if (newBorderWidth != map->getBorderWidth() || newBorderHeight != map->getBorderHeight()) {
map->layout->border = newBorder;
map->setBorderDimensions(newBorderWidth, newBorderHeight, false);
} else {
map->setBorderBlockData(newBorder);
}
renderMapBlocks(map);
map->layout->lastCommitBlocks.blocks = newMetatiles;
map->layout->lastCommitBlocks.mapDimensions = QSize(newMapWidth, newMapHeight);
map->layout->lastCommitBlocks.border = newBorder;
map->layout->lastCommitBlocks.borderDimensions = QSize(newBorderWidth, newBorderHeight);
map->mapNeedsRedrawing();
}
void ScriptEditMap::undo() {
@ -526,10 +551,19 @@ void ScriptEditMap::undo() {
map->setBlockdata(oldMetatiles);
}
map->layout->lastCommitMapBlocks.blocks = oldMetatiles;
map->layout->lastCommitMapBlocks.dimensions = QSize(oldMapWidth, oldMapHeight);
if (oldBorderWidth != map->getBorderWidth() || oldBorderHeight != map->getBorderHeight()) {
map->layout->border = oldBorder;
map->setBorderDimensions(oldBorderWidth, oldBorderHeight, false);
} else {
map->setBorderBlockData(oldBorder);
}
renderMapBlocks(map);
map->layout->lastCommitBlocks.blocks = oldMetatiles;
map->layout->lastCommitBlocks.mapDimensions = QSize(oldMapWidth, oldMapHeight);
map->layout->lastCommitBlocks.border = oldBorder;
map->layout->lastCommitBlocks.borderDimensions = QSize(oldBorderWidth, oldBorderHeight);
map->mapNeedsRedrawing();
QUndoCommand::undo();
}

View file

@ -328,9 +328,15 @@ void Map::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata)
setNewBorderDimensionsBlockdata(newWidth, newHeight);
}
int oldWidth = layout->border_width.toInt();
int oldHeight = layout->border_height.toInt();
layout->border_width = QString::number(newWidth);
layout->border_height = QString::number(newHeight);
if (oldWidth != newWidth || oldHeight != newHeight) {
Scripting::cb_BorderResized(oldWidth, oldHeight, newWidth, newHeight);
}
emit mapChanged(this);
}
@ -367,6 +373,35 @@ void Map::setBlockdata(Blockdata blockdata) {
}
}
uint16_t Map::getBorderMetatileId(int x, int y) {
int i = y * getBorderWidth() + x;
return layout->border[i].metatileId;
}
void Map::setBorderMetatileId(int x, int y, uint16_t metatileId, bool enableScriptCallback) {
int i = y * getBorderWidth() + x;
if (i < layout->border.size()) {
uint16_t prevMetatileId = layout->border[i].metatileId;
layout->border[i].metatileId = metatileId;
if (prevMetatileId != metatileId && enableScriptCallback) {
Scripting::cb_BorderMetatileChanged(x, y, prevMetatileId, metatileId);
}
}
}
void Map::setBorderBlockData(Blockdata blockdata) {
int width = getBorderWidth();
int size = qMin(blockdata.size(), layout->border.size());
for (int i = 0; i < size; i++) {
Block prevBlock = layout->border.at(i);
Block newBlock = blockdata.at(i);
if (prevBlock != newBlock) {
layout->border.replace(i, newBlock);
Scripting::cb_BorderMetatileChanged(i % width, i / width, prevBlock.metatileId, newBlock.metatileId);
}
}
}
void Map::_floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation) {
QList<QPoint> todo;
todo.append(QPoint(x, y));
@ -474,3 +509,7 @@ bool Map::hasUnsavedChanges() {
bool Map::isWithinBounds(int x, int y) {
return (x >= 0 && x < this->getWidth() && y >= 0 && y < this->getHeight());
}
bool Map::isWithinBorderBounds(int x, int y) {
return (x >= 0 && x < this->getBorderWidth() && y >= 0 && y < this->getBorderHeight());
}

View file

@ -1936,11 +1936,13 @@ void Editor::updateSecondaryTileset(QString tilesetLabel, bool forceLoad)
}
}
void Editor::toggleBorderVisibility(bool visible)
void Editor::toggleBorderVisibility(bool visible, bool enableScriptCallback)
{
this->setBorderItemsVisible(visible);
this->setConnectionsVisibility(visible);
porymapConfig.setShowBorder(visible);
if (enableScriptCallback)
Scripting::cb_BorderVisibilityToggled(visible);
}
void Editor::updateCustomMapHeaderValues(QTableWidget *table)

View file

@ -2913,9 +2913,8 @@ void MainWindow::on_pushButton_ChangeDimensions_clicked()
bheightSpinBox->setMinimum(1);
widthSpinBox->setMaximum(editor->project->getMaxMapWidth());
heightSpinBox->setMaximum(editor->project->getMaxMapHeight());
// Maximum based only on data type (u8) of map border width/height
bwidthSpinBox->setMaximum(255);
bheightSpinBox->setMaximum(255);
bwidthSpinBox->setMaximum(MAX_BORDER_WIDTH);
bheightSpinBox->setMaximum(MAX_BORDER_HEIGHT);
widthSpinBox->setValue(editor->map->getWidth());
heightSpinBox->setValue(editor->map->getHeight());
bwidthSpinBox->setValue(editor->map->getBorderWidth());

View file

@ -29,12 +29,15 @@ void MainWindow::tryRedrawMapArea(bool forceRedraw) {
if (this->needsFullRedraw) {
this->editor->map_item->draw(true);
this->editor->collision_item->draw(true);
this->editor->selected_border_metatiles_item->draw();
this->editor->updateMapBorder();
this->editor->updateMapConnections();
this->needsFullRedraw = false;
} else {
this->editor->map_item->draw();
this->editor->collision_item->draw();
this->editor->selected_border_metatiles_item->draw();
this->editor->updateMapBorder();
}
}
@ -43,8 +46,10 @@ void MainWindow::tryCommitMapChanges(bool commitChanges) {
Map *map = this->editor->map;
if (map) {
map->editHistory.push(new ScriptEditMap(map,
map->layout->lastCommitMapBlocks.dimensions, QSize(map->getWidth(), map->getHeight()),
map->layout->lastCommitMapBlocks.blocks, map->layout->blockdata
map->layout->lastCommitBlocks.mapDimensions, QSize(map->getWidth(), map->getHeight()),
map->layout->lastCommitBlocks.blocks, map->layout->blockdata,
map->layout->lastCommitBlocks.borderDimensions, QSize(map->getBorderWidth(), map->getBorderHeight()),
map->layout->lastCommitBlocks.border, map->layout->border
));
}
}
@ -88,6 +93,24 @@ void MainWindow::setMetatileId(int x, int y, int metatileId, bool forceRedraw, b
this->tryRedrawMapArea(forceRedraw);
}
int MainWindow::getBorderMetatileId(int x, int y) {
if (!this->editor || !this->editor->map)
return 0;
if (!this->editor->map->isWithinBorderBounds(x, y))
return 0;
return this->editor->map->getBorderMetatileId(x, y);
}
void MainWindow::setBorderMetatileId(int x, int y, int metatileId, bool forceRedraw, bool commitChanges) {
if (!this->editor || !this->editor->map)
return;
if (!this->editor->map->isWithinBorderBounds(x, y))
return;
this->editor->map->setBorderMetatileId(x, y, metatileId);
this->tryCommitMapChanges(commitChanges);
this->tryRedrawMapArea(forceRedraw);
}
int MainWindow::getCollision(int x, int y) {
if (!this->editor || !this->editor->map)
return 0;
@ -198,6 +221,24 @@ int MainWindow::getHeight() {
return this->editor->map->getHeight();
}
QJSValue MainWindow::getBorderDimensions() {
if (!this->editor || !this->editor->map)
return QJSValue();
return Scripting::dimensions(this->editor->map->getBorderWidth(), this->editor->map->getBorderHeight());
}
int MainWindow::getBorderWidth() {
if (!this->editor || !this->editor->map)
return 0;
return this->editor->map->getBorderWidth();
}
int MainWindow::getBorderHeight() {
if (!this->editor || !this->editor->map)
return 0;
return this->editor->map->getBorderHeight();
}
void MainWindow::setDimensions(int width, int height) {
if (!this->editor || !this->editor->map)
return;
@ -228,6 +269,36 @@ void MainWindow::setHeight(int height) {
this->onMapNeedsRedrawing();
}
void MainWindow::setBorderDimensions(int width, int height) {
if (!this->editor || !this->editor->map || !projectConfig.getUseCustomBorderSize())
return;
if (width < 1 || height < 1 || width > MAX_BORDER_WIDTH || height > MAX_BORDER_HEIGHT)
return;
this->editor->map->setBorderDimensions(width, height);
this->tryCommitMapChanges(true);
this->onMapNeedsRedrawing();
}
void MainWindow::setBorderWidth(int width) {
if (!this->editor || !this->editor->map || !projectConfig.getUseCustomBorderSize())
return;
if (width < 1 || width > MAX_BORDER_WIDTH)
return;
this->editor->map->setBorderDimensions(width, this->editor->map->getBorderHeight());
this->tryCommitMapChanges(true);
this->onMapNeedsRedrawing();
}
void MainWindow::setBorderHeight(int height) {
if (!this->editor || !this->editor->map || !projectConfig.getUseCustomBorderSize())
return;
if (height < 1 || height > MAX_BORDER_HEIGHT)
return;
this->editor->map->setBorderDimensions(this->editor->map->getBorderWidth(), height);
this->tryCommitMapChanges(true);
this->onMapNeedsRedrawing();
}
void MainWindow::clearOverlay(int layer) {
if (!this->ui || !this->ui->graphicsView_Map)
return;
@ -723,7 +794,7 @@ bool MainWindow::getGridVisibility() {
}
void MainWindow::setBorderVisibility(bool visible) {
this->editor->toggleBorderVisibility(visible);
this->editor->toggleBorderVisibility(visible, false);
}
bool MainWindow::getBorderVisibility() {

View file

@ -1163,8 +1163,8 @@ Tileset* Project::loadTileset(QString label, Tileset *tileset) {
bool Project::loadBlockdata(MapLayout *layout) {
QString path = QString("%1/%2").arg(root).arg(layout->blockdata_path);
layout->blockdata = readBlockdata(path);
layout->lastCommitMapBlocks.blocks = layout->blockdata;
layout->lastCommitMapBlocks.dimensions = QSize(layout->getWidth(), layout->getHeight());
layout->lastCommitBlocks.blocks = layout->blockdata;
layout->lastCommitBlocks.mapDimensions = QSize(layout->getWidth(), layout->getHeight());
if (layout->blockdata.count() != layout->getWidth() * layout->getHeight()) {
logWarn(QString("Layout blockdata length %1 does not match dimensions %2x%3 (should be %4). Resizing blockdata.")
@ -1182,13 +1182,16 @@ void Project::setNewMapBlockdata(Map *map) {
for (int i = 0; i < map->getWidth() * map->getHeight(); i++) {
map->layout->blockdata.append(qint16(0x3001));
}
map->layout->lastCommitMapBlocks.blocks = map->layout->blockdata;
map->layout->lastCommitMapBlocks.dimensions = QSize(map->getWidth(), map->getHeight());
map->layout->lastCommitBlocks.blocks = map->layout->blockdata;
map->layout->lastCommitBlocks.mapDimensions = QSize(map->getWidth(), map->getHeight());
}
bool Project::loadLayoutBorder(MapLayout *layout) {
QString path = QString("%1/%2").arg(root).arg(layout->border_path);
layout->border = readBlockdata(path);
layout->lastCommitBlocks.border = layout->border;
layout->lastCommitBlocks.borderDimensions = QSize(layout->getBorderWidth(), layout->getBorderHeight());
int borderLength = layout->getBorderWidth() * layout->getBorderHeight();
if (layout->border.count() != borderLength) {
logWarn(QString("Layout border blockdata length %1 must be %2. Resizing border blockdata.")
@ -1216,6 +1219,8 @@ void Project::setNewMapBorder(Map *map) {
map->layout->border.append(qint16(0x01DC));
map->layout->border.append(qint16(0x01DD));
}
map->layout->lastCommitBlocks.border = map->layout->border;
map->layout->lastCommitBlocks.borderDimensions = QSize(map->getBorderWidth(), map->getBorderHeight());
}
void Project::saveLayoutBorder(Map *map) {

View file

@ -5,14 +5,17 @@ QMap<CallbackType, QString> callbackFunctions = {
{OnProjectOpened, "onProjectOpened"},
{OnProjectClosed, "onProjectClosed"},
{OnBlockChanged, "onBlockChanged"},
{OnBorderMetatileChanged, "onBorderMetatileChanged"},
{OnBlockHoverChanged, "onBlockHoverChanged"},
{OnBlockHoverCleared, "onBlockHoverCleared"},
{OnMapOpened, "onMapOpened"},
{OnMapResized, "onMapResized"},
{OnBorderResized, "onBorderResized"},
{OnMapShifted, "onMapShifted"},
{OnTilesetUpdated, "onTilesetUpdated"},
{OnMainTabChanged, "onMainTabChanged"},
{OnMapViewTabChanged, "onMapViewTabChanged"},
{OnBorderVisibilityToggled, "onBorderVisibilityToggled"},
};
Scripting *instance = nullptr;
@ -140,6 +143,18 @@ void Scripting::cb_MetatileChanged(int x, int y, Block prevBlock, Block newBlock
instance->invokeCallback(OnBlockChanged, args);
}
void Scripting::cb_BorderMetatileChanged(int x, int y, uint16_t prevMetatileId, uint16_t newMetatileId) {
if (!instance) return;
QJSValueList args {
x,
y,
prevMetatileId,
newMetatileId,
};
instance->invokeCallback(OnBorderMetatileChanged, args);
}
void Scripting::cb_BlockHoverChanged(int x, int y) {
if (!instance) return;
@ -176,6 +191,18 @@ void Scripting::cb_MapResized(int oldWidth, int oldHeight, int newWidth, int new
instance->invokeCallback(OnMapResized, args);
}
void Scripting::cb_BorderResized(int oldWidth, int oldHeight, int newWidth, int newHeight) {
if (!instance) return;
QJSValueList args {
oldWidth,
oldHeight,
newWidth,
newHeight,
};
instance->invokeCallback(OnBorderResized, args);
}
void Scripting::cb_MapShifted(int xDelta, int yDelta) {
if (!instance) return;
@ -215,6 +242,15 @@ void Scripting::cb_MapViewTabChanged(int oldTab, int newTab) {
instance->invokeCallback(OnMapViewTabChanged, args);
}
void Scripting::cb_BorderVisibilityToggled(bool visible) {
if (!instance) return;
QJSValueList args {
visible,
};
instance->invokeCallback(OnBorderVisibilityToggled, args);
}
QJSValue Scripting::fromBlock(Block block) {
QJSValue obj = instance->engine->newObject();
obj.setProperty("metatileId", block.metatileId);

View file

@ -15,9 +15,8 @@ void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
for (int i = 0; i < selectionDimensions.x() && (i + pos.x()) < width; i++) {
for (int j = 0; j < selectionDimensions.y() && (j + pos.y()) < height; j++) {
int blockIndex = (j + pos.y()) * width + (i + pos.x());
uint16_t metatileId = selectedMetatiles->at(j * selectionDimensions.x() + i);
map->layout->border[blockIndex].metatileId = metatileId;
map->setBorderMetatileId(pos.x() + i, pos.y() + j, metatileId, true);
}
}
@ -40,9 +39,8 @@ void BorderMetatilesPixmapItem::draw() {
for (int j = 0; j < height; j++) {
int x = i * 16;
int y = j * 16;
int index = j * width + i;
QImage metatile_image = getMetatileImage(
map->layout->border.value(index).metatileId,
map->getBorderMetatileId(i, j),
map->layout->tileset_primary,
map->layout->tileset_secondary,
map->metatileLayerOrder,