Simplify metatile attribute layouts
This commit is contained in:
parent
9cd8777246
commit
577dc2fce2
5 changed files with 145 additions and 134 deletions
|
@ -30,6 +30,29 @@ enum {
|
|||
NUM_METATILE_TERRAIN_TYPES
|
||||
};
|
||||
|
||||
class MetatileAttr
|
||||
{
|
||||
public:
|
||||
MetatileAttr();
|
||||
MetatileAttr(uint32_t mask, int shift);
|
||||
|
||||
public:
|
||||
uint32_t mask;
|
||||
int shift;
|
||||
|
||||
// Given the raw value for all attributes of a metatile
|
||||
// Returns the extracted value for this attribute
|
||||
uint32_t fromRaw(uint32_t raw) const { return (raw & this->mask) >> this->shift; }
|
||||
|
||||
// Given a value for this attribute
|
||||
// Returns the raw value to OR together with the other attributes
|
||||
uint32_t toRaw(uint32_t value) const { return (value << this->shift) & this->mask; }
|
||||
|
||||
// Given an arbitrary value to set for an attribute
|
||||
// Returns a bounded value for that attribute
|
||||
uint32_t getClamped(int value) const { return static_cast<uint32_t>(value) & (this->mask >> this->shift); }
|
||||
};
|
||||
|
||||
class Metatile
|
||||
{
|
||||
public:
|
||||
|
@ -47,30 +70,23 @@ public:
|
|||
uint32_t unusedAttributes;
|
||||
QString label;
|
||||
|
||||
enum Attr {
|
||||
Behavior,
|
||||
TerrainType,
|
||||
EncounterType,
|
||||
LayerType,
|
||||
};
|
||||
|
||||
struct AttrLayout {
|
||||
uint32_t mask;
|
||||
int shift;
|
||||
};
|
||||
|
||||
static const QHash<Metatile::Attr, Metatile::AttrLayout> defaultLayoutFRLG;
|
||||
static const QHash<Metatile::Attr, Metatile::AttrLayout> defaultLayoutRSE;
|
||||
static QHash<Metatile::Attr, Metatile::AttrLayout> customLayout;
|
||||
|
||||
uint32_t getAttributes();
|
||||
void setAttributes(uint32_t data);
|
||||
void convertAttributes(uint32_t data, BaseGameVersion version);
|
||||
void setAttributes(uint32_t data, BaseGameVersion version);
|
||||
|
||||
void setBehavior(uint32_t);
|
||||
void setTerrainType(uint32_t);
|
||||
void setEncounterType(uint32_t);
|
||||
void setLayerType(uint32_t);
|
||||
void setBehavior(int value) { this->behavior = behaviorAttr.getClamped(value); }
|
||||
void setTerrainType(int value) { this->terrainType = terrainTypeAttr.getClamped(value); }
|
||||
void setEncounterType(int value) { this->encounterType = encounterTypeAttr.getClamped(value); }
|
||||
void setLayerType(int value) { this->layerType = layerTypeAttr.getClamped(value); }
|
||||
|
||||
static uint32_t getBehaviorMask() { return behaviorAttr.mask; }
|
||||
static uint32_t getTerrainTypeMask() { return terrainTypeAttr.mask; }
|
||||
static uint32_t getEncounterTypeMask() { return encounterTypeAttr.mask; }
|
||||
static uint32_t getLayerTypeMask() { return layerTypeAttr.mask; }
|
||||
static uint32_t getBehaviorMask(BaseGameVersion version);
|
||||
static uint32_t getTerrainTypeMask(BaseGameVersion version);
|
||||
static uint32_t getEncounterTypeMask(BaseGameVersion version);
|
||||
static uint32_t getLayerTypeMask(BaseGameVersion version);
|
||||
|
||||
static int getIndexInTileset(int);
|
||||
static QPoint coordFromPixmapCoord(const QPointF &pixelCoord);
|
||||
|
@ -78,11 +94,22 @@ public:
|
|||
static void setCustomLayout();
|
||||
|
||||
private:
|
||||
// Stores how each attribute should be laid out for all metatiles, according to the user's config
|
||||
static MetatileAttr behaviorAttr;
|
||||
static MetatileAttr terrainTypeAttr;
|
||||
static MetatileAttr encounterTypeAttr;
|
||||
static MetatileAttr layerTypeAttr;
|
||||
|
||||
static uint32_t unusedAttrMask;
|
||||
|
||||
void setAttributes(uint32_t, const QHash<Metatile::Attr, Metatile::AttrLayout>*);
|
||||
static void setCustomAttributeLayout(Metatile::AttrLayout *, uint32_t, uint32_t);
|
||||
static bool isMaskTooSmall(Metatile::AttrLayout * layout, int n);
|
||||
// Stores how each attribute should be laid out for all metatiles, according to the vanilla games
|
||||
// Used to set default config values and import maps with AdvanceMap
|
||||
static const QHash<QString, MetatileAttr> defaultLayoutFRLG;
|
||||
static const QHash<QString, MetatileAttr> defaultLayoutRSE;
|
||||
static const QHash<BaseGameVersion, const QHash<QString, MetatileAttr>*> defaultLayouts;
|
||||
|
||||
static void setCustomAttributeLayout(MetatileAttr *, uint32_t, uint32_t);
|
||||
static bool isMaskTooSmall(MetatileAttr *, int);
|
||||
static bool doMasksOverlap(QList<uint32_t>);
|
||||
};
|
||||
|
||||
|
|
|
@ -627,11 +627,10 @@ void ProjectConfig::setUnreadKeys() {
|
|||
if (!readKeys.contains("new_map_border_metatiles")) this->newMapBorderMetatileIds = isPokefirered ? DEFAULT_BORDER_FRLG : DEFAULT_BORDER_RSE;
|
||||
if (!readKeys.contains("default_secondary_tileset")) this->defaultSecondaryTileset = isPokefirered ? "gTileset_PalletTown" : "gTileset_Petalburg";
|
||||
if (!readKeys.contains("metatile_attributes_size")) this->metatileAttributesSize = Metatile::getDefaultAttributesSize(this->baseGameVersion);
|
||||
const QHash<Metatile::Attr, Metatile::AttrLayout> layout = isPokefirered ? Metatile::defaultLayoutFRLG : Metatile::defaultLayoutRSE;
|
||||
if (!readKeys.contains("metatile_behavior_mask")) this->metatileBehaviorMask = layout[Metatile::Attr::Behavior].mask;
|
||||
if (!readKeys.contains("metatile_terrain_type_mask")) this->metatileTerrainTypeMask = layout[Metatile::Attr::TerrainType].mask;
|
||||
if (!readKeys.contains("metatile_encounter_type_mask")) this->metatileEncounterTypeMask = layout[Metatile::Attr::EncounterType].mask;
|
||||
if (!readKeys.contains("metatile_layer_type_mask")) this-> metatileLayerTypeMask = layout[Metatile::Attr::LayerType].mask;
|
||||
if (!readKeys.contains("metatile_behavior_mask")) this->metatileBehaviorMask = Metatile::getBehaviorMask(this->baseGameVersion);
|
||||
if (!readKeys.contains("metatile_terrain_type_mask")) this->metatileTerrainTypeMask = Metatile::getTerrainTypeMask(this->baseGameVersion);
|
||||
if (!readKeys.contains("metatile_encounter_type_mask")) this->metatileEncounterTypeMask = Metatile::getEncounterTypeMask(this->baseGameVersion);
|
||||
if (!readKeys.contains("metatile_layer_type_mask")) this-> metatileLayerTypeMask = Metatile::getLayerTypeMask(this->baseGameVersion);
|
||||
if (!readKeys.contains("enable_map_allow_flags")) this->enableMapAllowFlags = (this->baseGameVersion != BaseGameVersion::pokeruby);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,22 +2,42 @@
|
|||
#include "tileset.h"
|
||||
#include "project.h"
|
||||
|
||||
QHash<Metatile::Attr, Metatile::AttrLayout> Metatile::customLayout = {};
|
||||
const QHash<QString, MetatileAttr> Metatile::defaultLayoutFRLG = {
|
||||
{"behavior", MetatileAttr(0x000001FF, 0) },
|
||||
{"terrainType", MetatileAttr(0x00003E00, 9) },
|
||||
{"encounterType", MetatileAttr(0x07000000, 24) },
|
||||
{"layerType", MetatileAttr(0x60000000, 29) },
|
||||
};
|
||||
|
||||
const QHash<QString, MetatileAttr> Metatile::defaultLayoutRSE = {
|
||||
{"behavior", MetatileAttr(0x00FF, 0) },
|
||||
{"terrainType", MetatileAttr() },
|
||||
{"encounterType", MetatileAttr() },
|
||||
{"layerType", MetatileAttr(0xF000, 12) },
|
||||
};
|
||||
|
||||
const QHash<BaseGameVersion, const QHash<QString, MetatileAttr>*> Metatile::defaultLayouts = {
|
||||
{ BaseGameVersion::pokeruby, &defaultLayoutRSE },
|
||||
{ BaseGameVersion::pokefirered, &defaultLayoutFRLG },
|
||||
{ BaseGameVersion::pokeemerald, &defaultLayoutRSE },
|
||||
};
|
||||
|
||||
MetatileAttr Metatile::behaviorAttr;
|
||||
MetatileAttr Metatile::terrainTypeAttr;
|
||||
MetatileAttr Metatile::encounterTypeAttr;
|
||||
MetatileAttr Metatile::layerTypeAttr;
|
||||
|
||||
uint32_t Metatile::unusedAttrMask = 0;
|
||||
|
||||
const QHash<Metatile::Attr, Metatile::AttrLayout> Metatile::defaultLayoutFRLG = {
|
||||
{Metatile::Attr::Behavior, { .mask = 0x000001FF, .shift = 0} },
|
||||
{Metatile::Attr::TerrainType, { .mask = 0x00003E00, .shift = 9} },
|
||||
{Metatile::Attr::EncounterType, { .mask = 0x07000000, .shift = 24} },
|
||||
{Metatile::Attr::LayerType, { .mask = 0x60000000, .shift = 29} },
|
||||
};
|
||||
MetatileAttr::MetatileAttr() :
|
||||
mask(0),
|
||||
shift(0)
|
||||
{ }
|
||||
|
||||
const QHash<Metatile::Attr, Metatile::AttrLayout> Metatile::defaultLayoutRSE = {
|
||||
{Metatile::Attr::Behavior, { .mask = 0x000000FF, .shift = 0} },
|
||||
{Metatile::Attr::TerrainType, { .mask = 0x00000000, .shift = 0} },
|
||||
{Metatile::Attr::EncounterType, { .mask = 0x00000000, .shift = 0} },
|
||||
{Metatile::Attr::LayerType, { .mask = 0x0000F000, .shift = 12} },
|
||||
};
|
||||
MetatileAttr::MetatileAttr(uint32_t mask, int shift) :
|
||||
mask(mask),
|
||||
shift(shift)
|
||||
{ }
|
||||
|
||||
Metatile::Metatile() :
|
||||
behavior(0),
|
||||
|
@ -48,19 +68,14 @@ int Metatile::getIndexInTileset(int metatileId) {
|
|||
}
|
||||
}
|
||||
|
||||
// Get the vanilla attribute sizes based on version.
|
||||
// Used as a default in the config and for AdvanceMap import.
|
||||
int Metatile::getDefaultAttributesSize(BaseGameVersion version) {
|
||||
return (version == BaseGameVersion::pokefirered) ? 4 : 2;
|
||||
}
|
||||
|
||||
QPoint Metatile::coordFromPixmapCoord(const QPointF &pixelCoord) {
|
||||
int x = static_cast<int>(pixelCoord.x()) / 16;
|
||||
int y = static_cast<int>(pixelCoord.y()) / 16;
|
||||
return QPoint(x, y);
|
||||
}
|
||||
|
||||
void Metatile::setCustomAttributeLayout(Metatile::AttrLayout * layout, uint32_t mask, uint32_t max) {
|
||||
// Set the layout of a metatile attribute using the mask read from the config file
|
||||
void Metatile::setCustomAttributeLayout(MetatileAttr * attr, uint32_t mask, uint32_t max) {
|
||||
if (mask > max) {
|
||||
uint32_t oldMask = mask;
|
||||
mask &= max;
|
||||
|
@ -68,15 +83,22 @@ void Metatile::setCustomAttributeLayout(Metatile::AttrLayout * layout, uint32_t
|
|||
.arg(QString::number(oldMask, 16).toUpper())
|
||||
.arg(QString::number(mask, 16).toUpper()));
|
||||
}
|
||||
layout->mask = mask;
|
||||
layout->shift = log2(mask & ~(mask - 1)); // Get the position of the rightmost set bit
|
||||
attr->mask = mask;
|
||||
attr->shift = mask ? log2(mask & ~(mask - 1)) : 0; // Get position of the least significant set bit
|
||||
}
|
||||
|
||||
// For checking whether a metatile attribute mask can contain all the hard-coded values
|
||||
bool Metatile::isMaskTooSmall(Metatile::AttrLayout * layout, int n) {
|
||||
if (!layout->mask) return false;
|
||||
uint32_t maxValue = n - 1;
|
||||
return (maxValue & (layout->mask >> layout->shift)) != maxValue;
|
||||
// For checking whether a metatile attribute mask can contain all the available hard-coded options
|
||||
bool Metatile::isMaskTooSmall(MetatileAttr * attr, int max) {
|
||||
if (attr->mask == 0 || max <= 0) return false;
|
||||
|
||||
// Get position of the most significant set bit
|
||||
uint32_t n = log2(max);
|
||||
|
||||
// Get a mask for all values 0 to max.
|
||||
// This may fail for n=31, but that's not a concern here.
|
||||
uint32_t rangeMask = (1 << (n + 1)) - 1;
|
||||
|
||||
return attr->getClamped(rangeMask) != rangeMask;
|
||||
}
|
||||
|
||||
bool Metatile::doMasksOverlap(QList<uint32_t> masks) {
|
||||
|
@ -98,107 +120,70 @@ void Metatile::setCustomLayout() {
|
|||
const uint32_t maxMask = maxMasks.value(projectConfig.getMetatileAttributesSize(), 0);
|
||||
|
||||
// Set custom attribute masks from the config file
|
||||
setCustomAttributeLayout(&customLayout[Attr::Behavior], projectConfig.getMetatileBehaviorMask(), maxMask);
|
||||
setCustomAttributeLayout(&customLayout[Attr::TerrainType], projectConfig.getMetatileTerrainTypeMask(), maxMask);
|
||||
setCustomAttributeLayout(&customLayout[Attr::EncounterType], projectConfig.getMetatileEncounterTypeMask(), maxMask);
|
||||
setCustomAttributeLayout(&customLayout[Attr::LayerType], projectConfig.getMetatileLayerTypeMask(), maxMask);
|
||||
setCustomAttributeLayout(&Metatile::behaviorAttr, projectConfig.getMetatileBehaviorMask(), maxMask);
|
||||
setCustomAttributeLayout(&Metatile::terrainTypeAttr, projectConfig.getMetatileTerrainTypeMask(), maxMask);
|
||||
setCustomAttributeLayout(&Metatile::encounterTypeAttr, projectConfig.getMetatileEncounterTypeMask(), maxMask);
|
||||
setCustomAttributeLayout(&Metatile::layerTypeAttr, projectConfig.getMetatileLayerTypeMask(), maxMask);
|
||||
|
||||
// Set mask for preserving any attribute bits not used by Porymap
|
||||
Metatile::unusedAttrMask = ~(customLayout[Attr::Behavior].mask
|
||||
| customLayout[Attr::TerrainType].mask
|
||||
| customLayout[Attr::EncounterType].mask
|
||||
| customLayout[Attr::LayerType].mask);
|
||||
Metatile::unusedAttrMask = ~(getBehaviorMask() | getTerrainTypeMask() | getEncounterTypeMask() | getLayerTypeMask());
|
||||
Metatile::unusedAttrMask &= maxMask;
|
||||
|
||||
// Overlapping masks are technically ok, but probably not intended.
|
||||
// Additionally, Porymap will not properly reflect that the values are linked.
|
||||
if (doMasksOverlap({customLayout[Attr::Behavior].mask,
|
||||
customLayout[Attr::TerrainType].mask,
|
||||
customLayout[Attr::EncounterType].mask,
|
||||
customLayout[Attr::LayerType].mask})) {
|
||||
logWarn("Metatile attribute masks are overlapping.");
|
||||
if (doMasksOverlap({getBehaviorMask(), getTerrainTypeMask(), getEncounterTypeMask(), getLayerTypeMask()})) {
|
||||
logWarn("Metatile attribute masks are overlapping. This may result in unexpected attribute values.");
|
||||
}
|
||||
|
||||
// The available options in the Tileset Editor for Terrain Type, Encounter Type, and Layer Type are hard-coded.
|
||||
// Warn the user if they have set a nonzero mask that is too small to contain these options.
|
||||
// They'll be allowed to select them, but they'll be truncated to a different value when revisited.
|
||||
if (isMaskTooSmall(&customLayout[Attr::TerrainType], NUM_METATILE_TERRAIN_TYPES))
|
||||
if (isMaskTooSmall(&Metatile::terrainTypeAttr, NUM_METATILE_TERRAIN_TYPES - 1))
|
||||
logWarn(QString("Metatile Terrain Type mask is too small to contain all %1 available options.").arg(NUM_METATILE_TERRAIN_TYPES));
|
||||
if (isMaskTooSmall(&customLayout[Attr::EncounterType], NUM_METATILE_ENCOUNTER_TYPES))
|
||||
if (isMaskTooSmall(&Metatile::encounterTypeAttr, NUM_METATILE_ENCOUNTER_TYPES - 1))
|
||||
logWarn(QString("Metatile Encounter Type mask is too small to contain all %1 available options.").arg(NUM_METATILE_ENCOUNTER_TYPES));
|
||||
if (isMaskTooSmall(&customLayout[Attr::LayerType], NUM_METATILE_LAYER_TYPES))
|
||||
if (isMaskTooSmall(&Metatile::layerTypeAttr, NUM_METATILE_LAYER_TYPES - 1))
|
||||
logWarn(QString("Metatile Layer Type mask is too small to contain all %1 available options.").arg(NUM_METATILE_LAYER_TYPES));
|
||||
}
|
||||
|
||||
uint32_t Metatile::getAttributes() {
|
||||
uint32_t attributes = this->unusedAttributes & Metatile::unusedAttrMask;
|
||||
|
||||
// Behavior
|
||||
Metatile::AttrLayout attr = Metatile::customLayout[Attr::Behavior];
|
||||
attributes |= (this->behavior << attr.shift) & attr.mask;
|
||||
|
||||
// Terrain Type
|
||||
attr = Metatile::customLayout[Attr::TerrainType];
|
||||
attributes |= (this->terrainType << attr.shift) & attr.mask;
|
||||
|
||||
// Encounter Type
|
||||
attr = Metatile::customLayout[Attr::EncounterType];
|
||||
attributes |= (this->encounterType << attr.shift) & attr.mask;
|
||||
|
||||
// Layer Type
|
||||
attr = Metatile::customLayout[Attr::LayerType];
|
||||
attributes |= (this->layerType << attr.shift) & attr.mask;
|
||||
|
||||
attributes |= Metatile::behaviorAttr.toRaw(this->behavior);
|
||||
attributes |= Metatile::terrainTypeAttr.toRaw(this->terrainType);
|
||||
attributes |= Metatile::encounterTypeAttr.toRaw(this->encounterType);
|
||||
attributes |= Metatile::layerTypeAttr.toRaw(this->layerType);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
void Metatile::setAttributes(uint32_t data, const QHash<Metatile::Attr, Metatile::AttrLayout> * layout) {
|
||||
// Behavior
|
||||
Metatile::AttrLayout attr = layout->value(Attr::Behavior);
|
||||
this->behavior = (data & attr.mask) >> attr.shift;
|
||||
|
||||
// Terrain Type
|
||||
attr = layout->value(Attr::TerrainType);
|
||||
this->terrainType = (data & attr.mask) >> attr.shift;
|
||||
|
||||
// Encounter Type
|
||||
attr = layout->value(Attr::EncounterType);
|
||||
this->encounterType = (data & attr.mask) >> attr.shift;
|
||||
|
||||
// Layer Type
|
||||
attr = layout->value(Attr::LayerType);
|
||||
this->layerType = (data & attr.mask) >> attr.shift;
|
||||
|
||||
void Metatile::setAttributes(uint32_t data) {
|
||||
this->behavior = Metatile::behaviorAttr.fromRaw(data);
|
||||
this->terrainType = Metatile::terrainTypeAttr.fromRaw(data);
|
||||
this->encounterType = Metatile::encounterTypeAttr.fromRaw(data);
|
||||
this->layerType = Metatile::layerTypeAttr.fromRaw(data);
|
||||
this->unusedAttributes = data & Metatile::unusedAttrMask;
|
||||
}
|
||||
|
||||
void Metatile::setAttributes(uint32_t data) {
|
||||
this->setAttributes(data, &Metatile::customLayout);
|
||||
}
|
||||
|
||||
// Read attributes using a vanilla layout, then set them using the user's layout. For AdvanceMap import
|
||||
void Metatile::convertAttributes(uint32_t data, BaseGameVersion version) {
|
||||
if (version == BaseGameVersion::pokefirered) {
|
||||
this->setAttributes(data, &Metatile::defaultLayoutFRLG);
|
||||
} else {
|
||||
this->setAttributes(data, &Metatile::defaultLayoutRSE);
|
||||
}
|
||||
// Clean data to fit the user's custom masks
|
||||
this->setAttributes(this->getAttributes());
|
||||
void Metatile::setAttributes(uint32_t data, BaseGameVersion version) {
|
||||
const auto defaultLayout = Metatile::defaultLayouts.value(version);
|
||||
this->setBehavior(defaultLayout->value("behavior").fromRaw(data));
|
||||
this->setTerrainType(defaultLayout->value("terrainType").fromRaw(data));
|
||||
this->setEncounterType(defaultLayout->value("encounterType").fromRaw(data));
|
||||
this->setLayerType(defaultLayout->value("layerType").fromRaw(data));
|
||||
}
|
||||
|
||||
void Metatile::setBehavior(uint32_t value) {
|
||||
this->behavior = value & Metatile::customLayout[Attr::Behavior].mask;
|
||||
int Metatile::getDefaultAttributesSize(BaseGameVersion version) {
|
||||
return (version == BaseGameVersion::pokefirered) ? 4 : 2;
|
||||
}
|
||||
|
||||
void Metatile::setTerrainType(uint32_t value) {
|
||||
this->terrainType = value & Metatile::customLayout[Attr::TerrainType].mask;
|
||||
uint32_t Metatile::getBehaviorMask(BaseGameVersion version) {
|
||||
return Metatile::defaultLayouts.value(version)->value("behavior").mask;
|
||||
}
|
||||
|
||||
void Metatile::setEncounterType(uint32_t value) {
|
||||
this->encounterType = value & Metatile::customLayout[Attr::EncounterType].mask;
|
||||
uint32_t Metatile::getTerrainTypeMask(BaseGameVersion version) {
|
||||
return Metatile::defaultLayouts.value(version)->value("terrainType").mask;
|
||||
}
|
||||
|
||||
void Metatile::setLayerType(uint32_t value) {
|
||||
this->layerType = value & Metatile::customLayout[Attr::LayerType].mask;
|
||||
uint32_t Metatile::getEncounterTypeMask(BaseGameVersion version) {
|
||||
return Metatile::defaultLayouts.value(version)->value("encounterType").mask;
|
||||
}
|
||||
uint32_t Metatile::getLayerTypeMask(BaseGameVersion version) {
|
||||
return Metatile::defaultLayouts.value(version)->value("layerType").mask;
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ QList<Metatile*> MetatileParser::parse(QString filepath, bool *error, bool prima
|
|||
uint32_t attributes = 0;
|
||||
for (int j = 0; j < attrSize; j++)
|
||||
attributes |= static_cast<unsigned char>(in.at(attrOffset + j)) << (8 * j);
|
||||
metatile->convertAttributes(attributes, version);
|
||||
metatile->setAttributes(attributes, version);
|
||||
metatile->tiles = tiles;
|
||||
metatiles.append(metatile);
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ void TilesetEditor::initUi() {
|
|||
|
||||
void TilesetEditor::setAttributesUi() {
|
||||
// Behavior
|
||||
if (Metatile::customLayout[Metatile::Attr::Behavior].mask) {
|
||||
if (Metatile::getBehaviorMask()) {
|
||||
for (int num : project->metatileBehaviorMapInverse.keys()) {
|
||||
this->ui->comboBox_metatileBehaviors->addItem(project->metatileBehaviorMapInverse[num], num);
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ void TilesetEditor::setAttributesUi() {
|
|||
}
|
||||
|
||||
// Terrain Type
|
||||
if (Metatile::customLayout[Metatile::Attr::TerrainType].mask) {
|
||||
if (Metatile::getTerrainTypeMask()) {
|
||||
this->ui->comboBox_terrainType->addItem("Normal", TERRAIN_NONE);
|
||||
this->ui->comboBox_terrainType->addItem("Grass", TERRAIN_GRASS);
|
||||
this->ui->comboBox_terrainType->addItem("Water", TERRAIN_WATER);
|
||||
|
@ -134,7 +134,7 @@ void TilesetEditor::setAttributesUi() {
|
|||
}
|
||||
|
||||
// Encounter Type
|
||||
if (Metatile::customLayout[Metatile::Attr::EncounterType].mask) {
|
||||
if (Metatile::getEncounterTypeMask()) {
|
||||
this->ui->comboBox_encounterType->addItem("None", ENCOUNTER_NONE);
|
||||
this->ui->comboBox_encounterType->addItem("Land", ENCOUNTER_LAND);
|
||||
this->ui->comboBox_encounterType->addItem("Water", ENCOUNTER_WATER);
|
||||
|
@ -148,7 +148,7 @@ void TilesetEditor::setAttributesUi() {
|
|||
this->ui->comboBox_layerType->addItem("Normal - Middle/Top", METATILE_LAYER_MIDDLE_TOP);
|
||||
this->ui->comboBox_layerType->addItem("Covered - Bottom/Middle", METATILE_LAYER_BOTTOM_MIDDLE);
|
||||
this->ui->comboBox_layerType->addItem("Split - Bottom/Top", METATILE_LAYER_BOTTOM_TOP);
|
||||
if (!Metatile::customLayout[Metatile::Attr::LayerType].mask) {
|
||||
if (!Metatile::getLayerTypeMask()) {
|
||||
// User doesn't have triple layer metatiles, but has no layer type attribute.
|
||||
// Porymap is still using the layer type value to render metatiles, and with
|
||||
// no mask set every metatile will be "Middle/Top", so just display the combo
|
||||
|
|
Loading…
Reference in a new issue