mirror of
https://github.com/huderlem/porymap.git
synced 2026-09-17 13:26:01 -05:00
Standardize API file names
This commit is contained in:
942
src/scriptapi/apimap.cpp
Normal file
942
src/scriptapi/apimap.cpp
Normal file
@@ -0,0 +1,942 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "scripting.h"
|
||||
#include "editcommands.h"
|
||||
#include "config.h"
|
||||
#include "imageproviders.h"
|
||||
|
||||
// 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.
|
||||
void MainWindow::tryRedrawMapArea(bool forceRedraw) {
|
||||
if (!forceRedraw) return;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::tryCommitMapChanges(bool commitChanges) {
|
||||
if (commitChanges) {
|
||||
Map *map = this->editor->map;
|
||||
if (map) {
|
||||
map->editHistory.push(new ScriptEditMap(map,
|
||||
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
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=====================
|
||||
// Editing map blocks
|
||||
//=====================
|
||||
|
||||
QJSValue MainWindow::getBlock(int x, int y) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return QJSValue();
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
return Scripting::fromBlock(Block());
|
||||
}
|
||||
return Scripting::fromBlock(block);
|
||||
}
|
||||
|
||||
void MainWindow::setBlock(int x, int y, int metatileId, int collision, int elevation, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return;
|
||||
this->editor->map->setBlock(x, y, Block(metatileId, collision, elevation));
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
void MainWindow::setBlock(int x, int y, int rawValue, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return;
|
||||
this->editor->map->setBlock(x, y, Block(static_cast<uint16_t>(rawValue)));
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
void MainWindow::setBlocksFromSelection(int x, int y, bool forceRedraw, bool commitChanges) {
|
||||
if (this->editor && this->editor->map_item) {
|
||||
this->editor->map_item->paintNormal(x, y, true);
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
}
|
||||
|
||||
int MainWindow::getMetatileId(int x, int y) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return 0;
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
return 0;
|
||||
}
|
||||
return block.metatileId;
|
||||
}
|
||||
|
||||
void MainWindow::setMetatileId(int x, int y, int metatileId, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return;
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
return;
|
||||
}
|
||||
this->editor->map->setBlock(x, y, Block(metatileId, block.collision, block.elevation));
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
int MainWindow::getCollision(int x, int y) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return 0;
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
return 0;
|
||||
}
|
||||
return block.collision;
|
||||
}
|
||||
|
||||
void MainWindow::setCollision(int x, int y, int collision, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return;
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
return;
|
||||
}
|
||||
this->editor->map->setBlock(x, y, Block(block.metatileId, collision, block.elevation));
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
int MainWindow::getElevation(int x, int y) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return 0;
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
return 0;
|
||||
}
|
||||
return block.elevation;
|
||||
}
|
||||
|
||||
void MainWindow::setElevation(int x, int y, int elevation, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return;
|
||||
Block block;
|
||||
if (!this->editor->map->getBlock(x, y, &block)) {
|
||||
return;
|
||||
}
|
||||
this->editor->map->setBlock(x, y, Block(block.metatileId, block.collision, elevation));
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
void MainWindow::bucketFill(int x, int y, int metatileId, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return;
|
||||
this->editor->map_item->floodFill(x, y, metatileId, true);
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
void MainWindow::bucketFillFromSelection(int x, int y, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return;
|
||||
this->editor->map_item->floodFill(x, y, true);
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
void MainWindow::magicFill(int x, int y, int metatileId, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return;
|
||||
this->editor->map_item->magicFill(x, y, metatileId, true);
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
void MainWindow::magicFillFromSelection(int x, int y, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return;
|
||||
this->editor->map_item->magicFill(x, y, true);
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
void MainWindow::shift(int xDelta, int yDelta, bool forceRedraw, bool commitChanges) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return;
|
||||
this->editor->map_item->shift(xDelta, yDelta, true);
|
||||
this->tryCommitMapChanges(commitChanges);
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
void MainWindow::redraw() {
|
||||
this->tryRedrawMapArea(true);
|
||||
}
|
||||
|
||||
void MainWindow::commit() {
|
||||
this->tryCommitMapChanges(true);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getDimensions() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return QJSValue();
|
||||
return Scripting::dimensions(this->editor->map->getWidth(), this->editor->map->getHeight());
|
||||
}
|
||||
|
||||
int MainWindow::getWidth() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return 0;
|
||||
return this->editor->map->getWidth();
|
||||
}
|
||||
|
||||
int MainWindow::getHeight() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return 0;
|
||||
return this->editor->map->getHeight();
|
||||
}
|
||||
|
||||
void MainWindow::setDimensions(int width, int height) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return;
|
||||
if (!Project::mapDimensionsValid(width, height))
|
||||
return;
|
||||
this->editor->map->setDimensions(width, height);
|
||||
this->tryCommitMapChanges(true);
|
||||
this->onMapNeedsRedrawing();
|
||||
}
|
||||
|
||||
void MainWindow::setWidth(int width) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return;
|
||||
if (!Project::mapDimensionsValid(width, this->editor->map->getHeight()))
|
||||
return;
|
||||
this->editor->map->setDimensions(width, this->editor->map->getHeight());
|
||||
this->tryCommitMapChanges(true);
|
||||
this->onMapNeedsRedrawing();
|
||||
}
|
||||
|
||||
void MainWindow::setHeight(int height) {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return;
|
||||
if (!Project::mapDimensionsValid(this->editor->map->getWidth(), height))
|
||||
return;
|
||||
this->editor->map->setDimensions(this->editor->map->getWidth(), height);
|
||||
this->tryCommitMapChanges(true);
|
||||
this->onMapNeedsRedrawing();
|
||||
}
|
||||
|
||||
//=====================
|
||||
// Editing map border
|
||||
//=====================
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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::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();
|
||||
}
|
||||
|
||||
//======================
|
||||
// Editing map tilesets
|
||||
//======================
|
||||
|
||||
void MainWindow::refreshAfterPaletteChange(Tileset *tileset) {
|
||||
if (this->tilesetEditor) {
|
||||
this->tilesetEditor->updateTilesets(this->editor->map->layout->tileset_primary_label, this->editor->map->layout->tileset_secondary_label);
|
||||
}
|
||||
this->editor->metatile_selector_item->draw();
|
||||
this->editor->selected_border_metatiles_item->draw();
|
||||
this->editor->map_item->draw(true);
|
||||
this->editor->updateMapBorder();
|
||||
this->editor->updateMapConnections();
|
||||
this->editor->project->saveTilesetPalettes(tileset);
|
||||
}
|
||||
|
||||
void MainWindow::setTilesetPalette(Tileset *tileset, int paletteIndex, QList<QList<int>> colors) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout)
|
||||
return;
|
||||
if (paletteIndex >= tileset->palettes.size())
|
||||
return;
|
||||
if (colors.size() != 16)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (colors[i].size() != 3)
|
||||
continue;
|
||||
tileset->palettes[paletteIndex][i] = qRgb(colors[i][0], colors[i][1], colors[i][2]);
|
||||
tileset->palettePreviews[paletteIndex][i] = qRgb(colors[i][0], colors[i][1], colors[i][2]);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setPrimaryTilesetPalette(int paletteIndex, QList<QList<int>> colors) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
return;
|
||||
this->setTilesetPalette(this->editor->map->layout->tileset_primary, paletteIndex, colors);
|
||||
this->refreshAfterPaletteChange(this->editor->map->layout->tileset_primary);
|
||||
}
|
||||
|
||||
void MainWindow::setPrimaryTilesetPalettes(QList<QList<QList<int>>> palettes) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
return;
|
||||
for (int i = 0; i < palettes.size(); i++) {
|
||||
this->setTilesetPalette(this->editor->map->layout->tileset_primary, i, palettes[i]);
|
||||
}
|
||||
this->refreshAfterPaletteChange(this->editor->map->layout->tileset_primary);
|
||||
}
|
||||
|
||||
void MainWindow::setSecondaryTilesetPalette(int paletteIndex, QList<QList<int>> colors) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
return;
|
||||
this->setTilesetPalette(this->editor->map->layout->tileset_secondary, paletteIndex, colors);
|
||||
this->refreshAfterPaletteChange(this->editor->map->layout->tileset_secondary);
|
||||
}
|
||||
|
||||
void MainWindow::setSecondaryTilesetPalettes(QList<QList<QList<int>>> palettes) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
return;
|
||||
for (int i = 0; i < palettes.size(); i++) {
|
||||
this->setTilesetPalette(this->editor->map->layout->tileset_secondary, i, palettes[i]);
|
||||
}
|
||||
this->refreshAfterPaletteChange(this->editor->map->layout->tileset_secondary);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getTilesetPalette(const QList<QList<QRgb>> &palettes, int paletteIndex) {
|
||||
if (paletteIndex >= palettes.size())
|
||||
return QJSValue();
|
||||
|
||||
QList<QList<int>> palette;
|
||||
for (auto color : palettes.value(paletteIndex)) {
|
||||
palette.append(QList<int>({qRed(color), qGreen(color), qBlue(color)}));
|
||||
}
|
||||
return Scripting::getEngine()->toScriptValue(palette);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getTilesetPalettes(const QList<QList<QRgb>> &palettes) {
|
||||
QList<QList<QList<int>>> outPalettes;
|
||||
for (int i = 0; i < palettes.size(); i++) {
|
||||
QList<QList<int>> colors;
|
||||
for (auto color : palettes.value(i)) {
|
||||
colors.append(QList<int>({qRed(color), qGreen(color), qBlue(color)}));
|
||||
}
|
||||
outPalettes.append(colors);
|
||||
}
|
||||
return Scripting::getEngine()->toScriptValue(outPalettes);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getPrimaryTilesetPalette(int paletteIndex) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalette(this->editor->map->layout->tileset_primary->palettes, paletteIndex);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getPrimaryTilesetPalettes() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalettes(this->editor->map->layout->tileset_primary->palettes);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getSecondaryTilesetPalette(int paletteIndex) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalette(this->editor->map->layout->tileset_secondary->palettes, paletteIndex);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getSecondaryTilesetPalettes() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalettes(this->editor->map->layout->tileset_secondary->palettes);
|
||||
}
|
||||
|
||||
void MainWindow::refreshAfterPalettePreviewChange() {
|
||||
this->editor->metatile_selector_item->draw();
|
||||
this->editor->selected_border_metatiles_item->draw();
|
||||
this->editor->map_item->draw(true);
|
||||
this->editor->updateMapBorder();
|
||||
this->editor->updateMapConnections();
|
||||
}
|
||||
|
||||
void MainWindow::setTilesetPalettePreview(Tileset *tileset, int paletteIndex, QList<QList<int>> colors) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout)
|
||||
return;
|
||||
if (paletteIndex >= tileset->palettePreviews.size())
|
||||
return;
|
||||
if (colors.size() != 16)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (colors[i].size() != 3)
|
||||
continue;
|
||||
tileset->palettePreviews[paletteIndex][i] = qRgb(colors[i][0], colors[i][1], colors[i][2]);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setPrimaryTilesetPalettePreview(int paletteIndex, QList<QList<int>> colors) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
return;
|
||||
this->setTilesetPalettePreview(this->editor->map->layout->tileset_primary, paletteIndex, colors);
|
||||
this->refreshAfterPalettePreviewChange();
|
||||
}
|
||||
|
||||
void MainWindow::setPrimaryTilesetPalettesPreview(QList<QList<QList<int>>> palettes) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
return;
|
||||
for (int i = 0; i < palettes.size(); i++) {
|
||||
this->setTilesetPalettePreview(this->editor->map->layout->tileset_primary, i, palettes[i]);
|
||||
}
|
||||
this->refreshAfterPalettePreviewChange();
|
||||
}
|
||||
|
||||
void MainWindow::setSecondaryTilesetPalettePreview(int paletteIndex, QList<QList<int>> colors) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
return;
|
||||
this->setTilesetPalettePreview(this->editor->map->layout->tileset_secondary, paletteIndex, colors);
|
||||
this->refreshAfterPalettePreviewChange();
|
||||
}
|
||||
|
||||
void MainWindow::setSecondaryTilesetPalettesPreview(QList<QList<QList<int>>> palettes) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
return;
|
||||
for (int i = 0; i < palettes.size(); i++) {
|
||||
this->setTilesetPalettePreview(this->editor->map->layout->tileset_secondary, i, palettes[i]);
|
||||
}
|
||||
this->refreshAfterPalettePreviewChange();
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getPrimaryTilesetPalettePreview(int paletteIndex) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalette(this->editor->map->layout->tileset_primary->palettePreviews, paletteIndex);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getPrimaryTilesetPalettesPreview() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalettes(this->editor->map->layout->tileset_primary->palettePreviews);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getSecondaryTilesetPalettePreview(int paletteIndex) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalette(this->editor->map->layout->tileset_secondary->palettePreviews, paletteIndex);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getSecondaryTilesetPalettesPreview() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
return QJSValue();
|
||||
return this->getTilesetPalettes(this->editor->map->layout->tileset_secondary->palettePreviews);
|
||||
}
|
||||
|
||||
int MainWindow::getNumPrimaryTilesetMetatiles() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
return 0;
|
||||
return this->editor->map->layout->tileset_primary->metatiles.length();
|
||||
}
|
||||
|
||||
int MainWindow::getNumSecondaryTilesetMetatiles() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
return 0;
|
||||
return this->editor->map->layout->tileset_secondary->metatiles.length();
|
||||
}
|
||||
|
||||
int MainWindow::getNumPrimaryTilesetTiles() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
return 0;
|
||||
return this->editor->map->layout->tileset_primary->tiles.length();
|
||||
}
|
||||
|
||||
int MainWindow::getNumSecondaryTilesetTiles() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
return 0;
|
||||
return this->editor->map->layout->tileset_secondary->tiles.length();
|
||||
}
|
||||
|
||||
QString MainWindow::getPrimaryTileset() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary)
|
||||
return QString();
|
||||
return this->editor->map->layout->tileset_primary->name;
|
||||
}
|
||||
|
||||
QString MainWindow::getSecondaryTileset() {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary)
|
||||
return QString();
|
||||
return this->editor->map->layout->tileset_secondary->name;
|
||||
}
|
||||
|
||||
void MainWindow::setPrimaryTileset(QString tileset) {
|
||||
this->on_comboBox_PrimaryTileset_currentTextChanged(tileset);
|
||||
}
|
||||
|
||||
void MainWindow::setSecondaryTileset(QString tileset) {
|
||||
this->on_comboBox_SecondaryTileset_currentTextChanged(tileset);
|
||||
}
|
||||
|
||||
void MainWindow::saveMetatilesByMetatileId(int metatileId) {
|
||||
Tileset * tileset = Tileset::getMetatileTileset(metatileId, this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary);
|
||||
if (this->editor->project && tileset)
|
||||
this->editor->project->saveTilesetMetatiles(tileset);
|
||||
|
||||
// Refresh anything that can display metatiles (except the actual map view)
|
||||
if (this->tilesetEditor)
|
||||
this->tilesetEditor->updateTilesets(this->editor->map->layout->tileset_primary_label, this->editor->map->layout->tileset_secondary_label);
|
||||
if (this->editor->metatile_selector_item)
|
||||
this->editor->metatile_selector_item->draw();
|
||||
if (this->editor->selected_border_metatiles_item)
|
||||
this->editor->selected_border_metatiles_item->draw();
|
||||
if (this->editor->current_metatile_selection_item)
|
||||
this->editor->current_metatile_selection_item->draw();
|
||||
}
|
||||
|
||||
void MainWindow::saveMetatileAttributesByMetatileId(int metatileId) {
|
||||
Tileset * tileset = Tileset::getMetatileTileset(metatileId, this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary);
|
||||
if (this->editor->project && tileset)
|
||||
this->editor->project->saveTilesetMetatileAttributes(tileset);
|
||||
|
||||
// If the Tileset Editor is currently displaying the updated metatile, refresh it
|
||||
if (this->tilesetEditor && this->tilesetEditor->getSelectedMetatileId() == metatileId)
|
||||
this->tilesetEditor->updateTilesets(this->editor->map->layout->tileset_primary_label, this->editor->map->layout->tileset_secondary_label);
|
||||
}
|
||||
|
||||
Metatile * MainWindow::getMetatile(int metatileId) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout)
|
||||
return nullptr;
|
||||
return Tileset::getMetatile(metatileId, this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary);
|
||||
}
|
||||
|
||||
QString MainWindow::getMetatileLabel(int metatileId) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
if (!metatile || metatile->label.size() == 0)
|
||||
return QString();
|
||||
return metatile->label;
|
||||
}
|
||||
|
||||
void MainWindow::setMetatileLabel(int metatileId, QString label) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
if (!metatile)
|
||||
return;
|
||||
|
||||
QRegularExpression expression("[_A-Za-z0-9]*$");
|
||||
QRegularExpressionValidator validator(expression);
|
||||
int pos = 0;
|
||||
if (validator.validate(label, pos) != QValidator::Acceptable) {
|
||||
logError(QString("Invalid metatile label %1").arg(label));
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->tilesetEditor && this->tilesetEditor->getSelectedMetatileId() == metatileId) {
|
||||
this->tilesetEditor->setMetatileLabel(label);
|
||||
} else if (metatile->label != label) {
|
||||
metatile->label = label;
|
||||
if (this->editor->project)
|
||||
this->editor->project->saveTilesetMetatileLabels(this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary);
|
||||
}
|
||||
}
|
||||
|
||||
int MainWindow::getMetatileLayerType(int metatileId) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
if (!metatile)
|
||||
return -1;
|
||||
return metatile->layerType;
|
||||
}
|
||||
|
||||
void MainWindow::setMetatileLayerType(int metatileId, int layerType) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
uint8_t u_layerType = static_cast<uint8_t>(layerType);
|
||||
if (!metatile || metatile->layerType == u_layerType || u_layerType >= NUM_METATILE_LAYER_TYPES)
|
||||
return;
|
||||
metatile->layerType = u_layerType;
|
||||
this->saveMetatileAttributesByMetatileId(metatileId);
|
||||
}
|
||||
|
||||
int MainWindow::getMetatileEncounterType(int metatileId) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
if (!metatile)
|
||||
return -1;
|
||||
return metatile->encounterType;
|
||||
}
|
||||
|
||||
void MainWindow::setMetatileEncounterType(int metatileId, int encounterType) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
uint8_t u_encounterType = static_cast<uint8_t>(encounterType);
|
||||
if (!metatile || metatile->encounterType == u_encounterType || u_encounterType >= NUM_METATILE_ENCOUNTER_TYPES)
|
||||
return;
|
||||
metatile->encounterType = u_encounterType;
|
||||
this->saveMetatileAttributesByMetatileId(metatileId);
|
||||
}
|
||||
|
||||
int MainWindow::getMetatileTerrainType(int metatileId) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
if (!metatile)
|
||||
return -1;
|
||||
return metatile->terrainType;
|
||||
}
|
||||
|
||||
void MainWindow::setMetatileTerrainType(int metatileId, int terrainType) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
uint8_t u_terrainType = static_cast<uint8_t>(terrainType);
|
||||
if (!metatile || metatile->terrainType == u_terrainType || u_terrainType >= NUM_METATILE_TERRAIN_TYPES)
|
||||
return;
|
||||
metatile->terrainType = u_terrainType;
|
||||
this->saveMetatileAttributesByMetatileId(metatileId);
|
||||
}
|
||||
|
||||
int MainWindow::getMetatileBehavior(int metatileId) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
if (!metatile)
|
||||
return -1;
|
||||
return metatile->behavior;
|
||||
}
|
||||
|
||||
void MainWindow::setMetatileBehavior(int metatileId, int behavior) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
uint16_t u_behavior = static_cast<uint16_t>(behavior);
|
||||
if (!metatile || metatile->behavior == u_behavior)
|
||||
return;
|
||||
metatile->behavior = u_behavior;
|
||||
this->saveMetatileAttributesByMetatileId(metatileId);
|
||||
}
|
||||
|
||||
int MainWindow::getMetatileAttributes(int metatileId) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
if (!metatile)
|
||||
return -1;
|
||||
return metatile->getAttributes(projectConfig.getBaseGameVersion());
|
||||
}
|
||||
|
||||
void MainWindow::setMetatileAttributes(int metatileId, int attributes) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
uint32_t u_attributes = static_cast<uint32_t>(attributes);
|
||||
if (!metatile)
|
||||
return;
|
||||
metatile->setAttributes(u_attributes, projectConfig.getBaseGameVersion());
|
||||
this->saveMetatileAttributesByMetatileId(metatileId);
|
||||
}
|
||||
|
||||
int MainWindow::calculateTileBounds(int * tileStart, int * tileEnd) {
|
||||
int maxNumTiles = projectConfig.getTripleLayerMetatilesEnabled() ? 12 : 8;
|
||||
if (*tileEnd >= maxNumTiles || *tileEnd < 0)
|
||||
*tileEnd = maxNumTiles - 1;
|
||||
if (*tileStart >= maxNumTiles || *tileStart < 0)
|
||||
*tileStart = 0;
|
||||
return 1 + (*tileEnd - *tileStart);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getMetatileTiles(int metatileId, int tileStart, int tileEnd) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
int numTiles = calculateTileBounds(&tileStart, &tileEnd);
|
||||
if (!metatile || numTiles <= 0)
|
||||
return QJSValue();
|
||||
|
||||
QJSValue tiles = Scripting::getEngine()->newArray(numTiles);
|
||||
for (int i = 0; i < numTiles; i++, tileStart++)
|
||||
tiles.setProperty(i, Scripting::fromTile(metatile->tiles[tileStart]));
|
||||
return tiles;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// Write to metatile using as many of the given Tiles as possible
|
||||
int numTileObjs = qMin(tilesObj.property("length").toInt(), numTiles);
|
||||
int i = 0;
|
||||
for (; i < numTileObjs; i++, tileStart++)
|
||||
metatile->tiles[tileStart] = Scripting::toTile(tilesObj.property(i));
|
||||
|
||||
// Fill remainder of specified length with empty Tiles
|
||||
for (; i < numTiles; i++, tileStart++)
|
||||
metatile->tiles[tileStart] = Tile();
|
||||
|
||||
this->saveMetatilesByMetatileId(metatileId);
|
||||
this->needsFullRedraw = true;
|
||||
this->tryRedrawMapArea(forceRedraw);
|
||||
}
|
||||
|
||||
void MainWindow::setMetatileTiles(int metatileId, int tileId, bool xflip, bool yflip, int palette, int tileStart, int tileEnd, bool forceRedraw) {
|
||||
Metatile * metatile = this->getMetatile(metatileId);
|
||||
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 = tileStart; i <= tileEnd; 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);
|
||||
}
|
||||
|
||||
QJSValue MainWindow::getTilePixels(int tileId) {
|
||||
if (tileId < 0 || !this->editor || !this->editor->project || !this->editor->map || !this->editor->map->layout)
|
||||
return QJSValue();
|
||||
QImage tileImage = getTileImage(tileId, this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary);
|
||||
if (tileImage.isNull() || tileImage.sizeInBytes() < 64)
|
||||
return QJSValue();
|
||||
const uchar * pixels = tileImage.constBits();
|
||||
QJSValue pixelArray = Scripting::getEngine()->newArray(64);
|
||||
for (int i = 0; i < 64; i++) {
|
||||
pixelArray.setProperty(i, pixels[i]);
|
||||
}
|
||||
return pixelArray;
|
||||
}
|
||||
|
||||
//=====================
|
||||
// Editing map header
|
||||
//=====================
|
||||
|
||||
bool MainWindow::gameStringToBool(QString s) {
|
||||
return (s.toInt() > 0 || s == "TRUE");
|
||||
}
|
||||
|
||||
QString MainWindow::getSong() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return QString();
|
||||
return this->editor->map->song;
|
||||
}
|
||||
|
||||
void MainWindow::setSong(QString song) {
|
||||
if (!this->ui || !this->editor || !this->editor->project)
|
||||
return;
|
||||
if (!this->editor->project->songNames.contains(song)) {
|
||||
logError(QString("Unknown song '%1'").arg(song));
|
||||
return;
|
||||
}
|
||||
this->ui->comboBox_Song->setCurrentText(song);
|
||||
}
|
||||
|
||||
QString MainWindow::getLocation() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return QString();
|
||||
return this->editor->map->location;
|
||||
}
|
||||
|
||||
void MainWindow::setLocation(QString location) {
|
||||
if (!this->ui || !this->editor || !this->editor->project)
|
||||
return;
|
||||
if (!this->editor->project->mapSectionNameToValue.contains(location)) {
|
||||
logError(QString("Unknown location '%1'").arg(location));
|
||||
return;
|
||||
}
|
||||
this->ui->comboBox_Location->setCurrentText(location);
|
||||
}
|
||||
|
||||
bool MainWindow::getRequiresFlash() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return false;
|
||||
return this->gameStringToBool(this->editor->map->requiresFlash);
|
||||
}
|
||||
|
||||
void MainWindow::setRequiresFlash(bool require) {
|
||||
if (!this->ui)
|
||||
return;
|
||||
this->ui->checkBox_Visibility->setChecked(require);
|
||||
}
|
||||
|
||||
QString MainWindow::getWeather() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return QString();
|
||||
return this->editor->map->weather;
|
||||
}
|
||||
|
||||
void MainWindow::setWeather(QString weather) {
|
||||
if (!this->ui || !this->editor || !this->editor->project)
|
||||
return;
|
||||
if (!this->editor->project->weatherNames.contains(weather)) {
|
||||
logError(QString("Unknown weather '%1'").arg(weather));
|
||||
return;
|
||||
}
|
||||
this->ui->comboBox_Weather->setCurrentText(weather);
|
||||
}
|
||||
|
||||
QString MainWindow::getType() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return QString();
|
||||
return this->editor->map->type;
|
||||
}
|
||||
|
||||
void MainWindow::setType(QString type) {
|
||||
if (!this->ui || !this->editor || !this->editor->project)
|
||||
return;
|
||||
if (!this->editor->project->mapTypes.contains(type)) {
|
||||
logError(QString("Unknown map type '%1'").arg(type));
|
||||
return;
|
||||
}
|
||||
this->ui->comboBox_Type->setCurrentText(type);
|
||||
}
|
||||
|
||||
QString MainWindow::getBattleScene() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return QString();
|
||||
return this->editor->map->battle_scene;
|
||||
}
|
||||
|
||||
void MainWindow::setBattleScene(QString battleScene) {
|
||||
if (!this->ui || !this->editor || !this->editor->project)
|
||||
return;
|
||||
if (!this->editor->project->mapBattleScenes.contains(battleScene)) {
|
||||
logError(QString("Unknown battle scene '%1'").arg(battleScene));
|
||||
return;
|
||||
}
|
||||
this->ui->comboBox_BattleScene->setCurrentText(battleScene);
|
||||
}
|
||||
|
||||
bool MainWindow::getShowLocationName() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return false;
|
||||
return this->gameStringToBool(this->editor->map->show_location);
|
||||
}
|
||||
|
||||
void MainWindow::setShowLocationName(bool show) {
|
||||
if (!this->ui)
|
||||
return;
|
||||
this->ui->checkBox_ShowLocation->setChecked(show);
|
||||
}
|
||||
|
||||
bool MainWindow::getAllowRunning() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return false;
|
||||
return this->gameStringToBool(this->editor->map->allowRunning);
|
||||
}
|
||||
|
||||
void MainWindow::setAllowRunning(bool allow) {
|
||||
if (!this->ui)
|
||||
return;
|
||||
this->ui->checkBox_AllowRunning->setChecked(allow);
|
||||
}
|
||||
|
||||
bool MainWindow::getAllowBiking() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return false;
|
||||
return this->gameStringToBool(this->editor->map->allowBiking);
|
||||
}
|
||||
|
||||
void MainWindow::setAllowBiking(bool allow) {
|
||||
if (!this->ui)
|
||||
return;
|
||||
this->ui->checkBox_AllowBiking->setChecked(allow);
|
||||
}
|
||||
|
||||
bool MainWindow::getAllowEscaping() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return false;
|
||||
return this->gameStringToBool(this->editor->map->allowEscapeRope);
|
||||
}
|
||||
|
||||
void MainWindow::setAllowEscaping(bool allow) {
|
||||
if (!this->ui)
|
||||
return;
|
||||
this->ui->checkBox_AllowEscapeRope->setChecked(allow);
|
||||
}
|
||||
|
||||
int MainWindow::getFloorNumber() {
|
||||
if (!this->editor || !this->editor->map)
|
||||
return 0;
|
||||
return this->editor->map->floorNumber;
|
||||
}
|
||||
|
||||
void MainWindow::setFloorNumber(int floorNumber) {
|
||||
if (!this->ui)
|
||||
return;
|
||||
if (floorNumber < -128 || floorNumber > 127) {
|
||||
logError(QString("Invalid floor number '%1'").arg(floorNumber));
|
||||
return;
|
||||
}
|
||||
this->ui->spinBox_FloorNumber->setValue(floorNumber);
|
||||
}
|
||||
|
||||
191
src/scriptapi/apioverlay.cpp
Normal file
191
src/scriptapi/apioverlay.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
#include "mapview.h"
|
||||
#include "scripting.h"
|
||||
#include "imageproviders.h"
|
||||
|
||||
void MapView::clear(int layer) {
|
||||
this->getOverlay(layer)->clearItems();
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
// Overload. No layer provided, clear all layers
|
||||
void MapView::clear() {
|
||||
this->clearOverlayMap();
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
void MapView::hide(int layer) {
|
||||
this->setVisibility(false, layer);
|
||||
}
|
||||
|
||||
// Overload. No layer provided, hide all layers
|
||||
void MapView::hide() {
|
||||
this->setVisibility(false);
|
||||
}
|
||||
|
||||
void MapView::show(int layer) {
|
||||
this->setVisibility(true, layer);
|
||||
}
|
||||
|
||||
// Overload. No layer provided, show all layers
|
||||
void MapView::show() {
|
||||
this->setVisibility(true);
|
||||
}
|
||||
|
||||
bool MapView::getVisibility(int layer) {
|
||||
return !(this->getOverlay(layer)->getHidden());
|
||||
}
|
||||
|
||||
void MapView::setVisibility(bool visible, int layer) {
|
||||
this->getOverlay(layer)->setHidden(!visible);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
// Overload. No layer provided, set visibility of all layers
|
||||
void MapView::setVisibility(bool visible) {
|
||||
foreach (Overlay * layer, this->overlayMap)
|
||||
layer->setHidden(!visible);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
int MapView::getX(int layer) {
|
||||
return this->getOverlay(layer)->getX();
|
||||
}
|
||||
|
||||
int MapView::getY(int layer) {
|
||||
return this->getOverlay(layer)->getY();
|
||||
}
|
||||
|
||||
void MapView::setX(int x, int layer) {
|
||||
this->getOverlay(layer)->setX(x);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
// Overload. No layer provided, set x of all layers
|
||||
void MapView::setX(int x) {
|
||||
foreach (Overlay * layer, this->overlayMap)
|
||||
layer->setX(x);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
void MapView::setY(int y, int layer) {
|
||||
this->getOverlay(layer)->setY(y);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
// Overload. No layer provided, set y of all layers
|
||||
void MapView::setY(int y) {
|
||||
foreach (Overlay * layer, this->overlayMap)
|
||||
layer->setY(y);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
QJSValue MapView::getPosition(int layer) {
|
||||
Overlay * overlay = this->getOverlay(layer);
|
||||
return Scripting::position(overlay->getX(), overlay->getY());
|
||||
}
|
||||
|
||||
void MapView::setPosition(int x, int y, int layer) {
|
||||
this->getOverlay(layer)->setPosition(x, y);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
// Overload. No layer provided, set position of all layers
|
||||
void MapView::setPosition(int x, int y) {
|
||||
foreach (Overlay * layer, this->overlayMap)
|
||||
layer->setPosition(x, y);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
void MapView::move(int deltaX, int deltaY, int layer) {
|
||||
this->getOverlay(layer)->move(deltaX, deltaY);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
// Overload. No layer provided, move all layers
|
||||
void MapView::move(int deltaX, int deltaY) {
|
||||
foreach (Overlay * layer, this->overlayMap)
|
||||
layer->move(deltaX, deltaY);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
int MapView::getOpacity(int layer) {
|
||||
return this->getOverlay(layer)->getOpacity();
|
||||
}
|
||||
|
||||
void MapView::setOpacity(int opacity, int layer) {
|
||||
this->getOverlay(layer)->setOpacity(opacity);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
// Overload. No layer provided, set opacity of all layers
|
||||
void MapView::setOpacity(int opacity) {
|
||||
foreach (Overlay * layer, this->overlayMap)
|
||||
layer->setOpacity(opacity);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
void MapView::addText(QString text, int x, int y, QString color, int fontSize, int layer) {
|
||||
this->getOverlay(layer)->addText(text, x, y, color, fontSize);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
void MapView::addRect(int x, int y, int width, int height, QString color, int layer) {
|
||||
this->getOverlay(layer)->addRect(x, y, width, height, color, false);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
void MapView::addFilledRect(int x, int y, int width, int height, QString color, int layer) {
|
||||
this->getOverlay(layer)->addRect(x, y, width, height, color, true);
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
void MapView::addImage(int x, int y, QString filepath, int layer, bool useCache) {
|
||||
if (this->getOverlay(layer)->addImage(x, y, filepath, useCache))
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
void MapView::createImage(int x, int y, QString filepath, int width, int height, unsigned offset, qreal hScale, qreal vScale, int paletteId, bool setTransparency, int layer, bool useCache) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout
|
||||
|| !this->editor->map->layout->tileset_primary || !this->editor->map->layout->tileset_secondary)
|
||||
return;
|
||||
QList<QRgb> palette;
|
||||
if (paletteId != -1)
|
||||
palette = Tileset::getPalette(paletteId, this->editor->map->layout->tileset_primary, this->editor->map->layout->tileset_secondary);
|
||||
if (this->getOverlay(layer)->addImage(x, y, filepath, useCache, width, height, offset, hScale, vScale, palette, setTransparency))
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
void MapView::addTileImage(int x, int y, int tileId, bool xflip, bool yflip, int paletteId, bool setTransparency, int layer) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout
|
||||
|| !this->editor->map->layout->tileset_primary || !this->editor->map->layout->tileset_secondary)
|
||||
return;
|
||||
QImage image = getPalettedTileImage(tileId,
|
||||
this->editor->map->layout->tileset_primary,
|
||||
this->editor->map->layout->tileset_secondary,
|
||||
paletteId)
|
||||
.mirrored(xflip, yflip);
|
||||
if (setTransparency)
|
||||
image.setColor(0, qRgba(0, 0, 0, 0));
|
||||
if (this->getOverlay(layer)->addImage(x, y, image))
|
||||
this->scene()->update();
|
||||
}
|
||||
|
||||
void MapView::addTileImage(int x, int y, QJSValue tileObj, bool setTransparency, int layer) {
|
||||
Tile tile = Scripting::toTile(tileObj);
|
||||
this->addTileImage(x, y, tile.tileId, tile.xflip, tile.yflip, tile.palette, setTransparency, layer);
|
||||
}
|
||||
|
||||
void MapView::addMetatileImage(int x, int y, int metatileId, bool setTransparency, int layer) {
|
||||
if (!this->editor || !this->editor->map || !this->editor->map->layout
|
||||
|| !this->editor->map->layout->tileset_primary || !this->editor->map->layout->tileset_secondary)
|
||||
return;
|
||||
QImage image = getMetatileImage(static_cast<uint16_t>(metatileId),
|
||||
this->editor->map->layout->tileset_primary,
|
||||
this->editor->map->layout->tileset_secondary,
|
||||
this->editor->map->metatileLayerOrder,
|
||||
this->editor->map->metatileLayerOpacity);
|
||||
if (setTransparency)
|
||||
image.setColor(0, qRgba(0, 0, 0, 0));
|
||||
if (this->getOverlay(layer)->addImage(x, y, image))
|
||||
this->scene()->update();
|
||||
}
|
||||
224
src/scriptapi/apiutility.cpp
Normal file
224
src/scriptapi/apiutility.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "scripting.h"
|
||||
#include "config.h"
|
||||
|
||||
ScriptUtility::ScriptUtility(MainWindow *mainWindow) {
|
||||
this->window = mainWindow;
|
||||
}
|
||||
|
||||
void ScriptUtility::registerAction(QString functionName, QString actionName, QString shortcut) {
|
||||
if (!window || !window->ui || !window->ui->menuTools)
|
||||
return;
|
||||
|
||||
this->actionMap.insert(actionName, functionName);
|
||||
if (this->actionMap.size() == 1) {
|
||||
QAction *section = window->ui->menuTools->addSection("Custom Actions");
|
||||
this->registeredActions.append(section);
|
||||
}
|
||||
QAction *action = window->ui->menuTools->addAction(actionName, [actionName](){
|
||||
Scripting::invokeAction(actionName);
|
||||
});
|
||||
if (!shortcut.isEmpty()) {
|
||||
action->setShortcut(QKeySequence(shortcut));
|
||||
}
|
||||
this->registeredActions.append(action);
|
||||
}
|
||||
|
||||
void ScriptUtility::clearActions() {
|
||||
for (auto action : this->registeredActions) {
|
||||
window->ui->menuTools->removeAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
QString ScriptUtility::getActionFunctionName(QString actionName) {
|
||||
return this->actionMap.value(actionName);
|
||||
}
|
||||
|
||||
void ScriptUtility::setTimeout(QJSValue callback, int milliseconds) {
|
||||
if (!callback.isCallable() || milliseconds < 0)
|
||||
return;
|
||||
|
||||
QTimer *timer = new QTimer(0);
|
||||
connect(timer, &QTimer::timeout, [=](){
|
||||
this->callTimeoutFunction(callback);
|
||||
});
|
||||
connect(timer, &QTimer::timeout, timer, &QTimer::deleteLater);
|
||||
timer->setSingleShot(true);
|
||||
timer->start(milliseconds);
|
||||
}
|
||||
|
||||
void ScriptUtility::callTimeoutFunction(QJSValue callback) {
|
||||
Scripting::tryErrorJS(callback.call());
|
||||
}
|
||||
|
||||
void ScriptUtility::log(QString message) {
|
||||
logInfo(message);
|
||||
}
|
||||
|
||||
void ScriptUtility::warn(QString message) {
|
||||
logWarn(message);
|
||||
}
|
||||
|
||||
void ScriptUtility::error(QString message) {
|
||||
logError(message);
|
||||
}
|
||||
|
||||
void ScriptUtility::runMessageBox(QString text, QString informativeText, QString detailedText, QMessageBox::Icon icon) {
|
||||
QMessageBox messageBox(window);
|
||||
messageBox.setText(text);
|
||||
messageBox.setInformativeText(informativeText);
|
||||
messageBox.setDetailedText(detailedText);
|
||||
messageBox.setIcon(icon);
|
||||
messageBox.exec();
|
||||
}
|
||||
|
||||
void ScriptUtility::showMessage(QString text, QString informativeText, QString detailedText) {
|
||||
this->runMessageBox(text, informativeText, detailedText, QMessageBox::Information);
|
||||
}
|
||||
|
||||
void ScriptUtility::showWarning(QString text, QString informativeText, QString detailedText) {
|
||||
this->runMessageBox(text, informativeText, detailedText, QMessageBox::Warning);
|
||||
}
|
||||
|
||||
void ScriptUtility::showError(QString text, QString informativeText, QString detailedText) {
|
||||
this->runMessageBox(text, informativeText, detailedText, QMessageBox::Critical);
|
||||
}
|
||||
|
||||
bool ScriptUtility::showQuestion(QString text, QString informativeText, QString detailedText) {
|
||||
QMessageBox messageBox(window);
|
||||
messageBox.setText(text);
|
||||
messageBox.setInformativeText(informativeText);
|
||||
messageBox.setDetailedText(detailedText);
|
||||
messageBox.setIcon(QMessageBox::Question);
|
||||
messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
return messageBox.exec() == QMessageBox::Yes;
|
||||
}
|
||||
|
||||
QJSValue ScriptUtility::getInputText(QString title, QString label, QString defaultValue) {
|
||||
bool ok;
|
||||
QString input = QInputDialog::getText(window, title, label, QLineEdit::Normal, defaultValue, &ok);
|
||||
return Scripting::dialogInput(input, ok);
|
||||
}
|
||||
|
||||
QJSValue ScriptUtility::getInputNumber(QString title, QString label, double defaultValue, double min, double max, int decimals, double step) {
|
||||
bool ok;
|
||||
double input = QInputDialog::getDouble(window, title, label, defaultValue, min, max, decimals, &ok, Qt::WindowFlags(), step);
|
||||
return Scripting::dialogInput(input, ok);
|
||||
}
|
||||
|
||||
QJSValue ScriptUtility::getInputItem(QString title, QString label, QStringList items, int defaultValue, bool editable) {
|
||||
bool ok;
|
||||
QString input = QInputDialog::getItem(window, title, label, items, defaultValue, editable, &ok);
|
||||
return Scripting::dialogInput(input, ok);
|
||||
}
|
||||
|
||||
int ScriptUtility::getMainTab() {
|
||||
if (!window || !window->ui || !window->ui->mainTabBar)
|
||||
return -1;
|
||||
return window->ui->mainTabBar->currentIndex();
|
||||
}
|
||||
|
||||
void ScriptUtility::setMainTab(int index) {
|
||||
if (!window || !window->ui || !window->ui->mainTabBar || index < 0 || index >= window->ui->mainTabBar->count())
|
||||
return;
|
||||
// Can't select Wild Encounters tab if it's disabled
|
||||
if (index == 4 && !projectConfig.getEncounterJsonActive())
|
||||
return;
|
||||
window->on_mainTabBar_tabBarClicked(index);
|
||||
}
|
||||
|
||||
int ScriptUtility::getMapViewTab() {
|
||||
if (!window || !window->ui || !window->ui->mapViewTab)
|
||||
return -1;
|
||||
return window->ui->mapViewTab->currentIndex();
|
||||
}
|
||||
|
||||
void ScriptUtility::setMapViewTab(int index) {
|
||||
if (this->getMainTab() != 0 || !window->ui->mapViewTab || index < 0 || index >= window->ui->mapViewTab->count())
|
||||
return;
|
||||
window->on_mapViewTab_tabBarClicked(index);
|
||||
}
|
||||
|
||||
void ScriptUtility::setGridVisibility(bool visible) {
|
||||
window->ui->checkBox_ToggleGrid->setChecked(visible);
|
||||
}
|
||||
|
||||
bool ScriptUtility::getGridVisibility() {
|
||||
return window->ui->checkBox_ToggleGrid->isChecked();
|
||||
}
|
||||
|
||||
void ScriptUtility::setBorderVisibility(bool visible) {
|
||||
window->editor->toggleBorderVisibility(visible, false);
|
||||
}
|
||||
|
||||
bool ScriptUtility::getBorderVisibility() {
|
||||
return window->ui->checkBox_ToggleBorder->isChecked();
|
||||
}
|
||||
|
||||
void ScriptUtility::setSmartPathsEnabled(bool visible) {
|
||||
window->ui->checkBox_smartPaths->setChecked(visible);
|
||||
}
|
||||
|
||||
bool ScriptUtility::getSmartPathsEnabled() {
|
||||
return window->ui->checkBox_smartPaths->isChecked();
|
||||
}
|
||||
|
||||
QList<QString> ScriptUtility::getCustomScripts() {
|
||||
return projectConfig.getCustomScripts();
|
||||
}
|
||||
|
||||
QList<int> ScriptUtility::getMetatileLayerOrder() {
|
||||
if (!window || !window->editor || !window->editor->map)
|
||||
return QList<int>();
|
||||
return window->editor->map->metatileLayerOrder;
|
||||
}
|
||||
|
||||
void ScriptUtility::setMetatileLayerOrder(QList<int> order) {
|
||||
if (!window || !window->editor || !window->editor->map)
|
||||
return;
|
||||
|
||||
const int numLayers = 3;
|
||||
int size = order.size();
|
||||
if (size < numLayers) {
|
||||
logError(QString("Metatile layer order has insufficient elements (%1), needs at least %2.").arg(size).arg(numLayers));
|
||||
return;
|
||||
}
|
||||
bool invalid = false;
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
int layer = order.at(i);
|
||||
if (layer < 0 || layer >= numLayers) {
|
||||
logError(QString("'%1' is not a valid metatile layer order value, must be in range 0-%2.").arg(layer).arg(numLayers - 1));
|
||||
invalid = true;
|
||||
}
|
||||
}
|
||||
if (invalid) return;
|
||||
|
||||
window->editor->map->metatileLayerOrder = order;
|
||||
window->refreshAfterPalettePreviewChange();
|
||||
}
|
||||
|
||||
QList<float> ScriptUtility::getMetatileLayerOpacity() {
|
||||
if (!window || !window->editor || !window->editor->map)
|
||||
return QList<float>();
|
||||
return window->editor->map->metatileLayerOpacity;
|
||||
}
|
||||
|
||||
void ScriptUtility::setMetatileLayerOpacity(QList<float> order) {
|
||||
if (!window || !window->editor || !window->editor->map)
|
||||
return;
|
||||
window->editor->map->metatileLayerOpacity = order;
|
||||
window->refreshAfterPalettePreviewChange();
|
||||
}
|
||||
|
||||
bool ScriptUtility::isPrimaryTileset(QString tilesetName) {
|
||||
if (!window || !window->editor || !window->editor->project)
|
||||
return false;
|
||||
return window->editor->project->tilesetLabels["primary"].contains(tilesetName);
|
||||
}
|
||||
|
||||
bool ScriptUtility::isSecondaryTileset(QString tilesetName) {
|
||||
if (!window || !window->editor || !window->editor->project)
|
||||
return false;
|
||||
return window->editor->project->tilesetLabels["secondary"].contains(tilesetName);
|
||||
}
|
||||
363
src/scriptapi/scripting.cpp
Normal file
363
src/scriptapi/scripting.cpp
Normal file
@@ -0,0 +1,363 @@
|
||||
#include "scripting.h"
|
||||
#include "log.h"
|
||||
#include "config.h"
|
||||
#include "aboutporymap.h"
|
||||
|
||||
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;
|
||||
|
||||
void Scripting::init(MainWindow *mainWindow) {
|
||||
if (instance) {
|
||||
instance->engine->setInterrupted(true);
|
||||
instance->scriptUtility->clearActions();
|
||||
qDeleteAll(instance->imageCache);
|
||||
delete instance;
|
||||
}
|
||||
instance = new Scripting(mainWindow);
|
||||
}
|
||||
|
||||
Scripting::Scripting(MainWindow *mainWindow) {
|
||||
this->engine = new QJSEngine(mainWindow);
|
||||
this->engine->installExtensions(QJSEngine::ConsoleExtension);
|
||||
for (QString script : projectConfig.getCustomScripts()) {
|
||||
this->filepaths.append(script);
|
||||
}
|
||||
this->loadModules(this->filepaths);
|
||||
this->scriptUtility = new ScriptUtility(mainWindow);
|
||||
}
|
||||
|
||||
void Scripting::loadModules(QStringList moduleFiles) {
|
||||
for (QString filepath : moduleFiles) {
|
||||
QJSValue module = this->engine->importModule(filepath);
|
||||
if (module.isError()) {
|
||||
QString relativePath = QDir::cleanPath(projectConfig.getProjectDir() + QDir::separator() + filepath);
|
||||
module = this->engine->importModule(relativePath);
|
||||
if (tryErrorJS(module)) continue;
|
||||
}
|
||||
|
||||
logInfo(QString("Successfully loaded custom script file '%1'").arg(filepath));
|
||||
this->modules.append(module);
|
||||
}
|
||||
}
|
||||
|
||||
void Scripting::populateGlobalObject(MainWindow *mainWindow) {
|
||||
if (!instance || !instance->engine) return;
|
||||
|
||||
instance->engine->globalObject().setProperty("map", instance->engine->newQObject(mainWindow));
|
||||
instance->engine->globalObject().setProperty("overlay", instance->engine->newQObject(mainWindow->ui->graphicsView_Map));
|
||||
instance->engine->globalObject().setProperty("utility", instance->engine->newQObject(instance->scriptUtility));
|
||||
|
||||
QJSValue constants = instance->engine->newObject();
|
||||
|
||||
// Get basic tile/metatile information
|
||||
int numTilesPrimary = Project::getNumTilesPrimary();
|
||||
int numTilesTotal = Project::getNumTilesTotal();
|
||||
int numMetatilesPrimary = Project::getNumMetatilesPrimary();
|
||||
int numMetatilesTotal = Project::getNumMetatilesTotal();
|
||||
bool tripleLayerEnabled = projectConfig.getTripleLayerMetatilesEnabled();
|
||||
|
||||
// Invisibly create an "About" window to read Porymap version
|
||||
AboutPorymap *about = new AboutPorymap(mainWindow);
|
||||
if (about) {
|
||||
QJSValue version = Scripting::version(about->getVersionNumbers());
|
||||
constants.setProperty("version", version);
|
||||
delete about;
|
||||
} else {
|
||||
logError("Failed to read Porymap version for API");
|
||||
}
|
||||
constants.setProperty("max_primary_tiles", numTilesPrimary);
|
||||
constants.setProperty("max_secondary_tiles", numTilesTotal - numTilesPrimary);
|
||||
constants.setProperty("max_primary_metatiles", numMetatilesPrimary);
|
||||
constants.setProperty("max_secondary_metatiles", numMetatilesTotal - numMetatilesPrimary);
|
||||
constants.setProperty("layers_per_metatile", tripleLayerEnabled ? 3 : 2);
|
||||
constants.setProperty("tiles_per_metatile", tripleLayerEnabled ? 12 : 8);
|
||||
constants.setProperty("base_game_version", projectConfig.getBaseGameVersionString());
|
||||
|
||||
instance->engine->globalObject().setProperty("constants", constants);
|
||||
|
||||
// Prevent changes to the object properties of the global object
|
||||
instance->engine->evaluate("Object.freeze(map);");
|
||||
instance->engine->evaluate("Object.freeze(overlay);");
|
||||
instance->engine->evaluate("Object.freeze(utility);");
|
||||
instance->engine->evaluate("Object.freeze(constants.version);");
|
||||
instance->engine->evaluate("Object.freeze(constants);");
|
||||
}
|
||||
|
||||
bool Scripting::tryErrorJS(QJSValue js) {
|
||||
if (!js.isError()) return false;
|
||||
|
||||
// Get properties of the error
|
||||
QFileInfo file(js.property("fileName").toString());
|
||||
QString fileName = file.fileName();
|
||||
QString lineNumber = js.property("lineNumber").toString();
|
||||
|
||||
// Convert properties to message strings
|
||||
QString fileErrStr = fileName == "undefined" ? "" : QString(" '%1'").arg(fileName);
|
||||
QString lineErrStr = lineNumber == "undefined" ? "" : QString(" at line %1").arg(lineNumber);
|
||||
|
||||
logError(QString("Error in custom script%1%2: '%3'")
|
||||
.arg(fileErrStr)
|
||||
.arg(lineErrStr)
|
||||
.arg(js.toString()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void Scripting::invokeCallback(CallbackType type, QJSValueList args) {
|
||||
for (QJSValue module : this->modules) {
|
||||
QString functionName = callbackFunctions[type];
|
||||
QJSValue callbackFunction = module.property(functionName);
|
||||
if (tryErrorJS(callbackFunction)) continue;
|
||||
|
||||
QJSValue result = callbackFunction.call(args);
|
||||
if (tryErrorJS(result)) continue;
|
||||
}
|
||||
}
|
||||
|
||||
void Scripting::invokeAction(QString actionName) {
|
||||
if (!instance || !instance->scriptUtility) return;
|
||||
QString functionName = instance->scriptUtility->getActionFunctionName(actionName);
|
||||
if (functionName.isEmpty()) return;
|
||||
|
||||
bool foundFunction = false;
|
||||
for (QJSValue module : instance->modules) {
|
||||
QJSValue callbackFunction = module.property(functionName);
|
||||
if (callbackFunction.isUndefined() || !callbackFunction.isCallable())
|
||||
continue;
|
||||
foundFunction = true;
|
||||
if (tryErrorJS(callbackFunction)) continue;
|
||||
|
||||
QJSValue result = callbackFunction.call(QJSValueList());
|
||||
if (tryErrorJS(result)) continue;
|
||||
}
|
||||
if (!foundFunction)
|
||||
logError(QString("Unknown custom script function '%1'").arg(functionName));
|
||||
}
|
||||
|
||||
void Scripting::cb_ProjectOpened(QString projectPath) {
|
||||
if (!instance) return;
|
||||
|
||||
QJSValueList args {
|
||||
projectPath,
|
||||
};
|
||||
instance->invokeCallback(OnProjectOpened, args);
|
||||
}
|
||||
|
||||
void Scripting::cb_ProjectClosed(QString projectPath) {
|
||||
if (!instance) return;
|
||||
|
||||
QJSValueList args {
|
||||
projectPath,
|
||||
};
|
||||
instance->invokeCallback(OnProjectClosed, args);
|
||||
}
|
||||
|
||||
void Scripting::cb_MetatileChanged(int x, int y, Block prevBlock, Block newBlock) {
|
||||
if (!instance) return;
|
||||
|
||||
QJSValueList args {
|
||||
x,
|
||||
y,
|
||||
instance->fromBlock(prevBlock),
|
||||
instance->fromBlock(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;
|
||||
|
||||
QJSValueList args {
|
||||
x,
|
||||
y,
|
||||
};
|
||||
instance->invokeCallback(OnBlockHoverChanged, args);
|
||||
}
|
||||
|
||||
void Scripting::cb_BlockHoverCleared() {
|
||||
if (!instance) return;
|
||||
instance->invokeCallback(OnBlockHoverCleared, QJSValueList());
|
||||
}
|
||||
|
||||
void Scripting::cb_MapOpened(QString mapName) {
|
||||
if (!instance) return;
|
||||
|
||||
QJSValueList args {
|
||||
mapName,
|
||||
};
|
||||
instance->invokeCallback(OnMapOpened, args);
|
||||
}
|
||||
|
||||
void Scripting::cb_MapResized(int oldWidth, int oldHeight, int newWidth, int newHeight) {
|
||||
if (!instance) return;
|
||||
|
||||
QJSValueList args {
|
||||
oldWidth,
|
||||
oldHeight,
|
||||
newWidth,
|
||||
newHeight,
|
||||
};
|
||||
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;
|
||||
|
||||
QJSValueList args {
|
||||
xDelta,
|
||||
yDelta,
|
||||
};
|
||||
instance->invokeCallback(OnMapShifted, args);
|
||||
}
|
||||
|
||||
void Scripting::cb_TilesetUpdated(QString tilesetName) {
|
||||
if (!instance) return;
|
||||
|
||||
QJSValueList args {
|
||||
tilesetName,
|
||||
};
|
||||
instance->invokeCallback(OnTilesetUpdated, args);
|
||||
}
|
||||
|
||||
void Scripting::cb_MainTabChanged(int oldTab, int newTab) {
|
||||
if (!instance) return;
|
||||
|
||||
QJSValueList args {
|
||||
oldTab,
|
||||
newTab,
|
||||
};
|
||||
instance->invokeCallback(OnMainTabChanged, args);
|
||||
}
|
||||
|
||||
void Scripting::cb_MapViewTabChanged(int oldTab, int newTab) {
|
||||
if (!instance) return;
|
||||
|
||||
QJSValueList args {
|
||||
oldTab,
|
||||
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);
|
||||
obj.setProperty("collision", block.collision);
|
||||
obj.setProperty("elevation", block.elevation);
|
||||
obj.setProperty("rawValue", block.rawValue());
|
||||
return obj;
|
||||
}
|
||||
|
||||
QJSValue Scripting::dimensions(int width, int height) {
|
||||
QJSValue obj = instance->engine->newObject();
|
||||
obj.setProperty("width", width);
|
||||
obj.setProperty("height", height);
|
||||
return obj;
|
||||
}
|
||||
|
||||
QJSValue Scripting::position(int x, int y) {
|
||||
QJSValue obj = instance->engine->newObject();
|
||||
obj.setProperty("x", x);
|
||||
obj.setProperty("y", y);
|
||||
return obj;
|
||||
}
|
||||
|
||||
QJSValue Scripting::version(QList<int> versionNums) {
|
||||
QJSValue obj = instance->engine->newObject();
|
||||
obj.setProperty("major", versionNums.at(0));
|
||||
obj.setProperty("minor", versionNums.at(1));
|
||||
obj.setProperty("patch", versionNums.at(2));
|
||||
return obj;
|
||||
}
|
||||
|
||||
Tile Scripting::toTile(QJSValue obj) {
|
||||
Tile tile = Tile();
|
||||
|
||||
if (obj.hasProperty("tileId"))
|
||||
tile.tileId = obj.property("tileId").toInt();
|
||||
if (obj.hasProperty("xflip"))
|
||||
tile.xflip = obj.property("xflip").toBool();
|
||||
if (obj.hasProperty("yflip"))
|
||||
tile.yflip = obj.property("yflip").toBool();
|
||||
if (obj.hasProperty("palette"))
|
||||
tile.palette = obj.property("palette").toInt();
|
||||
|
||||
return tile;
|
||||
}
|
||||
|
||||
QJSValue Scripting::fromTile(Tile tile) {
|
||||
QJSValue obj = instance->engine->newObject();
|
||||
obj.setProperty("tileId", tile.tileId);
|
||||
obj.setProperty("xflip", tile.xflip);
|
||||
obj.setProperty("yflip", tile.yflip);
|
||||
obj.setProperty("palette", tile.palette);
|
||||
return obj;
|
||||
}
|
||||
|
||||
QJSValue Scripting::dialogInput(QJSValue input, bool selectedOk) {
|
||||
QJSValue obj = instance->engine->newObject();
|
||||
obj.setProperty("input", input);
|
||||
obj.setProperty("ok", selectedOk);
|
||||
return obj;
|
||||
}
|
||||
|
||||
QJSEngine *Scripting::getEngine() {
|
||||
return instance->engine;
|
||||
}
|
||||
|
||||
QImage Scripting::getImage(QString filepath) {
|
||||
const QImage * image = instance->imageCache.value(filepath, nullptr);
|
||||
if (!image) {
|
||||
image = new QImage(filepath);
|
||||
instance->imageCache.insert(filepath, image);
|
||||
}
|
||||
return QImage(*image);
|
||||
}
|
||||
Reference in New Issue
Block a user