First stab at generating metatiles
This commit is contained in:
parent
23747d9822
commit
95a1da1930
3 changed files with 114 additions and 7 deletions
|
@ -3,6 +3,7 @@
|
||||||
#define PAINTSELECTION_H
|
#define PAINTSELECTION_H
|
||||||
|
|
||||||
#include "block.h"
|
#include "block.h"
|
||||||
|
#include "map.h"
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QPoint>
|
#include <QPoint>
|
||||||
|
@ -24,7 +25,7 @@ class PaintSelection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QPoint dimensions;
|
QPoint dimensions;
|
||||||
virtual bool paintNormal(int, Block*) = 0;
|
virtual bool paintNormal(int, Block*, Map*, int layer) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MetatileSelection: public PaintSelection
|
class MetatileSelection: public PaintSelection
|
||||||
|
@ -37,7 +38,7 @@ public:
|
||||||
this->metatileItems = other.metatileItems;
|
this->metatileItems = other.metatileItems;
|
||||||
this->collisionItems = other.collisionItems;
|
this->collisionItems = other.collisionItems;
|
||||||
}
|
}
|
||||||
bool paintNormal(int index, Block *block) override;
|
bool paintNormal(int index, Block *block, Map*, int layer) override;
|
||||||
bool hasCollision = false;
|
bool hasCollision = false;
|
||||||
QList<MetatileSelectionItem> metatileItems;
|
QList<MetatileSelectionItem> metatileItems;
|
||||||
QList<CollisionSelectionItem> collisionItems;
|
QList<CollisionSelectionItem> collisionItems;
|
||||||
|
@ -47,7 +48,7 @@ class StampSelection: public PaintSelection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StampSelection() {}
|
StampSelection() {}
|
||||||
bool paintNormal(int index, Block *block) override;
|
bool paintNormal(int index, Block *block, Map*, int layer) override;
|
||||||
QList<uint16_t> stampIds;
|
QList<uint16_t> stampIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ void MapPixmapItem::paintNormal(int x, int y, bool fromScriptCall) {
|
||||||
Block block;
|
Block block;
|
||||||
if (map->getBlock(actualX, actualY, &block)) {
|
if (map->getBlock(actualX, actualY, &block)) {
|
||||||
int index = j * selectionWidth + i;
|
int index = j * selectionWidth + i;
|
||||||
if (selection->paintNormal(index, &block)) {
|
if (selection->paintNormal(index, &block, map, 2)) {
|
||||||
map->setBlock(actualX, actualY, block, !fromScriptCall);
|
map->setBlock(actualX, actualY, block, !fromScriptCall);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "paintselection.h"
|
#include "paintselection.h"
|
||||||
|
#include "project.h"
|
||||||
|
#include "metatile.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
bool MetatileSelection::paintNormal(int index, Block *block) {
|
bool MetatileSelection::paintNormal(int index, Block *block, Map *map, int layer) {
|
||||||
MetatileSelectionItem item = this->metatileItems.at(index);
|
MetatileSelectionItem item = this->metatileItems.at(index);
|
||||||
if (!item.enabled)
|
if (!item.enabled)
|
||||||
return false;
|
return false;
|
||||||
|
@ -15,7 +17,111 @@ bool MetatileSelection::paintNormal(int index, Block *block) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StampSelection::paintNormal(int index, Block *block) {
|
void adjustMetatileForLayer(int layer, int *baseOffset, Metatile *metatile) {
|
||||||
block->metatileId = 1;
|
switch (metatile->layerType)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case METATILE_LAYER_MIDDLE_TOP:
|
||||||
|
switch (layer)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
*baseOffset = 0;
|
||||||
|
metatile->layerType = METATILE_LAYER_BOTTOM_TOP;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
metatile->tiles[i+4] = metatile->tiles[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
*baseOffset = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*baseOffset = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case METATILE_LAYER_BOTTOM_MIDDLE:
|
||||||
|
switch (layer)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
*baseOffset = 0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
*baseOffset = 4;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*baseOffset = 4;
|
||||||
|
metatile->layerType = METATILE_LAYER_MIDDLE_TOP;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
metatile->tiles[i] = metatile->tiles[i+4];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case METATILE_LAYER_BOTTOM_TOP:
|
||||||
|
switch (layer)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
*baseOffset = 0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
*baseOffset = 4;
|
||||||
|
metatile->layerType = METATILE_LAYER_BOTTOM_MIDDLE;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*baseOffset = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StampSelection::paintNormal(int index, Block *block, Map *map, int layer) {
|
||||||
|
Tileset *primaryTileset = map->layout->tileset_primary;
|
||||||
|
Tileset *secondaryTileset = map->layout->tileset_secondary;
|
||||||
|
// 1. Build metatile by applying the stamp to the existing block.
|
||||||
|
Metatile metatile = *(Tileset::getMetatile(block->metatileId, map->layout->tileset_primary, map->layout->tileset_secondary));
|
||||||
|
int baseOffset;
|
||||||
|
adjustMetatileForLayer(layer, &baseOffset, &metatile);
|
||||||
|
metatile.tiles[baseOffset] = Tile(0x5, false, false, 2);
|
||||||
|
metatile.tiles[baseOffset + 1] = Tile(0x5, true, false, 2);
|
||||||
|
metatile.tiles[baseOffset + 2] = Tile(0x15, false, false, 2);
|
||||||
|
metatile.tiles[baseOffset + 3] = Tile(0x15, true, false, 2);
|
||||||
|
|
||||||
|
// 2. Check if the metatile already exists in the map layout's primary or secondary tilesets.
|
||||||
|
bool exists = false;
|
||||||
|
uint16_t metatileId = 0;
|
||||||
|
uint16_t i = 0;
|
||||||
|
for (auto m : primaryTileset->metatiles) {
|
||||||
|
if (*m == metatile) {
|
||||||
|
exists = true;
|
||||||
|
metatileId = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (!exists) {
|
||||||
|
i = Project::getNumMetatilesPrimary();
|
||||||
|
for (auto m : secondaryTileset->metatiles) {
|
||||||
|
if (*m == metatile) {
|
||||||
|
exists = true;
|
||||||
|
metatileId = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. If the metatile doesn't exist, append the new metatile to the secondary tileset.
|
||||||
|
if (!exists) {
|
||||||
|
int maxSecondaryMetatiles = Project::getNumMetatilesTotal() - Project::getNumMetatilesPrimary();
|
||||||
|
if (secondaryTileset->metatiles.length() >= maxSecondaryMetatiles) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
secondaryTileset->metatiles.append(new Metatile(metatile));
|
||||||
|
metatileId = Project::getNumMetatilesPrimary() + secondaryTileset->metatiles.length() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Set the block's metatile id.
|
||||||
|
block->metatileId = metatileId;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue