Add onBorderMetatileChanged, onBorderResized, implement some basic border API

This commit is contained in:
GriffinR 2022-08-29 12:44:17 -04:00
parent 8f90ca64b4
commit 21ed9bc140
9 changed files with 122 additions and 18 deletions

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

@ -46,6 +46,8 @@ public:
Q_INVOKABLE QJSValue getBlock(int x, int y);
void tryRedrawMapArea(bool forceRedraw);
void tryCommitMapChanges(bool commitChanges);
void tryRedrawBorder(bool forceRedraw);
void tryCommitBorderChanges(bool commitChanges);
Q_INVOKABLE void setBlock(int x, int y, int tile, int collision, int elevation, bool forceRedraw = true, bool commitChanges = true);
Q_INVOKABLE void setBlocksFromSelection(int x, int y, bool forceRedraw = true, bool commitChanges = true);
Q_INVOKABLE int getMetatileId(int x, int y);

View file

@ -12,10 +12,12 @@ enum CallbackType {
OnProjectOpened,
OnProjectClosed,
OnBlockChanged,
OnBorderMetatileChanged,
OnBlockHoverChanged,
OnBlockHoverCleared,
OnMapOpened,
OnMapResized,
OnBorderResized,
OnMapShifted,
OnTilesetUpdated,
OnMainTabChanged,
@ -40,10 +42,12 @@ 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);

View file

@ -101,7 +101,7 @@ void PaintBorder::redo() {
if (!map) return;
map->layout->border = newBorder;
map->setBorderBlockData(newBorder);
map->borderItem->draw();
}
@ -109,7 +109,7 @@ void PaintBorder::redo() {
void PaintBorder::undo() {
if (!map) return;
map->layout->border = oldBorder;
map->setBorderBlockData(oldBorder);
map->borderItem->draw();

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

@ -2906,9 +2906,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

@ -50,6 +50,16 @@ void MainWindow::tryCommitMapChanges(bool commitChanges) {
}
}
void MainWindow::tryRedrawBorder(bool forceRedraw) {
if (!forceRedraw) return;
// TODO
}
void MainWindow::tryCommitBorderChanges(bool commitChanges) {
if (!commitChanges) return;
// TODO
}
void MainWindow::setBlock(int x, int y, int tile, int collision, int elevation, bool forceRedraw, bool commitChanges) {
if (!this->editor || !this->editor->map)
return;
@ -91,13 +101,19 @@ void MainWindow::setMetatileId(int x, int y, int metatileId, bool forceRedraw, b
int MainWindow::getBorderMetatileId(int x, int y) {
if (!this->editor || !this->editor->map)
return 0;
// TODO
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;
// TODO
if (!this->editor->map->isWithinBorderBounds(x, y))
return;
this->editor->map->setBorderMetatileId(x, y, metatileId);
this->tryCommitBorderChanges(commitChanges);
this->tryRedrawBorder(forceRedraw);
}
int MainWindow::getCollision(int x, int y) {
@ -213,19 +229,19 @@ int MainWindow::getHeight() {
QJSValue MainWindow::getBorderDimensions() {
if (!this->editor || !this->editor->map)
return QJSValue();
// TODO
return Scripting::dimensions(this->editor->map->getBorderWidth(), this->editor->map->getBorderHeight());
}
int MainWindow::getBorderWidth() {
if (!this->editor || !this->editor->map)
return 0;
// TODO
return this->editor->map->getBorderWidth();
}
int MainWindow::getBorderHeight() {
if (!this->editor || !this->editor->map)
return 0;
// TODO
return this->editor->map->getBorderHeight();
}
void MainWindow::setDimensions(int width, int height) {
@ -259,20 +275,32 @@ void MainWindow::setHeight(int height) {
}
void MainWindow::setBorderDimensions(int width, int height) {
if (!this->editor || !this->editor->map)
if (!this->editor || !this->editor->map || !projectConfig.getUseCustomBorderSize())
return;
// TODO
if (width < 1 || height < 1 || width > MAX_BORDER_WIDTH || height > MAX_BORDER_HEIGHT)
return;
this->editor->map->setBorderDimensions(width, height);
this->tryCommitBorderChanges(true);
// TODO
}
void MainWindow::setBorderWidth(int width) {
if (!this->editor || !this->editor->map)
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->tryCommitBorderChanges(true);
// TODO
}
void MainWindow::setBorderHeight(int height) {
if (!this->editor || !this->editor->map)
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->tryCommitBorderChanges(true);
// TODO
}

View file

@ -5,10 +5,12 @@ 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"},
@ -140,6 +142,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 +190,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;

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,