mirror of
https://github.com/huderlem/porymap.git
synced 2026-09-25 09:15:34 -05:00
Allow editing border dimensions
This commit is contained in:
@@ -1,13 +1,17 @@
|
||||
#include "historyitem.h"
|
||||
|
||||
HistoryItem::HistoryItem(Blockdata *metatiles, int layoutWidth, int layoutHeight) {
|
||||
HistoryItem::HistoryItem(Blockdata *metatiles, Blockdata *border, int layoutWidth, int layoutHeight, int borderWidth, int borderHeight) {
|
||||
this->metatiles = metatiles;
|
||||
this->border = border;
|
||||
this->layoutWidth = layoutWidth;
|
||||
this->layoutHeight = layoutHeight;
|
||||
this->borderWidth = borderWidth;
|
||||
this->borderHeight = borderHeight;
|
||||
}
|
||||
|
||||
HistoryItem::~HistoryItem() {
|
||||
if (this->metatiles) delete this->metatiles;
|
||||
if (this->border) delete this->border;
|
||||
}
|
||||
|
||||
RegionMapHistoryItem::RegionMapHistoryItem(int which, QVector<uint8_t> tiles, QString cityMap) {
|
||||
|
||||
136
src/core/map.cpp
136
src/core/map.cpp
@@ -67,7 +67,7 @@ int Map::getBorderHeight() {
|
||||
return layout->border_height.toInt(nullptr, 0);
|
||||
}
|
||||
|
||||
bool Map::blockChanged(int i, Blockdata *cache) {
|
||||
bool Map::mapBlockChanged(int i, Blockdata *cache) {
|
||||
if (!cache)
|
||||
return true;
|
||||
if (!layout->blockdata)
|
||||
@@ -84,6 +84,23 @@ bool Map::blockChanged(int i, Blockdata *cache) {
|
||||
return layout->blockdata->blocks->value(i) != cache->blocks->value(i);
|
||||
}
|
||||
|
||||
bool Map::borderBlockChanged(int i, Blockdata *cache) {
|
||||
if (!cache)
|
||||
return true;
|
||||
if (!layout->border)
|
||||
return true;
|
||||
if (!cache->blocks)
|
||||
return true;
|
||||
if (!layout->border->blocks)
|
||||
return true;
|
||||
if (cache->blocks->length() <= i)
|
||||
return true;
|
||||
if (layout->border->blocks->length() <= i)
|
||||
return true;
|
||||
|
||||
return layout->border->blocks->value(i) != cache->blocks->value(i);
|
||||
}
|
||||
|
||||
void Map::cacheBorder() {
|
||||
if (layout->cached_border) delete layout->cached_border;
|
||||
layout->cached_border = new Blockdata;
|
||||
@@ -135,7 +152,7 @@ QPixmap Map::renderCollision(qreal opacity, bool ignoreCache) {
|
||||
}
|
||||
QPainter painter(&collision_image);
|
||||
for (int i = 0; i < layout->blockdata->blocks->length(); i++) {
|
||||
if (!ignoreCache && layout->cached_collision && !blockChanged(i, layout->cached_collision)) {
|
||||
if (!ignoreCache && layout->cached_collision && !mapBlockChanged(i, layout->cached_collision)) {
|
||||
continue;
|
||||
}
|
||||
changed_any = true;
|
||||
@@ -179,7 +196,7 @@ QPixmap Map::render(bool ignoreCache = false, MapLayout * fromLayout) {
|
||||
|
||||
QPainter painter(&image);
|
||||
for (int i = 0; i < layout->blockdata->blocks->length(); i++) {
|
||||
if (!ignoreCache && !blockChanged(i, layout->cached_blockdata)) {
|
||||
if (!ignoreCache && !mapBlockChanged(i, layout->cached_blockdata)) {
|
||||
continue;
|
||||
}
|
||||
changed_any = true;
|
||||
@@ -204,27 +221,33 @@ QPixmap Map::render(bool ignoreCache = false, MapLayout * fromLayout) {
|
||||
}
|
||||
|
||||
QPixmap Map::renderBorder() {
|
||||
bool changed_any = false;
|
||||
bool changed_any = false, border_resized = false;
|
||||
int width_ = getBorderWidth();
|
||||
int height_ = getBorderHeight();
|
||||
if (layout->border_image.isNull()) {
|
||||
layout->border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
|
||||
changed_any = true;
|
||||
}
|
||||
if (layout->border_image.width() != width_ * 16 || layout->border_image.height() != height_ * 16) {
|
||||
layout->border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
|
||||
border_resized = true;
|
||||
}
|
||||
if (!(layout->border && layout->border->blocks)) {
|
||||
layout->border_pixmap = layout->border_pixmap.fromImage(layout->border_image);
|
||||
return layout->border_pixmap;
|
||||
}
|
||||
QPainter painter(&layout->border_image);
|
||||
for (int i = 0; i < layout->border->blocks->length(); i++) {
|
||||
if (!blockChanged(i, layout->cached_border)) {
|
||||
if (!border_resized && !borderBlockChanged(i, layout->cached_border)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
changed_any = true;
|
||||
Block block = layout->border->blocks->value(i);
|
||||
QImage metatile_image = getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary);
|
||||
int map_y = i / width_;
|
||||
int map_x = i % width_;
|
||||
uint16_t tile = block.tile;
|
||||
QImage metatile_image = getMetatileImage(tile, layout->tileset_primary, layout->tileset_secondary);
|
||||
int map_y = width_ ? i / width_ : 0;
|
||||
int map_x = width_ ? i % width_ : 0;
|
||||
painter.drawImage(QPoint(map_x * 16, map_y * 16), metatile_image);
|
||||
}
|
||||
painter.end();
|
||||
@@ -240,23 +263,23 @@ QPixmap Map::renderConnection(MapConnection connection, MapLayout * fromLayout)
|
||||
int x, y, w, h;
|
||||
if (connection.direction == "up") {
|
||||
x = 0;
|
||||
y = getHeight() - 6;
|
||||
y = getHeight() - BORDER_DISTANCE;
|
||||
w = getWidth();
|
||||
h = 6;
|
||||
h = BORDER_DISTANCE;
|
||||
} else if (connection.direction == "down") {
|
||||
x = 0;
|
||||
y = 0;
|
||||
w = getWidth();
|
||||
h = 6;
|
||||
h = BORDER_DISTANCE;
|
||||
} else if (connection.direction == "left") {
|
||||
x = getWidth() - 6;
|
||||
x = getWidth() - BORDER_DISTANCE;
|
||||
y = 0;
|
||||
w = 6;
|
||||
w = BORDER_DISTANCE;
|
||||
h = getHeight();
|
||||
} else if (connection.direction == "right") {
|
||||
x = 0;
|
||||
y = 0;
|
||||
w = 6;
|
||||
w = BORDER_DISTANCE;
|
||||
h = getHeight();
|
||||
} else {
|
||||
// this should not happen
|
||||
@@ -289,6 +312,25 @@ void Map::setNewDimensionsBlockdata(int newWidth, int newHeight) {
|
||||
layout->blockdata->copyFrom(newBlockData);
|
||||
}
|
||||
|
||||
void Map::setNewBorderDimensionsBlockdata(int newWidth, int newHeight) {
|
||||
int oldWidth = getBorderWidth();
|
||||
int oldHeight = getBorderHeight();
|
||||
|
||||
Blockdata* newBlockData = new Blockdata;
|
||||
|
||||
for (int y = 0; y < newHeight; y++)
|
||||
for (int x = 0; x < newWidth; x++) {
|
||||
if (x < oldWidth && y < oldHeight) {
|
||||
int index = y * oldWidth + x;
|
||||
newBlockData->addBlock(layout->border->blocks->value(index));
|
||||
} else {
|
||||
newBlockData->addBlock(0);
|
||||
}
|
||||
}
|
||||
|
||||
layout->border->copyFrom(newBlockData);
|
||||
}
|
||||
|
||||
void Map::setDimensions(int newWidth, int newHeight, bool setNewBlockdata) {
|
||||
if (setNewBlockdata) {
|
||||
setNewDimensionsBlockdata(newWidth, newHeight);
|
||||
@@ -300,6 +342,17 @@ void Map::setDimensions(int newWidth, int newHeight, bool setNewBlockdata) {
|
||||
emit mapChanged(this);
|
||||
}
|
||||
|
||||
void Map::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata) {
|
||||
if (setNewBlockdata) {
|
||||
setNewBorderDimensionsBlockdata(newWidth, newHeight);
|
||||
}
|
||||
|
||||
layout->border_width = QString::number(newWidth);
|
||||
layout->border_height = QString::number(newHeight);
|
||||
|
||||
emit mapChanged(this);
|
||||
}
|
||||
|
||||
Block* Map::getBlock(int x, int y) {
|
||||
if (layout->blockdata && layout->blockdata->blocks) {
|
||||
if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
|
||||
@@ -354,35 +407,64 @@ void Map::_floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_
|
||||
}
|
||||
|
||||
void Map::undo() {
|
||||
bool redraw = false, changed = false;
|
||||
HistoryItem *commit = metatileHistory.back();
|
||||
if (!commit)
|
||||
return;
|
||||
|
||||
|
||||
if (layout->blockdata) {
|
||||
layout->blockdata->copyFrom(commit->metatiles);
|
||||
if (commit->layoutWidth != this->getWidth() || commit->layoutHeight != this->getHeight())
|
||||
{
|
||||
if (commit->layoutWidth != this->getWidth() || commit->layoutHeight != this->getHeight()) {
|
||||
this->setDimensions(commit->layoutWidth, commit->layoutHeight, false);
|
||||
emit mapNeedsRedrawing();
|
||||
redraw = true;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
if (layout->border) {
|
||||
layout->border->copyFrom(commit->border);
|
||||
if (commit->borderWidth != this->getBorderWidth() || commit->borderHeight != this->getBorderHeight()) {
|
||||
this->setBorderDimensions(commit->borderWidth, commit->borderHeight, false);
|
||||
redraw = true;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (redraw) {
|
||||
emit mapNeedsRedrawing();
|
||||
}
|
||||
if (changed) {
|
||||
emit mapChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Map::redo() {
|
||||
bool redraw = false, changed = false;
|
||||
HistoryItem *commit = metatileHistory.next();
|
||||
if (!commit)
|
||||
return;
|
||||
|
||||
if (layout->blockdata) {
|
||||
layout->blockdata->copyFrom(commit->metatiles);
|
||||
if (commit->layoutWidth != this->getWidth() || commit->layoutHeight != this->getHeight())
|
||||
{
|
||||
if (commit->layoutWidth != this->getWidth() || commit->layoutHeight != this->getHeight()) {
|
||||
this->setDimensions(commit->layoutWidth, commit->layoutHeight, false);
|
||||
emit mapNeedsRedrawing();
|
||||
redraw = true;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
if (layout->border) {
|
||||
layout->border->copyFrom(commit->border);
|
||||
if (commit->borderWidth != this->getBorderWidth() || commit->borderHeight != this->getBorderHeight()) {
|
||||
this->setBorderDimensions(commit->borderWidth, commit->borderHeight, false);
|
||||
redraw = true;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (redraw) {
|
||||
emit mapNeedsRedrawing();
|
||||
}
|
||||
if (changed) {
|
||||
emit mapChanged(this);
|
||||
}
|
||||
}
|
||||
@@ -392,14 +474,22 @@ void Map::commit() {
|
||||
return;
|
||||
}
|
||||
|
||||
int layoutWidth = this->getWidth();
|
||||
int layoutHeight = this->getHeight();
|
||||
int borderWidth = this->getBorderWidth();
|
||||
int borderHeight = this->getBorderHeight();
|
||||
|
||||
if (layout->blockdata) {
|
||||
HistoryItem *item = metatileHistory.current();
|
||||
bool atCurrentHistory = item
|
||||
&& layout->blockdata->equals(item->metatiles)
|
||||
&& this->getWidth() == item->layoutWidth
|
||||
&& this->getHeight() == item->layoutHeight;
|
||||
&& layout->border->equals(item->border)
|
||||
&& layoutWidth == item->layoutWidth
|
||||
&& layoutHeight == item->layoutHeight
|
||||
&& borderWidth == item->borderWidth
|
||||
&& borderHeight == item->borderHeight;
|
||||
if (!atCurrentHistory) {
|
||||
HistoryItem *commit = new HistoryItem(layout->blockdata->copy(), this->getWidth(), this->getHeight());
|
||||
HistoryItem *commit = new HistoryItem(layout->blockdata->copy(), layout->border->copy(), layoutWidth, layoutHeight, borderWidth, borderHeight);
|
||||
metatileHistory.push(commit);
|
||||
emit mapChanged(this);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user