2020-09-13 23:37:55 +01:00
|
|
|
#pragma once
|
2018-09-23 00:47:28 +01:00
|
|
|
#ifndef METATILE_H
|
|
|
|
#define METATILE_H
|
|
|
|
|
|
|
|
#include "tile.h"
|
2022-02-03 23:10:50 +00:00
|
|
|
#include "config.h"
|
2018-09-23 00:47:28 +01:00
|
|
|
#include <QImage>
|
2020-09-27 17:17:12 +01:00
|
|
|
#include <QPoint>
|
2019-04-04 06:44:31 +01:00
|
|
|
#include <QString>
|
2018-09-23 00:47:28 +01:00
|
|
|
|
2022-10-27 12:52:07 +01:00
|
|
|
class Project;
|
|
|
|
|
2021-11-23 21:11:07 +00:00
|
|
|
enum {
|
|
|
|
METATILE_LAYER_MIDDLE_TOP,
|
|
|
|
METATILE_LAYER_BOTTOM_MIDDLE,
|
|
|
|
METATILE_LAYER_BOTTOM_TOP,
|
|
|
|
NUM_METATILE_LAYER_TYPES
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
ENCOUNTER_NONE,
|
|
|
|
ENCOUNTER_LAND,
|
|
|
|
ENCOUNTER_WATER,
|
|
|
|
NUM_METATILE_ENCOUNTER_TYPES
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
TERRAIN_NONE,
|
|
|
|
TERRAIN_GRASS,
|
|
|
|
TERRAIN_WATER,
|
|
|
|
TERRAIN_WATERFALL,
|
|
|
|
NUM_METATILE_TERRAIN_TYPES
|
|
|
|
};
|
|
|
|
|
2022-10-26 09:13:53 +01:00
|
|
|
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); }
|
|
|
|
};
|
|
|
|
|
2018-09-23 00:47:28 +01:00
|
|
|
class Metatile
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Metatile();
|
2021-02-16 18:22:41 +00:00
|
|
|
Metatile(const Metatile &other) = default;
|
|
|
|
Metatile &operator=(const Metatile &other) = default;
|
2022-10-04 02:28:16 +01:00
|
|
|
Metatile(const int numTiles);
|
2021-02-16 18:22:41 +00:00
|
|
|
|
2018-09-23 00:47:28 +01:00
|
|
|
public:
|
2021-02-16 17:14:27 +00:00
|
|
|
QList<Tile> tiles;
|
2022-10-25 22:51:32 +01:00
|
|
|
uint32_t behavior;
|
|
|
|
uint32_t terrainType;
|
2022-10-26 07:42:55 +01:00
|
|
|
uint32_t encounterType;
|
|
|
|
uint32_t layerType;
|
2022-02-03 23:10:50 +00:00
|
|
|
uint32_t unusedAttributes;
|
2018-09-23 00:47:28 +01:00
|
|
|
|
2022-10-25 22:51:32 +01:00
|
|
|
uint32_t getAttributes();
|
|
|
|
void setAttributes(uint32_t data);
|
2022-10-26 09:13:53 +01:00
|
|
|
void setAttributes(uint32_t data, BaseGameVersion version);
|
|
|
|
|
|
|
|
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);
|
2022-10-26 07:42:55 +01:00
|
|
|
|
2022-01-04 02:35:15 +00:00
|
|
|
static int getIndexInTileset(int);
|
2020-09-27 17:17:12 +01:00
|
|
|
static QPoint coordFromPixmapCoord(const QPointF &pixelCoord);
|
2022-10-26 05:14:55 +01:00
|
|
|
static int getDefaultAttributesSize(BaseGameVersion version);
|
2022-10-27 12:52:07 +01:00
|
|
|
static void setCustomLayout(Project*);
|
2023-09-19 19:21:36 +01:00
|
|
|
static QString getMetatileIdString(uint16_t metatileId) {
|
|
|
|
return "0x" + QString("%1").arg(metatileId, 3, 16, QChar('0')).toUpper();
|
|
|
|
};
|
|
|
|
static QString getMetatileIdStringList(const QList<uint16_t> metatileIds) {
|
|
|
|
QStringList metatiles;
|
|
|
|
for (auto metatileId : metatileIds)
|
|
|
|
metatiles << Metatile::getMetatileIdString(metatileId);
|
|
|
|
return metatiles.join(",");
|
|
|
|
};
|
2022-10-25 22:51:32 +01:00
|
|
|
|
|
|
|
private:
|
2022-10-26 09:13:53 +01:00
|
|
|
// 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;
|
|
|
|
|
2022-10-25 22:51:32 +01:00
|
|
|
static uint32_t unusedAttrMask;
|
|
|
|
|
2022-10-26 09:13:53 +01:00
|
|
|
// 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);
|
2022-10-26 05:14:55 +01:00
|
|
|
static bool doMasksOverlap(QList<uint32_t>);
|
2018-09-23 00:47:28 +01:00
|
|
|
};
|
|
|
|
|
2022-06-29 19:53:14 +01:00
|
|
|
inline bool operator==(const Metatile &a, const Metatile &b) {
|
|
|
|
return a.behavior == b.behavior &&
|
|
|
|
a.layerType == b.layerType &&
|
|
|
|
a.encounterType == b.encounterType &&
|
|
|
|
a.terrainType == b.terrainType &&
|
|
|
|
a.unusedAttributes == b.unusedAttributes &&
|
|
|
|
a.tiles == b.tiles;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator!=(const Metatile &a, const Metatile &b) {
|
|
|
|
return !(operator==(a, b));
|
|
|
|
}
|
|
|
|
|
2018-09-23 00:47:28 +01:00
|
|
|
#endif // METATILE_H
|