Merge remote-tracking branch 'origin/master' into metatile-leaks

This commit is contained in:
Marcus Huderle 2021-02-17 16:56:15 -06:00
commit c351f069ff
26 changed files with 534 additions and 841 deletions

View file

@ -12,12 +12,12 @@ public:
Block(uint16_t tile, uint16_t collision, uint16_t elevation); Block(uint16_t tile, uint16_t collision, uint16_t elevation);
Block(const Block &); Block(const Block &);
Block &operator=(const Block &); Block &operator=(const Block &);
bool operator ==(Block); bool operator ==(Block) const;
bool operator !=(Block); bool operator !=(Block) const;
uint16_t tile:10; uint16_t tile:10;
uint16_t collision:2; uint16_t collision:2;
uint16_t elevation:4; uint16_t elevation:4;
uint16_t rawValue(); uint16_t rawValue() const;
}; };
#endif // BLOCK_H #endif // BLOCK_H

View file

@ -4,31 +4,13 @@
#include "block.h" #include "block.h"
#include <QObject>
#include <QByteArray> #include <QByteArray>
#include <QVector> #include <QVector>
class Blockdata : public QObject class Blockdata : public QVector<Block>
{ {
Q_OBJECT
public: public:
explicit Blockdata(QObject *parent = nullptr); QByteArray serialize() const;
~Blockdata() {
if (blocks) delete blocks;
}
public:
QVector<Block> *blocks = nullptr;
void addBlock(uint16_t);
void addBlock(Block);
QByteArray serialize();
void copyFrom(Blockdata*);
Blockdata* copy();
bool equals(Blockdata *);
signals:
public slots:
}; };
#endif // BLOCKDATA_H #endif // BLOCKDATA_H

View file

@ -2,6 +2,8 @@
#ifndef EDITCOMMANDS_H #ifndef EDITCOMMANDS_H
#define EDITCOMMANDS_H #define EDITCOMMANDS_H
#include "blockdata.h"
#include <QUndoCommand> #include <QUndoCommand>
#include <QList> #include <QList>
@ -41,9 +43,8 @@ enum CommandId {
class PaintMetatile : public QUndoCommand { class PaintMetatile : public QUndoCommand {
public: public:
PaintMetatile(Map *map, PaintMetatile(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles, const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
unsigned actionId, QUndoCommand *parent = nullptr); unsigned actionId, QUndoCommand *parent = nullptr);
virtual ~PaintMetatile();
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -54,8 +55,8 @@ public:
private: private:
Map *map; Map *map;
Blockdata *newMetatiles; Blockdata newMetatiles;
Blockdata *oldMetatiles; Blockdata oldMetatiles;
unsigned actionId; unsigned actionId;
}; };
@ -67,7 +68,7 @@ private:
class PaintCollision : public PaintMetatile { class PaintCollision : public PaintMetatile {
public: public:
PaintCollision(Map *map, PaintCollision(Map *map,
Blockdata *oldCollision, Blockdata *newCollision, const Blockdata &oldCollision, const Blockdata &newCollision,
unsigned actionId, QUndoCommand *parent = nullptr) unsigned actionId, QUndoCommand *parent = nullptr)
: PaintMetatile(map, oldCollision, newCollision, actionId, parent) { : PaintMetatile(map, oldCollision, newCollision, actionId, parent) {
setText("Paint Collision"); setText("Paint Collision");
@ -82,9 +83,8 @@ public:
class PaintBorder : public QUndoCommand { class PaintBorder : public QUndoCommand {
public: public:
PaintBorder(Map *map, PaintBorder(Map *map,
Blockdata *oldBorder, Blockdata *newBorder, const Blockdata &oldBorder, const Blockdata &newBorder,
unsigned actionId, QUndoCommand *parent = nullptr); unsigned actionId, QUndoCommand *parent = nullptr);
~PaintBorder();
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -95,8 +95,8 @@ public:
private: private:
Map *map; Map *map;
Blockdata *newBorder; Blockdata newBorder;
Blockdata *oldBorder; Blockdata oldBorder;
unsigned actionId; unsigned actionId;
}; };
@ -108,7 +108,7 @@ private:
class BucketFillMetatile : public PaintMetatile { class BucketFillMetatile : public PaintMetatile {
public: public:
BucketFillMetatile(Map *map, BucketFillMetatile(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles, const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
unsigned actionId, QUndoCommand *parent = nullptr) unsigned actionId, QUndoCommand *parent = nullptr)
: PaintMetatile(map, oldMetatiles, newMetatiles, actionId, parent) { : PaintMetatile(map, oldMetatiles, newMetatiles, actionId, parent) {
setText("Bucket Fill Metatiles"); setText("Bucket Fill Metatiles");
@ -124,7 +124,7 @@ public:
class BucketFillCollision : public PaintCollision { class BucketFillCollision : public PaintCollision {
public: public:
BucketFillCollision(Map *map, BucketFillCollision(Map *map,
Blockdata *oldCollision, Blockdata *newCollision, const Blockdata &oldCollision, const Blockdata &newCollision,
QUndoCommand *parent = nullptr) QUndoCommand *parent = nullptr)
: PaintCollision(map, oldCollision, newCollision, -1, parent) { : PaintCollision(map, oldCollision, newCollision, -1, parent) {
setText("Flood Fill Collision"); setText("Flood Fill Collision");
@ -141,7 +141,7 @@ public:
class MagicFillMetatile : public PaintMetatile { class MagicFillMetatile : public PaintMetatile {
public: public:
MagicFillMetatile(Map *map, MagicFillMetatile(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles, const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
unsigned actionId, QUndoCommand *parent = nullptr) unsigned actionId, QUndoCommand *parent = nullptr)
: PaintMetatile(map, oldMetatiles, newMetatiles, actionId, parent) { : PaintMetatile(map, oldMetatiles, newMetatiles, actionId, parent) {
setText("Magic Fill Metatiles"); setText("Magic Fill Metatiles");
@ -156,7 +156,7 @@ public:
class MagicFillCollision : public PaintCollision { class MagicFillCollision : public PaintCollision {
public: public:
MagicFillCollision(Map *map, MagicFillCollision(Map *map,
Blockdata *oldCollision, Blockdata *newCollision, const Blockdata &oldCollision, const Blockdata &newCollision,
QUndoCommand *parent = nullptr) QUndoCommand *parent = nullptr)
: PaintCollision(map, oldCollision, newCollision, -1, parent) { : PaintCollision(map, oldCollision, newCollision, -1, parent) {
setText("Magic Fill Collision"); setText("Magic Fill Collision");
@ -172,9 +172,8 @@ public:
class ShiftMetatiles : public QUndoCommand { class ShiftMetatiles : public QUndoCommand {
public: public:
ShiftMetatiles(Map *map, ShiftMetatiles(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles, const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
unsigned actionId, QUndoCommand *parent = nullptr); unsigned actionId, QUndoCommand *parent = nullptr);
~ShiftMetatiles();
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -185,8 +184,8 @@ public:
private: private:
Map *map; Map *map;
Blockdata *newMetatiles; Blockdata newMetatiles;
Blockdata *oldMetatiles; Blockdata oldMetatiles;
unsigned actionId; unsigned actionId;
}; };
@ -197,11 +196,10 @@ private:
class ResizeMap : public QUndoCommand { class ResizeMap : public QUndoCommand {
public: public:
ResizeMap(Map *map, QSize oldMapDimensions, QSize newMapDimensions, ResizeMap(Map *map, QSize oldMapDimensions, QSize newMapDimensions,
Blockdata *oldMetatiles, Blockdata *newMetatiles, const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
QSize oldBorderDimensions, QSize newBorderDimensions, QSize oldBorderDimensions, QSize newBorderDimensions,
Blockdata *oldBorder, Blockdata *newBorder, const Blockdata &oldBorder, const Blockdata &newBorder,
QUndoCommand *parent = nullptr); QUndoCommand *parent = nullptr);
~ResizeMap();
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -222,11 +220,11 @@ private:
int newBorderWidth; int newBorderWidth;
int newBorderHeight; int newBorderHeight;
Blockdata *newMetatiles; Blockdata newMetatiles;
Blockdata *oldMetatiles; Blockdata oldMetatiles;
Blockdata *newBorder; Blockdata newBorder;
Blockdata *oldBorder; Blockdata oldBorder;
}; };
@ -238,7 +236,6 @@ public:
EventMove(QList<Event *> events, EventMove(QList<Event *> events,
int deltaX, int deltaY, unsigned actionId, int deltaX, int deltaY, unsigned actionId,
QUndoCommand *parent = nullptr); QUndoCommand *parent = nullptr);
~EventMove();
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -262,7 +259,6 @@ public:
EventShift(QList<Event *> events, EventShift(QList<Event *> events,
int deltaX, int deltaY, unsigned actionId, int deltaX, int deltaY, unsigned actionId,
QUndoCommand *parent = nullptr); QUndoCommand *parent = nullptr);
~EventShift();
int id() const override; int id() const override;
private: private:
QList<Event *> events; QList<Event *> events;
@ -276,7 +272,6 @@ class EventCreate : public QUndoCommand {
public: public:
EventCreate(Editor *editor, Map *map, Event *event, EventCreate(Editor *editor, Map *map, Event *event,
QUndoCommand *parent = nullptr); QUndoCommand *parent = nullptr);
~EventCreate();
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -299,7 +294,6 @@ public:
EventDelete(Editor *editor, Map *map, EventDelete(Editor *editor, Map *map,
QList<Event *> selectedEvents, Event *nextSelectedEvent, QList<Event *> selectedEvents, Event *nextSelectedEvent,
QUndoCommand *parent = nullptr); QUndoCommand *parent = nullptr);
~EventDelete();
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -321,7 +315,6 @@ class EventDuplicate : public QUndoCommand {
public: public:
EventDuplicate(Editor *editor, Map *map, QList<Event *> selectedEvents, EventDuplicate(Editor *editor, Map *map, QList<Event *> selectedEvents,
QUndoCommand *parent = nullptr); QUndoCommand *parent = nullptr);
~EventDuplicate();
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -343,9 +336,8 @@ class ScriptEditMap : public QUndoCommand {
public: public:
ScriptEditMap(Map *map, ScriptEditMap(Map *map,
QSize oldMapDimensions, QSize newMapDimensions, QSize oldMapDimensions, QSize newMapDimensions,
Blockdata *oldMetatiles, Blockdata *newMetatiles, const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
QUndoCommand *parent = nullptr); QUndoCommand *parent = nullptr);
~ScriptEditMap();
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -356,8 +348,8 @@ public:
private: private:
Map *map; Map *map;
Blockdata *newMetatiles; Blockdata newMetatiles;
Blockdata *oldMetatiles; Blockdata oldMetatiles;
int oldMapWidth; int oldMapWidth;
int oldMapHeight; int oldMapHeight;

View file

@ -77,7 +77,7 @@ public:
static Event* createNewSecretBaseEvent(Project*); static Event* createNewSecretBaseEvent(Project*);
OrderedJson::object buildObjectEventJSON(); OrderedJson::object buildObjectEventJSON();
OrderedJson::object buildWarpEventJSON(QMap<QString, QString>*); OrderedJson::object buildWarpEventJSON(const QMap<QString, QString> &);
OrderedJson::object buildTriggerEventJSON(); OrderedJson::object buildTriggerEventJSON();
OrderedJson::object buildWeatherTriggerEventJSON(); OrderedJson::object buildWeatherTriggerEventJSON();
OrderedJson::object buildSignEventJSON(); OrderedJson::object buildSignEventJSON();

View file

@ -75,8 +75,8 @@ public:
int getBorderHeight(); int getBorderHeight();
QPixmap render(bool ignoreCache, MapLayout * fromLayout = nullptr); QPixmap render(bool ignoreCache, MapLayout * fromLayout = nullptr);
QPixmap renderCollision(qreal opacity, bool ignoreCache); QPixmap renderCollision(qreal opacity, bool ignoreCache);
bool mapBlockChanged(int i, Blockdata * cache); bool mapBlockChanged(int i, const Blockdata &cache);
bool borderBlockChanged(int i, Blockdata * cache); bool borderBlockChanged(int i, const Blockdata &cache);
void cacheBlockdata(); void cacheBlockdata();
void cacheCollision(); void cacheCollision();
bool getBlock(int x, int y, Block *out); bool getBlock(int x, int y, Block *out);

View file

@ -24,15 +24,15 @@ public:
QString tileset_secondary_label; QString tileset_secondary_label;
Tileset *tileset_primary = nullptr; Tileset *tileset_primary = nullptr;
Tileset *tileset_secondary = nullptr; Tileset *tileset_secondary = nullptr;
Blockdata *blockdata = nullptr; Blockdata blockdata;
QImage border_image; QImage border_image;
QPixmap border_pixmap; QPixmap border_pixmap;
Blockdata *border = nullptr; Blockdata border;
Blockdata *cached_blockdata = nullptr; Blockdata cached_blockdata;
Blockdata *cached_collision = nullptr; Blockdata cached_collision;
Blockdata *cached_border = nullptr; Blockdata cached_border;
struct { struct {
Blockdata *blocks = nullptr; Blockdata blocks;
QSize dimensions; QSize dimensions;
} lastCommitMapBlocks; // to track map changes } lastCommitMapBlocks; // to track map changes
}; };

View file

@ -39,31 +39,30 @@ public:
class ParseUtil class ParseUtil
{ {
public: public:
ParseUtil(); ParseUtil() { };
void set_root(QString); void set_root(const QString &dir);
static QString readTextFile(QString); static QString readTextFile(const QString &path);
static int textFileLineCount(const QString &path); static int textFileLineCount(const QString &path);
void strip_comment(QString*); QList<QStringList> parseAsm(const QString &filename);
QList<QStringList>* parseAsm(QString); int evaluateDefine(const QString&, const QMap<QString, int>&);
int evaluateDefine(QString, QMap<QString, int>*); QStringList readCArray(const QString &text, const QString &label);
QStringList readCArray(QString text, QString label); QMap<QString, QString> readNamedIndexCArray(const QString &text, const QString &label);
QMap<QString, QString> readNamedIndexCArray(QString text, QString label); QString readCIncbin(const QString &text, const QString &label);
QString readCIncbin(QString text, QString label); QMap<QString, int> readCDefines(const QString &filename, const QStringList &prefixes, QMap<QString, int> = { });
QMap<QString, int> readCDefines(QString filename, QStringList prefixes, QMap<QString, int> = QMap<QString, int>()); QStringList readCDefinesSorted(const QString&, const QStringList&, const QMap<QString, int>& = { });
void readCDefinesSorted(QString, QStringList, QStringList*, QMap<QString, int> = QMap<QString, int>()); QList<QStringList> getLabelMacros(const QList<QStringList>&, const QString&);
QList<QStringList>* getLabelMacros(QList<QStringList>*, QString); QStringList getLabelValues(const QList<QStringList>&, const QString&);
QStringList* getLabelValues(QList<QStringList>*, QString); bool tryParseJsonFile(QJsonDocument *out, const QString &filepath);
bool tryParseJsonFile(QJsonDocument *out, QString filepath); bool ensureFieldsExist(const QJsonObject &obj, const QList<QString> &fields);
bool ensureFieldsExist(QJsonObject obj, QList<QString> fields);
// Returns the 1-indexed line number for the definition of scriptLabel in the scripts file at filePath. // Returns the 1-indexed line number for the definition of scriptLabel in the scripts file at filePath.
// Returns 0 if a definition for scriptLabel cannot be found. // Returns 0 if a definition for scriptLabel cannot be found.
static int getScriptLineNumber(const QString &filePath, const QString &scriptLabel); static int getScriptLineNumber(const QString &filePath, const QString &scriptLabel);
static int getRawScriptLineNumber(QString text, const QString &scriptLabel); static int getRawScriptLineNumber(QString text, const QString &scriptLabel);
static int getPoryScriptLineNumber(QString text, const QString &scriptLabel); static int getPoryScriptLineNumber(QString text, const QString &scriptLabel);
static QString &removeStringLiterals(QString &text); static QString removeStringLiterals(QString text);
static QString &removeLineComments(QString &text, const QString &commentSymbol); static QString removeLineComments(QString text, const QString &commentSymbol);
static QString &removeLineComments(QString &text, const QStringList &commentSymbols); static QString removeLineComments(QString text, const QStringList &commentSymbols);
static QStringList splitShellCommand(QStringView command); static QStringList splitShellCommand(QStringView command);
@ -71,10 +70,10 @@ private:
QString root; QString root;
QString text; QString text;
QString file; QString file;
QList<Token> tokenizeExpression(QString expression, QMap<QString, int>* knownIdentifiers); QList<Token> tokenizeExpression(QString expression, const QMap<QString, int> &knownIdentifiers);
QList<Token> generatePostfix(QList<Token> tokens); QList<Token> generatePostfix(const QList<Token> &tokens);
int evaluatePostfix(QList<Token> postfix); int evaluatePostfix(const QList<Token> &postfix);
void error(QString message, QString expression); void error(const QString &message, const QString &expression);
}; };
#endif // PARSEUTIL_H #endif // PARSEUTIL_H

View file

@ -31,35 +31,37 @@ public:
Project(const Project &) = delete; Project(const Project &) = delete;
Project & operator = (const Project &) = delete; Project & operator = (const Project &) = delete;
inline QWidget *parentWidget() const { return static_cast<QWidget *>(parent()); }
public: public:
QString root; QString root;
QStringList *groupNames = nullptr; QStringList groupNames;
QMap<QString, int> *mapGroups; QMap<QString, int> mapGroups;
QList<QStringList> groupedMapNames; QList<QStringList> groupedMapNames;
QStringList *mapNames = nullptr; QStringList mapNames;
QMap<QString, QVariant> miscConstants; QMap<QString, QVariant> miscConstants;
QList<HealLocation> healLocations; QList<HealLocation> healLocations;
QMap<QString, QString>* mapConstantsToMapNames; QMap<QString, QString> mapConstantsToMapNames;
QMap<QString, QString>* mapNamesToMapConstants; QMap<QString, QString> mapNamesToMapConstants;
QList<QString> mapLayoutsTable; QStringList mapLayoutsTable;
QList<QString> mapLayoutsTableMaster; QStringList mapLayoutsTableMaster;
QString layoutsLabel; QString layoutsLabel;
QMap<QString, MapLayout*> mapLayouts; QMap<QString, MapLayout*> mapLayouts;
QMap<QString, MapLayout*> mapLayoutsMaster; QMap<QString, MapLayout*> mapLayoutsMaster;
QMap<QString, QString> *mapSecToMapHoverName; QMap<QString, QString> mapSecToMapHoverName;
QMap<QString, int> mapSectionNameToValue; QMap<QString, int> mapSectionNameToValue;
QMap<int, QString> mapSectionValueToName; QMap<int, QString> mapSectionValueToName;
QStringList *itemNames = nullptr; QStringList itemNames;
QStringList *flagNames = nullptr; QStringList flagNames;
QStringList *varNames = nullptr; QStringList varNames;
QStringList *movementTypes = nullptr; QStringList movementTypes;
QStringList *mapTypes = nullptr; QStringList mapTypes;
QStringList *mapBattleScenes = nullptr; QStringList mapBattleScenes;
QStringList *weatherNames = nullptr; QStringList weatherNames;
QStringList *coordEventWeatherNames = nullptr; QStringList coordEventWeatherNames;
QStringList *secretBaseIds = nullptr; QStringList secretBaseIds;
QStringList *bgEventFacingDirections = nullptr; QStringList bgEventFacingDirections;
QStringList *trainerTypes = nullptr; QStringList trainerTypes;
QMap<QString, int> metatileBehaviorMap; QMap<QString, int> metatileBehaviorMap;
QMap<int, QString> metatileBehaviorMapInverse; QMap<int, QString> metatileBehaviorMapInverse;
QMap<QString, QString> facingDirections; QMap<QString, QString> facingDirections;
@ -82,16 +84,16 @@ public:
DataQualifiers getDataQualifiers(QString, QString); DataQualifiers getDataQualifiers(QString, QString);
QMap<QString, DataQualifiers> dataQualifiers; QMap<QString, DataQualifiers> dataQualifiers;
QMap<QString, Map*> *mapCache; QMap<QString, Map*> mapCache;
Map* loadMap(QString); Map* loadMap(QString);
Map* getMap(QString); Map* getMap(QString);
QMap<QString, Tileset*> *tilesetCache = nullptr; QMap<QString, Tileset*> tilesetCache;
Tileset* loadTileset(QString, Tileset *tileset = nullptr); Tileset* loadTileset(QString, Tileset *tileset = nullptr);
Tileset* getTileset(QString, bool forceLoad = false); Tileset* getTileset(QString, bool forceLoad = false);
QMap<QString, QStringList> tilesetLabels; QMap<QString, QStringList> tilesetLabels;
Blockdata* readBlockdata(QString); Blockdata readBlockdata(QString);
bool loadBlockdata(Map*); bool loadBlockdata(Map*);
void saveTextFile(QString path, QString text); void saveTextFile(QString path, QString text);
@ -129,7 +131,7 @@ public:
void saveLayoutBlockdata(Map*); void saveLayoutBlockdata(Map*);
void saveLayoutBorder(Map*); void saveLayoutBorder(Map*);
void writeBlockdata(QString, Blockdata*); void writeBlockdata(QString, const Blockdata &);
void saveAllMaps(); void saveAllMaps();
void saveMap(Map*); void saveMap(Map*);
void saveAllDataStructures(); void saveAllDataStructures();
@ -219,8 +221,6 @@ private:
static int default_map_size; static int default_map_size;
static int max_object_events; static int max_object_events;
QWidget *parent;
signals: signals:
void reloadProject(); void reloadProject();
void uncheckMonitorFilesAction(); void uncheckMonitorFilesAction();

View file

@ -27,17 +27,17 @@ Block &Block::operator=(const Block &other) {
return *this; return *this;
} }
uint16_t Block::rawValue() { uint16_t Block::rawValue() const {
return static_cast<uint16_t>( return static_cast<uint16_t>(
(tile & 0x3ff) + (tile & 0x3ff) +
((collision & 0x3) << 10) + ((collision & 0x3) << 10) +
((elevation & 0xf) << 12)); ((elevation & 0xf) << 12));
} }
bool Block::operator ==(Block other) { bool Block::operator ==(Block other) const {
return (tile == other.tile) && (collision == other.collision) && (elevation == other.elevation); return (tile == other.tile) && (collision == other.collision) && (elevation == other.elevation);
} }
bool Block::operator !=(Block other) { bool Block::operator !=(Block other) const {
return !(operator ==(other)); return !(operator ==(other));
} }

View file

@ -1,54 +1,11 @@
#include "blockdata.h" #include "blockdata.h"
Blockdata::Blockdata(QObject *parent) : QObject(parent) QByteArray Blockdata::serialize() const {
{
blocks = new QVector<Block>;
}
void Blockdata::addBlock(uint16_t word) {
Block block(word);
blocks->append(block);
}
void Blockdata::addBlock(Block block) {
blocks->append(block);
}
QByteArray Blockdata::serialize() {
QByteArray data; QByteArray data;
for (int i = 0; i < blocks->length(); i++) { for (const auto &block : *this) {
Block block = blocks->value(i);
uint16_t word = block.rawValue(); uint16_t word = block.rawValue();
data.append(static_cast<char>(word & 0xff)); data.append(static_cast<char>(word & 0xff));
data.append(static_cast<char>((word >> 8) & 0xff)); data.append(static_cast<char>((word >> 8) & 0xff));
} }
return data; return data;
} }
void Blockdata::copyFrom(Blockdata* other) {
blocks->clear();
for (int i = 0; i < other->blocks->length(); i++) {
addBlock(other->blocks->value(i));
}
}
Blockdata* Blockdata::copy() {
Blockdata* blockdata = new Blockdata;
blockdata->copyFrom(this);
return blockdata;
}
bool Blockdata::equals(Blockdata *other) {
if (!other) {
return false;
}
if (blocks->length() != other->blocks->length()) {
return false;
}
for (int i = 0; i < blocks->length(); i++) {
if (blocks->value(i) != other->blocks->value(i)) {
return false;
}
}
return true;
}

View file

@ -31,8 +31,9 @@ void renderMapBlocks(Map *map, bool ignoreCache = false) {
map->mapItem->draw(ignoreCache); map->mapItem->draw(ignoreCache);
map->collisionItem->draw(ignoreCache); map->collisionItem->draw(ignoreCache);
} }
PaintMetatile::PaintMetatile(Map *map, PaintMetatile::PaintMetatile(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles, const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
unsigned actionId, QUndoCommand *parent) : QUndoCommand(parent) { unsigned actionId, QUndoCommand *parent) : QUndoCommand(parent) {
setText("Paint Metatiles"); setText("Paint Metatiles");
@ -43,21 +44,14 @@ PaintMetatile::PaintMetatile(Map *map,
this->actionId = actionId; this->actionId = actionId;
} }
PaintMetatile::~PaintMetatile() {
if (newMetatiles) delete newMetatiles;
if (oldMetatiles) delete oldMetatiles;
}
void PaintMetatile::redo() { void PaintMetatile::redo() {
QUndoCommand::redo(); QUndoCommand::redo();
if (!map) return; if (!map) return;
if (map->layout->blockdata) { map->layout->blockdata = newMetatiles;
map->layout->blockdata->copyFrom(newMetatiles);
}
map->layout->lastCommitMapBlocks.blocks->copyFrom(map->layout->blockdata); map->layout->lastCommitMapBlocks.blocks = map->layout->blockdata;
renderMapBlocks(map); renderMapBlocks(map);
} }
@ -65,11 +59,9 @@ void PaintMetatile::redo() {
void PaintMetatile::undo() { void PaintMetatile::undo() {
if (!map) return; if (!map) return;
if (map->layout->blockdata) { map->layout->blockdata = oldMetatiles;
map->layout->blockdata->copyFrom(oldMetatiles);
}
map->layout->lastCommitMapBlocks.blocks->copyFrom(map->layout->blockdata); map->layout->lastCommitMapBlocks.blocks = map->layout->blockdata;
renderMapBlocks(map); renderMapBlocks(map);
@ -79,13 +71,13 @@ void PaintMetatile::undo() {
bool PaintMetatile::mergeWith(const QUndoCommand *command) { bool PaintMetatile::mergeWith(const QUndoCommand *command) {
const PaintMetatile *other = static_cast<const PaintMetatile *>(command); const PaintMetatile *other = static_cast<const PaintMetatile *>(command);
if (this->map != other->map) if (map != other->map)
return false; return false;
if (actionId != other->actionId) if (actionId != other->actionId)
return false; return false;
this->newMetatiles->copyFrom(other->newMetatiles); newMetatiles = other->newMetatiles;
return true; return true;
} }
@ -95,7 +87,7 @@ bool PaintMetatile::mergeWith(const QUndoCommand *command) {
******************************************************************************/ ******************************************************************************/
PaintBorder::PaintBorder(Map *map, PaintBorder::PaintBorder(Map *map,
Blockdata *oldBorder, Blockdata *newBorder, const Blockdata &oldBorder, const Blockdata &newBorder,
unsigned actionId, QUndoCommand *parent) : QUndoCommand(parent) { unsigned actionId, QUndoCommand *parent) : QUndoCommand(parent) {
setText("Paint Border"); setText("Paint Border");
@ -106,19 +98,12 @@ PaintBorder::PaintBorder(Map *map,
this->actionId = actionId; this->actionId = actionId;
} }
PaintBorder::~PaintBorder() {
if (newBorder) delete newBorder;
if (oldBorder) delete oldBorder;
}
void PaintBorder::redo() { void PaintBorder::redo() {
QUndoCommand::redo(); QUndoCommand::redo();
if (!map) return; if (!map) return;
if (map->layout->border) { map->layout->border = newBorder;
map->layout->border->copyFrom(newBorder);
}
map->borderItem->draw(); map->borderItem->draw();
} }
@ -126,9 +111,7 @@ void PaintBorder::redo() {
void PaintBorder::undo() { void PaintBorder::undo() {
if (!map) return; if (!map) return;
if (map->layout->border) { map->layout->border = oldBorder;
map->layout->border->copyFrom(oldBorder);
}
map->borderItem->draw(); map->borderItem->draw();
@ -140,7 +123,7 @@ void PaintBorder::undo() {
******************************************************************************/ ******************************************************************************/
ShiftMetatiles::ShiftMetatiles(Map *map, ShiftMetatiles::ShiftMetatiles(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles, const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
unsigned actionId, QUndoCommand *parent) : QUndoCommand(parent) { unsigned actionId, QUndoCommand *parent) : QUndoCommand(parent) {
setText("Shift Metatiles"); setText("Shift Metatiles");
@ -151,21 +134,14 @@ ShiftMetatiles::ShiftMetatiles(Map *map,
this->actionId = actionId; this->actionId = actionId;
} }
ShiftMetatiles::~ShiftMetatiles() {
if (newMetatiles) delete newMetatiles;
if (oldMetatiles) delete oldMetatiles;
}
void ShiftMetatiles::redo() { void ShiftMetatiles::redo() {
QUndoCommand::redo(); QUndoCommand::redo();
if (!map) return; if (!map) return;
if (map->layout->blockdata) { map->layout->blockdata = newMetatiles;
map->layout->blockdata->copyFrom(newMetatiles);
}
map->layout->lastCommitMapBlocks.blocks->copyFrom(map->layout->blockdata); map->layout->lastCommitMapBlocks.blocks = map->layout->blockdata;
renderMapBlocks(map, true); renderMapBlocks(map, true);
} }
@ -173,11 +149,9 @@ void ShiftMetatiles::redo() {
void ShiftMetatiles::undo() { void ShiftMetatiles::undo() {
if (!map) return; if (!map) return;
if (map->layout->blockdata) { map->layout->blockdata = oldMetatiles;
map->layout->blockdata->copyFrom(oldMetatiles);
}
map->layout->lastCommitMapBlocks.blocks->copyFrom(map->layout->blockdata); map->layout->lastCommitMapBlocks.blocks = map->layout->blockdata;
renderMapBlocks(map, true); renderMapBlocks(map, true);
@ -193,7 +167,7 @@ bool ShiftMetatiles::mergeWith(const QUndoCommand *command) {
if (actionId != other->actionId) if (actionId != other->actionId)
return false; return false;
this->newMetatiles->copyFrom(other->newMetatiles); this->newMetatiles = other->newMetatiles;
return true; return true;
} }
@ -203,9 +177,9 @@ bool ShiftMetatiles::mergeWith(const QUndoCommand *command) {
******************************************************************************/ ******************************************************************************/
ResizeMap::ResizeMap(Map *map, QSize oldMapDimensions, QSize newMapDimensions, ResizeMap::ResizeMap(Map *map, QSize oldMapDimensions, QSize newMapDimensions,
Blockdata *oldMetatiles, Blockdata *newMetatiles, const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
QSize oldBorderDimensions, QSize newBorderDimensions, QSize oldBorderDimensions, QSize newBorderDimensions,
Blockdata *oldBorder, Blockdata *newBorder, const Blockdata &oldBorder, const Blockdata &newBorder,
QUndoCommand *parent) : QUndoCommand(parent) { QUndoCommand *parent) : QUndoCommand(parent) {
setText("Resize Map"); setText("Resize Map");
@ -230,25 +204,16 @@ ResizeMap::ResizeMap(Map *map, QSize oldMapDimensions, QSize newMapDimensions,
this->newBorder = newBorder; this->newBorder = newBorder;
} }
ResizeMap::~ResizeMap() {
if (newMetatiles) delete newMetatiles;
if (oldMetatiles) delete oldMetatiles;
}
void ResizeMap::redo() { void ResizeMap::redo() {
QUndoCommand::redo(); QUndoCommand::redo();
if (!map) return; if (!map) return;
if (map->layout->blockdata) { map->layout->blockdata = newMetatiles;
map->layout->blockdata->copyFrom(newMetatiles); map->setDimensions(newMapWidth, newMapHeight, false);
map->setDimensions(newMapWidth, newMapHeight, false);
}
if (map->layout->border) { map->layout->border = newBorder;
map->layout->border->copyFrom(newBorder); map->setBorderDimensions(newBorderWidth, newBorderHeight, false);
map->setBorderDimensions(newBorderWidth, newBorderHeight, false);
}
map->layout->lastCommitMapBlocks.dimensions = QSize(map->getWidth(), map->getHeight()); map->layout->lastCommitMapBlocks.dimensions = QSize(map->getWidth(), map->getHeight());
@ -258,15 +223,11 @@ void ResizeMap::redo() {
void ResizeMap::undo() { void ResizeMap::undo() {
if (!map) return; if (!map) return;
if (map->layout->blockdata) { map->layout->blockdata = oldMetatiles;
map->layout->blockdata->copyFrom(oldMetatiles); map->setDimensions(oldMapWidth, oldMapHeight, false);
map->setDimensions(oldMapWidth, oldMapHeight, false);
}
if (map->layout->border) { map->layout->border = oldBorder;
map->layout->border->copyFrom(oldBorder); map->setBorderDimensions(oldBorderWidth, oldBorderHeight, false);
map->setBorderDimensions(oldBorderWidth, oldBorderHeight, false);
}
map->layout->lastCommitMapBlocks.dimensions = QSize(map->getWidth(), map->getHeight()); map->layout->lastCommitMapBlocks.dimensions = QSize(map->getWidth(), map->getHeight());
@ -292,8 +253,6 @@ EventMove::EventMove(QList<Event *> events,
this->actionId = actionId; this->actionId = actionId;
} }
EventMove::~EventMove() {}
void EventMove::redo() { void EventMove::redo() {
QUndoCommand::redo(); QUndoCommand::redo();
@ -340,8 +299,6 @@ EventShift::EventShift(QList<Event *> events,
setText("Shift Events"); setText("Shift Events");
} }
EventShift::~EventShift() {}
int EventShift::id() const { int EventShift::id() const {
return CommandId::ID_EventShift | getEventTypeMask(events); return CommandId::ID_EventShift | getEventTypeMask(events);
} }
@ -360,13 +317,11 @@ EventCreate::EventCreate(Editor *editor, Map *map, Event *event,
this->event = event; this->event = event;
} }
EventCreate::~EventCreate() {}
void EventCreate::redo() { void EventCreate::redo() {
QUndoCommand::redo(); QUndoCommand::redo();
map->addEvent(event); map->addEvent(event);
editor->project->loadEventPixmaps(map->getAllEvents()); editor->project->loadEventPixmaps(map->getAllEvents());
editor->addMapEvent(event); editor->addMapEvent(event);
@ -412,8 +367,6 @@ EventDelete::EventDelete(Editor *editor, Map *map,
this->nextSelectedEvent = nextSelectedEvent; this->nextSelectedEvent = nextSelectedEvent;
} }
EventDelete::~EventDelete() {}
void EventDelete::redo() { void EventDelete::redo() {
QUndoCommand::redo(); QUndoCommand::redo();
@ -435,7 +388,7 @@ void EventDelete::redo() {
void EventDelete::undo() { void EventDelete::undo() {
for (Event *event : selectedEvents) { for (Event *event : selectedEvents) {
map->addEvent(event); map->addEvent(event);
editor->project->loadEventPixmaps(map->getAllEvents()); editor->project->loadEventPixmaps(map->getAllEvents());
editor->addMapEvent(event); editor->addMapEvent(event);
} }
@ -469,8 +422,6 @@ EventDuplicate::EventDuplicate(Editor *editor, Map *map,
this->selectedEvents = selectedEvents; this->selectedEvents = selectedEvents;
} }
EventDuplicate::~EventDuplicate() {}
void EventDuplicate::redo() { void EventDuplicate::redo() {
QUndoCommand::redo(); QUndoCommand::redo();
@ -517,7 +468,7 @@ int EventDuplicate::id() const {
ScriptEditMap::ScriptEditMap(Map *map, ScriptEditMap::ScriptEditMap(Map *map,
QSize oldMapDimensions, QSize newMapDimensions, QSize oldMapDimensions, QSize newMapDimensions,
Blockdata *oldMetatiles, Blockdata *newMetatiles, const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
QUndoCommand *parent) : QUndoCommand(parent) { QUndoCommand *parent) : QUndoCommand(parent) {
setText("Script Edit Map"); setText("Script Edit Map");
@ -532,24 +483,17 @@ ScriptEditMap::ScriptEditMap(Map *map,
this->newMapHeight = newMapDimensions.height(); this->newMapHeight = newMapDimensions.height();
} }
ScriptEditMap::~ScriptEditMap() {
if (newMetatiles) delete newMetatiles;
if (oldMetatiles) delete oldMetatiles;
}
void ScriptEditMap::redo() { void ScriptEditMap::redo() {
QUndoCommand::redo(); QUndoCommand::redo();
if (!map) return; if (!map) return;
if (map->layout->blockdata) { map->layout->blockdata = newMetatiles;
map->layout->blockdata->copyFrom(newMetatiles); if (newMapWidth != map->getWidth() || newMapHeight != map->getHeight()) {
if (newMapWidth != map->getWidth() || newMapHeight != map->getHeight()) { map->setDimensions(newMapWidth, newMapHeight, false);
map->setDimensions(newMapWidth, newMapHeight, false);
}
} }
map->layout->lastCommitMapBlocks.blocks->copyFrom(newMetatiles); map->layout->lastCommitMapBlocks.blocks = newMetatiles;
map->layout->lastCommitMapBlocks.dimensions = QSize(newMapWidth, newMapHeight); map->layout->lastCommitMapBlocks.dimensions = QSize(newMapWidth, newMapHeight);
renderMapBlocks(map); renderMapBlocks(map);
@ -558,14 +502,12 @@ void ScriptEditMap::redo() {
void ScriptEditMap::undo() { void ScriptEditMap::undo() {
if (!map) return; if (!map) return;
if (map->layout->blockdata) { map->layout->blockdata = oldMetatiles;
map->layout->blockdata->copyFrom(oldMetatiles); if (oldMapWidth != map->getWidth() || oldMapHeight != map->getHeight()) {
if (oldMapWidth != map->getWidth() || oldMapHeight != map->getHeight()) { map->setDimensions(oldMapWidth, oldMapHeight, false);
map->setDimensions(oldMapWidth, oldMapHeight, false);
}
} }
map->layout->lastCommitMapBlocks.blocks->copyFrom(oldMetatiles); map->layout->lastCommitMapBlocks.blocks = oldMetatiles;
map->layout->lastCommitMapBlocks.dimensions = QSize(oldMapWidth, oldMapHeight); map->layout->lastCommitMapBlocks.dimensions = QSize(oldMapWidth, oldMapHeight);
renderMapBlocks(map); renderMapBlocks(map);

View file

@ -71,7 +71,7 @@ Event* Event::createNewObjectEvent(Project *project)
event->put("event_group_type", "object_event_group"); event->put("event_group_type", "object_event_group");
event->put("event_type", EventType::Object); event->put("event_type", EventType::Object);
event->put("sprite", project->getEventObjGfxConstants().keys().first()); event->put("sprite", project->getEventObjGfxConstants().keys().first());
event->put("movement_type", project->movementTypes->first()); event->put("movement_type", project->movementTypes.first());
if (projectConfig.getObjectEventInConnectionEnabled()) { if (projectConfig.getObjectEventInConnectionEnabled()) {
event->put("in_connection", false); event->put("in_connection", false);
} }
@ -80,7 +80,7 @@ Event* Event::createNewObjectEvent(Project *project)
event->put("script_label", "NULL"); event->put("script_label", "NULL");
event->put("event_flag", "0"); event->put("event_flag", "0");
event->put("replacement", "0"); event->put("replacement", "0");
event->put("trainer_type", project->trainerTypes->value(0, "0")); event->put("trainer_type", project->trainerTypes.value(0, "0"));
event->put("sight_radius_tree_id", 0); event->put("sight_radius_tree_id", 0);
event->put("elevation", 3); event->put("elevation", 3);
return event; return event;
@ -118,7 +118,7 @@ Event* Event::createNewTriggerEvent(Project *project)
event->put("event_group_type", "coord_event_group"); event->put("event_group_type", "coord_event_group");
event->put("event_type", EventType::Trigger); event->put("event_type", EventType::Trigger);
event->put("script_label", "NULL"); event->put("script_label", "NULL");
event->put("script_var", project->varNames->first()); event->put("script_var", project->varNames.first());
event->put("script_var_value", "0"); event->put("script_var_value", "0");
event->put("elevation", 0); event->put("elevation", 0);
return event; return event;
@ -129,7 +129,7 @@ Event* Event::createNewWeatherTriggerEvent(Project *project)
Event *event = new Event; Event *event = new Event;
event->put("event_group_type", "coord_event_group"); event->put("event_group_type", "coord_event_group");
event->put("event_type", EventType::WeatherTrigger); event->put("event_type", EventType::WeatherTrigger);
event->put("weather", project->coordEventWeatherNames->first()); event->put("weather", project->coordEventWeatherNames.first());
event->put("elevation", 0); event->put("elevation", 0);
return event; return event;
} }
@ -139,7 +139,7 @@ Event* Event::createNewSignEvent(Project *project)
Event *event = new Event; Event *event = new Event;
event->put("event_group_type", "bg_event_group"); event->put("event_group_type", "bg_event_group");
event->put("event_type", EventType::Sign); event->put("event_type", EventType::Sign);
event->put("player_facing_direction", project->bgEventFacingDirections->first()); event->put("player_facing_direction", project->bgEventFacingDirections.first());
event->put("script_label", "NULL"); event->put("script_label", "NULL");
event->put("elevation", 0); event->put("elevation", 0);
return event; return event;
@ -150,8 +150,8 @@ Event* Event::createNewHiddenItemEvent(Project *project)
Event *event = new Event; Event *event = new Event;
event->put("event_group_type", "bg_event_group"); event->put("event_group_type", "bg_event_group");
event->put("event_type", EventType::HiddenItem); event->put("event_type", EventType::HiddenItem);
event->put("item", project->itemNames->first()); event->put("item", project->itemNames.first());
event->put("flag", project->flagNames->first()); event->put("flag", project->flagNames.first());
event->put("elevation", 3); event->put("elevation", 3);
if (projectConfig.getHiddenItemQuantityEnabled()) { if (projectConfig.getHiddenItemQuantityEnabled()) {
event->put("quantity", 1); event->put("quantity", 1);
@ -167,7 +167,7 @@ Event* Event::createNewSecretBaseEvent(Project *project)
Event *event = new Event; Event *event = new Event;
event->put("event_group_type", "bg_event_group"); event->put("event_group_type", "bg_event_group");
event->put("event_type", EventType::SecretBase); event->put("event_type", EventType::SecretBase);
event->put("secret_base_id", project->secretBaseIds->first()); event->put("secret_base_id", project->secretBaseIds.first());
event->put("elevation", 0); event->put("elevation", 0);
return event; return event;
} }
@ -321,13 +321,13 @@ OrderedJson::object Event::buildObjectEventJSON()
return eventObj; return eventObj;
} }
OrderedJson::object Event::buildWarpEventJSON(QMap<QString, QString> *mapNamesToMapConstants) OrderedJson::object Event::buildWarpEventJSON(const QMap<QString, QString> &mapNamesToMapConstants)
{ {
OrderedJson::object warpObj; OrderedJson::object warpObj;
warpObj["x"] = this->getU16("x"); warpObj["x"] = this->getU16("x");
warpObj["y"] = this->getU16("y"); warpObj["y"] = this->getU16("y");
warpObj["elevation"] = this->getInt("elevation"); warpObj["elevation"] = this->getInt("elevation");
warpObj["dest_map"] = mapNamesToMapConstants->value(this->get("destination_map_name")); warpObj["dest_map"] = mapNamesToMapConstants.value(this->get("destination_map_name"));
warpObj["dest_warp_id"] = this->getInt("destination_warp"); warpObj["dest_warp_id"] = this->getInt("destination_warp");
this->addCustomValuesTo(&warpObj); this->addCustomValuesTo(&warpObj);

View file

@ -78,96 +78,61 @@ int Map::getBorderHeight() {
return layout->border_height.toInt(nullptr, 0); return layout->border_height.toInt(nullptr, 0);
} }
bool Map::mapBlockChanged(int i, Blockdata * cache) { bool Map::mapBlockChanged(int i, const Blockdata &cache) {
if (!cache) if (cache.length() <= i)
return true; return true;
if (!layout->blockdata) if (layout->blockdata.length() <= i)
return true;
if (!cache->blocks)
return true;
if (!layout->blockdata->blocks)
return true;
if (cache->blocks->length() <= i)
return true;
if (layout->blockdata->blocks->length() <= i)
return true; return true;
return layout->blockdata->blocks->value(i) != cache->blocks->value(i); return layout->blockdata.at(i) != cache.at(i);
} }
bool Map::borderBlockChanged(int i, Blockdata * cache) { bool Map::borderBlockChanged(int i, const Blockdata &cache) {
if (!cache) if (cache.length() <= i)
return true; return true;
if (!layout->border) if (layout->border.length() <= i)
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 true;
return layout->border->blocks->value(i) != cache->blocks->value(i); return layout->border.at(i) != cache.at(i);
} }
void Map::cacheBorder() { void Map::cacheBorder() {
if (layout->cached_border) delete layout->cached_border; layout->cached_border.clear();
layout->cached_border = new Blockdata; for (const auto &block : layout->border)
if (layout->border && layout->border->blocks) { layout->cached_border.append(block);
for (int i = 0; i < layout->border->blocks->length(); i++) {
Block block = layout->border->blocks->value(i);
layout->cached_border->blocks->append(block);
}
}
} }
void Map::cacheBlockdata() { void Map::cacheBlockdata() {
if (layout->cached_blockdata) delete layout->cached_blockdata; layout->cached_blockdata.clear();
layout->cached_blockdata = new Blockdata; for (const auto &block : layout->blockdata)
if (layout->blockdata && layout->blockdata->blocks) { layout->cached_blockdata.append(block);
for (int i = 0; i < layout->blockdata->blocks->length(); i++) {
Block block = layout->blockdata->blocks->value(i);
layout->cached_blockdata->blocks->append(block);
}
}
} }
void Map::cacheCollision() { void Map::cacheCollision() {
if (layout->cached_collision) delete layout->cached_collision; layout->cached_collision.clear();
layout->cached_collision = new Blockdata; for (const auto &block : layout->blockdata)
if (layout->blockdata && layout->blockdata->blocks) { layout->cached_collision.append(block);
for (int i = 0; i < layout->blockdata->blocks->length(); i++) {
Block block = layout->blockdata->blocks->value(i);
layout->cached_collision->blocks->append(block);
}
}
} }
QPixmap Map::renderCollision(qreal opacity, bool ignoreCache) { QPixmap Map::renderCollision(qreal opacity, bool ignoreCache) {
bool changed_any = false; bool changed_any = false;
int width_ = getWidth(); int width_ = getWidth();
int height_ = getHeight(); int height_ = getHeight();
if ( if (collision_image.isNull() || collision_image.width() != width_ * 16 || collision_image.height() != height_ * 16) {
collision_image.isNull()
|| collision_image.width() != width_ * 16
|| collision_image.height() != height_ * 16
) {
collision_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888); collision_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
changed_any = true; changed_any = true;
} }
if (!(layout->blockdata && layout->blockdata->blocks && width_ && height_)) { if (layout->blockdata.isEmpty() || !width_ || !height_) {
collision_pixmap = collision_pixmap.fromImage(collision_image); collision_pixmap = collision_pixmap.fromImage(collision_image);
return collision_pixmap; return collision_pixmap;
} }
QPainter painter(&collision_image); QPainter painter(&collision_image);
for (int i = 0; i < layout->blockdata->blocks->length(); i++) { for (int i = 0; i < layout->blockdata.length(); i++) {
if (!ignoreCache && layout->cached_collision && !mapBlockChanged(i, layout->cached_collision)) { if (!ignoreCache && !mapBlockChanged(i, layout->cached_collision)) {
continue; continue;
} }
changed_any = true; changed_any = true;
Block block = layout->blockdata->blocks->value(i); Block block = layout->blockdata.at(i);
QImage metatile_image = getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary, metatileLayerOrder, metatileLayerOpacity); QImage metatile_image = getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary, metatileLayerOrder, metatileLayerOpacity);
QImage collision_metatile_image = getCollisionMetatileImage(block); QImage collision_metatile_image = getCollisionMetatileImage(block);
int map_y = width_ ? i / width_ : 0; int map_y = width_ ? i / width_ : 0;
@ -192,26 +157,22 @@ QPixmap Map::render(bool ignoreCache = false, MapLayout * fromLayout) {
bool changed_any = false; bool changed_any = false;
int width_ = getWidth(); int width_ = getWidth();
int height_ = getHeight(); int height_ = getHeight();
if ( if (image.isNull() || image.width() != width_ * 16 || image.height() != height_ * 16) {
image.isNull()
|| image.width() != width_ * 16
|| image.height() != height_ * 16
) {
image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888); image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
changed_any = true; changed_any = true;
} }
if (!(layout->blockdata && layout->blockdata->blocks && width_ && height_)) { if (layout->blockdata.isEmpty() || !width_ || !height_) {
pixmap = pixmap.fromImage(image); pixmap = pixmap.fromImage(image);
return pixmap; return pixmap;
} }
QPainter painter(&image); QPainter painter(&image);
for (int i = 0; i < layout->blockdata->blocks->length(); i++) { for (int i = 0; i < layout->blockdata.length(); i++) {
if (!ignoreCache && !mapBlockChanged(i, layout->cached_blockdata)) { if (!ignoreCache && !mapBlockChanged(i, layout->cached_blockdata)) {
continue; continue;
} }
changed_any = true; changed_any = true;
Block block = layout->blockdata->blocks->value(i); Block block = layout->blockdata.at(i);
QImage metatile_image = getMetatileImage( QImage metatile_image = getMetatileImage(
block.tile, block.tile,
fromLayout ? fromLayout->tileset_primary : layout->tileset_primary, fromLayout ? fromLayout->tileset_primary : layout->tileset_primary,
@ -245,18 +206,18 @@ QPixmap Map::renderBorder(bool ignoreCache) {
layout->border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888); layout->border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
border_resized = true; border_resized = true;
} }
if (!(layout->border && layout->border->blocks)) { if (layout->border.isEmpty()) {
layout->border_pixmap = layout->border_pixmap.fromImage(layout->border_image); layout->border_pixmap = layout->border_pixmap.fromImage(layout->border_image);
return layout->border_pixmap; return layout->border_pixmap;
} }
QPainter painter(&layout->border_image); QPainter painter(&layout->border_image);
for (int i = 0; i < layout->border->blocks->length(); i++) { for (int i = 0; i < layout->border.length(); i++) {
if (!ignoreCache && (!border_resized && !borderBlockChanged(i, layout->cached_border))) { if (!ignoreCache && (!border_resized && !borderBlockChanged(i, layout->cached_border))) {
continue; continue;
} }
changed_any = true; changed_any = true;
Block block = layout->border->blocks->value(i); Block block = layout->border.at(i);
uint16_t tile = block.tile; uint16_t tile = block.tile;
QImage metatile_image = getMetatileImage(tile, layout->tileset_primary, layout->tileset_secondary, metatileLayerOrder, metatileLayerOpacity); QImage metatile_image = getMetatileImage(tile, layout->tileset_primary, layout->tileset_secondary, metatileLayerOrder, metatileLayerOpacity);
int map_y = width_ ? i / width_ : 0; int map_y = width_ ? i / width_ : 0;
@ -310,38 +271,38 @@ void Map::setNewDimensionsBlockdata(int newWidth, int newHeight) {
int oldWidth = getWidth(); int oldWidth = getWidth();
int oldHeight = getHeight(); int oldHeight = getHeight();
Blockdata* newBlockData = new Blockdata; Blockdata newBlockdata;
for (int y = 0; y < newHeight; y++) for (int y = 0; y < newHeight; y++)
for (int x = 0; x < newWidth; x++) { for (int x = 0; x < newWidth; x++) {
if (x < oldWidth && y < oldHeight) { if (x < oldWidth && y < oldHeight) {
int index = y * oldWidth + x; int index = y * oldWidth + x;
newBlockData->addBlock(layout->blockdata->blocks->value(index)); newBlockdata.append(layout->blockdata.value(index));
} else { } else {
newBlockData->addBlock(0); newBlockdata.append(0);
} }
} }
layout->blockdata->copyFrom(newBlockData); layout->blockdata = newBlockdata;
} }
void Map::setNewBorderDimensionsBlockdata(int newWidth, int newHeight) { void Map::setNewBorderDimensionsBlockdata(int newWidth, int newHeight) {
int oldWidth = getBorderWidth(); int oldWidth = getBorderWidth();
int oldHeight = getBorderHeight(); int oldHeight = getBorderHeight();
Blockdata* newBlockData = new Blockdata; Blockdata newBlockdata;
for (int y = 0; y < newHeight; y++) for (int y = 0; y < newHeight; y++)
for (int x = 0; x < newWidth; x++) { for (int x = 0; x < newWidth; x++) {
if (x < oldWidth && y < oldHeight) { if (x < oldWidth && y < oldHeight) {
int index = y * oldWidth + x; int index = y * oldWidth + x;
newBlockData->addBlock(layout->border->blocks->value(index)); newBlockdata.append(layout->border.value(index));
} else { } else {
newBlockData->addBlock(0); newBlockdata.append(0);
} }
} }
layout->border->copyFrom(newBlockData); layout->border = newBlockdata;
} }
void Map::setDimensions(int newWidth, int newHeight, bool setNewBlockdata) { void Map::setDimensions(int newWidth, int newHeight, bool setNewBlockdata) {
@ -368,21 +329,19 @@ void Map::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata)
} }
bool Map::getBlock(int x, int y, Block *out) { bool Map::getBlock(int x, int y, Block *out) {
if (layout->blockdata && layout->blockdata->blocks) { if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) { int i = y * getWidth() + x;
int i = y * getWidth() + x; *out = layout->blockdata.value(i);
*out = layout->blockdata->blocks->value(i); return true;
return true;
}
} }
return false; return false;
} }
void Map::setBlock(int x, int y, Block block, bool enableScriptCallback) { void Map::setBlock(int x, int y, Block block, bool enableScriptCallback) {
int i = y * getWidth() + x; int i = y * getWidth() + x;
if (layout->blockdata && layout->blockdata->blocks && i < layout->blockdata->blocks->size()) { if (i < layout->blockdata.size()) {
Block prevBlock = layout->blockdata->blocks->value(i); Block prevBlock = layout->blockdata.at(i);
layout->blockdata->blocks->replace(i, block); layout->blockdata.replace(i, block);
if (enableScriptCallback) { if (enableScriptCallback) {
Scripting::cb_MetatileChanged(x, y, prevBlock, block); Scripting::cb_MetatileChanged(x, y, prevBlock, block);
} }
@ -393,40 +352,40 @@ void Map::_floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_
QList<QPoint> todo; QList<QPoint> todo;
todo.append(QPoint(x, y)); todo.append(QPoint(x, y));
while (todo.length()) { while (todo.length()) {
QPoint point = todo.takeAt(0); QPoint point = todo.takeAt(0);
x = point.x(); x = point.x();
y = point.y(); y = point.y();
Block block; Block block;
if (!getBlock(x, y, &block)) { if (!getBlock(x, y, &block)) {
continue; continue;
} }
uint old_coll = block.collision; uint old_coll = block.collision;
uint old_elev = block.elevation; uint old_elev = block.elevation;
if (old_coll == collision && old_elev == elevation) { if (old_coll == collision && old_elev == elevation) {
continue; continue;
} }
block.collision = collision; block.collision = collision;
block.elevation = elevation; block.elevation = elevation;
setBlock(x, y, block, true); setBlock(x, y, block, true);
if (getBlock(x + 1, y, &block) && block.collision == old_coll && block.elevation == old_elev) { if (getBlock(x + 1, y, &block) && block.collision == old_coll && block.elevation == old_elev) {
todo.append(QPoint(x + 1, y)); todo.append(QPoint(x + 1, y));
} }
if (getBlock(x - 1, y, &block) && block.collision == old_coll && block.elevation == old_elev) { if (getBlock(x - 1, y, &block) && block.collision == old_coll && block.elevation == old_elev) {
todo.append(QPoint(x - 1, y)); todo.append(QPoint(x - 1, y));
} }
if (getBlock(x, y + 1, &block) && block.collision == old_coll && block.elevation == old_elev) { if (getBlock(x, y + 1, &block) && block.collision == old_coll && block.elevation == old_elev) {
todo.append(QPoint(x, y + 1)); todo.append(QPoint(x, y + 1));
} }
if (getBlock(x, y - 1, &block) && block.collision == old_coll && block.elevation == old_elev) { if (getBlock(x, y - 1, &block) && block.collision == old_coll && block.elevation == old_elev) {
todo.append(QPoint(x, y - 1)); todo.append(QPoint(x, y - 1));
} }
} }
} }
void Map::floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation) { void Map::floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation) {
Block block;; Block block;
if (getBlock(x, y, &block) && (block.collision != collision || block.elevation != elevation)) { if (getBlock(x, y, &block) && (block.collision != collision || block.elevation != elevation)) {
_floodFillCollisionElevation(x, y, collision, elevation); _floodFillCollisionElevation(x, y, collision, elevation);
} }

View file

@ -6,15 +6,12 @@
#include <QJsonObject> #include <QJsonObject>
#include <QStack> #include <QStack>
ParseUtil::ParseUtil()
{
}
void ParseUtil::set_root(QString dir) { void ParseUtil::set_root(const QString &dir) {
this->root = dir; this->root = dir;
} }
void ParseUtil::error(QString message, QString expression) { void ParseUtil::error(const QString &message, const QString &expression) {
QStringList lines = text.split(QRegularExpression("[\r\n]")); QStringList lines = text.split(QRegularExpression("[\r\n]"));
int lineNum = 0, colNum = 0; int lineNum = 0, colNum = 0;
for (QString line : lines) { for (QString line : lines) {
@ -25,21 +22,7 @@ void ParseUtil::error(QString message, QString expression) {
logError(QString("%1:%2:%3: %4").arg(file).arg(lineNum).arg(colNum).arg(message)); logError(QString("%1:%2:%3: %4").arg(file).arg(lineNum).arg(colNum).arg(message));
} }
void ParseUtil::strip_comment(QString *line) { QString ParseUtil::readTextFile(const QString &path) {
bool in_string = false;
for (int i = 0; i < line->length(); i++) {
if (line->at(i) == '"') {
in_string = !in_string;
} else if (line->at(i) == '@') {
if (!in_string) {
line->truncate(i);
break;
}
}
}
}
QString ParseUtil::readTextFile(QString path) {
QFile file(path); QFile file(path);
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
logError(QString("Could not open '%1': ").arg(path) + file.errorString()); logError(QString("Could not open '%1': ").arg(path) + file.errorString());
@ -59,45 +42,41 @@ int ParseUtil::textFileLineCount(const QString &path) {
return text.split('\n').count() + 1; return text.split('\n').count() + 1;
} }
QList<QStringList>* ParseUtil::parseAsm(QString filename) { QList<QStringList> ParseUtil::parseAsm(const QString &filename) {
QList<QStringList> *parsed = new QList<QStringList>; QList<QStringList> parsed;
text = readTextFile(root + "/" + filename); text = readTextFile(root + '/' + filename);
QStringList lines = text.split('\n'); const QStringList lines = removeLineComments(text, "@").split('\n');
for (QString line : lines) { for (const auto &line : lines) {
QString label; const QString trimmedLine = line.trimmed();
strip_comment(&line); if (trimmedLine.isEmpty()) {
if (line.trimmed().isEmpty()) { continue;
} else if (line.contains(':')) { }
label = line.left(line.indexOf(':'));
QStringList *list = new QStringList; if (line.contains(':')) {
list->append(".label"); // This is not a real keyword. It's used only to make the output more regular. const QString label = line.left(line.indexOf(':'));
list->append(label); const QStringList list{ ".label", label }; // .label is not a real keyword. It's used only to make the output more regular.
parsed->append(*list); parsed.append(list);
// There should not be anything else on the line. // There should not be anything else on the line.
// gas will raise a syntax error if there is. // gas will raise a syntax error if there is.
} else { } else {
line = line.trimmed(); int index = trimmedLine.indexOf(QRegExp("\\s+"));
//parsed->append(line.split(QRegExp("\\s*,\\s*"))); const QString macro = trimmedLine.left(index);
QString macro; QStringList params(trimmedLine.right(trimmedLine.length() - index).trimmed().split(QRegExp("\\s*,\\s*")));
QStringList params;
int index = line.indexOf(QRegExp("\\s+"));
macro = line.left(index);
params = line.right(line.length() - index).trimmed().split(QRegExp("\\s*,\\s*"));
params.prepend(macro); params.prepend(macro);
parsed->append(params); parsed.append(params);
} }
} }
return parsed; return parsed;
} }
int ParseUtil::evaluateDefine(QString define, QMap<QString, int>* knownDefines) { int ParseUtil::evaluateDefine(const QString &define, const QMap<QString, int> &knownDefines) {
QList<Token> tokens = tokenizeExpression(define, knownDefines); QList<Token> tokens = tokenizeExpression(define, knownDefines);
QList<Token> postfixExpression = generatePostfix(tokens); QList<Token> postfixExpression = generatePostfix(tokens);
return evaluatePostfix(postfixExpression); return evaluatePostfix(postfixExpression);
} }
QList<Token> ParseUtil::tokenizeExpression(QString expression, QMap<QString, int>* knownIdentifiers) { QList<Token> ParseUtil::tokenizeExpression(QString expression, const QMap<QString, int> &knownIdentifiers) {
QList<Token> tokens; QList<Token> tokens;
QStringList tokenTypes = (QStringList() << "hex" << "decimal" << "identifier" << "operator" << "leftparen" << "rightparen"); QStringList tokenTypes = (QStringList() << "hex" << "decimal" << "identifier" << "operator" << "leftparen" << "rightparen");
@ -114,8 +93,8 @@ QList<Token> ParseUtil::tokenizeExpression(QString expression, QMap<QString, int
QString token = match.captured(tokenType); QString token = match.captured(tokenType);
if (!token.isEmpty()) { if (!token.isEmpty()) {
if (tokenType == "identifier") { if (tokenType == "identifier") {
if (knownIdentifiers->contains(token)) { if (knownIdentifiers.contains(token)) {
QString actualToken = QString("%1").arg(knownIdentifiers->value(token)); QString actualToken = QString("%1").arg(knownIdentifiers.value(token));
expression = expression.replace(0, token.length(), actualToken); expression = expression.replace(0, token.length(), actualToken);
token = actualToken; token = actualToken;
tokenType = "decimal"; tokenType = "decimal";
@ -158,7 +137,7 @@ QMap<QString, int> Token::precedenceMap = QMap<QString, int>(
// Shunting-yard algorithm for generating postfix notation. // Shunting-yard algorithm for generating postfix notation.
// https://en.wikipedia.org/wiki/Shunting-yard_algorithm // https://en.wikipedia.org/wiki/Shunting-yard_algorithm
QList<Token> ParseUtil::generatePostfix(QList<Token> tokens) { QList<Token> ParseUtil::generatePostfix(const QList<Token> &tokens) {
QList<Token> output; QList<Token> output;
QStack<Token> operatorStack; QStack<Token> operatorStack;
for (Token token : tokens) { for (Token token : tokens) {
@ -200,7 +179,7 @@ QList<Token> ParseUtil::generatePostfix(QList<Token> tokens) {
// Evaluate postfix expression. // Evaluate postfix expression.
// https://en.wikipedia.org/wiki/Reverse_Polish_notation#Postfix_evaluation_algorithm // https://en.wikipedia.org/wiki/Reverse_Polish_notation#Postfix_evaluation_algorithm
int ParseUtil::evaluatePostfix(QList<Token> postfix) { int ParseUtil::evaluatePostfix(const QList<Token> &postfix) {
QStack<Token> stack; QStack<Token> stack;
for (Token token : postfix) { for (Token token : postfix) {
if (token.type == TokenClass::Operator && stack.size() > 1) { if (token.type == TokenClass::Operator && stack.size() > 1) {
@ -234,7 +213,7 @@ int ParseUtil::evaluatePostfix(QList<Token> postfix) {
return stack.size() ? stack.pop().value.toInt(nullptr, 0) : 0; return stack.size() ? stack.pop().value.toInt(nullptr, 0) : 0;
} }
QString ParseUtil::readCIncbin(QString filename, QString label) { QString ParseUtil::readCIncbin(const QString &filename, const QString &label) {
QString path; QString path;
if (label.isNull()) { if (label.isNull()) {
@ -257,7 +236,10 @@ QString ParseUtil::readCIncbin(QString filename, QString label) {
return path; return path;
} }
QMap<QString, int> ParseUtil::readCDefines(QString filename, QStringList prefixes, QMap<QString, int> allDefines) { QMap<QString, int> ParseUtil::readCDefines(const QString &filename,
const QStringList &prefixes,
QMap<QString, int> allDefines)
{
QMap<QString, int> filteredDefines; QMap<QString, int> filteredDefines;
file = filename; file = filename;
@ -286,7 +268,7 @@ QMap<QString, int> ParseUtil::readCDefines(QString filename, QStringList prefixe
QString name = match.captured("defineName"); QString name = match.captured("defineName");
QString expression = match.captured("defineValue"); QString expression = match.captured("defineValue");
if (expression == " ") continue; if (expression == " ") continue;
int value = evaluateDefine(expression, &allDefines); int value = evaluateDefine(expression, allDefines);
allDefines.insert(name, value); allDefines.insert(name, value);
for (QString prefix : prefixes) { for (QString prefix : prefixes) {
if (name.startsWith(prefix) || QRegularExpression(prefix).match(name).hasMatch()) { if (name.startsWith(prefix) || QRegularExpression(prefix).match(name).hasMatch()) {
@ -297,7 +279,10 @@ QMap<QString, int> ParseUtil::readCDefines(QString filename, QStringList prefixe
return filteredDefines; return filteredDefines;
} }
void ParseUtil::readCDefinesSorted(QString filename, QStringList prefixes, QStringList* definesToSet, QMap<QString, int> knownDefines) { QStringList ParseUtil::readCDefinesSorted(const QString &filename,
const QStringList &prefixes,
const QMap<QString, int> &knownDefines)
{
QMap<QString, int> defines = readCDefines(filename, prefixes, knownDefines); QMap<QString, int> defines = readCDefines(filename, prefixes, knownDefines);
// The defines should to be sorted by their underlying value, not alphabetically. // The defines should to be sorted by their underlying value, not alphabetically.
@ -306,10 +291,10 @@ void ParseUtil::readCDefinesSorted(QString filename, QStringList prefixes, QStri
for (QString defineName : defines.keys()) { for (QString defineName : defines.keys()) {
definesInverse.insert(defines[defineName], defineName); definesInverse.insert(defines[defineName], defineName);
} }
*definesToSet = definesInverse.values(); return definesInverse.values();
} }
QStringList ParseUtil::readCArray(QString filename, QString label) { QStringList ParseUtil::readCArray(const QString &filename, const QString &label) {
QStringList list; QStringList list;
if (label.isNull()) { if (label.isNull()) {
@ -335,13 +320,13 @@ QStringList ParseUtil::readCArray(QString filename, QString label) {
return list; return list;
} }
QMap<QString, QString> ParseUtil::readNamedIndexCArray(QString filename, QString label) { QMap<QString, QString> ParseUtil::readNamedIndexCArray(const QString &filename, const QString &label) {
text = readTextFile(root + "/" + filename); text = readTextFile(root + "/" + filename);
QMap<QString, QString> map; QMap<QString, QString> map;
QRegularExpression re_text(QString(R"(\b%1\b\s*(\[?[^\]]*\])?\s*=\s*\{([^\}]*)\})").arg(label)); QRegularExpression re_text(QString(R"(\b%1\b\s*(\[?[^\]]*\])?\s*=\s*\{([^\}]*)\})").arg(label));
QString body = re_text.match(text).captured(2).replace(QRegularExpression("\\s*"), ""); QString body = re_text.match(text).captured(2).replace(QRegularExpression("\\s*"), "");
QRegularExpression re("\\[(?<index>[A-Za-z0-9_]*)\\]=(?<value>&?[A-Za-z0-9_]*)"); QRegularExpression re("\\[(?<index>[A-Za-z0-9_]*)\\]=(?<value>&?[A-Za-z0-9_]*)");
QRegularExpressionMatchIterator iter = re.globalMatch(body); QRegularExpressionMatchIterator iter = re.globalMatch(body);
@ -355,24 +340,23 @@ QMap<QString, QString> ParseUtil::readNamedIndexCArray(QString filename, QString
return map; return map;
} }
QList<QStringList>* ParseUtil::getLabelMacros(QList<QStringList> *list, QString label) { QList<QStringList> ParseUtil::getLabelMacros(const QList<QStringList> &list, const QString &label) {
bool in_label = false; bool in_label = false;
QList<QStringList> *new_list = new QList<QStringList>; QList<QStringList> new_list;
for (int i = 0; i < list->length(); i++) { for (const auto &params : list) {
QStringList params = list->value(i); const QString macro = params.value(0);
QString macro = params.value(0);
if (macro == ".label") { if (macro == ".label") {
if (params.value(1) == label) { if (params.value(1) == label) {
in_label = true; in_label = true;
} else if (in_label) { } else if (in_label) {
// If nothing has been read yet, assume the label // If nothing has been read yet, assume the label
// we're looking for is in a stack of labels. // we're looking for is in a stack of labels.
if (new_list->length() > 0) { if (new_list.length() > 0) {
break; break;
} }
} }
} else if (in_label) { } else if (in_label) {
new_list->append(params); new_list.append(params);
} }
} }
return new_list; return new_list;
@ -380,32 +364,31 @@ QList<QStringList>* ParseUtil::getLabelMacros(QList<QStringList> *list, QString
// For if you don't care about filtering by macro, // For if you don't care about filtering by macro,
// and just want all values associated with some label. // and just want all values associated with some label.
QStringList* ParseUtil::getLabelValues(QList<QStringList> *list, QString label) { QStringList ParseUtil::getLabelValues(const QList<QStringList> &list, const QString &label) {
list = getLabelMacros(list, label); const QList<QStringList> labelMacros = getLabelMacros(list, label);
QStringList *values = new QStringList; QStringList values;
for (int i = 0; i < list->length(); i++) { for (const auto &params : labelMacros) {
QStringList params = list->value(i); const QString macro = params.value(0);
QString macro = params.value(0);
if (macro == ".align" || macro == ".ifdef" || macro == ".ifndef") { if (macro == ".align" || macro == ".ifdef" || macro == ".ifndef") {
continue; continue;
} }
for (int j = 1; j < params.length(); j++) { for (int i = 1; i < params.length(); i++) {
values->append(params.value(j)); values.append(params.value(i));
} }
} }
return values; return values;
} }
bool ParseUtil::tryParseJsonFile(QJsonDocument *out, QString filepath) { bool ParseUtil::tryParseJsonFile(QJsonDocument *out, const QString &filepath) {
QFile file(filepath); QFile file(filepath);
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
logError(QString("Error: Could not open %1 for reading").arg(filepath)); logError(QString("Error: Could not open %1 for reading").arg(filepath));
return false; return false;
} }
QByteArray data = file.readAll(); const QByteArray data = file.readAll();
QJsonParseError parseError; QJsonParseError parseError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &parseError); const QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &parseError);
file.close(); file.close();
if (parseError.error != QJsonParseError::NoError) { if (parseError.error != QJsonParseError::NoError) {
logError(QString("Error: Failed to parse json file %1: %2").arg(filepath).arg(parseError.errorString())); logError(QString("Error: Failed to parse json file %1: %2").arg(filepath).arg(parseError.errorString()));
@ -416,7 +399,7 @@ bool ParseUtil::tryParseJsonFile(QJsonDocument *out, QString filepath) {
return true; return true;
} }
bool ParseUtil::ensureFieldsExist(QJsonObject obj, QList<QString> fields) { bool ParseUtil::ensureFieldsExist(const QJsonObject &obj, const QList<QString> &fields) {
for (QString field : fields) { for (QString field : fields) {
if (!obj.contains(field)) { if (!obj.contains(field)) {
logError(QString("JSON object is missing field '%1'.").arg(field)); logError(QString("JSON object is missing field '%1'.").arg(field));
@ -439,8 +422,8 @@ int ParseUtil::getScriptLineNumber(const QString &filePath, const QString &scrip
} }
int ParseUtil::getRawScriptLineNumber(QString text, const QString &scriptLabel) { int ParseUtil::getRawScriptLineNumber(QString text, const QString &scriptLabel) {
removeStringLiterals(text); text = removeStringLiterals(text);
removeLineComments(text, "@"); text = removeLineComments(text, "@");
static const QRegularExpression re_incScriptLabel("\\b(?<label>[\\w_][\\w\\d_]*):{1,2}"); static const QRegularExpression re_incScriptLabel("\\b(?<label>[\\w_][\\w\\d_]*):{1,2}");
QRegularExpressionMatchIterator it = re_incScriptLabel.globalMatch(text); QRegularExpressionMatchIterator it = re_incScriptLabel.globalMatch(text);
@ -454,8 +437,8 @@ int ParseUtil::getRawScriptLineNumber(QString text, const QString &scriptLabel)
} }
int ParseUtil::getPoryScriptLineNumber(QString text, const QString &scriptLabel) { int ParseUtil::getPoryScriptLineNumber(QString text, const QString &scriptLabel) {
removeStringLiterals(text); text = removeStringLiterals(text);
removeLineComments(text, {"//", "#"}); text = removeLineComments(text, {"//", "#"});
static const QRegularExpression re_poryScriptLabel("\\b(script)(\\((global|local)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)"); static const QRegularExpression re_poryScriptLabel("\\b(script)(\\((global|local)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)");
QRegularExpressionMatchIterator it = re_poryScriptLabel.globalMatch(text); QRegularExpressionMatchIterator it = re_poryScriptLabel.globalMatch(text);
@ -477,19 +460,19 @@ int ParseUtil::getPoryScriptLineNumber(QString text, const QString &scriptLabel)
return 0; return 0;
} }
QString &ParseUtil::removeStringLiterals(QString &text) { QString ParseUtil::removeStringLiterals(QString text) {
static const QRegularExpression re_string("\".*\""); static const QRegularExpression re_string("\".*\"");
return text.remove(re_string); return text.remove(re_string);
} }
QString &ParseUtil::removeLineComments(QString &text, const QString &commentSymbol) { QString ParseUtil::removeLineComments(QString text, const QString &commentSymbol) {
const QRegularExpression re_lineComment(commentSymbol + "+.*"); const QRegularExpression re_lineComment(commentSymbol + "+.*");
return text.remove(re_lineComment); return text.remove(re_lineComment);
} }
QString &ParseUtil::removeLineComments(QString &text, const QStringList &commentSymbols) { QString ParseUtil::removeLineComments(QString text, const QStringList &commentSymbols) {
for (const auto &commentSymbol : commentSymbols) for (const auto &commentSymbol : commentSymbols)
removeLineComments(text, commentSymbol); text = removeLineComments(text, commentSymbol);
return text; return text;
} }

View file

@ -130,7 +130,7 @@ bool RegionMap::readLayout() {
return false; return false;
} }
QMap<QString, QString> *qmap = new QMap<QString, QString>; QMap<QString, QString> qmap;
bool mapNamesQualified = false, mapEntriesQualified = false; bool mapNamesQualified = false, mapEntriesQualified = false;
@ -155,7 +155,7 @@ bool RegionMap::readLayout() {
QStringList entry = reAfter.match(line).captured(1).remove(" ").split(","); QStringList entry = reAfter.match(line).captured(1).remove(" ").split(",");
QString mapsec = reBefore.match(line).captured(1); QString mapsec = reBefore.match(line).captured(1);
QString insertion = entry[4].remove("sMapName_"); QString insertion = entry[4].remove("sMapName_");
qmap->insert(mapsec, sMapNamesMap.value(insertion)); qmap.insert(mapsec, sMapNamesMap.value(insertion));
mapSecToMapEntry[mapsec] = { mapSecToMapEntry[mapsec] = {
// x y width height name // x y width height name
entry[0].toInt(), entry[1].toInt(), entry[2].toInt(), entry[3].toInt(), insertion entry[0].toInt(), entry[1].toInt(), entry[2].toInt(), entry[3].toInt(), insertion
@ -265,7 +265,7 @@ void RegionMap::saveOptions(int id, QString sec, QString name, int x, int y) {
this->map_squares[index].mapsec = sec; this->map_squares[index].mapsec = sec;
if (!name.isEmpty()) { if (!name.isEmpty()) {
this->map_squares[index].map_name = name; this->map_squares[index].map_name = name;
this->project->mapSecToMapHoverName->insert(sec, name); this->project->mapSecToMapHoverName.insert(sec, name);
QString sName = fixCase(sec); QString sName = fixCase(sec);
sMapNamesMap.insert(sName, name); sMapNamesMap.insert(sName, name);
if (!mapSecToMapEntry.keys().contains(sec)) { if (!mapSecToMapEntry.keys().contains(sec)) {

View file

@ -726,11 +726,11 @@ void Editor::populateConnectionMapPickers() {
ui->comboBox_EmergeMap->blockSignals(true); ui->comboBox_EmergeMap->blockSignals(true);
ui->comboBox_ConnectedMap->clear(); ui->comboBox_ConnectedMap->clear();
ui->comboBox_ConnectedMap->addItems(*project->mapNames); ui->comboBox_ConnectedMap->addItems(project->mapNames);
ui->comboBox_DiveMap->clear(); ui->comboBox_DiveMap->clear();
ui->comboBox_DiveMap->addItems(*project->mapNames); ui->comboBox_DiveMap->addItems(project->mapNames);
ui->comboBox_EmergeMap->clear(); ui->comboBox_EmergeMap->clear();
ui->comboBox_EmergeMap->addItems(*project->mapNames); ui->comboBox_EmergeMap->addItems(project->mapNames);
ui->comboBox_ConnectedMap->blockSignals(false); ui->comboBox_ConnectedMap->blockSignals(false);
ui->comboBox_DiveMap->blockSignals(true); ui->comboBox_DiveMap->blockSignals(true);
@ -959,7 +959,7 @@ void Editor::onHoveredMapMetatileChanged(const QPoint &pos) {
if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles
&& pos.x() >= 0 && pos.x() < map->getWidth() && pos.y() >= 0 && pos.y() < map->getHeight()) { && pos.x() >= 0 && pos.x() < map->getWidth() && pos.y() >= 0 && pos.y() < map->getHeight()) {
int blockIndex = pos.y() * map->getWidth() + pos.x(); int blockIndex = pos.y() * map->getWidth() + pos.x();
int metatileId = map->layout->blockdata->blocks->at(blockIndex).tile; int metatileId = map->layout->blockdata.at(blockIndex).tile;
this->ui->statusBar->showMessage(QString("X: %1, Y: %2, %3, Scale = %4x") this->ui->statusBar->showMessage(QString("X: %1, Y: %2, %3, Scale = %4x")
.arg(pos.x()) .arg(pos.x())
.arg(pos.y()) .arg(pos.y())
@ -989,8 +989,8 @@ void Editor::onHoveredMapMovementPermissionChanged(int x, int y) {
if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles
&& x >= 0 && x < map->getWidth() && y >= 0 && y < map->getHeight()) { && x >= 0 && x < map->getWidth() && y >= 0 && y < map->getHeight()) {
int blockIndex = y * map->getWidth() + x; int blockIndex = y * map->getWidth() + x;
uint16_t collision = map->layout->blockdata->blocks->at(blockIndex).collision; uint16_t collision = map->layout->blockdata.at(blockIndex).collision;
uint16_t elevation = map->layout->blockdata->blocks->at(blockIndex).elevation; uint16_t elevation = map->layout->blockdata.at(blockIndex).elevation;
QString message = QString("X: %1, Y: %2, %3") QString message = QString("X: %1, Y: %2, %3")
.arg(x) .arg(x)
.arg(y) .arg(y)
@ -1678,7 +1678,7 @@ void Editor::updateConnectionOffset(int offset) {
} }
void Editor::setConnectionMap(QString mapName) { void Editor::setConnectionMap(QString mapName) {
if (!mapName.isEmpty() && !project->mapNames->contains(mapName)) { if (!mapName.isEmpty() && !project->mapNames.contains(mapName)) {
logError(QString("Invalid map name '%1' specified for connection.").arg(mapName)); logError(QString("Invalid map name '%1' specified for connection.").arg(mapName));
return; return;
} }
@ -1714,9 +1714,9 @@ void Editor::addNewConnection() {
} }
// Don't connect the map to itself. // Don't connect the map to itself.
QString defaultMapName = project->mapNames->first(); QString defaultMapName = project->mapNames.first();
if (defaultMapName == map->name) { if (defaultMapName == map->name) {
defaultMapName = project->mapNames->value(1); defaultMapName = project->mapNames.value(1);
} }
MapConnection* newConnection = new MapConnection; MapConnection* newConnection = new MapConnection;
@ -1824,7 +1824,7 @@ void Editor::updateEmergeMap(QString mapName) {
} }
void Editor::updateDiveEmergeMap(QString mapName, QString direction) { void Editor::updateDiveEmergeMap(QString mapName, QString direction) {
if (!mapName.isEmpty() && !project->mapNamesToMapConstants->contains(mapName)) { if (!mapName.isEmpty() && !project->mapNamesToMapConstants.contains(mapName)) {
logError(QString("Invalid %1 connection map name: '%2'").arg(direction).arg(mapName)); logError(QString("Invalid %1 connection map name: '%2'").arg(direction).arg(mapName));
return; return;
} }

View file

@ -672,7 +672,7 @@ void MainWindow::refreshMapScene()
void MainWindow::openWarpMap(QString map_name, QString warp_num) { void MainWindow::openWarpMap(QString map_name, QString warp_num) {
// Ensure valid destination map name. // Ensure valid destination map name.
if (!editor->project->mapNames->contains(map_name)) { if (!editor->project->mapNames.contains(map_name)) {
logError(QString("Invalid warp destination map name '%1'").arg(map_name)); logError(QString("Invalid warp destination map name '%1'").arg(map_name));
return; return;
} }
@ -910,11 +910,11 @@ bool MainWindow::loadProjectCombos() {
ui->comboBox_SecondaryTileset->clear(); ui->comboBox_SecondaryTileset->clear();
ui->comboBox_SecondaryTileset->addItems(tilesets.value("secondary")); ui->comboBox_SecondaryTileset->addItems(tilesets.value("secondary"));
ui->comboBox_Weather->clear(); ui->comboBox_Weather->clear();
ui->comboBox_Weather->addItems(*project->weatherNames); ui->comboBox_Weather->addItems(project->weatherNames);
ui->comboBox_BattleScene->clear(); ui->comboBox_BattleScene->clear();
ui->comboBox_BattleScene->addItems(*project->mapBattleScenes); ui->comboBox_BattleScene->addItems(project->mapBattleScenes);
ui->comboBox_Type->clear(); ui->comboBox_Type->clear();
ui->comboBox_Type->addItems(*project->mapTypes); ui->comboBox_Type->addItems(project->mapTypes);
return true; return true;
} }
@ -946,8 +946,8 @@ void MainWindow::sortMapList() {
switch (mapSortOrder) switch (mapSortOrder)
{ {
case MapSortOrder::Group: case MapSortOrder::Group:
for (int i = 0; i < project->groupNames->length(); i++) { for (int i = 0; i < project->groupNames.length(); i++) {
QString group_name = project->groupNames->value(i); QString group_name = project->groupNames.value(i);
QStandardItem *group = new QStandardItem; QStandardItem *group = new QStandardItem;
group->setText(group_name); group->setText(group_name);
group->setIcon(mapFolderIcon); group->setIcon(mapFolderIcon);
@ -982,7 +982,7 @@ void MainWindow::sortMapList() {
mapGroupItemsList->append(mapsec); mapGroupItemsList->append(mapsec);
mapsecToGroupNum.insert(mapsec_name, i); mapsecToGroupNum.insert(mapsec_name, i);
} }
for (int i = 0; i < project->groupNames->length(); i++) { for (int i = 0; i < project->groupNames.length(); i++) {
QStringList names = project->groupedMapNames.value(i); QStringList names = project->groupedMapNames.value(i);
for (int j = 0; j < names.length(); j++) { for (int j = 0; j < names.length(); j++) {
QString map_name = names.value(j); QString map_name = names.value(j);
@ -1014,7 +1014,7 @@ void MainWindow::sortMapList() {
mapGroupItemsList->append(layoutItem); mapGroupItemsList->append(layoutItem);
layoutIndices[layoutId] = i; layoutIndices[layoutId] = i;
} }
for (int i = 0; i < project->groupNames->length(); i++) { for (int i = 0; i < project->groupNames.length(); i++) {
QStringList names = project->groupedMapNames.value(i); QStringList names = project->groupedMapNames.value(i);
for (int j = 0; j < names.length(); j++) { for (int j = 0; j < names.length(); j++) {
QString map_name = names.value(j); QString map_name = names.value(j);
@ -1340,10 +1340,10 @@ void MainWindow::drawMapListIcons(QAbstractItemModel *model) {
QVariant data = index.data(Qt::UserRole); QVariant data = index.data(Qt::UserRole);
if (!data.isNull()) { if (!data.isNull()) {
QString map_name = data.toString(); QString map_name = data.toString();
if (editor->project && editor->project->mapCache->contains(map_name)) { if (editor->project && editor->project->mapCache.contains(map_name)) {
QStandardItem *map = mapListModel->itemFromIndex(mapListIndexes.value(map_name)); QStandardItem *map = mapListModel->itemFromIndex(mapListIndexes.value(map_name));
map->setIcon(*mapIcon); map->setIcon(*mapIcon);
if (editor->project->mapCache->value(map_name)->hasUnsavedChanges()) { if (editor->project->mapCache.value(map_name)->hasUnsavedChanges()) {
map->setIcon(*mapEditedIcon); map->setIcon(*mapEditedIcon);
projectHasUnsavedChanges = true; projectHasUnsavedChanges = true;
} }
@ -1821,19 +1821,19 @@ void MainWindow::updateSelectedObjects() {
} }
if (key == "destination_map_name") { if (key == "destination_map_name") {
if (!editor->project->mapNames->contains(value)) { if (!editor->project->mapNames.contains(value)) {
combo->addItem(value); combo->addItem(value);
} }
combo->addItems(*editor->project->mapNames); combo->addItems(editor->project->mapNames);
combo->setCurrentIndex(combo->findText(value)); combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The destination map name of the warp."); combo->setToolTip("The destination map name of the warp.");
} else if (key == "destination_warp") { } else if (key == "destination_warp") {
combo->setToolTip("The warp id on the destination map."); combo->setToolTip("The warp id on the destination map.");
} else if (key == "item") { } else if (key == "item") {
if (!editor->project->itemNames->contains(value)) { if (!editor->project->itemNames.contains(value)) {
combo->addItem(value); combo->addItem(value);
} }
combo->addItems(*editor->project->itemNames); combo->addItems(editor->project->itemNames);
combo->setCurrentIndex(combo->findText(value)); combo->setCurrentIndex(combo->findText(value));
} else if (key == "quantity") { } else if (key == "quantity") {
spin->setToolTip("The number of items received when the hidden item is picked up."); spin->setToolTip("The number of items received when the hidden item is picked up.");
@ -1842,27 +1842,27 @@ void MainWindow::updateSelectedObjects() {
} else if (key == "underfoot") { } else if (key == "underfoot") {
check->setToolTip("If checked, hidden item can only be picked up using the Itemfinder"); check->setToolTip("If checked, hidden item can only be picked up using the Itemfinder");
} else if (key == "flag" || key == "event_flag") { } else if (key == "flag" || key == "event_flag") {
if (!editor->project->flagNames->contains(value)) { if (!editor->project->flagNames.contains(value)) {
combo->addItem(value); combo->addItem(value);
} }
combo->addItems(*editor->project->flagNames); combo->addItems(editor->project->flagNames);
combo->setCurrentIndex(combo->findText(value)); combo->setCurrentIndex(combo->findText(value));
if (key == "flag") if (key == "flag")
combo->setToolTip("The flag which is set when the hidden item is picked up."); combo->setToolTip("The flag which is set when the hidden item is picked up.");
else if (key == "event_flag") else if (key == "event_flag")
combo->setToolTip("The flag which hides the object when set."); combo->setToolTip("The flag which hides the object when set.");
} else if (key == "script_var") { } else if (key == "script_var") {
if (!editor->project->varNames->contains(value)) { if (!editor->project->varNames.contains(value)) {
combo->addItem(value); combo->addItem(value);
} }
combo->addItems(*editor->project->varNames); combo->addItems(editor->project->varNames);
combo->setCurrentIndex(combo->findText(value)); combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The variable by which the script is triggered.\n" combo->setToolTip("The variable by which the script is triggered.\n"
"The script is triggered when this variable's value matches 'Var Value'."); "The script is triggered when this variable's value matches 'Var Value'.");
} else if (key == "script_var_value") { } else if (key == "script_var_value") {
combo->setToolTip("The variable's value which triggers the script."); combo->setToolTip("The variable's value which triggers the script.");
} else if (key == "movement_type") { } else if (key == "movement_type") {
if (!editor->project->movementTypes->contains(value)) { if (!editor->project->movementTypes.contains(value)) {
combo->addItem(value); combo->addItem(value);
} }
connect(combo, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentTextChanged), connect(combo, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentTextChanged),
@ -1870,31 +1870,31 @@ void MainWindow::updateSelectedObjects() {
item->event->setFrameFromMovement(editor->project->facingDirections.value(value)); item->event->setFrameFromMovement(editor->project->facingDirections.value(value));
item->updatePixmap(); item->updatePixmap();
}); });
combo->addItems(*editor->project->movementTypes); combo->addItems(editor->project->movementTypes);
combo->setCurrentIndex(combo->findText(value)); combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The object's natural movement behavior when\n" combo->setToolTip("The object's natural movement behavior when\n"
"the player is not interacting with it."); "the player is not interacting with it.");
} else if (key == "weather") { } else if (key == "weather") {
if (!editor->project->coordEventWeatherNames->contains(value)) { if (!editor->project->coordEventWeatherNames.contains(value)) {
combo->addItem(value); combo->addItem(value);
} }
combo->addItems(*editor->project->coordEventWeatherNames); combo->addItems(editor->project->coordEventWeatherNames);
combo->setCurrentIndex(combo->findText(value)); combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The weather that starts when the player steps on this spot."); combo->setToolTip("The weather that starts when the player steps on this spot.");
} else if (key == "secret_base_id") { } else if (key == "secret_base_id") {
if (!editor->project->secretBaseIds->contains(value)) { if (!editor->project->secretBaseIds.contains(value)) {
combo->addItem(value); combo->addItem(value);
} }
combo->addItems(*editor->project->secretBaseIds); combo->addItems(editor->project->secretBaseIds);
combo->setCurrentIndex(combo->findText(value)); combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The secret base id which is inside this secret\n" combo->setToolTip("The secret base id which is inside this secret\n"
"base entrance. Secret base ids are meant to be\n" "base entrance. Secret base ids are meant to be\n"
"unique to each and every secret base entrance."); "unique to each and every secret base entrance.");
} else if (key == "player_facing_direction") { } else if (key == "player_facing_direction") {
if (!editor->project->bgEventFacingDirections->contains(value)) { if (!editor->project->bgEventFacingDirections.contains(value)) {
combo->addItem(value); combo->addItem(value);
} }
combo->addItems(*editor->project->bgEventFacingDirections); combo->addItems(editor->project->bgEventFacingDirections);
combo->setCurrentIndex(combo->findText(value)); combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The direction which the player must be facing\n" combo->setToolTip("The direction which the player must be facing\n"
"to be able to interact with this event."); "to be able to interact with this event.");
@ -1912,7 +1912,7 @@ void MainWindow::updateSelectedObjects() {
combo->addItems(editor->map->eventScriptLabels()); combo->addItems(editor->map->eventScriptLabels());
combo->setToolTip("The script which is executed with this event."); combo->setToolTip("The script which is executed with this event.");
} else if (key == "trainer_type") { } else if (key == "trainer_type") {
combo->addItems(*editor->project->trainerTypes); combo->addItems(editor->project->trainerTypes);
combo->setCurrentIndex(combo->findText(value)); combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The trainer type of this object event.\n" combo->setToolTip("The trainer type of this object event.\n"
"If it is not a trainer, use NONE. SEE ALL DIRECTIONS\n" "If it is not a trainer, use NONE. SEE ALL DIRECTIONS\n"
@ -1924,10 +1924,10 @@ void MainWindow::updateSelectedObjects() {
} else if (key == "in_connection") { } else if (key == "in_connection") {
check->setToolTip("Check if object is positioned in the connection to another map."); check->setToolTip("Check if object is positioned in the connection to another map.");
} else if (key == "respawn_map") { } else if (key == "respawn_map") {
if (!editor->project->mapNames->contains(value)) { if (!editor->project->mapNames.contains(value)) {
combo->addItem(value); combo->addItem(value);
} }
combo->addItems(*editor->project->mapNames); combo->addItems(editor->project->mapNames);
combo->setToolTip("The map where the player will respawn after whiteout."); combo->setToolTip("The map where the player will respawn after whiteout.");
} else if (key == "respawn_npc") { } else if (key == "respawn_npc") {
spin->setToolTip("event_object ID of the NPC the player interacts with\n" spin->setToolTip("event_object ID of the NPC the player interacts with\n"
@ -2475,7 +2475,7 @@ void MainWindow::on_spinBox_ConnectionOffset_valueChanged(int offset)
void MainWindow::on_comboBox_ConnectedMap_currentTextChanged(const QString &mapName) void MainWindow::on_comboBox_ConnectedMap_currentTextChanged(const QString &mapName)
{ {
if (editor->project->mapNames->contains(mapName)) if (editor->project->mapNames.contains(mapName))
editor->setConnectionMap(mapName); editor->setConnectionMap(mapName);
} }
@ -2503,13 +2503,13 @@ void MainWindow::on_pushButton_ConfigureEncountersJSON_clicked() {
void MainWindow::on_comboBox_DiveMap_currentTextChanged(const QString &mapName) void MainWindow::on_comboBox_DiveMap_currentTextChanged(const QString &mapName)
{ {
if (editor->project->mapNames->contains(mapName)) if (editor->project->mapNames.contains(mapName))
editor->updateDiveMap(mapName); editor->updateDiveMap(mapName);
} }
void MainWindow::on_comboBox_EmergeMap_currentTextChanged(const QString &mapName) void MainWindow::on_comboBox_EmergeMap_currentTextChanged(const QString &mapName)
{ {
if (editor->project->mapNames->contains(mapName)) if (editor->project->mapNames.contains(mapName))
editor->updateEmergeMap(mapName); editor->updateEmergeMap(mapName);
} }
@ -2603,8 +2603,8 @@ void MainWindow::on_pushButton_ChangeDimensions_clicked()
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
Map *map = editor->map; Map *map = editor->map;
Blockdata *oldMetatiles = map->layout->blockdata->copy(); Blockdata oldMetatiles = map->layout->blockdata;
Blockdata *oldBorder = map->layout->border->copy(); Blockdata oldBorder = map->layout->border;
QSize oldMapDimensions(map->getWidth(), map->getHeight()); QSize oldMapDimensions(map->getWidth(), map->getHeight());
QSize oldBorderDimensions(map->getBorderWidth(), map->getBorderHeight()); QSize oldBorderDimensions(map->getBorderWidth(), map->getBorderHeight());
QSize newMapDimensions(widthSpinBox->value(), heightSpinBox->value()); QSize newMapDimensions(widthSpinBox->value(), heightSpinBox->value());
@ -2612,11 +2612,11 @@ void MainWindow::on_pushButton_ChangeDimensions_clicked()
if (oldMapDimensions != newMapDimensions || oldBorderDimensions != newBorderDimensions) { if (oldMapDimensions != newMapDimensions || oldBorderDimensions != newBorderDimensions) {
editor->map->setDimensions(newMapDimensions.width(), newMapDimensions.height()); editor->map->setDimensions(newMapDimensions.width(), newMapDimensions.height());
editor->map->setBorderDimensions(newBorderDimensions.width(), newBorderDimensions.height()); editor->map->setBorderDimensions(newBorderDimensions.width(), newBorderDimensions.height());
editor->map->editHistory.push(new ResizeMap(map, editor->map->editHistory.push(new ResizeMap(map,
oldMapDimensions, newMapDimensions, oldMapDimensions, newMapDimensions,
oldMetatiles, map->layout->blockdata->copy(), oldMetatiles, map->layout->blockdata,
oldBorderDimensions, newBorderDimensions, oldBorderDimensions, newBorderDimensions,
oldBorder, map->layout->border->copy() oldBorder, map->layout->border
)); ));
} }
} }

View file

@ -26,7 +26,7 @@ void MainWindow::tryCommitMapChanges(bool commitChanges) {
if (map) { if (map) {
map->editHistory.push(new ScriptEditMap(map, map->editHistory.push(new ScriptEditMap(map,
map->layout->lastCommitMapBlocks.dimensions, QSize(map->getWidth(), map->getHeight()), map->layout->lastCommitMapBlocks.dimensions, QSize(map->getWidth(), map->getHeight()),
map->layout->lastCommitMapBlocks.blocks->copy(), map->layout->blockdata->copy() map->layout->lastCommitMapBlocks.blocks, map->layout->blockdata
)); ));
} }
} }
@ -149,7 +149,7 @@ void MainWindow::magicFillFromSelection(int x, int y, bool forceRedraw, bool com
void MainWindow::shift(int xDelta, int yDelta, bool forceRedraw, bool commitChanges) { void MainWindow::shift(int xDelta, int yDelta, bool forceRedraw, bool commitChanges) {
if (!this->editor || !this->editor->map) if (!this->editor || !this->editor->map)
return; return;
this->editor->map_item->shift(xDelta, yDelta); this->editor->map_item->shift(xDelta, yDelta, true);
this->tryCommitMapChanges(commitChanges); this->tryCommitMapChanges(commitChanges);
this->tryRedrawMapArea(forceRedraw); this->tryRedrawMapArea(forceRedraw);
} }

View file

@ -36,55 +36,15 @@ int Project::max_map_data_size = 10240; // 0x2800
int Project::default_map_size = 20; int Project::default_map_size = 20;
int Project::max_object_events = 64; int Project::max_object_events = 64;
Project::Project(QWidget *parent) : parent(parent) Project::Project(QWidget *parent) : QObject(parent)
{ {
groupNames = new QStringList;
mapGroups = new QMap<QString, int>;
mapNames = new QStringList;
itemNames = new QStringList;
flagNames = new QStringList;
varNames = new QStringList;
movementTypes = new QStringList;
mapTypes = new QStringList;
mapBattleScenes = new QStringList;
weatherNames = new QStringList;
coordEventWeatherNames = new QStringList;
secretBaseIds = new QStringList;
bgEventFacingDirections = new QStringList;
trainerTypes = new QStringList;
mapCache = new QMap<QString, Map*>;
mapConstantsToMapNames = new QMap<QString, QString>;
mapNamesToMapConstants = new QMap<QString, QString>;
tilesetCache = new QMap<QString, Tileset*>;
initSignals(); initSignals();
} }
Project::~Project() Project::~Project()
{ {
delete this->groupNames;
delete this->mapGroups;
delete this->mapNames;
delete this->itemNames;
delete this->flagNames;
delete this->varNames;
delete this->weatherNames;
delete this->coordEventWeatherNames;
delete this->secretBaseIds;
delete this->movementTypes;
delete this->bgEventFacingDirections;
delete this->mapBattleScenes;
delete this->trainerTypes;
delete this->mapTypes;
delete this->mapConstantsToMapNames;
delete this->mapNamesToMapConstants;
clearMapCache(); clearMapCache();
delete this->mapCache;
clearTilesetCache(); clearTilesetCache();
delete this->tilesetCache;
} }
void Project::initSignals() { void Project::initSignals() {
@ -101,7 +61,7 @@ void Project::initSignals() {
static bool showing = false; static bool showing = false;
if (showing) return; if (showing) return;
QMessageBox notice(this->parent); QMessageBox notice(this->parentWidget());
notice.setText("File Changed"); notice.setText("File Changed");
notice.setInformativeText(QString("The file %1 has changed on disk. Would you like to reload the project?") notice.setInformativeText(QString("The file %1 has changed on disk. Would you like to reload the project?")
.arg(changed.remove(this->root + "/"))); .arg(changed.remove(this->root + "/")));
@ -139,24 +99,24 @@ QString Project::getProjectTitle() {
} }
void Project::clearMapCache() { void Project::clearMapCache() {
for (QString mapName : mapCache->keys()) { for (QString mapName : mapCache.keys()) {
Map *map = mapCache->take(mapName); Map *map = mapCache.take(mapName);
if (map) delete map; if (map) delete map;
} }
emit mapCacheCleared(); emit mapCacheCleared();
} }
void Project::clearTilesetCache() { void Project::clearTilesetCache() {
for (QString tilesetName : tilesetCache->keys()) { for (QString tilesetName : tilesetCache.keys()) {
Tileset *tileset = tilesetCache->take(tilesetName); Tileset *tileset = tilesetCache.take(tilesetName);
if (tileset) delete tileset; if (tileset) delete tileset;
} }
} }
Map* Project::loadMap(QString map_name) { Map* Project::loadMap(QString map_name) {
Map *map; Map *map;
if (mapCache->contains(map_name)) { if (mapCache.contains(map_name)) {
map = mapCache->value(map_name); map = mapCache.value(map_name);
// TODO: uncomment when undo/redo history is fully implemented for all actions. // TODO: uncomment when undo/redo history is fully implemented for all actions.
if (true/*map->hasUnsavedChanges()*/) { if (true/*map->hasUnsavedChanges()*/) {
return map; return map;
@ -169,7 +129,7 @@ Map* Project::loadMap(QString map_name) {
if (!(loadMapData(map) && loadMapLayout(map))) if (!(loadMapData(map) && loadMapLayout(map)))
return nullptr; return nullptr;
mapCache->insert(map_name, map); mapCache.insert(map_name, map);
return map; return map;
} }
@ -204,7 +164,7 @@ QMap<QString, bool> Project::getTopLevelMapFields() {
topLevelMapFields.insert("allow_escaping", true); topLevelMapFields.insert("allow_escaping", true);
topLevelMapFields.insert("allow_running", true); topLevelMapFields.insert("allow_running", true);
} }
if (projectConfig.getFloorNumberEnabled()) { if (projectConfig.getFloorNumberEnabled()) {
topLevelMapFields.insert("floor_number", true); topLevelMapFields.insert("floor_number", true);
} }
@ -283,8 +243,8 @@ bool Project::loadMapData(Map* map) {
// Ensure the warp destination map constant is valid before adding it to the warps. // Ensure the warp destination map constant is valid before adding it to the warps.
QString mapConstant = event["dest_map"].toString(); QString mapConstant = event["dest_map"].toString();
if (mapConstantsToMapNames->contains(mapConstant)) { if (mapConstantsToMapNames.contains(mapConstant)) {
warp->put("destination_map_name", mapConstantsToMapNames->value(mapConstant)); warp->put("destination_map_name", mapConstantsToMapNames.value(mapConstant));
warp->put("event_group_type", "warp_event_group"); warp->put("event_group_type", "warp_event_group");
map->events["warp_event_group"].append(warp); map->events["warp_event_group"].append(warp);
} else if (mapConstant == NONE_MAP_CONSTANT) { } else if (mapConstant == NONE_MAP_CONSTANT) {
@ -302,7 +262,7 @@ bool Project::loadMapData(Map* map) {
HealLocation loc = *it; HealLocation loc = *it;
//if TRUE map is flyable / has healing location //if TRUE map is flyable / has healing location
if (loc.mapName == QString(mapNamesToMapConstants->value(map->name)).remove(0,4)) { if (loc.mapName == QString(mapNamesToMapConstants.value(map->name)).remove(0,4)) {
Event *heal = new Event; Event *heal = new Event;
heal->put("map_name", map->name); heal->put("map_name", map->name);
heal->put("x", loc.x); heal->put("x", loc.x);
@ -311,11 +271,11 @@ bool Project::loadMapData(Map* map) {
heal->put("id_name", loc.idName); heal->put("id_name", loc.idName);
heal->put("index", loc.index); heal->put("index", loc.index);
heal->put("elevation", 3); // TODO: change this? heal->put("elevation", 3); // TODO: change this?
heal->put("destination_map_name", mapConstantsToMapNames->value(map->name)); heal->put("destination_map_name", mapConstantsToMapNames.value(map->name));
heal->put("event_group_type", "heal_event_group"); heal->put("event_group_type", "heal_event_group");
heal->put("event_type", EventType::HealLocation); heal->put("event_type", EventType::HealLocation);
if (projectConfig.getHealLocationRespawnDataEnabled()) { if (projectConfig.getHealLocationRespawnDataEnabled()) {
heal->put("respawn_map", mapConstantsToMapNames->value(QString("MAP_" + loc.respawnMap))); heal->put("respawn_map", mapConstantsToMapNames.value(QString("MAP_" + loc.respawnMap)));
heal->put("respawn_npc", loc.respawnNPC); heal->put("respawn_npc", loc.respawnNPC);
} }
map->events["heal_event_group"].append(heal); map->events["heal_event_group"].append(heal);
@ -408,8 +368,8 @@ bool Project::loadMapData(Map* map) {
connection->direction = connectionObj["direction"].toString(); connection->direction = connectionObj["direction"].toString();
connection->offset = QString::number(connectionObj["offset"].toInt()); connection->offset = QString::number(connectionObj["offset"].toInt());
QString mapConstant = connectionObj["map"].toString(); QString mapConstant = connectionObj["map"].toString();
if (mapConstantsToMapNames->contains(mapConstant)) { if (mapConstantsToMapNames.contains(mapConstant)) {
connection->map_name = mapConstantsToMapNames->value(mapConstant); connection->map_name = mapConstantsToMapNames.value(mapConstant);
map->connections.append(connection); map->connections.append(connection);
} else { } else {
logError(QString("Failed to find connected map for map constant '%1'").arg(mapConstant)); logError(QString("Failed to find connected map for map constant '%1'").arg(mapConstant));
@ -429,8 +389,8 @@ bool Project::loadMapData(Map* map) {
} }
QString Project::readMapLayoutId(QString map_name) { QString Project::readMapLayoutId(QString map_name) {
if (mapCache->contains(map_name)) { if (mapCache.contains(map_name)) {
return mapCache->value(map_name)->layoutId; return mapCache.value(map_name)->layoutId;
} }
QString mapFilepath = QString("%1/data/maps/%2/map.json").arg(root).arg(map_name); QString mapFilepath = QString("%1/data/maps/%2/map.json").arg(root).arg(map_name);
@ -445,8 +405,8 @@ QString Project::readMapLayoutId(QString map_name) {
} }
QString Project::readMapLocation(QString map_name) { QString Project::readMapLocation(QString map_name) {
if (mapCache->contains(map_name)) { if (mapCache.contains(map_name)) {
return mapCache->value(map_name)->location; return mapCache.value(map_name)->location;
} }
QString mapFilepath = QString("%1/data/maps/%2/map.json").arg(root).arg(map_name); QString mapFilepath = QString("%1/data/maps/%2/map.json").arg(root).arg(map_name);
@ -464,8 +424,8 @@ void Project::setNewMapHeader(Map* map, int mapIndex) {
map->layoutId = QString("%1").arg(mapIndex); map->layoutId = QString("%1").arg(mapIndex);
map->location = mapSectionValueToName.value(0); map->location = mapSectionValueToName.value(0);
map->requiresFlash = "FALSE"; map->requiresFlash = "FALSE";
map->weather = weatherNames->value(0, "WEATHER_NONE"); map->weather = weatherNames.value(0, "WEATHER_NONE");
map->type = mapTypes->value(0, "MAP_TYPE_NONE"); map->type = mapTypes.value(0, "MAP_TYPE_NONE");
map->song = defaultSong; map->song = defaultSong;
if (projectConfig.getBaseGameVersion() == BaseGameVersion::pokeruby) { if (projectConfig.getBaseGameVersion() == BaseGameVersion::pokeruby) {
map->show_location = "TRUE"; map->show_location = "TRUE";
@ -479,7 +439,7 @@ void Project::setNewMapHeader(Map* map, int mapIndex) {
map->floorNumber = 0; map->floorNumber = 0;
} }
map->battle_scene = mapBattleScenes->value(0, "MAP_BATTLE_SCENE_NORMAL"); map->battle_scene = mapBattleScenes.value(0, "MAP_BATTLE_SCENE_NORMAL");
} }
bool Project::loadMapLayout(Map* map) { bool Project::loadMapLayout(Map* map) {
@ -703,7 +663,7 @@ void Project::saveMapGroups() {
mapGroupsObj["layouts_table_label"] = layoutsLabel; mapGroupsObj["layouts_table_label"] = layoutsLabel;
OrderedJson::array groupNamesArr; OrderedJson::array groupNamesArr;
for (QString groupName : *this->groupNames) { for (QString groupName : this->groupNames) {
groupNamesArr.push_back(groupName); groupNamesArr.push_back(groupName);
} }
mapGroupsObj["group_order"] = groupNamesArr; mapGroupsObj["group_order"] = groupNamesArr;
@ -714,7 +674,7 @@ void Project::saveMapGroups() {
for (QString mapName : mapNames) { for (QString mapName : mapNames) {
groupArr.push_back(mapName); groupArr.push_back(mapName);
} }
mapGroupsObj[this->groupNames->at(groupNum)] = groupArr; mapGroupsObj[this->groupNames.at(groupNum)] = groupArr;
groupNum++; groupNum++;
} }
@ -826,13 +786,13 @@ void Project::saveMapConstantsHeader() {
text += QString("// Map Group %1\n").arg(groupNum); text += QString("// Map Group %1\n").arg(groupNum);
int maxLength = 0; int maxLength = 0;
for (QString mapName : mapNames) { for (QString mapName : mapNames) {
QString mapConstantName = mapNamesToMapConstants->value(mapName); QString mapConstantName = mapNamesToMapConstants.value(mapName);
if (mapConstantName.length() > maxLength) if (mapConstantName.length() > maxLength)
maxLength = mapConstantName.length(); maxLength = mapConstantName.length();
} }
int groupIndex = 0; int groupIndex = 0;
for (QString mapName : mapNames) { for (QString mapName : mapNames) {
QString mapConstantName = mapNamesToMapConstants->value(mapName); QString mapConstantName = mapNamesToMapConstants.value(mapName);
text += QString("#define %1%2(%3 | (%4 << 8))\n") text += QString("#define %1%2(%3 | (%4 << 8))\n")
.arg(mapConstantName) .arg(mapConstantName)
.arg(QString(" ").repeated(maxLength - mapConstantName.length() + 1)) .arg(QString(" ").repeated(maxLength - mapConstantName.length() + 1))
@ -1148,31 +1108,31 @@ bool Project::loadMapTilesets(Map* map) {
} }
Tileset* Project::loadTileset(QString label, Tileset *tileset) { Tileset* Project::loadTileset(QString label, Tileset *tileset) {
QStringList *values = parser.getLabelValues(parser.parseAsm("data/tilesets/headers.inc"), label); const QStringList values = parser.getLabelValues(parser.parseAsm("data/tilesets/headers.inc"), label);
if (values->isEmpty()) { if (values.isEmpty()) {
return nullptr; return nullptr;
} }
if (tileset == nullptr) { if (tileset == nullptr) {
tileset = new Tileset; tileset = new Tileset;
} }
tileset->name = label; tileset->name = label;
tileset->is_compressed = values->value(0); tileset->is_compressed = values.value(0);
tileset->is_secondary = values->value(1); tileset->is_secondary = values.value(1);
tileset->padding = values->value(2); tileset->padding = values.value(2);
tileset->tiles_label = values->value(3); tileset->tiles_label = values.value(3);
tileset->palettes_label = values->value(4); tileset->palettes_label = values.value(4);
tileset->metatiles_label = values->value(5); tileset->metatiles_label = values.value(5);
if (projectConfig.getBaseGameVersion() == BaseGameVersion::pokefirered) { if (projectConfig.getBaseGameVersion() == BaseGameVersion::pokefirered) {
tileset->callback_label = values->value(6); tileset->callback_label = values.value(6);
tileset->metatile_attrs_label = values->value(7); tileset->metatile_attrs_label = values.value(7);
} else { } else {
tileset->metatile_attrs_label = values->value(6); tileset->metatile_attrs_label = values.value(6);
tileset->callback_label = values->value(7); tileset->callback_label = values.value(7);
} }
loadTilesetAssets(tileset); loadTilesetAssets(tileset);
tilesetCache->insert(label, tileset); tilesetCache.insert(label, tileset);
return tileset; return tileset;
} }
@ -1183,32 +1143,26 @@ bool Project::loadBlockdata(Map *map) {
QString path = QString("%1/%2").arg(root).arg(map->layout->blockdata_path); QString path = QString("%1/%2").arg(root).arg(map->layout->blockdata_path);
map->layout->blockdata = readBlockdata(path); map->layout->blockdata = readBlockdata(path);
if (map->layout->lastCommitMapBlocks.blocks) { map->layout->lastCommitMapBlocks.blocks = map->layout->blockdata;
delete map->layout->lastCommitMapBlocks.blocks;
}
map->layout->lastCommitMapBlocks.blocks = new Blockdata;
map->layout->lastCommitMapBlocks.blocks->copyFrom(map->layout->blockdata);
map->layout->lastCommitMapBlocks.dimensions = QSize(map->getWidth(), map->getHeight()); map->layout->lastCommitMapBlocks.dimensions = QSize(map->getWidth(), map->getHeight());
if (map->layout->blockdata->blocks->count() != map->getWidth() * map->getHeight()) { if (map->layout->blockdata.count() != map->getWidth() * map->getHeight()) {
logWarn(QString("Layout blockdata length %1 does not match dimensions %2x%3 (should be %4). Resizing blockdata.") logWarn(QString("Layout blockdata length %1 does not match dimensions %2x%3 (should be %4). Resizing blockdata.")
.arg(map->layout->blockdata->blocks->count()) .arg(map->layout->blockdata.count())
.arg(map->getWidth()) .arg(map->getWidth())
.arg(map->getHeight()) .arg(map->getHeight())
.arg(map->getWidth() * map->getHeight())); .arg(map->getWidth() * map->getHeight()));
map->layout->blockdata->blocks->resize(map->getWidth() * map->getHeight()); map->layout->blockdata.resize(map->getWidth() * map->getHeight());
} }
return true; return true;
} }
void Project::setNewMapBlockdata(Map *map) { void Project::setNewMapBlockdata(Map *map) {
Blockdata *blockdata = new Blockdata; map->layout->blockdata.clear();
for (int i = 0; i < map->getWidth() * map->getHeight(); i++) { for (int i = 0; i < map->getWidth() * map->getHeight(); i++) {
blockdata->addBlock(qint16(0x3001)); map->layout->blockdata.append(qint16(0x3001));
} }
map->layout->blockdata = blockdata; map->layout->lastCommitMapBlocks.blocks = map->layout->blockdata;
map->layout->lastCommitMapBlocks.blocks = new Blockdata;
map->layout->lastCommitMapBlocks.blocks->copyFrom(map->layout->blockdata);
map->layout->lastCommitMapBlocks.dimensions = QSize(map->getWidth(), map->getHeight()); map->layout->lastCommitMapBlocks.dimensions = QSize(map->getWidth(), map->getHeight());
} }
@ -1220,33 +1174,32 @@ bool Project::loadMapBorder(Map *map) {
QString path = QString("%1/%2").arg(root).arg(map->layout->border_path); QString path = QString("%1/%2").arg(root).arg(map->layout->border_path);
map->layout->border = readBlockdata(path); map->layout->border = readBlockdata(path);
int borderLength = map->getBorderWidth() * map->getBorderHeight(); int borderLength = map->getBorderWidth() * map->getBorderHeight();
if (map->layout->border->blocks->count() != borderLength) { if (map->layout->border.count() != borderLength) {
logWarn(QString("Layout border blockdata length %1 must be %2. Resizing border blockdata.") logWarn(QString("Layout border blockdata length %1 must be %2. Resizing border blockdata.")
.arg(map->layout->border->blocks->count()) .arg(map->layout->border.count())
.arg(borderLength)); .arg(borderLength));
map->layout->border->blocks->resize(borderLength); map->layout->border.resize(borderLength);
} }
return true; return true;
} }
void Project::setNewMapBorder(Map *map) { void Project::setNewMapBorder(Map *map) {
Blockdata *blockdata = new Blockdata; map->layout->border.clear();
if (map->getBorderWidth() != DEFAULT_BORDER_WIDTH || map->getBorderHeight() != DEFAULT_BORDER_HEIGHT) { if (map->getBorderWidth() != DEFAULT_BORDER_WIDTH || map->getBorderHeight() != DEFAULT_BORDER_HEIGHT) {
for (int i = 0; i < map->getBorderWidth() * map->getBorderHeight(); i++) { for (int i = 0; i < map->getBorderWidth() * map->getBorderHeight(); i++) {
blockdata->addBlock(0); map->layout->border.append(0);
} }
} else if (projectConfig.getBaseGameVersion() == BaseGameVersion::pokefirered) { } else if (projectConfig.getBaseGameVersion() == BaseGameVersion::pokefirered) {
blockdata->addBlock(qint16(0x0014)); map->layout->border.append(qint16(0x0014));
blockdata->addBlock(qint16(0x0015)); map->layout->border.append(qint16(0x0015));
blockdata->addBlock(qint16(0x001C)); map->layout->border.append(qint16(0x001C));
blockdata->addBlock(qint16(0x001D)); map->layout->border.append(qint16(0x001D));
} else { } else {
blockdata->addBlock(qint16(0x01D4)); map->layout->border.append(qint16(0x01D4));
blockdata->addBlock(qint16(0x01D5)); map->layout->border.append(qint16(0x01D5));
blockdata->addBlock(qint16(0x01DC)); map->layout->border.append(qint16(0x01DC));
blockdata->addBlock(qint16(0x01DD)); map->layout->border.append(qint16(0x01DD));
} }
map->layout->border = blockdata;
} }
void Project::saveLayoutBorder(Map *map) { void Project::saveLayoutBorder(Map *map) {
@ -1259,10 +1212,10 @@ void Project::saveLayoutBlockdata(Map* map) {
writeBlockdata(path, map->layout->blockdata); writeBlockdata(path, map->layout->blockdata);
} }
void Project::writeBlockdata(QString path, Blockdata *blockdata) { void Project::writeBlockdata(QString path, const Blockdata &blockdata) {
QFile file(path); QFile file(path);
if (file.open(QIODevice::WriteOnly)) { if (file.open(QIODevice::WriteOnly)) {
QByteArray data = blockdata->serialize(); QByteArray data = blockdata.serialize();
file.write(data); file.write(data);
} else { } else {
logError(QString("Failed to open blockdata file for writing: '%1'").arg(path)); logError(QString("Failed to open blockdata file for writing: '%1'").arg(path));
@ -1270,10 +1223,10 @@ void Project::writeBlockdata(QString path, Blockdata *blockdata) {
} }
void Project::saveAllMaps() { void Project::saveAllMaps() {
QList<QString> keys = mapCache->keys(); QList<QString> keys = mapCache.keys();
for (int i = 0; i < keys.length(); i++) { for (int i = 0; i < keys.length(); i++) {
QString key = keys.value(i); QString key = keys.value(i);
Map* map = mapCache->value(key); Map* map = mapCache.value(key);
saveMap(map); saveMap(map);
} }
} }
@ -1376,11 +1329,11 @@ void Project::saveMap(Map *map) {
if (map->connections.length() > 0) { if (map->connections.length() > 0) {
OrderedJson::array connectionsArr; OrderedJson::array connectionsArr;
for (MapConnection* connection : map->connections) { for (MapConnection* connection : map->connections) {
if (mapNamesToMapConstants->contains(connection->map_name)) { if (mapNamesToMapConstants.contains(connection->map_name)) {
OrderedJson::object connectionObj; OrderedJson::object connectionObj;
connectionObj["direction"] = connection->direction; connectionObj["direction"] = connection->direction;
connectionObj["offset"] = connection->offset.toInt(); connectionObj["offset"] = connection->offset.toInt();
connectionObj["map"] = this->mapNamesToMapConstants->value(connection->map_name); connectionObj["map"] = this->mapNamesToMapConstants.value(connection->map_name);
connectionsArr.append(connectionObj); connectionsArr.append(connectionObj);
} else { } else {
logError(QString("Failed to write map connection. '%1' is not a valid map name").arg(connection->map_name)); logError(QString("Failed to write map connection. '%1' is not a valid map name").arg(connection->map_name));
@ -1497,15 +1450,15 @@ void Project::loadTilesetAssets(Tileset* tileset) {
} }
QRegularExpression re("([a-z])([A-Z0-9])"); QRegularExpression re("([a-z])([A-Z0-9])");
QString tilesetName = tileset->name; QString tilesetName = tileset->name;
QString dir_path = root + "/data/tilesets/" + category + "/" + tilesetName.replace("gTileset_", "").replace(re, "\\1_\\2").toLower(); QString dir_path = root + "/data/tilesets/" + category + '/' + tilesetName.replace("gTileset_", "").replace(re, "\\1_\\2").toLower();
QList<QStringList> *graphics = parser.parseAsm("data/tilesets/graphics.inc"); const QList<QStringList> graphics = parser.parseAsm("data/tilesets/graphics.inc");
QStringList *tiles_values = parser.getLabelValues(graphics, tileset->tiles_label); const QStringList tiles_values = parser.getLabelValues(graphics, tileset->tiles_label);
QStringList *palettes_values = parser.getLabelValues(graphics, tileset->palettes_label); const QStringList palettes_values = parser.getLabelValues(graphics, tileset->palettes_label);
QString tiles_path; QString tiles_path;
if (!tiles_values->isEmpty()) { if (!tiles_values.isEmpty()) {
tiles_path = root + "/" + tiles_values->value(0).section('"', 1, 1); tiles_path = root + '/' + tiles_values.value(0).section('"', 1, 1);
} else { } else {
tiles_path = dir_path + "/tiles.4bpp"; tiles_path = dir_path + "/tiles.4bpp";
if (tileset->is_compressed == "TRUE") { if (tileset->is_compressed == "TRUE") {
@ -1513,28 +1466,27 @@ void Project::loadTilesetAssets(Tileset* tileset) {
} }
} }
if (!palettes_values->isEmpty()) { if (!palettes_values.isEmpty()) {
for (int i = 0; i < palettes_values->length(); i++) { for (const auto &value : palettes_values) {
QString value = palettes_values->value(i); tileset->palettePaths.append(this->fixPalettePath(root + '/' + value.section('"', 1, 1)));
tileset->palettePaths.append(this->fixPalettePath(root + "/" + value.section('"', 1, 1)));
} }
} else { } else {
QString palettes_dir_path = dir_path + "/palettes"; QString palettes_dir_path = dir_path + "/palettes";
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
tileset->palettePaths.append(palettes_dir_path + "/" + QString("%1").arg(i, 2, 10, QLatin1Char('0')) + ".pal"); tileset->palettePaths.append(palettes_dir_path + '/' + QString("%1").arg(i, 2, 10, QLatin1Char('0')) + ".pal");
} }
} }
QList<QStringList> *metatiles_macros = parser.parseAsm("data/tilesets/metatiles.inc"); const QList<QStringList> metatiles_macros = parser.parseAsm("data/tilesets/metatiles.inc");
QStringList *metatiles_values = parser.getLabelValues(metatiles_macros, tileset->metatiles_label); const QStringList metatiles_values = parser.getLabelValues(metatiles_macros, tileset->metatiles_label);
if (!metatiles_values->isEmpty()) { if (!metatiles_values.isEmpty()) {
tileset->metatiles_path = root + "/" + metatiles_values->value(0).section('"', 1, 1); tileset->metatiles_path = root + '/' + metatiles_values.value(0).section('"', 1, 1);
} else { } else {
tileset->metatiles_path = dir_path + "/metatiles.bin"; tileset->metatiles_path = dir_path + "/metatiles.bin";
} }
QStringList *metatile_attrs_values = parser.getLabelValues(metatiles_macros, tileset->metatile_attrs_label); const QStringList metatile_attrs_values = parser.getLabelValues(metatiles_macros, tileset->metatile_attrs_label);
if (!metatile_attrs_values->isEmpty()) { if (!metatile_attrs_values.isEmpty()) {
tileset->metatile_attrs_path = root + "/" + metatile_attrs_values->value(0).section('"', 1, 1); tileset->metatile_attrs_path = root + '/' + metatile_attrs_values.value(0).section('"', 1, 1);
} else { } else {
tileset->metatile_attrs_path = dir_path + "/metatile_attributes.bin"; tileset->metatile_attrs_path = dir_path + "/metatile_attributes.bin";
} }
@ -1702,14 +1654,14 @@ void Project::loadTilesetMetatileLabels(Tileset* tileset) {
} }
} }
Blockdata* Project::readBlockdata(QString path) { Blockdata Project::readBlockdata(QString path) {
Blockdata *blockdata = new Blockdata; Blockdata blockdata;
QFile file(path); QFile file(path);
if (file.open(QIODevice::ReadOnly)) { if (file.open(QIODevice::ReadOnly)) {
QByteArray data = file.readAll(); QByteArray data = file.readAll();
for (int i = 0; (i + 1) < data.length(); i += 2) { for (int i = 0; (i + 1) < data.length(); i += 2) {
uint16_t word = static_cast<uint16_t>((data[i] & 0xff) + ((data[i + 1] & 0xff) << 8)); uint16_t word = static_cast<uint16_t>((data[i] & 0xff) + ((data[i + 1] & 0xff) << 8));
blockdata->addBlock(word); blockdata.append(word);
} }
} else { } else {
logError(QString("Failed to open blockdata path '%1'").arg(path)); logError(QString("Failed to open blockdata path '%1'").arg(path));
@ -1719,8 +1671,8 @@ Blockdata* Project::readBlockdata(QString path) {
} }
Map* Project::getMap(QString map_name) { Map* Project::getMap(QString map_name) {
if (mapCache->contains(map_name)) { if (mapCache.contains(map_name)) {
return mapCache->value(map_name); return mapCache.value(map_name);
} else { } else {
Map *map = loadMap(map_name); Map *map = loadMap(map_name);
return map; return map;
@ -1729,8 +1681,8 @@ Map* Project::getMap(QString map_name) {
Tileset* Project::getTileset(QString label, bool forceLoad) { Tileset* Project::getTileset(QString label, bool forceLoad) {
Tileset *existingTileset = nullptr; Tileset *existingTileset = nullptr;
if (tilesetCache->contains(label)) { if (tilesetCache.contains(label)) {
existingTileset = tilesetCache->value(label); existingTileset = tilesetCache.value(label);
} }
if (existingTileset && !forceLoad) { if (existingTileset && !forceLoad) {
@ -1840,9 +1792,9 @@ bool Project::readWildMonData() {
} }
bool Project::readMapGroups() { bool Project::readMapGroups() {
mapConstantsToMapNames->clear(); mapConstantsToMapNames.clear();
mapNamesToMapConstants->clear(); mapNamesToMapConstants.clear();
mapGroups->clear(); mapGroups.clear();
QString mapGroupsFilepath = QString("%1/data/maps/map_groups.json").arg(root); QString mapGroupsFilepath = QString("%1/data/maps/map_groups.json").arg(root);
fileWatcher.addPath(mapGroupsFilepath); fileWatcher.addPath(mapGroupsFilepath);
@ -1856,29 +1808,29 @@ bool Project::readMapGroups() {
QJsonArray mapGroupOrder = mapGroupsObj["group_order"].toArray(); QJsonArray mapGroupOrder = mapGroupsObj["group_order"].toArray();
QList<QStringList> groupedMaps; QList<QStringList> groupedMaps;
QStringList *maps = new QStringList; QStringList maps;
QStringList *groups = new QStringList; QStringList groups;
for (int groupIndex = 0; groupIndex < mapGroupOrder.size(); groupIndex++) { for (int groupIndex = 0; groupIndex < mapGroupOrder.size(); groupIndex++) {
QString groupName = mapGroupOrder.at(groupIndex).toString(); QString groupName = mapGroupOrder.at(groupIndex).toString();
QJsonArray mapNames = mapGroupsObj.value(groupName).toArray(); QJsonArray mapNames = mapGroupsObj.value(groupName).toArray();
groupedMaps.append(QStringList()); groupedMaps.append(QStringList());
groups->append(groupName); groups.append(groupName);
for (int j = 0; j < mapNames.size(); j++) { for (int j = 0; j < mapNames.size(); j++) {
QString mapName = mapNames.at(j).toString(); QString mapName = mapNames.at(j).toString();
mapGroups->insert(mapName, groupIndex); mapGroups.insert(mapName, groupIndex);
groupedMaps[groupIndex].append(mapName); groupedMaps[groupIndex].append(mapName);
maps->append(mapName); maps.append(mapName);
// Build the mapping and reverse mapping between map constants and map names. // Build the mapping and reverse mapping between map constants and map names.
QString mapConstant = Map::mapConstantFromName(mapName); QString mapConstant = Map::mapConstantFromName(mapName);
mapConstantsToMapNames->insert(mapConstant, mapName); mapConstantsToMapNames.insert(mapConstant, mapName);
mapNamesToMapConstants->insert(mapName, mapConstant); mapNamesToMapConstants.insert(mapName, mapConstant);
} }
} }
mapConstantsToMapNames->insert(NONE_MAP_CONSTANT, NONE_MAP_NAME); mapConstantsToMapNames.insert(NONE_MAP_CONSTANT, NONE_MAP_NAME);
mapNamesToMapConstants->insert(NONE_MAP_NAME, NONE_MAP_CONSTANT); mapNamesToMapConstants.insert(NONE_MAP_NAME, NONE_MAP_CONSTANT);
maps->append(NONE_MAP_NAME); maps.append(NONE_MAP_NAME);
groupNames = groups; groupNames = groups;
groupedMapNames = groupedMaps; groupedMapNames = groupedMaps;
@ -1888,15 +1840,15 @@ bool Project::readMapGroups() {
Map* Project::addNewMapToGroup(QString mapName, int groupNum) { Map* Project::addNewMapToGroup(QString mapName, int groupNum) {
// Setup new map in memory, but don't write to file until map is actually saved later. // Setup new map in memory, but don't write to file until map is actually saved later.
mapNames->append(mapName); mapNames.append(mapName);
mapGroups->insert(mapName, groupNum); mapGroups.insert(mapName, groupNum);
groupedMapNames[groupNum].append(mapName); groupedMapNames[groupNum].append(mapName);
Map *map = new Map; Map *map = new Map;
map->isPersistedToFile = false; map->isPersistedToFile = false;
map->setName(mapName); map->setName(mapName);
mapConstantsToMapNames->insert(map->constantName, map->name); mapConstantsToMapNames.insert(map->constantName, map->name);
mapNamesToMapConstants->insert(map->name, map->constantName); mapNamesToMapConstants.insert(map->name, map->constantName);
setNewMapHeader(map, mapLayoutsTable.size() + 1); setNewMapHeader(map, mapLayoutsTable.size() + 1);
setNewMapLayout(map); setNewMapLayout(map);
loadMapTilesets(map); loadMapTilesets(map);
@ -1904,14 +1856,14 @@ Map* Project::addNewMapToGroup(QString mapName, int groupNum) {
setNewMapBorder(map); setNewMapBorder(map);
setNewMapEvents(map); setNewMapEvents(map);
setNewMapConnections(map); setNewMapConnections(map);
mapCache->insert(mapName, map); mapCache.insert(mapName, map);
return map; return map;
} }
Map* Project::addNewMapToGroup(QString mapName, int groupNum, Map *newMap, bool existingLayout) { Map* Project::addNewMapToGroup(QString mapName, int groupNum, Map *newMap, bool existingLayout) {
mapNames->append(mapName); mapNames.append(mapName);
mapGroups->insert(mapName, groupNum); mapGroups.insert(mapName, groupNum);
groupedMapNames[groupNum].append(mapName); groupedMapNames[groupNum].append(mapName);
Map *map = new Map; Map *map = new Map;
@ -1920,8 +1872,8 @@ Map* Project::addNewMapToGroup(QString mapName, int groupNum, Map *newMap, bool
map->isPersistedToFile = false; map->isPersistedToFile = false;
map->setName(mapName); map->setName(mapName);
mapConstantsToMapNames->insert(map->constantName, map->name); mapConstantsToMapNames.insert(map->constantName, map->name);
mapNamesToMapConstants->insert(map->name, map->constantName); mapNamesToMapConstants.insert(map->name, map->constantName);
if (!existingLayout) { if (!existingLayout) {
mapLayouts.insert(map->layoutId, map->layout); mapLayouts.insert(map->layoutId, map->layout);
mapLayoutsTable.append(map->layoutId); mapLayoutsTable.append(map->layoutId);
@ -1942,7 +1894,7 @@ QString Project::getNewMapName() {
QString newMapName; QString newMapName;
do { do {
newMapName = QString("NewMap%1").arg(++i); newMapName = QString("NewMap%1").arg(++i);
} while (mapNames->contains(newMapName)); } while (mapNames.contains(newMapName));
return newMapName; return newMapName;
} }
@ -2160,12 +2112,11 @@ bool Project::readHealLocations() {
} }
bool Project::readItemNames() { bool Project::readItemNames() {
itemNames->clear(); QStringList prefixes("\\bITEM_(?!(B_)?USE_)"); // Exclude ITEM_USE_ and ITEM_B_USE_ constants
QStringList prefixes = (QStringList() << "\\bITEM_(?!(B_)?USE_)"); // Exclude ITEM_USE_ and ITEM_B_USE_ constants
QString filename = "include/constants/items.h"; QString filename = "include/constants/items.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
parser.readCDefinesSorted(filename, prefixes, itemNames); itemNames = parser.readCDefinesSorted(filename, prefixes);
if (itemNames->isEmpty()) { if (itemNames.isEmpty()) {
logError(QString("Failed to read item constants from %1").arg(filename)); logError(QString("Failed to read item constants from %1").arg(filename));
return false; return false;
} }
@ -2179,12 +2130,11 @@ bool Project::readFlagNames() {
fileWatcher.addPath(root + "/" + opponentsFilename); fileWatcher.addPath(root + "/" + opponentsFilename);
QMap<QString, int> maxTrainers = parser.readCDefines(opponentsFilename, QStringList() << "\\bMAX_"); QMap<QString, int> maxTrainers = parser.readCDefines(opponentsFilename, QStringList() << "\\bMAX_");
// Parse flags // Parse flags
flagNames->clear(); QStringList prefixes("\\bFLAG_");
QStringList prefixes = (QStringList() << "\\bFLAG_");
QString flagsFilename = "include/constants/flags.h"; QString flagsFilename = "include/constants/flags.h";
fileWatcher.addPath(root + "/" + flagsFilename); fileWatcher.addPath(root + "/" + flagsFilename);
parser.readCDefinesSorted(flagsFilename, prefixes, flagNames, maxTrainers); flagNames = parser.readCDefinesSorted(flagsFilename, prefixes, maxTrainers);
if (flagNames->isEmpty()) { if (flagNames.isEmpty()) {
logError(QString("Failed to read flag constants from %1").arg(flagsFilename)); logError(QString("Failed to read flag constants from %1").arg(flagsFilename));
return false; return false;
} }
@ -2192,12 +2142,11 @@ bool Project::readFlagNames() {
} }
bool Project::readVarNames() { bool Project::readVarNames() {
varNames->clear(); QStringList prefixes("\\bVAR_");
QStringList prefixes = (QStringList() << "\\bVAR_");
QString filename = "include/constants/vars.h"; QString filename = "include/constants/vars.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
parser.readCDefinesSorted(filename, prefixes, varNames); varNames = parser.readCDefinesSorted(filename, prefixes);
if (varNames->isEmpty()) { if (varNames.isEmpty()) {
logError(QString("Failed to read var constants from %1").arg(filename)); logError(QString("Failed to read var constants from %1").arg(filename));
return false; return false;
} }
@ -2205,12 +2154,11 @@ bool Project::readVarNames() {
} }
bool Project::readMovementTypes() { bool Project::readMovementTypes() {
movementTypes->clear(); QStringList prefixes("\\bMOVEMENT_TYPE_");
QStringList prefixes = (QStringList() << "\\bMOVEMENT_TYPE_");
QString filename = "include/constants/event_object_movement.h"; QString filename = "include/constants/event_object_movement.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
parser.readCDefinesSorted(filename, prefixes, movementTypes); movementTypes = parser.readCDefinesSorted(filename, prefixes);
if (movementTypes->isEmpty()) { if (movementTypes.isEmpty()) {
logError(QString("Failed to read movement type constants from %1").arg(filename)); logError(QString("Failed to read movement type constants from %1").arg(filename));
return false; return false;
} }
@ -2229,12 +2177,11 @@ bool Project::readInitialFacingDirections() {
} }
bool Project::readMapTypes() { bool Project::readMapTypes() {
mapTypes->clear(); QStringList prefixes("\\bMAP_TYPE_");
QStringList prefixes = (QStringList() << "\\bMAP_TYPE_");
QString filename = "include/constants/map_types.h"; QString filename = "include/constants/map_types.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
parser.readCDefinesSorted(filename, prefixes, mapTypes); mapTypes = parser.readCDefinesSorted(filename, prefixes);
if (mapTypes->isEmpty()) { if (mapTypes.isEmpty()) {
logError(QString("Failed to read map type constants from %1").arg(filename)); logError(QString("Failed to read map type constants from %1").arg(filename));
return false; return false;
} }
@ -2242,12 +2189,11 @@ bool Project::readMapTypes() {
} }
bool Project::readMapBattleScenes() { bool Project::readMapBattleScenes() {
mapBattleScenes->clear(); QStringList prefixes("\\bMAP_BATTLE_SCENE_");
QStringList prefixes = (QStringList() << "\\bMAP_BATTLE_SCENE_");
QString filename = "include/constants/map_types.h"; QString filename = "include/constants/map_types.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
parser.readCDefinesSorted("include/constants/map_types.h", prefixes, mapBattleScenes); mapBattleScenes = parser.readCDefinesSorted("include/constants/map_types.h", prefixes);
if (mapBattleScenes->isEmpty()) { if (mapBattleScenes.isEmpty()) {
logError(QString("Failed to read map battle scene constants from %1").arg(filename)); logError(QString("Failed to read map battle scene constants from %1").arg(filename));
return false; return false;
} }
@ -2255,12 +2201,11 @@ bool Project::readMapBattleScenes() {
} }
bool Project::readWeatherNames() { bool Project::readWeatherNames() {
weatherNames->clear(); QStringList prefixes("\\bWEATHER_");
QStringList prefixes = (QStringList() << "\\bWEATHER_");
QString filename = "include/constants/weather.h"; QString filename = "include/constants/weather.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
parser.readCDefinesSorted(filename, prefixes, weatherNames); weatherNames = parser.readCDefinesSorted(filename, prefixes);
if (weatherNames->isEmpty()) { if (weatherNames.isEmpty()) {
logError(QString("Failed to read weather constants from %1").arg(filename)); logError(QString("Failed to read weather constants from %1").arg(filename));
return false; return false;
} }
@ -2268,14 +2213,14 @@ bool Project::readWeatherNames() {
} }
bool Project::readCoordEventWeatherNames() { bool Project::readCoordEventWeatherNames() {
if (!projectConfig.getEventWeatherTriggerEnabled()) return true; if (!projectConfig.getEventWeatherTriggerEnabled())
return true;
coordEventWeatherNames->clear(); QStringList prefixes("\\bCOORD_EVENT_WEATHER_");
QStringList prefixes = (QStringList() << "\\bCOORD_EVENT_WEATHER_");
QString filename = "include/constants/weather.h"; QString filename = "include/constants/weather.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
parser.readCDefinesSorted(filename, prefixes, coordEventWeatherNames); coordEventWeatherNames = parser.readCDefinesSorted(filename, prefixes);
if (coordEventWeatherNames->isEmpty()) { if (coordEventWeatherNames.isEmpty()) {
logError(QString("Failed to read coord event weather constants from %1").arg(filename)); logError(QString("Failed to read coord event weather constants from %1").arg(filename));
return false; return false;
} }
@ -2283,14 +2228,14 @@ bool Project::readCoordEventWeatherNames() {
} }
bool Project::readSecretBaseIds() { bool Project::readSecretBaseIds() {
if (!projectConfig.getEventSecretBaseEnabled()) return true; if (!projectConfig.getEventSecretBaseEnabled())
return true;
secretBaseIds->clear(); QStringList prefixes("\\bSECRET_BASE_[A-Za-z0-9_]*_[0-9]+");
QStringList prefixes = (QStringList() << "\\bSECRET_BASE_[A-Za-z0-9_]*_[0-9]+");
QString filename = "include/constants/secret_bases.h"; QString filename = "include/constants/secret_bases.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
parser.readCDefinesSorted(filename, prefixes, secretBaseIds); secretBaseIds = parser.readCDefinesSorted(filename, prefixes);
if (secretBaseIds->isEmpty()) { if (secretBaseIds.isEmpty()) {
logError(QString("Failed to read secret base id constants from %1").arg(filename)); logError(QString("Failed to read secret base id constants from %1").arg(filename));
return false; return false;
} }
@ -2298,12 +2243,11 @@ bool Project::readSecretBaseIds() {
} }
bool Project::readBgEventFacingDirections() { bool Project::readBgEventFacingDirections() {
bgEventFacingDirections->clear(); QStringList prefixes("\\bBG_EVENT_PLAYER_FACING_");
QStringList prefixes = (QStringList() << "\\bBG_EVENT_PLAYER_FACING_");
QString filename = "include/constants/event_bg.h"; QString filename = "include/constants/event_bg.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
parser.readCDefinesSorted(filename, prefixes, bgEventFacingDirections); bgEventFacingDirections = parser.readCDefinesSorted(filename, prefixes);
if (bgEventFacingDirections->isEmpty()) { if (bgEventFacingDirections.isEmpty()) {
logError(QString("Failed to read bg event facing direction constants from %1").arg(filename)); logError(QString("Failed to read bg event facing direction constants from %1").arg(filename));
return false; return false;
} }
@ -2311,12 +2255,11 @@ bool Project::readBgEventFacingDirections() {
} }
bool Project::readTrainerTypes() { bool Project::readTrainerTypes() {
trainerTypes->clear(); QStringList prefixes("\\bTRAINER_TYPE_");
QStringList prefixes = (QStringList() << "\\bTRAINER_TYPE_");
QString filename = "include/constants/trainer_types.h"; QString filename = "include/constants/trainer_types.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
parser.readCDefinesSorted(filename, prefixes, trainerTypes); trainerTypes = parser.readCDefinesSorted(filename, prefixes);
if (trainerTypes->isEmpty()) { if (trainerTypes.isEmpty()) {
logError(QString("Failed to read trainer type constants from %1").arg(filename)); logError(QString("Failed to read trainer type constants from %1").arg(filename));
return false; return false;
} }
@ -2327,7 +2270,7 @@ bool Project::readMetatileBehaviors() {
this->metatileBehaviorMap.clear(); this->metatileBehaviorMap.clear();
this->metatileBehaviorMapInverse.clear(); this->metatileBehaviorMapInverse.clear();
QStringList prefixes = (QStringList() << "\\bMB_"); QStringList prefixes("\\bMB_");
QString filename = "include/constants/metatile_behaviors.h"; QString filename = "include/constants/metatile_behaviors.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
this->metatileBehaviorMap = parser.readCDefines(filename, prefixes); this->metatileBehaviorMap = parser.readCDefines(filename, prefixes);
@ -2343,8 +2286,7 @@ bool Project::readMetatileBehaviors() {
} }
QStringList Project::getSongNames() { QStringList Project::getSongNames() {
QStringList songDefinePrefixes; QStringList songDefinePrefixes{ "\\bSE_", "\\bMUS_" };
songDefinePrefixes << "\\bSE_" << "\\bMUS_";
QString filename = "include/constants/songs.h"; QString filename = "include/constants/songs.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
QMap<QString, int> songDefines = parser.readCDefines(filename, songDefinePrefixes); QMap<QString, int> songDefines = parser.readCDefines(filename, songDefinePrefixes);
@ -2355,8 +2297,7 @@ QStringList Project::getSongNames() {
} }
QMap<QString, int> Project::getEventObjGfxConstants() { QMap<QString, int> Project::getEventObjGfxConstants() {
QStringList eventObjGfxPrefixes; QStringList eventObjGfxPrefixes("\\bOBJ_EVENT_GFX_");
eventObjGfxPrefixes << "\\bOBJ_EVENT_GFX_";
QString filename = "include/constants/event_objects.h"; QString filename = "include/constants/event_objects.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
@ -2370,15 +2311,14 @@ bool Project::readMiscellaneousConstants() {
if (projectConfig.getEncounterJsonActive()) { if (projectConfig.getEncounterJsonActive()) {
QString filename = "include/constants/pokemon.h"; QString filename = "include/constants/pokemon.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
QMap<QString, int> pokemonDefines = parser.readCDefines(filename, QStringList() << "MIN_" << "MAX_"); QMap<QString, int> pokemonDefines = parser.readCDefines(filename, { "MIN_", "MAX_" });
miscConstants.insert("max_level_define", pokemonDefines.value("MAX_LEVEL") > pokemonDefines.value("MIN_LEVEL") ? pokemonDefines.value("MAX_LEVEL") : 100); miscConstants.insert("max_level_define", pokemonDefines.value("MAX_LEVEL") > pokemonDefines.value("MIN_LEVEL") ? pokemonDefines.value("MAX_LEVEL") : 100);
miscConstants.insert("min_level_define", pokemonDefines.value("MIN_LEVEL") < pokemonDefines.value("MAX_LEVEL") ? pokemonDefines.value("MIN_LEVEL") : 1); miscConstants.insert("min_level_define", pokemonDefines.value("MIN_LEVEL") < pokemonDefines.value("MAX_LEVEL") ? pokemonDefines.value("MIN_LEVEL") : 1);
} }
QString filename = "include/constants/global.h"; QString filename = "include/constants/global.h";
fileWatcher.addPath(root + "/" + filename); fileWatcher.addPath(root + "/" + filename);
QStringList definePrefixes; QStringList definePrefixes("\\bOBJECT_");
definePrefixes << "\\bOBJECT_";
QMap<QString, int> defines = parser.readCDefines(filename, definePrefixes); QMap<QString, int> defines = parser.readCDefines(filename, definePrefixes);
auto it = defines.find("OBJECT_EVENT_TEMPLATES_COUNT"); auto it = defines.find("OBJECT_EVENT_TEMPLATES_COUNT");

View file

@ -11,22 +11,18 @@ void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
int width = map->getBorderWidth(); int width = map->getBorderWidth();
int height = map->getBorderHeight(); int height = map->getBorderHeight();
Blockdata *oldBorder = map->layout->border->copy(); Blockdata oldBorder = map->layout->border;
for (int i = 0; i < selectionDimensions.x() && (i + pos.x()) < width; i++) { for (int i = 0; i < selectionDimensions.x() && (i + pos.x()) < width; i++) {
for (int j = 0; j < selectionDimensions.y() && (j + pos.y()) < height; j++) { for (int j = 0; j < selectionDimensions.y() && (j + pos.y()) < height; j++) {
int blockIndex = (j + pos.y()) * width + (i + pos.x()); int blockIndex = (j + pos.y()) * width + (i + pos.x());
uint16_t tile = selectedMetatiles->at(j * selectionDimensions.x() + i); uint16_t tile = selectedMetatiles->at(j * selectionDimensions.x() + i);
(*map->layout->border->blocks)[blockIndex].tile = tile; map->layout->border[blockIndex].tile = tile;
} }
} }
Blockdata *newBorder = map->layout->border->copy(); if (map->layout->border != oldBorder) {
if (newBorder->equals(oldBorder)) { map->editHistory.push(new PaintBorder(map, oldBorder, map->layout->border, 0));
delete newBorder;
delete oldBorder;
} else {
map->editHistory.push(new PaintBorder(map, oldBorder, newBorder, 0));
} }
emit borderMetatilesChanged(); emit borderMetatilesChanged();
@ -39,7 +35,6 @@ void BorderMetatilesPixmapItem::draw() {
int height = map->getBorderHeight(); int height = map->getBorderHeight();
QImage image(16 * width, 16 * height, QImage::Format_RGBA8888); QImage image(16 * width, 16 * height, QImage::Format_RGBA8888);
QPainter painter(&image); QPainter painter(&image);
QVector<Block> *blocks = map->layout->border->blocks;
for (int i = 0; i < width; i++) { for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) { for (int j = 0; j < height; j++) {
@ -47,7 +42,7 @@ void BorderMetatilesPixmapItem::draw() {
int y = j * 16; int y = j * 16;
int index = j * width + i; int index = j * width + i;
QImage metatile_image = getMetatileImage( QImage metatile_image = getMetatileImage(
blocks->value(index).tile, map->layout->border.value(index).tile,
map->layout->tileset_primary, map->layout->tileset_primary,
map->layout->tileset_secondary, map->layout->tileset_secondary,
map->metatileLayerOrder, map->metatileLayerOrder,

View file

@ -45,7 +45,7 @@ void CollisionPixmapItem::paint(QGraphicsSceneMouseEvent *event) {
if (event->type() == QEvent::GraphicsSceneMouseRelease) { if (event->type() == QEvent::GraphicsSceneMouseRelease) {
actionId_++; actionId_++;
} else if (map) { } else if (map) {
Blockdata *oldCollision = map->layout->blockdata->copy(); Blockdata oldCollision = map->layout->blockdata;
QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
@ -65,12 +65,8 @@ void CollisionPixmapItem::paint(QGraphicsSceneMouseEvent *event) {
map->setBlock(pos.x(), pos.y(), block, true); map->setBlock(pos.x(), pos.y(), block, true);
} }
Blockdata *newCollision = map->layout->blockdata->copy(); if (map->layout->blockdata != oldCollision) {
if (newCollision->equals(oldCollision)) { map->editHistory.push(new PaintCollision(map, oldCollision, map->layout->blockdata, actionId_));
delete newCollision;
delete oldCollision;
} else {
map->editHistory.push(new PaintCollision(map, oldCollision, newCollision, actionId_));
} }
} }
} }
@ -79,19 +75,15 @@ void CollisionPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) {
if (event->type() == QEvent::GraphicsSceneMouseRelease) { if (event->type() == QEvent::GraphicsSceneMouseRelease) {
this->actionId_++; this->actionId_++;
} else if (map) { } else if (map) {
Blockdata *oldCollision = map->layout->blockdata->copy(); Blockdata oldCollision = map->layout->blockdata;
QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
uint16_t collision = this->movementPermissionsSelector->getSelectedCollision(); uint16_t collision = this->movementPermissionsSelector->getSelectedCollision();
uint16_t elevation = this->movementPermissionsSelector->getSelectedElevation(); uint16_t elevation = this->movementPermissionsSelector->getSelectedElevation();
map->floodFillCollisionElevation(pos.x(), pos.y(), collision, elevation); map->floodFillCollisionElevation(pos.x(), pos.y(), collision, elevation);
Blockdata *newCollision = map->layout->blockdata->copy(); if (map->layout->blockdata != oldCollision) {
if (newCollision->equals(oldCollision)) { map->editHistory.push(new BucketFillCollision(map, oldCollision, map->layout->blockdata));
delete newCollision;
delete oldCollision;
} else {
map->editHistory.push(new BucketFillCollision(map, oldCollision, newCollision));
} }
} }
} }
@ -100,18 +92,14 @@ void CollisionPixmapItem::magicFill(QGraphicsSceneMouseEvent *event) {
if (event->type() == QEvent::GraphicsSceneMouseRelease) { if (event->type() == QEvent::GraphicsSceneMouseRelease) {
this->actionId_++; this->actionId_++;
} else if (map) { } else if (map) {
Blockdata *oldCollision = map->layout->blockdata->copy(); Blockdata oldCollision = map->layout->blockdata;
QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
uint16_t collision = this->movementPermissionsSelector->getSelectedCollision(); uint16_t collision = this->movementPermissionsSelector->getSelectedCollision();
uint16_t elevation = this->movementPermissionsSelector->getSelectedElevation(); uint16_t elevation = this->movementPermissionsSelector->getSelectedElevation();
map->magicFillCollisionElevation(pos.x(), pos.y(), collision, elevation); map->magicFillCollisionElevation(pos.x(), pos.y(), collision, elevation);
Blockdata *newCollision = map->layout->blockdata->copy(); if (map->layout->blockdata != oldCollision) {
if (newCollision->equals(oldCollision)) { map->editHistory.push(new MagicFillCollision(map, oldCollision, map->layout->blockdata));
delete newCollision;
delete oldCollision;
} else {
map->editHistory.push(new MagicFillCollision(map, oldCollision, newCollision));
} }
} }
} }

View file

@ -106,7 +106,7 @@ void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) {
} }
else if (this->event->get("event_type") == EventType::SecretBase) { else if (this->event->get("event_type") == EventType::SecretBase) {
QString baseId = this->event->get("secret_base_id"); QString baseId = this->event->get("secret_base_id");
QString destMap = editor->project->mapConstantsToMapNames->value("MAP_" + baseId.left(baseId.lastIndexOf("_"))); QString destMap = editor->project->mapConstantsToMapNames.value("MAP_" + baseId.left(baseId.lastIndexOf("_")));
if (destMap != NONE_MAP_NAME) { if (destMap != NONE_MAP_NAME) {
emit editor->warpEventDoubleClicked(destMap, "0"); emit editor->warpEventDoubleClicked(destMap, "0");
} }

View file

@ -36,7 +36,7 @@ MapImageExporter::MapImageExporter(QWidget *parent_, Editor *editor_, ImageExpor
this->ui->groupBox_Connections->setVisible(this->mode == ImageExporterMode::Normal); this->ui->groupBox_Connections->setVisible(this->mode == ImageExporterMode::Normal);
this->ui->groupBox_Timelapse->setVisible(this->mode == ImageExporterMode::Timelapse); this->ui->groupBox_Timelapse->setVisible(this->mode == ImageExporterMode::Timelapse);
this->ui->comboBox_MapSelection->addItems(*editor->project->mapNames); this->ui->comboBox_MapSelection->addItems(editor->project->mapNames);
this->ui->comboBox_MapSelection->setCurrentText(map->name); this->ui->comboBox_MapSelection->setCurrentText(map->name);
this->ui->comboBox_MapSelection->setEnabled(false);// TODO: allow selecting map from drop-down this->ui->comboBox_MapSelection->setEnabled(false);// TODO: allow selecting map from drop-down

View file

@ -76,7 +76,8 @@ void MapPixmapItem::shift(QGraphicsSceneMouseEvent *event) {
} }
void MapPixmapItem::shift(int xDelta, int yDelta, bool fromScriptCall) { void MapPixmapItem::shift(int xDelta, int yDelta, bool fromScriptCall) {
Blockdata *backupBlockdata = map->layout->blockdata->copy(); Blockdata oldMetatiles = map->layout->blockdata;
for (int i = 0; i < map->getWidth(); i++) for (int i = 0; i < map->getWidth(); i++)
for (int j = 0; j < map->getHeight(); j++) { for (int j = 0; j < map->getHeight(); j++) {
int destX = i + xDelta; int destX = i + xDelta;
@ -89,20 +90,12 @@ void MapPixmapItem::shift(int xDelta, int yDelta, bool fromScriptCall) {
destY %= map->getHeight(); destY %= map->getHeight();
int blockIndex = j * map->getWidth() + i; int blockIndex = j * map->getWidth() + i;
Block srcBlock = backupBlockdata->blocks->at(blockIndex); Block srcBlock = oldMetatiles.at(blockIndex);
map->setBlock(destX, destY, srcBlock); map->setBlock(destX, destY, srcBlock);
} }
if (!fromScriptCall) { if (!fromScriptCall && map->layout->blockdata != oldMetatiles) {
Blockdata *newMetatiles = map->layout->blockdata->copy(); map->editHistory.push(new ShiftMetatiles(map, oldMetatiles, map->layout->blockdata, actionId_));
if (newMetatiles->equals(backupBlockdata)) {
delete newMetatiles;
delete backupBlockdata;
} else {
map->editHistory.push(new ShiftMetatiles(map, backupBlockdata, newMetatiles, actionId_));
}
} else {
delete backupBlockdata;
} }
} }
@ -124,8 +117,7 @@ void MapPixmapItem::paintNormal(int x, int y, bool fromScriptCall) {
y = initialY + (yDiff / selectionDimensions.y()) * selectionDimensions.y(); y = initialY + (yDiff / selectionDimensions.y()) * selectionDimensions.y();
// for edit history // for edit history
Blockdata *oldMetatiles = nullptr; Blockdata oldMetatiles = !fromScriptCall ? map->layout->blockdata : Blockdata();
if (!fromScriptCall) oldMetatiles = map->layout->blockdata->copy();
for (int i = 0; i < selectionDimensions.x() && i + x < map->getWidth(); i++) for (int i = 0; i < selectionDimensions.x() && i + x < map->getWidth(); i++)
for (int j = 0; j < selectionDimensions.y() && j + y < map->getHeight(); j++) { for (int j = 0; j < selectionDimensions.y() && j + y < map->getHeight(); j++) {
@ -143,14 +135,8 @@ void MapPixmapItem::paintNormal(int x, int y, bool fromScriptCall) {
} }
} }
if (!fromScriptCall) { if (!fromScriptCall && map->layout->blockdata != oldMetatiles) {
Blockdata *newMetatiles = map->layout->blockdata->copy(); map->editHistory.push(new PaintMetatile(map, oldMetatiles, map->layout->blockdata, actionId_));
if (newMetatiles->equals(oldMetatiles)) {
delete newMetatiles;
delete oldMetatiles;
} else {
map->editHistory.push(new PaintMetatile(map, oldMetatiles, newMetatiles, actionId_));
}
} }
} }
@ -198,8 +184,7 @@ void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
} }
// for edit history // for edit history
Blockdata *oldMetatiles = nullptr; Blockdata oldMetatiles = !fromScriptCall ? map->layout->blockdata : Blockdata();
if (!fromScriptCall) oldMetatiles = map->layout->blockdata->copy();
// Fill the region with the open tile. // Fill the region with the open tile.
for (int i = 0; i <= 1; i++) for (int i = 0; i <= 1; i++)
@ -263,14 +248,8 @@ void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
map->setBlock(actualX, actualY, block, !fromScriptCall); map->setBlock(actualX, actualY, block, !fromScriptCall);
} }
if (!fromScriptCall) { if (!fromScriptCall && map->layout->blockdata != oldMetatiles) {
Blockdata *newMetatiles = map->layout->blockdata->copy(); map->editHistory.push(new PaintMetatile(map, oldMetatiles, map->layout->blockdata, actionId_));
if (newMetatiles->equals(oldMetatiles)) {
delete newMetatiles;
delete oldMetatiles;
} else {
map->editHistory.push(new PaintMetatile(map, oldMetatiles, newMetatiles, actionId_));
}
} }
} }
@ -287,7 +266,7 @@ void MapPixmapItem::lockNondominantAxis(QGraphicsSceneMouseEvent *event) {
this->straight_path_initial_x = pos.x(); this->straight_path_initial_x = pos.x();
this->straight_path_initial_y = pos.y(); this->straight_path_initial_y = pos.y();
} }
// Only lock an axis when the current position != initial // Only lock an axis when the current position != initial
int xDiff = pos.x() - this->straight_path_initial_x; int xDiff = pos.x() - this->straight_path_initial_x;
int yDiff = pos.y() - this->straight_path_initial_y; int yDiff = pos.y() - this->straight_path_initial_y;
@ -352,7 +331,7 @@ void MapPixmapItem::updateMetatileSelection(QGraphicsSceneMouseEvent *event) {
metatiles.append(block.tile); metatiles.append(block.tile);
} }
int blockIndex = y * map->getWidth() + x; int blockIndex = y * map->getWidth() + x;
block = map->layout->blockdata->blocks->at(blockIndex); block = map->layout->blockdata.at(blockIndex);
auto collision = block.collision; auto collision = block.collision;
auto elevation = block.elevation; auto elevation = block.elevation;
collisions.append(QPair<uint16_t, uint16_t>(collision, elevation)); collisions.append(QPair<uint16_t, uint16_t>(collision, elevation));
@ -421,8 +400,7 @@ void MapPixmapItem::magicFill(
return; return;
} }
Blockdata *oldMetatiles = nullptr; Blockdata oldMetatiles = !fromScriptCall ? map->layout->blockdata : Blockdata();
if (!fromScriptCall) oldMetatiles = map->layout->blockdata->copy();
bool setCollisions = selectedCollisions && selectedCollisions->length() == selectedMetatiles->length(); bool setCollisions = selectedCollisions && selectedCollisions->length() == selectedMetatiles->length();
uint16_t tile = block.tile; uint16_t tile = block.tile;
@ -446,14 +424,8 @@ void MapPixmapItem::magicFill(
} }
} }
if (!fromScriptCall) { if (!fromScriptCall && map->layout->blockdata != oldMetatiles) {
Blockdata *newMetatiles = map->layout->blockdata->copy(); map->editHistory.push(new MagicFillMetatile(map, oldMetatiles, map->layout->blockdata, actionId_));
if (newMetatiles->equals(oldMetatiles)) {
delete newMetatiles;
delete oldMetatiles;
} else {
map->editHistory.push(new MagicFillMetatile(map, oldMetatiles, newMetatiles, actionId_));
}
} }
} }
} }
@ -480,10 +452,7 @@ void MapPixmapItem::floodFill(
QList<QPair<uint16_t, uint16_t>> *selectedCollisions, QList<QPair<uint16_t, uint16_t>> *selectedCollisions,
bool fromScriptCall) { bool fromScriptCall) {
bool setCollisions = selectedCollisions && selectedCollisions->length() == selectedMetatiles->length(); bool setCollisions = selectedCollisions && selectedCollisions->length() == selectedMetatiles->length();
Blockdata *oldMetatiles = nullptr; Blockdata oldMetatiles = !fromScriptCall ? map->layout->blockdata : Blockdata();
if (!fromScriptCall) {
oldMetatiles = map->layout->blockdata->copy();
}
QSet<int> visited; QSet<int> visited;
QList<QPoint> todo; QList<QPoint> todo;
@ -533,14 +502,8 @@ void MapPixmapItem::floodFill(
} }
} }
if (!fromScriptCall) { if (!fromScriptCall && map->layout->blockdata != oldMetatiles) {
Blockdata *newMetatiles = map->layout->blockdata->copy(); map->editHistory.push(new BucketFillMetatile(map, oldMetatiles, map->layout->blockdata, actionId_));
if (newMetatiles->equals(oldMetatiles)) {
delete newMetatiles;
delete oldMetatiles;
} else {
map->editHistory.push(new BucketFillMetatile(map, oldMetatiles, newMetatiles, actionId_));
}
} }
} }
@ -563,8 +526,7 @@ void MapPixmapItem::floodFillSmartPath(int initialX, int initialY, bool fromScri
setCollisions = true; setCollisions = true;
} }
Blockdata *oldMetatiles = nullptr; Blockdata oldMetatiles = !fromScriptCall ? map->layout->blockdata : Blockdata();
if (!fromScriptCall) oldMetatiles = map->layout->blockdata->copy();
// Flood fill the region with the open tile. // Flood fill the region with the open tile.
QList<QPoint> todo; QList<QPoint> todo;
@ -659,14 +621,8 @@ void MapPixmapItem::floodFillSmartPath(int initialX, int initialY, bool fromScri
} }
} }
if (!fromScriptCall) { if (!fromScriptCall && map->layout->blockdata != oldMetatiles) {
Blockdata *newMetatiles = map->layout->blockdata->copy(); map->editHistory.push(new BucketFillMetatile(map, oldMetatiles, map->layout->blockdata, actionId_));
if (newMetatiles->equals(oldMetatiles)) {
delete newMetatiles;
delete oldMetatiles;
} else {
map->editHistory.push(new BucketFillMetatile(map, oldMetatiles, newMetatiles, actionId_));
}
} }
} }

View file

@ -89,8 +89,8 @@ void NewMapPopup::setDefaultValues(int groupNum, QString mapSec) {
ui->comboBox_NewMap_Primary_Tileset->addItems(tilesets.value("primary")); ui->comboBox_NewMap_Primary_Tileset->addItems(tilesets.value("primary"));
ui->comboBox_NewMap_Secondary_Tileset->addItems(tilesets.value("secondary")); ui->comboBox_NewMap_Secondary_Tileset->addItems(tilesets.value("secondary"));
ui->comboBox_NewMap_Group->addItems(*project->groupNames); ui->comboBox_NewMap_Group->addItems(project->groupNames);
ui->comboBox_NewMap_Group->setCurrentText(project->groupNames->at(groupNum)); ui->comboBox_NewMap_Group->setCurrentText(project->groupNames.at(groupNum));
if (existingLayout) { if (existingLayout) {
ui->spinBox_NewMap_Width->setValue(project->mapLayouts.value(layoutId)->width.toInt(nullptr, 0)); ui->spinBox_NewMap_Width->setValue(project->mapLayouts.value(layoutId)->width.toInt(nullptr, 0));
@ -110,7 +110,7 @@ void NewMapPopup::setDefaultValues(int groupNum, QString mapSec) {
ui->spinBox_NewMap_BorderHeight->setValue(DEFAULT_BORDER_HEIGHT); ui->spinBox_NewMap_BorderHeight->setValue(DEFAULT_BORDER_HEIGHT);
} }
ui->comboBox_NewMap_Type->addItems(*project->mapTypes); ui->comboBox_NewMap_Type->addItems(project->mapTypes);
ui->comboBox_NewMap_Location->addItems(project->mapSectionValueToName.values()); ui->comboBox_NewMap_Location->addItems(project->mapSectionValueToName.values());
if (!mapSec.isEmpty()) ui->comboBox_NewMap_Location->setCurrentText(mapSec); if (!mapSec.isEmpty()) ui->comboBox_NewMap_Location->setCurrentText(mapSec);
ui->checkBox_NewMap_Show_Location->setChecked(true); ui->checkBox_NewMap_Show_Location->setChecked(true);
@ -165,7 +165,7 @@ void NewMapPopup::setDefaultValues(int groupNum, QString mapSec) {
} }
void NewMapPopup::on_lineEdit_NewMap_Name_textChanged(const QString &text) { void NewMapPopup::on_lineEdit_NewMap_Name_textChanged(const QString &text) {
if (project->mapNames->contains(text)) { if (project->mapNames.contains(text)) {
QPalette palette = this->ui->lineEdit_NewMap_Name->palette(); QPalette palette = this->ui->lineEdit_NewMap_Name->palette();
QColor color = Qt::red; QColor color = Qt::red;
color.setAlpha(25); color.setAlpha(25);
@ -188,7 +188,7 @@ void NewMapPopup::on_pushButton_NewMap_Accept_clicked() {
// After stripping invalid characters, strip any leading digits. // After stripping invalid characters, strip any leading digits.
QString newMapName = this->ui->lineEdit_NewMap_Name->text().remove(QRegularExpression("[^a-zA-Z0-9_]+")); QString newMapName = this->ui->lineEdit_NewMap_Name->text().remove(QRegularExpression("[^a-zA-Z0-9_]+"));
newMapName.remove(QRegularExpression("^[0-9]*")); newMapName.remove(QRegularExpression("^[0-9]*"));
if (project->mapNames->contains(newMapName) || newMapName.isEmpty()) { if (project->mapNames.contains(newMapName) || newMapName.isEmpty()) {
newMapName = project->getNewMapName(); newMapName = project->getNewMapName();
} }
@ -197,9 +197,9 @@ void NewMapPopup::on_pushButton_NewMap_Accept_clicked() {
newMap->location = this->ui->comboBox_NewMap_Location->currentText(); newMap->location = this->ui->comboBox_NewMap_Location->currentText();
newMap->song = this->project->defaultSong; newMap->song = this->project->defaultSong;
newMap->requiresFlash = "0"; newMap->requiresFlash = "0";
newMap->weather = this->project->weatherNames->value(0, "WEATHER_NONE"); newMap->weather = this->project->weatherNames.value(0, "WEATHER_NONE");
newMap->show_location = this->ui->checkBox_NewMap_Show_Location->isChecked() ? "1" : "0"; newMap->show_location = this->ui->checkBox_NewMap_Show_Location->isChecked() ? "1" : "0";
newMap->battle_scene = this->project->mapBattleScenes->value(0, "MAP_BATTLE_SCENE_NORMAL"); newMap->battle_scene = this->project->mapBattleScenes.value(0, "MAP_BATTLE_SCENE_NORMAL");
if (this->existingLayout) { if (this->existingLayout) {
layout = this->project->mapLayouts.value(this->layoutId); layout = this->project->mapLayouts.value(this->layoutId);
@ -236,7 +236,7 @@ void NewMapPopup::on_pushButton_NewMap_Accept_clicked() {
newMap->floorNumber = this->ui->spinBox_NewMap_Floor_Number->value(); newMap->floorNumber = this->ui->spinBox_NewMap_Floor_Number->value();
} }
group = project->groupNames->indexOf(this->ui->comboBox_NewMap_Group->currentText()); group = project->groupNames.indexOf(this->ui->comboBox_NewMap_Group->currentText());
newMap->layout = layout; newMap->layout = layout;
newMap->layoutId = layout->id; newMap->layoutId = layout->id;
if (this->existingLayout) { if (this->existingLayout) {

View file

@ -215,7 +215,7 @@ void RegionMapEditor::displayRegionMapLayoutOptions() {
void RegionMapEditor::updateRegionMapLayoutOptions(int index) { void RegionMapEditor::updateRegionMapLayoutOptions(int index) {
this->ui->comboBox_RM_ConnectedMap->blockSignals(true); this->ui->comboBox_RM_ConnectedMap->blockSignals(true);
this->ui->lineEdit_RM_MapName->setText(this->project->mapSecToMapHoverName->value(this->region_map->map_squares[index].mapsec)); this->ui->lineEdit_RM_MapName->setText(this->project->mapSecToMapHoverName.value(this->region_map->map_squares[index].mapsec));
this->ui->comboBox_RM_ConnectedMap->setCurrentText(this->region_map->map_squares[index].mapsec); this->ui->comboBox_RM_ConnectedMap->setCurrentText(this->region_map->map_squares[index].mapsec);
this->ui->comboBox_RM_ConnectedMap->blockSignals(false); this->ui->comboBox_RM_ConnectedMap->blockSignals(false);
} }
@ -438,7 +438,7 @@ void RegionMapEditor::onRegionMapLayoutSelectedTileChanged(int index) {
this->currIndex = index; this->currIndex = index;
this->region_map_layout_item->highlightedTile = index; this->region_map_layout_item->highlightedTile = index;
if (this->region_map->map_squares[index].has_map) { if (this->region_map->map_squares[index].has_map) {
message = QString("\t %1").arg(this->project->mapSecToMapHoverName->value( message = QString("\t %1").arg(this->project->mapSecToMapHoverName.value(
this->region_map->map_squares[index].mapsec)).remove("{NAME_END}"); this->region_map->map_squares[index].mapsec)).remove("{NAME_END}");
} }
this->ui->statusbar->showMessage(message); this->ui->statusbar->showMessage(message);
@ -454,7 +454,7 @@ void RegionMapEditor::onRegionMapLayoutHoveredTileChanged(int index) {
if (x >= 0 && y >= 0) { if (x >= 0 && y >= 0) {
message = QString("(%1, %2)").arg(x).arg(y); message = QString("(%1, %2)").arg(x).arg(y);
if (this->region_map->map_squares[index].has_map) { if (this->region_map->map_squares[index].has_map) {
message += QString("\t %1").arg(this->project->mapSecToMapHoverName->value( message += QString("\t %1").arg(this->project->mapSecToMapHoverName.value(
this->region_map->map_squares[index].mapsec)).remove("{NAME_END}"); this->region_map->map_squares[index].mapsec)).remove("{NAME_END}");
} }
} }
@ -551,7 +551,7 @@ void RegionMapEditor::on_tabWidget_Region_Map_currentChanged(int index) {
} }
void RegionMapEditor::on_comboBox_RM_ConnectedMap_activated(const QString &mapsec) { void RegionMapEditor::on_comboBox_RM_ConnectedMap_activated(const QString &mapsec) {
this->ui->lineEdit_RM_MapName->setText(this->project->mapSecToMapHoverName->value(mapsec)); this->ui->lineEdit_RM_MapName->setText(this->project->mapSecToMapHoverName.value(mapsec));
onRegionMapLayoutSelectedTileChanged(this->currIndex);// re-draw layout image onRegionMapLayoutSelectedTileChanged(this->currIndex);// re-draw layout image
this->hasUnsavedChanges = true;// sometimes this is called for unknown reasons this->hasUnsavedChanges = true;// sometimes this is called for unknown reasons
} }