Merge branch 'master' into script-editing

This commit is contained in:
BigBahss 2021-04-16 07:28:09 -04:00
commit 61ffcc3259
58 changed files with 1344 additions and 1647 deletions

View file

@ -11,6 +11,9 @@ The **"Breaking Changes"** listed below are changes that have been made in the d
### Added
- Add ability to export map timelapse animated GIFs with `File -> Export Map Timelapse Image...`.
### Changed
- New events will be placed in the center of the current view of the map.
### Fixed
- Fix tileset palette editor crash that could occur when switching maps or tilesets with it open.

View file

@ -44,6 +44,7 @@ determined by this file.
``enable_heal_location_respawn_data``, 1 if ``pokefirered``, project, yes, Adds ``Respawn Map`` and ``Respawn NPC`` to Heal Location events
``enable_object_event_in_connection``, 1 if ``pokefirered``, project, yes, Adds ``In Connection`` to Object events
``enable_floor_number``, 1 if ``pokefirered``, project, yes, Adds ``Floor Number`` to map headers
``create_map_text_file``, 1 if not ``pokeemerald``, project, yes, A ``text.inc`` or ``text.pory`` file will be created for any new map
``enable_triple_layer_metatiles``, 0, project, yes, Enables triple-layer metatiles (See https://github.com/pret/pokeemerald/wiki/Triple-layer-metatiles)
``custom_scripts``, , project, yes, A list of script files to load into the scripting engine

View file

@ -2649,6 +2649,8 @@
<string>Help</string>
</property>
<addaction name="actionAbout_Porymap"/>
<addaction name="actionOpen_Log_File"/>
<addaction name="actionOpen_Config_Folder"/>
</widget>
<widget class="QMenu" name="menuOptions">
<property name="title">
@ -2944,6 +2946,16 @@
<string>Export Map Timelapse Image...</string>
</property>
</action>
<action name="actionOpen_Log_File">
<property name="text">
<string>Open Log File</string>
</property>
</action>
<action name="actionOpen_Config_Folder">
<property name="text">
<string>Open Config Folder</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View file

@ -210,13 +210,30 @@
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_Song">
<property name="text">
<string>Song</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="NoScrollComboBox" name="comboBox_Song">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The default background music for this map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_NewMap_Flyable">
<property name="text">
<string>Can Fly To</string>
</property>
</widget>
</item>
<item row="10" column="1">
<item row="11" column="1">
<widget class="QCheckBox" name="checkBox_NewMap_Flyable">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Whether to add a heal location to the new map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -226,14 +243,14 @@
</property>
</widget>
</item>
<item row="11" column="0">
<item row="12" column="0">
<widget class="QLabel" name="label_NewMap_Show_Location">
<property name="text">
<string>Show Location Name</string>
</property>
</widget>
</item>
<item row="11" column="1">
<item row="12" column="1">
<widget class="QCheckBox" name="checkBox_NewMap_Show_Location">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Whether or not to display the location name when the player enters the map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -243,14 +260,14 @@
</property>
</widget>
</item>
<item row="12" column="0">
<item row="13" column="0">
<widget class="QLabel" name="label_NewMap_Allow_Running">
<property name="text">
<string>Allow Running</string>
</property>
</widget>
</item>
<item row="12" column="1">
<item row="13" column="1">
<widget class="QCheckBox" name="checkBox_NewMap_Allow_Running">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Allows the player to use Running Shoes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -260,14 +277,14 @@
</property>
</widget>
</item>
<item row="13" column="0">
<item row="14" column="0">
<widget class="QLabel" name="label_NewMap_Allow_Biking">
<property name="text">
<string>Allow Biking</string>
</property>
</widget>
</item>
<item row="13" column="1">
<item row="14" column="1">
<widget class="QCheckBox" name="checkBox_NewMap_Allow_Biking">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Allows the player to use a Bike&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -277,14 +294,14 @@
</property>
</widget>
</item>
<item row="14" column="0">
<item row="15" column="0">
<widget class="QLabel" name="label_NewMap_Allow_Escape_Rope">
<property name="text">
<string>Allow Dig &amp; Escape Rope</string>
</property>
</widget>
</item>
<item row="14" column="1">
<item row="15" column="1">
<widget class="QCheckBox" name="checkBox_NewMap_Allow_Escape_Rope">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Allows the player to use Dig or Escape Rope&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -294,14 +311,14 @@
</property>
</widget>
</item>
<item row="15" column="0">
<item row="16" column="0">
<widget class="QLabel" name="label_NewMap_Floor_Number">
<property name="text">
<string>Floor Number</string>
</property>
</widget>
</item>
<item row="15" column="1">
<item row="16" column="1">
<widget class="QSpinBox" name="spinBox_NewMap_Floor_Number">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Floor number to be used for maps with elevators.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>

View file

@ -15,7 +15,7 @@ enum MapSortOrder {
Layout = 2,
};
class KeyValueConfigBase : public QObject
class KeyValueConfigBase
{
public:
void save();
@ -38,7 +38,6 @@ public:
}
virtual void reset() override {
this->recentProject = "";
this->recentMap = "";
this->mapSortOrder = MapSortOrder::Group;
this->prettyCursors = true;
this->collisionOpacity = 50;
@ -52,7 +51,6 @@ public:
this->textEditorGotoLine = "";
}
void setRecentProject(QString project);
void setRecentMap(QString map);
void setMapSortOrder(MapSortOrder order);
void setPrettyCursors(bool enabled);
void setMainGeometry(QByteArray, QByteArray, QByteArray, QByteArray);
@ -69,7 +67,6 @@ public:
void setTextEditorOpenFolder(const QString &command);
void setTextEditorGotoLine(const QString &command);
QString getRecentProject();
QString getRecentMap();
MapSortOrder getMapSortOrder();
bool getPrettyCursors();
QMap<QString, QByteArray> getMainGeometry();
@ -93,7 +90,6 @@ protected:
virtual void setUnreadKeys() override {};
private:
QString recentProject;
QString recentMap;
QString stringFromByteArray(QByteArray);
QByteArray bytesFromString(QString);
MapSortOrder mapSortOrder;
@ -136,6 +132,7 @@ public:
}
virtual void reset() override {
this->baseGameVersion = BaseGameVersion::pokeemerald;
this->recentMap = QString();
this->useEncounterJson = true;
this->useCustomBorderSize = false;
this->enableEventWeatherTrigger = true;
@ -145,12 +142,15 @@ public:
this->enableHealLocationRespawnData = false;
this->enableObjectEventInConnection = false;
this->enableFloorNumber = false;
this->createMapTextFile = false;
this->enableTripleLayerMetatiles = false;
this->customScripts.clear();
this->readKeys.clear();
}
void setBaseGameVersion(BaseGameVersion baseGameVersion);
BaseGameVersion getBaseGameVersion();
void setRecentMap(const QString &map);
QString getRecentMap();
void setEncounterJsonActive(bool active);
bool getEncounterJsonActive();
void setUsePoryScript(bool usePoryScript);
@ -173,6 +173,8 @@ public:
bool getObjectEventInConnectionEnabled();
void setFloorNumberEnabled(bool enable);
bool getFloorNumberEnabled();
void setCreateMapTextFileEnabled(bool enable);
bool getCreateMapTextFileEnabled();
void setTripleLayerMetatilesEnabled(bool enable);
bool getTripleLayerMetatilesEnabled();
void setCustomScripts(QList<QString> scripts);
@ -186,6 +188,7 @@ protected:
private:
BaseGameVersion baseGameVersion;
QString projectDir;
QString recentMap;
bool useEncounterJson;
bool usePoryScript;
bool useCustomBorderSize;
@ -196,6 +199,7 @@ private:
bool enableHealLocationRespawnData;
bool enableObjectEventInConnection;
bool enableFloorNumber;
bool createMapTextFile;
bool enableTripleLayerMetatiles;
QList<QString> customScripts;
QStringList readKeys;

View file

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

View file

@ -4,31 +4,13 @@
#include "block.h"
#include <QObject>
#include <QByteArray>
#include <QVector>
class Blockdata : public QObject
class Blockdata : public QVector<Block>
{
Q_OBJECT
public:
explicit Blockdata(QObject *parent = nullptr);
~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:
QByteArray serialize() const;
};
#endif // BLOCKDATA_H

View file

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

View file

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

View file

@ -47,7 +47,7 @@ public:
QString allowRunning;
QString allowBiking;
QString allowEscapeRope;
int floorNumber;
int floorNumber = 0;
QString battle_scene;
QString sharedEventsMap = "";
QString sharedScriptsMap = "";
@ -75,11 +75,11 @@ public:
int getBorderHeight();
QPixmap render(bool ignoreCache, MapLayout * fromLayout = nullptr);
QPixmap renderCollision(qreal opacity, bool ignoreCache);
bool mapBlockChanged(int i, Blockdata * cache);
bool borderBlockChanged(int i, Blockdata * cache);
bool mapBlockChanged(int i, const Blockdata &cache);
bool borderBlockChanged(int i, const Blockdata &cache);
void cacheBlockdata();
void cacheCollision();
Block *getBlock(int x, int y);
bool getBlock(int x, int y, Block *out);
void setBlock(int x, int y, Block block, bool enableScriptCallback = false);
void floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
void _floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);

View file

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

View file

@ -11,16 +11,17 @@ class Metatile
{
public:
Metatile();
Metatile(const Metatile &other) = default;
Metatile &operator=(const Metatile &other) = default;
public:
QList<Tile> *tiles = nullptr;
QList<Tile> tiles;
uint16_t behavior; // 8 bits RSE, 9 bits FRLG
uint8_t layerType;
uint8_t encounterType; // FRLG only
uint8_t terrainType; // FRLG only
QString label;
Metatile *copy();
void copyInPlace(Metatile*);
static int getBlockIndex(int);
static QPoint coordFromPixmapCoord(const QPointF &pixelCoord);
};

View file

@ -4,13 +4,9 @@
#include "metatile.h"
#include <QList>
#include <QString>
class MetatileParser
{
public:
MetatileParser();
QList<Metatile*> *parse(QString filepath, bool *error, bool primaryTileset);
};
namespace MetatileParser {
QList<Metatile*> parse(QString filepath, bool *error, bool primaryTileset);
}
#endif // METATILEPARSER_H

View file

@ -4,22 +4,10 @@
#include <QList>
#include <QRgb>
#include <QString>
class PaletteUtil
{
public:
PaletteUtil();
namespace PaletteUtil {
QList<QRgb> parse(QString filepath, bool *error);
void writeJASC(QString filepath, QVector<QRgb> colors, int offset, int nColors);
private:
QList<QRgb> parsePal(QString filepath, bool *error);
QList<QRgb> parseJASC(QString filepath, bool *error);
QList<QRgb> parseAdvanceMapPal(QString filepath, bool *error);
QList<QRgb> parseAdobeColorTable(QString filepath, bool *error);
QList<QRgb> parseTileLayerPro(QString filepath, bool *error);
QList<QRgb> parseAdvancePaletteEditor(QString filepath, bool *error);
int clampColorValue(int value);
};
}
#endif // PALETTEUTIL_H

View file

@ -39,21 +39,21 @@ public:
class ParseUtil
{
public:
ParseUtil();
void set_root(QString);
static QString readTextFile(QString);
void strip_comment(QString*);
QList<QStringList>* parseAsm(QString);
int evaluateDefine(QString, QMap<QString, int>*);
QStringList readCArray(QString text, QString label);
QMap<QString, QString> readNamedIndexCArray(QString text, QString label);
QString readCIncbin(QString text, QString label);
QMap<QString, int> readCDefines(QString filename, QStringList prefixes, QMap<QString, int> = QMap<QString, int>());
void readCDefinesSorted(QString, QStringList, QStringList*, QMap<QString, int> = QMap<QString, int>());
QList<QStringList>* getLabelMacros(QList<QStringList>*, QString);
QStringList* getLabelValues(QList<QStringList>*, QString);
bool tryParseJsonFile(QJsonDocument *out, QString filepath);
bool ensureFieldsExist(QJsonObject obj, QList<QString> fields);
ParseUtil() { };
void set_root(const QString &dir);
static QString readTextFile(const QString &path);
static int textFileLineCount(const QString &path);
QList<QStringList> parseAsm(const QString &filename);
int evaluateDefine(const QString&, const QMap<QString, int>&);
QStringList readCArray(const QString &text, const QString &label);
QMap<QString, QString> readNamedIndexCArray(const QString &text, const QString &label);
QString readCIncbin(const QString &text, const QString &label);
QMap<QString, int> readCDefines(const QString &filename, const QStringList &prefixes, QMap<QString, int> = { });
QStringList readCDefinesSorted(const QString&, const QStringList&, const QMap<QString, int>& = { });
QList<QStringList> getLabelMacros(const QList<QStringList>&, const QString&);
QStringList getLabelValues(const QList<QStringList>&, const QString&);
bool tryParseJsonFile(QJsonDocument *out, const QString &filepath);
bool ensureFieldsExist(const QJsonObject &obj, const QList<QString> &fields);
// 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.
@ -63,9 +63,9 @@ public:
static QStringList getGlobalScriptLabels(const QString &filePath);
static QStringList getGlobalRawScriptLabels(QString text);
static QStringList getGlobalPoryScriptLabels(QString text);
static QString &removeStringLiterals(QString &text);
static QString &removeLineComments(QString &text, const QString &commentSymbol);
static QString &removeLineComments(QString &text, const QStringList &commentSymbols);
static QString removeStringLiterals(QString text);
static QString removeLineComments(QString text, const QString &commentSymbol);
static QString removeLineComments(QString text, const QStringList &commentSymbols);
static QStringList splitShellCommand(QStringView command);
@ -73,10 +73,10 @@ private:
QString root;
QString text;
QString file;
QList<Token> tokenizeExpression(QString expression, QMap<QString, int>* knownIdentifiers);
QList<Token> generatePostfix(QList<Token> tokens);
int evaluatePostfix(QList<Token> postfix);
void error(QString message, QString expression);
QList<Token> tokenizeExpression(QString expression, const QMap<QString, int> &knownIdentifiers);
QList<Token> generatePostfix(const QList<Token> &tokens);
int evaluatePostfix(const QList<Token> &postfix);
void error(const QString &message, const QString &expression);
static const QRegularExpression re_incScriptLabel;
static const QRegularExpression re_globalIncScriptLabel;

View file

@ -79,15 +79,11 @@ public:
QString city_map_name;
};
class RegionMap : public QObject
class RegionMap
{
Q_OBJECT
public:
RegionMap() = default;
~RegionMap() {};
Project *project = nullptr;
QVector<RegionMapSquare> map_squares;

View file

@ -6,8 +6,20 @@
class Tile
{
public:
Tile() {}
Tile(int tile, bool xflip, bool yflip, int palette);
Tile() :
tile(0),
xflip(false),
yflip(false),
palette(0)
{ }
Tile(int tile, bool xflip, bool yflip, int palette) :
tile(tile),
xflip(xflip),
yflip(yflip),
palette(palette)
{ }
public:
int tile;
bool xflip;

View file

@ -9,7 +9,10 @@
class Tileset
{
public:
Tileset();
Tileset() = default;
Tileset(const Tileset &other);
Tileset &operator=(const Tileset &other);
public:
QString name;
QString is_compressed;
@ -24,14 +27,12 @@ public:
QString metatile_attrs_path;
QString tilesImagePath;
QImage tilesImage;
QList<QString> palettePaths;
QStringList palettePaths;
QList<QImage> *tiles = nullptr;
QList<Metatile*> *metatiles = nullptr;
QList<QList<QRgb>> *palettes = nullptr;
QList<QList<QRgb>> *palettePreviews = nullptr;
Tileset* copy();
QList<QImage> tiles;
QList<Metatile*> metatiles;
QList<QList<QRgb>> palettes;
QList<QList<QRgb>> palettePreviews;
static Tileset* getBlockTileset(int, Tileset*, Tileset*);
static Metatile* getMetatile(int, Tileset*, Tileset*);

View file

@ -60,7 +60,6 @@ public:
void displayCurrentMetatilesSelection();
void redrawCurrentMetatilesSelection();
void displayMovementPermissionSelector();
void displayElevationMetatiles();
void displayMapEvents();
void displayMapConnections();
void displayMapBorder();
@ -75,7 +74,6 @@ public:
void setEditingObjects();
void setEditingConnections();
void setMapEditingButtonsEnabled(bool enabled);
void clearWildMonTabWidgets();
void setCurrentConnectionDirection(QString curDirection);
void updateCurrentConnectionDirection(QString curDirection);
void setConnectionsVisibility(bool visible);
@ -99,7 +97,6 @@ public:
void selectMapEvent(DraggablePixmapItem *object);
void selectMapEvent(DraggablePixmapItem *object, bool toggle);
DraggablePixmapItem *addNewEvent(QString event_type);
Event* createNewEvent(QString event_type);
void deleteEvent(Event *);
void updateSelectedEvents();
void duplicateSelectedEvents();
@ -143,8 +140,6 @@ public:
qreal collisionOpacity = 0.5;
void objectsView_onMousePress(QMouseEvent *event);
void objectsView_onMouseMove(QMouseEvent *event);
void objectsView_onMouseRelease(QMouseEvent *event);
int getBorderDrawDistance(int dimension);
@ -154,6 +149,7 @@ public:
void shouldReselectEvents();
void scaleMapView(int);
void openInTextEditor(const QString &path, int lineNum = 0) const;
public slots:
void openMapScripts() const;
@ -177,18 +173,9 @@ private:
void updateMirroredConnectionMap(MapConnection*, QString);
void updateMirroredConnection(MapConnection*, QString, QString, bool isDelete = false);
void updateEncounterFields(EncounterFields newFields);
Event* createNewObjectEvent();
Event* createNewWarpEvent();
Event* createNewHealLocationEvent();
Event* createNewTriggerEvent();
Event* createNewWeatherTriggerEvent();
Event* createNewSignEvent();
Event* createNewHiddenItemEvent();
Event* createNewSecretBaseEvent();
QString getMovementPermissionText(uint16_t collision, uint16_t elevation);
QString getMetatileDisplayMessage(uint16_t metatileId);
bool eventLimitReached(Map *, QString);
void openInTextEditor(const QString &path, int lineNum = 0) const;
bool startDetachedProcess(const QString &command,
const QString &workingDirectory = QString(),
qint64 *pid = nullptr) const;

View file

@ -77,8 +77,8 @@ public:
Q_INVOKABLE void setPrimaryTilesetPalettes(QList<QList<QList<int>>> palettes);
Q_INVOKABLE void setSecondaryTilesetPalette(int paletteIndex, QList<QList<int>> colors);
Q_INVOKABLE void setSecondaryTilesetPalettes(QList<QList<QList<int>>> palettes);
QJSValue getTilesetPalette(QList<QList<QRgb>> *palettes, int paletteIndex);
QJSValue getTilesetPalettes(QList<QList<QRgb>> *palettes);
QJSValue getTilesetPalette(const QList<QList<QRgb>> &palettes, int paletteIndex);
QJSValue getTilesetPalettes(const QList<QList<QRgb>> &palettes);
Q_INVOKABLE QJSValue getPrimaryTilesetPalette(int paletteIndex);
Q_INVOKABLE QJSValue getPrimaryTilesetPalettes();
Q_INVOKABLE QJSValue getSecondaryTilesetPalette(int paletteIndex);
@ -222,6 +222,8 @@ private slots:
void on_toolButton_ExpandAll_clicked();
void on_toolButton_CollapseAll_clicked();
void on_actionAbout_Porymap_triggered();
void on_actionOpen_Log_File_triggered();
void on_actionOpen_Config_Folder_triggered();
void on_pushButton_AddCustomHeaderField_clicked();
void on_pushButton_DeleteCustomHeaderField_clicked();
void on_tableWidget_CustomHeaderFields_cellChanged(int row, int column);
@ -236,14 +238,14 @@ private slots:
private:
Ui::MainWindow *ui;
QLabel *label_MapRulerStatus;
TilesetEditor *tilesetEditor = nullptr;
RegionMapEditor *regionMapEditor = nullptr;
ShortcutsEditor *shortcutsEditor = nullptr;
MapImageExporter *mapImageExporter = nullptr;
QLabel *label_MapRulerStatus = nullptr;
QPointer<TilesetEditor> tilesetEditor = nullptr;
QPointer<RegionMapEditor> regionMapEditor = nullptr;
QPointer<ShortcutsEditor> shortcutsEditor = nullptr;
QPointer<MapImageExporter> mapImageExporter = nullptr;
QPointer<NewMapPopup> newmapprompt = nullptr;
QPointer<PreferenceEditor> preferenceEditor = nullptr;
FilterChildrenProxyModel *mapListProxyModel;
NewMapPopup *newmapprompt = nullptr;
PreferenceEditor *preferenceEditor = nullptr;
QStandardItemModel *mapListModel;
QList<QStandardItem*> *mapGroupItemsList;
QMap<QString, QModelIndex> mapListIndexes;

View file

@ -31,35 +31,37 @@ public:
Project(const Project &) = delete;
Project & operator = (const Project &) = delete;
inline QWidget *parentWidget() const { return static_cast<QWidget *>(parent()); }
public:
QString root;
QStringList *groupNames = nullptr;
QMap<QString, int> *mapGroups;
QStringList groupNames;
QMap<QString, int> mapGroups;
QList<QStringList> groupedMapNames;
QStringList *mapNames = nullptr;
QStringList mapNames;
QMap<QString, QVariant> miscConstants;
QList<HealLocation> healLocations;
QMap<QString, QString>* mapConstantsToMapNames;
QMap<QString, QString>* mapNamesToMapConstants;
QList<QString> mapLayoutsTable;
QList<QString> mapLayoutsTableMaster;
QMap<QString, QString> mapConstantsToMapNames;
QMap<QString, QString> mapNamesToMapConstants;
QStringList mapLayoutsTable;
QStringList mapLayoutsTableMaster;
QString layoutsLabel;
QMap<QString, MapLayout*> mapLayouts;
QMap<QString, MapLayout*> mapLayoutsMaster;
QMap<QString, QString> *mapSecToMapHoverName;
QMap<QString, QString> mapSecToMapHoverName;
QMap<QString, int> mapSectionNameToValue;
QMap<int, QString> mapSectionValueToName;
QStringList *itemNames = nullptr;
QStringList *flagNames = nullptr;
QStringList *varNames = nullptr;
QStringList *movementTypes = nullptr;
QStringList *mapTypes = nullptr;
QStringList *mapBattleScenes = nullptr;
QStringList *weatherNames = nullptr;
QStringList *coordEventWeatherNames = nullptr;
QStringList *secretBaseIds = nullptr;
QStringList *bgEventFacingDirections = nullptr;
QStringList *trainerTypes = nullptr;
QStringList itemNames;
QStringList flagNames;
QStringList varNames;
QStringList movementTypes;
QStringList mapTypes;
QStringList mapBattleScenes;
QStringList weatherNames;
QStringList coordEventWeatherNames;
QStringList secretBaseIds;
QStringList bgEventFacingDirections;
QStringList trainerTypes;
QStringList eventScriptLabels;
QMap<QString, int> metatileBehaviorMap;
QMap<int, QString> metatileBehaviorMapInverse;
@ -83,16 +85,16 @@ public:
DataQualifiers getDataQualifiers(QString, QString);
QMap<QString, DataQualifiers> dataQualifiers;
QMap<QString, Map*> *mapCache;
QMap<QString, Map*> mapCache;
Map* loadMap(QString);
Map* getMap(QString);
QMap<QString, Tileset*> *tilesetCache = nullptr;
QMap<QString, Tileset*> tilesetCache;
Tileset* loadTileset(QString, Tileset *tileset = nullptr);
Tileset* getTileset(QString, bool forceLoad = false);
QMap<QString, QStringList> tilesetLabels;
Blockdata* readBlockdata(QString);
Blockdata readBlockdata(QString);
bool loadBlockdata(Map*);
void saveTextFile(QString path, QString text);
@ -100,7 +102,6 @@ public:
void deleteFile(QString path);
bool readMapGroups();
Map* addNewMapToGroup(QString mapName, int groupNum);
Map* addNewMapToGroup(QString, int, Map*, bool);
QString getNewMapName();
QString getProjectTitle();
@ -130,7 +131,7 @@ public:
void saveLayoutBlockdata(Map*);
void saveLayoutBorder(Map*);
void writeBlockdata(QString, Blockdata*);
void writeBlockdata(QString, const Blockdata &);
void saveAllMaps();
void saveMap(Map*);
void saveAllDataStructures();
@ -222,7 +223,6 @@ private:
static int default_map_size;
static int max_object_events;
QWidget *parent;
QStringListModel *eventScriptLabelModel = nullptr;
QCompleter *eventScriptLabelCompleter = nullptr;

View file

@ -5,8 +5,7 @@
#include "metatileselector.h"
#include <QGraphicsPixmapItem>
class CurrentSelectedMetatilesPixmapItem : public QObject, public QGraphicsPixmapItem {
Q_OBJECT
class CurrentSelectedMetatilesPixmapItem : public QGraphicsPixmapItem {
public:
CurrentSelectedMetatilesPixmapItem(Map *map, MetatileSelector *metatileSelector) {
this->map = map;

View file

@ -33,7 +33,8 @@ public:
int last_y;
void updatePosition();
void move(int x, int y);
void move(int dx, int dy);
void moveTo(const QPoint &pos);
void emitPositionChanged();
void updatePixmap();
void bind(QComboBox *combo, QString key);

View file

@ -33,6 +33,7 @@ private:
Project *project;
void setDefaultValues(int, QString);
bool checkNewMapDimensions();
bool checkNewMapGroup();
private slots:
void on_pushButton_NewMap_Accept_clicked();

View file

@ -25,7 +25,6 @@ SOURCES += src/core/block.cpp \
src/core/metatileparser.cpp \
src/core/paletteutil.cpp \
src/core/parseutil.cpp \
src/core/tile.cpp \
src/core/tileset.cpp \
src/core/regionmap.cpp \
src/core/wildmoninfo.cpp \

View file

@ -109,8 +109,6 @@ QString PorymapConfig::getConfigFilepath() {
void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
if (key == "recent_project") {
this->recentProject = value;
} else if (key == "recent_map") {
this->recentMap = value;
} else if (key == "pretty_cursors") {
bool ok;
this->prettyCursors = value.toInt(&ok);
@ -202,7 +200,6 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
QMap<QString, QString> PorymapConfig::getKeyValueMap() {
QMap<QString, QString> map;
map.insert("recent_project", this->recentProject);
map.insert("recent_map", this->recentMap);
map.insert("pretty_cursors", this->prettyCursors ? "1" : "0");
map.insert("map_sort_order", mapSortOrderMap.value(this->mapSortOrder));
map.insert("main_window_geometry", stringFromByteArray(this->mainWindowGeometry));
@ -250,11 +247,6 @@ void PorymapConfig::setRecentProject(QString project) {
this->save();
}
void PorymapConfig::setRecentMap(QString map) {
this->recentMap = map;
this->save();
}
void PorymapConfig::setMapSortOrder(MapSortOrder order) {
this->mapSortOrder = order;
this->save();
@ -339,10 +331,6 @@ QString PorymapConfig::getRecentProject() {
return this->recentProject;
}
QString PorymapConfig::getRecentMap() {
return this->recentMap;
}
MapSortOrder PorymapConfig::getMapSortOrder() {
return this->mapSortOrder;
}
@ -453,6 +441,8 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
this->baseGameVersion = BaseGameVersion::pokeemerald;
logWarn(QString("Invalid config value for base_game_version: '%1'. Must be 'pokeruby', 'pokefirered' or 'pokeemerald'.").arg(value));
}
} else if (key == "recent_map") {
this->recentMap = value;
} else if (key == "use_encounter_json") {
bool ok;
this->useEncounterJson = value.toInt(&ok);
@ -513,6 +503,12 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
if (!ok) {
logWarn(QString("Invalid config value for enable_floor_number: '%1'. Must be 0 or 1.").arg(value));
}
} else if (key == "create_map_text_file") {
bool ok;
this->createMapTextFile = value.toInt(&ok);
if (!ok) {
logWarn(QString("Invalid config value for create_map_text_file: '%1'. Must be 0 or 1.").arg(value));
}
} else if (key == "enable_triple_layer_metatiles") {
bool ok;
this->enableTripleLayerMetatiles = value.toInt(&ok);
@ -545,11 +541,13 @@ void ProjectConfig::setUnreadKeys() {
if (!readKeys.contains("enable_heal_location_respawn_data")) this->enableHealLocationRespawnData = isPokefirered;
if (!readKeys.contains("enable_object_event_in_connection")) this->enableObjectEventInConnection = isPokefirered;
if (!readKeys.contains("enable_floor_number")) this->enableFloorNumber = isPokefirered;
if (!readKeys.contains("create_map_text_file")) this->createMapTextFile = (this->baseGameVersion != BaseGameVersion::pokeemerald);
}
QMap<QString, QString> ProjectConfig::getKeyValueMap() {
QMap<QString, QString> map;
map.insert("base_game_version", baseGameVersionMap.value(this->baseGameVersion));
map.insert("recent_map", this->recentMap);
map.insert("use_encounter_json", QString::number(this->useEncounterJson));
map.insert("use_poryscript", QString::number(this->usePoryScript));
map.insert("use_custom_border_size", QString::number(this->useCustomBorderSize));
@ -560,6 +558,7 @@ QMap<QString, QString> ProjectConfig::getKeyValueMap() {
map.insert("enable_heal_location_respawn_data", QString::number(this->enableHealLocationRespawnData));
map.insert("enable_object_event_in_connection", QString::number(this->enableObjectEventInConnection));
map.insert("enable_floor_number", QString::number(this->enableFloorNumber));
map.insert("create_map_text_file", QString::number(this->createMapTextFile));
map.insert("enable_triple_layer_metatiles", QString::number(this->enableTripleLayerMetatiles));
map.insert("custom_scripts", this->customScripts.join(","));
return map;
@ -584,7 +583,7 @@ void ProjectConfig::onNewConfigFileCreated() {
form.addRow(new QLabel("Game Version"), baseGameVersionComboBox);
QDialogButtonBox buttonBox(QDialogButtonBox::Ok, Qt::Horizontal, &dialog);
connect(&buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
QObject::connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
form.addRow(&buttonBox);
if (dialog.exec() == QDialog::Accepted) {
@ -600,6 +599,7 @@ void ProjectConfig::onNewConfigFileCreated() {
this->enableHealLocationRespawnData = isPokefirered;
this->enableObjectEventInConnection = isPokefirered;
this->enableFloorNumber = isPokefirered;
this->createMapTextFile = (this->baseGameVersion != BaseGameVersion::pokeemerald);
this->useEncounterJson = true;
this->usePoryScript = false;
this->enableTripleLayerMetatiles = false;
@ -623,6 +623,15 @@ BaseGameVersion ProjectConfig::getBaseGameVersion() {
return this->baseGameVersion;
}
void ProjectConfig::setRecentMap(const QString &map) {
this->recentMap = map;
this->save();
}
QString ProjectConfig::getRecentMap() {
return this->recentMap;
}
void ProjectConfig::setEncounterJsonActive(bool active) {
this->useEncounterJson = active;
this->save();
@ -713,6 +722,15 @@ bool ProjectConfig::getFloorNumberEnabled() {
return this->enableFloorNumber;
}
void ProjectConfig::setCreateMapTextFileEnabled(bool enable) {
this->createMapTextFile = enable;
this->save();
}
bool ProjectConfig::getCreateMapTextFileEnabled() {
return this->createMapTextFile;
}
void ProjectConfig::setTripleLayerMetatilesEnabled(bool enable) {
this->enableTripleLayerMetatiles = enable;
this->save();

View file

@ -1,38 +1,43 @@
#include "block.h"
Block::Block() : tile(0), collision(0), elevation(0) {
Block::Block() : tile(0), collision(0), elevation(0) { }
Block::Block(uint16_t tile, uint16_t collision, uint16_t elevation) :
tile(tile),
collision(collision),
elevation(elevation)
{ }
Block::Block(uint16_t word) :
tile(word & 0x3ff),
collision((word >> 10) & 0x3),
elevation((word >> 12) & 0xf)
{ }
Block::Block(const Block &other) :
tile(other.tile),
collision(other.collision),
elevation(other.elevation)
{ }
Block &Block::operator=(const Block &other) {
tile = other.tile;
collision = other.collision;
elevation = other.elevation;
return *this;
}
Block::Block(uint16_t tile, uint16_t collision, uint16_t elevation) {
this->tile = tile;
this->collision = collision;
this->elevation = elevation;
}
Block::Block(uint16_t word)
{
tile = word & 0x3ff;
collision = (word >> 10) & 0x3;
elevation = (word >> 12) & 0xf;
}
Block::Block(const Block &block) {
tile = block.tile;
collision = block.collision;
elevation = block.elevation;
}
uint16_t Block::rawValue() {
uint16_t Block::rawValue() const {
return static_cast<uint16_t>(
(tile & 0x3ff) +
((collision & 0x3) << 10) +
((elevation & 0xf) << 12));
}
bool Block::operator ==(Block other) {
bool Block::operator ==(Block other) const {
return (tile == other.tile) && (collision == other.collision) && (elevation == other.elevation);
}
bool Block::operator !=(Block other) {
bool Block::operator !=(Block other) const {
return !(operator ==(other));
}

View file

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

View file

@ -12,29 +12,25 @@ QString EventType::HiddenItem = "event_hidden_item";
QString EventType::SecretBase = "event_secret_base";
QString EventType::HealLocation = "event_heal_location";
Event::Event()
{
this->spriteWidth = 16;
this->spriteHeight = 16;
this->usingSprite = false;
}
Event::Event() :
spriteWidth(16),
spriteHeight(16),
usingSprite(false)
{ }
Event::Event(const Event& toCopy)
{
Event();
this->values = toCopy.values;
this->customValues = toCopy.customValues;
this->pixmap = toCopy.pixmap;
this->spriteWidth = toCopy.spriteWidth;
this->spriteHeight = toCopy.spriteHeight;
this->frame = toCopy.frame;
this->hFlip = toCopy.hFlip;
this->usingSprite = toCopy.usingSprite;
}
Event::Event(const Event& toCopy) :
values(toCopy.values),
customValues(toCopy.customValues),
pixmap(toCopy.pixmap),
spriteWidth(toCopy.spriteWidth),
spriteHeight(toCopy.spriteHeight),
frame(toCopy.frame),
hFlip(toCopy.hFlip),
usingSprite(toCopy.usingSprite)
{ }
Event::Event(QJsonObject obj, QString type)
Event::Event(QJsonObject obj, QString type) : Event()
{
Event();
this->put("event_type", type);
this->readCustomValues(obj);
}
@ -75,7 +71,7 @@ Event* Event::createNewObjectEvent(Project *project)
event->put("event_group_type", "object_event_group");
event->put("event_type", EventType::Object);
event->put("sprite", project->getEventObjGfxConstants().keys().first());
event->put("movement_type", project->movementTypes->first());
event->put("movement_type", project->movementTypes.first());
if (projectConfig.getObjectEventInConnectionEnabled()) {
event->put("in_connection", false);
}
@ -84,7 +80,7 @@ Event* Event::createNewObjectEvent(Project *project)
event->put("script_label", "NULL");
event->put("event_flag", "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("elevation", 3);
return event;
@ -122,7 +118,7 @@ Event* Event::createNewTriggerEvent(Project *project)
event->put("event_group_type", "coord_event_group");
event->put("event_type", EventType::Trigger);
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("elevation", 0);
return event;
@ -133,7 +129,7 @@ Event* Event::createNewWeatherTriggerEvent(Project *project)
Event *event = new Event;
event->put("event_group_type", "coord_event_group");
event->put("event_type", EventType::WeatherTrigger);
event->put("weather", project->coordEventWeatherNames->first());
event->put("weather", project->coordEventWeatherNames.first());
event->put("elevation", 0);
return event;
}
@ -143,7 +139,7 @@ Event* Event::createNewSignEvent(Project *project)
Event *event = new Event;
event->put("event_group_type", "bg_event_group");
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("elevation", 0);
return event;
@ -154,8 +150,8 @@ Event* Event::createNewHiddenItemEvent(Project *project)
Event *event = new Event;
event->put("event_group_type", "bg_event_group");
event->put("event_type", EventType::HiddenItem);
event->put("item", project->itemNames->first());
event->put("flag", project->flagNames->first());
event->put("item", project->itemNames.first());
event->put("flag", project->flagNames.first());
event->put("elevation", 3);
if (projectConfig.getHiddenItemQuantityEnabled()) {
event->put("quantity", 1);
@ -171,7 +167,7 @@ Event* Event::createNewSecretBaseEvent(Project *project)
Event *event = new Event;
event->put("event_group_type", "bg_event_group");
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);
return event;
}
@ -325,13 +321,13 @@ OrderedJson::object Event::buildObjectEventJSON()
return eventObj;
}
OrderedJson::object Event::buildWarpEventJSON(QMap<QString, QString> *mapNamesToMapConstants)
OrderedJson::object Event::buildWarpEventJSON(const QMap<QString, QString> &mapNamesToMapConstants)
{
OrderedJson::object warpObj;
warpObj["x"] = this->getU16("x");
warpObj["y"] = this->getU16("y");
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");
this->addCustomValuesTo(&warpObj);

View file

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

View file

@ -2,35 +2,12 @@
#include "tileset.h"
#include "project.h"
Metatile::Metatile()
{
tiles = new QList<Tile>;
}
Metatile* Metatile::copy() {
Metatile *copy = new Metatile;
copy->behavior = this->behavior;
copy->layerType = this->layerType;
copy->encounterType = this->encounterType;
copy->terrainType = this->terrainType;
copy->tiles = new QList<Tile>;
copy->label = this->label;
for (Tile tile : *this->tiles) {
copy->tiles->append(tile);
}
return copy;
}
void Metatile::copyInPlace(Metatile *other) {
this->behavior = other->behavior;
this->layerType = other->layerType;
this->encounterType = other->encounterType;
this->terrainType = other->terrainType;
this->label = other->label;
for (int i = 0; i < this->tiles->length(); i++) {
(*this->tiles)[i] = other->tiles->at(i);
}
}
Metatile::Metatile() :
behavior(0),
layerType(0),
encounterType(0),
terrainType(0)
{ }
int Metatile::getBlockIndex(int index) {
if (index < Project::getNumMetatilesPrimary()) {

View file

@ -2,19 +2,15 @@
#include "config.h"
#include "log.h"
#include "project.h"
#include <QString>
MetatileParser::MetatileParser()
{
}
QList<Metatile*> *MetatileParser::parse(QString filepath, bool *error, bool primaryTileset)
QList<Metatile*> MetatileParser::parse(QString filepath, bool *error, bool primaryTileset)
{
QFile file(filepath);
if (!file.open(QIODevice::ReadOnly)) {
*error = true;
logError(QString("Could not open Advance Map 1.92 Metatile .bvd file '%1': ").arg(filepath) + file.errorString());
return nullptr;
return { };
}
QByteArray in = file.readAll();
@ -23,7 +19,7 @@ QList<Metatile*> *MetatileParser::parse(QString filepath, bool *error, bool prim
if (in.length() < 9 || in.length() % 2 != 0) {
*error = true;
logError(QString("Advance Map 1.92 Metatile .bvd file '%1' is an unexpected size.").arg(filepath));
return nullptr;
return { };
}
int projIdOffset = in.length() - 4;
@ -46,7 +42,7 @@ QList<Metatile*> *MetatileParser::parse(QString filepath, bool *error, bool prim
} else {
*error = true;
logError(QString("Detected unsupported game type from .bvd file. Last 4 bytes of file must be 'RSE ' or 'FRLG'."));
return nullptr;
return { };
}
int maxMetatiles = primaryTileset ? Project::getNumMetatilesPrimary() : Project::getNumMetatilesTotal() - Project::getNumMetatilesPrimary();
@ -57,32 +53,32 @@ QList<Metatile*> *MetatileParser::parse(QString filepath, bool *error, bool prim
if (numMetatiles > maxMetatiles) {
*error = true;
logError(QString(".bvd file contains data for %1 metatiles, but the maximum number of metatiles is %2.").arg(numMetatiles).arg(maxMetatiles));
return nullptr;
return { };
}
if (numMetatiles < 1) {
*error = true;
logError(QString(".bvd file contains no data for metatiles."));
return nullptr;
return { };
}
int expectedFileSize = 4 + (metatileSize * numMetatiles) + (attrSize * numMetatiles) + 4;
if (in.length() != expectedFileSize) {
*error = true;
logError(QString(".bvd file is an unexpected size. Expected %1 bytes, but it has %2 bytes.").arg(expectedFileSize).arg(in.length()));
return nullptr;
return { };
}
QList<Metatile*> *metatiles = new QList<Metatile*>();
QList<Metatile*> metatiles;
for (int i = 0; i < numMetatiles; i++) {
Metatile *metatile = new Metatile();
QList<Tile> *tiles = new QList<Tile>();
QList<Tile> tiles;
for (int j = 0; j < 8; j++) {
int metatileOffset = 4 + i * metatileSize + j * 2;
uint16_t word = static_cast<uint16_t>(
static_cast<unsigned char>(in.at(metatileOffset)) |
(static_cast<unsigned char>(in.at(metatileOffset + 1)) << 8));
Tile tile(word & 0x3ff, (word >> 10) & 1, (word >> 11) & 1, (word >> 12) & 0xf);
tiles->append(tile);
tiles.append(tile);
}
int attrOffset = 4 + (numMetatiles * metatileSize) + (i * attrSize);
@ -104,7 +100,7 @@ QList<Metatile*> *MetatileParser::parse(QString filepath, bool *error, bool prim
metatile->terrainType = 0;
}
metatile->tiles = tiles;
metatiles->append(metatile);
metatiles.append(metatile);
}
return metatiles;

View file

@ -2,11 +2,15 @@
#include "log.h"
#include <QFileInfo>
#include <QRegularExpression>
#include <QString>
PaletteUtil::PaletteUtil()
{
}
QList<QRgb> parsePal(QString filepath, bool *error);
QList<QRgb> parseJASC(QString filepath, bool *error);
QList<QRgb> parseAdvanceMapPal(QString filepath, bool *error);
QList<QRgb> parseAdobeColorTable(QString filepath, bool *error);
QList<QRgb> parseTileLayerPro(QString filepath, bool *error);
QList<QRgb> parseAdvancePaletteEditor(QString filepath, bool *error);
int clampColorValue(int value);
QList<QRgb> PaletteUtil::parse(QString filepath, bool *error) {
QFileInfo info(filepath);
@ -34,7 +38,35 @@ QList<QRgb> PaletteUtil::parse(QString filepath, bool *error) {
return QList<QRgb>();
}
QList<QRgb> PaletteUtil::parsePal(QString filepath, bool *error) {
void PaletteUtil::writeJASC(QString filepath, QVector<QRgb> palette, int offset, int nColors) {
if (!nColors) {
logWarn(QString("Cannot save a palette with no colors."));
return;
}
if (offset > palette.size() || offset + nColors > palette.size()) {
logWarn("Palette offset out of range for color table.");
return;
}
QString text = "JASC-PAL\r\n0100\r\n";
text += QString::number(nColors) + "\r\n";
for (int i = offset; i < offset + nColors; i++) {
QRgb color = palette.at(i);
text += QString::number(qRed(color)) + " "
+ QString::number(qGreen(color)) + " "
+ QString::number(qBlue(color)) + "\r\n";
}
QFile file(filepath);
if (file.open(QIODevice::WriteOnly)) {
file.write(text.toUtf8());
} else {
logWarn(QString("Could not write to file '%1': ").arg(filepath) + file.errorString());
}
}
QList<QRgb> parsePal(QString filepath, bool *error) {
QFile file(filepath);
if (!file.open(QIODevice::ReadOnly)) {
*error = true;
@ -53,7 +85,7 @@ QList<QRgb> PaletteUtil::parsePal(QString filepath, bool *error) {
}
}
QList<QRgb> PaletteUtil::parseJASC(QString filepath, bool *error) {
QList<QRgb> parseJASC(QString filepath, bool *error) {
QFile file(filepath);
if (!file.open(QIODevice::ReadOnly)) {
*error = true;
@ -105,9 +137,9 @@ QList<QRgb> PaletteUtil::parseJASC(QString filepath, bool *error) {
return QList<QRgb>();
}
palette.append(qRgb(this->clampColorValue(red),
this->clampColorValue(green),
this->clampColorValue(blue)));
palette.append(qRgb(clampColorValue(red),
clampColorValue(green),
clampColorValue(blue)));
} else {
*error = true;
logError(QString("JASC palette file '%1' had an unexpected format. Invalid color '%2'.").arg(filepath).arg(line));
@ -120,7 +152,7 @@ QList<QRgb> PaletteUtil::parseJASC(QString filepath, bool *error) {
return palette;
}
QList<QRgb> PaletteUtil::parseAdvanceMapPal(QString filepath, bool *error) {
QList<QRgb> parseAdvanceMapPal(QString filepath, bool *error) {
QFile file(filepath);
if (!file.open(QIODevice::ReadOnly)) {
*error = true;
@ -143,16 +175,16 @@ QList<QRgb> PaletteUtil::parseAdvanceMapPal(QString filepath, bool *error) {
unsigned char red = static_cast<unsigned char>(in.at(i));
unsigned char green = static_cast<unsigned char>(in.at(i + 1));
unsigned char blue = static_cast<unsigned char>(in.at(i + 2));
palette.append(qRgb(this->clampColorValue(red),
this->clampColorValue(green),
this->clampColorValue(blue)));
palette.append(qRgb(clampColorValue(red),
clampColorValue(green),
clampColorValue(blue)));
i += 4;
}
return palette;
}
QList<QRgb> PaletteUtil::parseAdobeColorTable(QString filepath, bool *error) {
QList<QRgb> parseAdobeColorTable(QString filepath, bool *error) {
QFile file(filepath);
if (!file.open(QIODevice::ReadOnly)) {
*error = true;
@ -175,16 +207,16 @@ QList<QRgb> PaletteUtil::parseAdobeColorTable(QString filepath, bool *error) {
unsigned char red = static_cast<unsigned char>(in.at(i));
unsigned char green = static_cast<unsigned char>(in.at(i + 1));
unsigned char blue = static_cast<unsigned char>(in.at(i + 2));
palette.append(qRgb(this->clampColorValue(red),
this->clampColorValue(green),
this->clampColorValue(blue)));
palette.append(qRgb(clampColorValue(red),
clampColorValue(green),
clampColorValue(blue)));
i += 3;
}
return palette;
}
QList<QRgb> PaletteUtil::parseTileLayerPro(QString filepath, bool *error) {
QList<QRgb> parseTileLayerPro(QString filepath, bool *error) {
QFile file(filepath);
if (!file.open(QIODevice::ReadOnly)) {
*error = true;
@ -213,16 +245,16 @@ QList<QRgb> PaletteUtil::parseTileLayerPro(QString filepath, bool *error) {
unsigned char red = static_cast<unsigned char>(in.at(i));
unsigned char green = static_cast<unsigned char>(in.at(i + 1));
unsigned char blue = static_cast<unsigned char>(in.at(i + 2));
palette.append(qRgb(this->clampColorValue(red),
this->clampColorValue(green),
this->clampColorValue(blue)));
palette.append(qRgb(clampColorValue(red),
clampColorValue(green),
clampColorValue(blue)));
i += 3;
}
return palette;
}
QList<QRgb> PaletteUtil::parseAdvancePaletteEditor(QString filepath, bool *error) {
QList<QRgb> parseAdvancePaletteEditor(QString filepath, bool *error) {
QFile file(filepath);
if (!file.open(QIODevice::ReadOnly)) {
*error = true;
@ -258,44 +290,16 @@ QList<QRgb> PaletteUtil::parseAdvancePaletteEditor(QString filepath, bool *error
int red = (raw & 0x1F) * 8;
int green = ((raw >> 5) & 0x1F) * 8;
int blue = ((raw >> 10) & 0x1F) * 8;
palette.append(qRgb(this->clampColorValue(red),
this->clampColorValue(green),
this->clampColorValue(blue)));
palette.append(qRgb(clampColorValue(red),
clampColorValue(green),
clampColorValue(blue)));
}
file.close();
return palette;
}
void PaletteUtil::writeJASC(QString filepath, QVector<QRgb> palette, int offset, int nColors) {
if (!nColors) {
logWarn(QString("Cannot save a palette with no colors."));
return;
}
if (offset > palette.size() || offset + nColors > palette.size()) {
logWarn("Palette offset out of range for color table.");
return;
}
QString text = "JASC-PAL\r\n0100\r\n";
text += QString::number(nColors) + "\r\n";
for (int i = offset; i < offset + nColors; i++) {
QRgb color = palette.at(i);
text += QString::number(qRed(color)) + " "
+ QString::number(qGreen(color)) + " "
+ QString::number(qBlue(color)) + "\r\n";
}
QFile file(filepath);
if (file.open(QIODevice::WriteOnly)) {
file.write(text.toUtf8());
} else {
logWarn(QString("Could not write to file '%1': ").arg(filepath) + file.errorString());
}
}
int PaletteUtil::clampColorValue(int value) {
int clampColorValue(int value) {
if (value < 0) {
value = 0;
}

View file

@ -12,15 +12,11 @@ const QRegularExpression ParseUtil::re_poryScriptLabel("\\b(script)(\\((global|l
const QRegularExpression ParseUtil::re_globalPoryScriptLabel("\\b(script)(\\((global)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)");
const QRegularExpression ParseUtil::re_poryRawSection("\\b(raw)\\s*`(?<raw_script>[^`]*)");
ParseUtil::ParseUtil()
{
}
void ParseUtil::set_root(QString dir) {
void ParseUtil::set_root(const QString &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]"));
int lineNum = 0, colNum = 0;
for (QString line : lines) {
@ -31,21 +27,7 @@ void ParseUtil::error(QString message, QString expression) {
logError(QString("%1:%2:%3: %4").arg(file).arg(lineNum).arg(colNum).arg(message));
}
void ParseUtil::strip_comment(QString *line) {
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) {
QString ParseUtil::readTextFile(const QString &path) {
QFile file(path);
if (!file.open(QIODevice::ReadOnly)) {
logError(QString("Could not open '%1': ").arg(path) + file.errorString());
@ -55,50 +37,51 @@ QString ParseUtil::readTextFile(QString path) {
in.setCodec("UTF-8");
QString text = "";
while (!in.atEnd()) {
text += in.readLine() + "\n";
text += in.readLine() + '\n';
}
return text;
}
QList<QStringList>* ParseUtil::parseAsm(QString filename) {
QList<QStringList> *parsed = new QList<QStringList>;
int ParseUtil::textFileLineCount(const QString &path) {
const QString text = readTextFile(path);
return text.split('\n').count() + 1;
}
text = readTextFile(root + "/" + filename);
QStringList lines = text.split('\n');
for (QString line : lines) {
QString label;
strip_comment(&line);
if (line.trimmed().isEmpty()) {
} else if (line.contains(':')) {
label = line.left(line.indexOf(':'));
QStringList *list = new QStringList;
list->append(".label"); // This is not a real keyword. It's used only to make the output more regular.
list->append(label);
parsed->append(*list);
QList<QStringList> ParseUtil::parseAsm(const QString &filename) {
QList<QStringList> parsed;
text = readTextFile(root + '/' + filename);
const QStringList lines = removeLineComments(text, "@").split('\n');
for (const auto &line : lines) {
const QString trimmedLine = line.trimmed();
if (trimmedLine.isEmpty()) {
continue;
}
if (line.contains(':')) {
const QString label = line.left(line.indexOf(':'));
const QStringList list{ ".label", label }; // .label is not a real keyword. It's used only to make the output more regular.
parsed.append(list);
// There should not be anything else on the line.
// gas will raise a syntax error if there is.
} else {
line = line.trimmed();
//parsed->append(line.split(QRegExp("\\s*,\\s*")));
QString macro;
QStringList params;
int index = line.indexOf(QRegExp("\\s+"));
macro = line.left(index);
params = line.right(line.length() - index).trimmed().split(QRegExp("\\s*,\\s*"));
int index = trimmedLine.indexOf(QRegExp("\\s+"));
const QString macro = trimmedLine.left(index);
QStringList params(trimmedLine.right(trimmedLine.length() - index).trimmed().split(QRegExp("\\s*,\\s*")));
params.prepend(macro);
parsed->append(params);
parsed.append(params);
}
}
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> postfixExpression = generatePostfix(tokens);
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;
QStringList tokenTypes = (QStringList() << "hex" << "decimal" << "identifier" << "operator" << "leftparen" << "rightparen");
@ -115,8 +98,8 @@ QList<Token> ParseUtil::tokenizeExpression(QString expression, QMap<QString, int
QString token = match.captured(tokenType);
if (!token.isEmpty()) {
if (tokenType == "identifier") {
if (knownIdentifiers->contains(token)) {
QString actualToken = QString("%1").arg(knownIdentifiers->value(token));
if (knownIdentifiers.contains(token)) {
QString actualToken = QString("%1").arg(knownIdentifiers.value(token));
expression = expression.replace(0, token.length(), actualToken);
token = actualToken;
tokenType = "decimal";
@ -159,7 +142,7 @@ QMap<QString, int> Token::precedenceMap = QMap<QString, int>(
// Shunting-yard algorithm for generating postfix notation.
// 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;
QStack<Token> operatorStack;
for (Token token : tokens) {
@ -201,7 +184,7 @@ QList<Token> ParseUtil::generatePostfix(QList<Token> tokens) {
// Evaluate postfix expression.
// 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;
for (Token token : postfix) {
if (token.type == TokenClass::Operator && stack.size() > 1) {
@ -235,7 +218,7 @@ int ParseUtil::evaluatePostfix(QList<Token> postfix) {
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;
if (label.isNull()) {
@ -258,7 +241,10 @@ QString ParseUtil::readCIncbin(QString filename, QString label) {
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;
file = filename;
@ -287,7 +273,7 @@ QMap<QString, int> ParseUtil::readCDefines(QString filename, QStringList prefixe
QString name = match.captured("defineName");
QString expression = match.captured("defineValue");
if (expression == " ") continue;
int value = evaluateDefine(expression, &allDefines);
int value = evaluateDefine(expression, allDefines);
allDefines.insert(name, value);
for (QString prefix : prefixes) {
if (name.startsWith(prefix) || QRegularExpression(prefix).match(name).hasMatch()) {
@ -298,7 +284,10 @@ QMap<QString, int> ParseUtil::readCDefines(QString filename, QStringList prefixe
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);
// The defines should to be sorted by their underlying value, not alphabetically.
@ -307,10 +296,10 @@ void ParseUtil::readCDefinesSorted(QString filename, QStringList prefixes, QStri
for (QString defineName : defines.keys()) {
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;
if (label.isNull()) {
@ -336,13 +325,13 @@ QStringList ParseUtil::readCArray(QString filename, QString label) {
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);
QMap<QString, QString> map;
QRegularExpression re_text(QString(R"(\b%1\b\s*(\[?[^\]]*\])?\s*=\s*\{([^\}]*)\})").arg(label));
QString body = re_text.match(text).captured(2).replace(QRegularExpression("\\s*"), "");
QRegularExpression re("\\[(?<index>[A-Za-z0-9_]*)\\]=(?<value>&?[A-Za-z0-9_]*)");
QRegularExpressionMatchIterator iter = re.globalMatch(body);
@ -356,24 +345,23 @@ QMap<QString, QString> ParseUtil::readNamedIndexCArray(QString filename, QString
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;
QList<QStringList> *new_list = new QList<QStringList>;
for (int i = 0; i < list->length(); i++) {
QStringList params = list->value(i);
QString macro = params.value(0);
QList<QStringList> new_list;
for (const auto &params : list) {
const QString macro = params.value(0);
if (macro == ".label") {
if (params.value(1) == label) {
in_label = true;
} else if (in_label) {
// If nothing has been read yet, assume the label
// we're looking for is in a stack of labels.
if (new_list->length() > 0) {
if (new_list.length() > 0) {
break;
}
}
} else if (in_label) {
new_list->append(params);
new_list.append(params);
}
}
return new_list;
@ -381,32 +369,31 @@ QList<QStringList>* ParseUtil::getLabelMacros(QList<QStringList> *list, QString
// For if you don't care about filtering by macro,
// and just want all values associated with some label.
QStringList* ParseUtil::getLabelValues(QList<QStringList> *list, QString label) {
list = getLabelMacros(list, label);
QStringList *values = new QStringList;
for (int i = 0; i < list->length(); i++) {
QStringList params = list->value(i);
QString macro = params.value(0);
QStringList ParseUtil::getLabelValues(const QList<QStringList> &list, const QString &label) {
const QList<QStringList> labelMacros = getLabelMacros(list, label);
QStringList values;
for (const auto &params : labelMacros) {
const QString macro = params.value(0);
if (macro == ".align" || macro == ".ifdef" || macro == ".ifndef") {
continue;
}
for (int j = 1; j < params.length(); j++) {
values->append(params.value(j));
for (int i = 1; i < params.length(); i++) {
values.append(params.value(i));
}
}
return values;
}
bool ParseUtil::tryParseJsonFile(QJsonDocument *out, QString filepath) {
bool ParseUtil::tryParseJsonFile(QJsonDocument *out, const QString &filepath) {
QFile file(filepath);
if (!file.open(QIODevice::ReadOnly)) {
logError(QString("Error: Could not open %1 for reading").arg(filepath));
return false;
}
QByteArray data = file.readAll();
const QByteArray data = file.readAll();
QJsonParseError parseError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &parseError);
const QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &parseError);
file.close();
if (parseError.error != QJsonParseError::NoError) {
logError(QString("Error: Failed to parse json file %1: %2").arg(filepath).arg(parseError.errorString()));
@ -417,7 +404,7 @@ bool ParseUtil::tryParseJsonFile(QJsonDocument *out, QString filepath) {
return true;
}
bool ParseUtil::ensureFieldsExist(QJsonObject obj, QList<QString> fields) {
bool ParseUtil::ensureFieldsExist(const QJsonObject &obj, const QList<QString> &fields) {
for (QString field : fields) {
if (!obj.contains(field)) {
logError(QString("JSON object is missing field '%1'.").arg(field));
@ -440,8 +427,8 @@ int ParseUtil::getScriptLineNumber(const QString &filePath, const QString &scrip
}
int ParseUtil::getRawScriptLineNumber(QString text, const QString &scriptLabel) {
removeStringLiterals(text);
removeLineComments(text, "@");
text = removeStringLiterals(text);
text = removeLineComments(text, "@");
QRegularExpressionMatchIterator it = re_incScriptLabel.globalMatch(text);
while (it.hasNext()) {
@ -454,8 +441,8 @@ int ParseUtil::getRawScriptLineNumber(QString text, const QString &scriptLabel)
}
int ParseUtil::getPoryScriptLineNumber(QString text, const QString &scriptLabel) {
removeStringLiterals(text);
removeLineComments(text, {"//", "#"});
text = removeStringLiterals(text);
text = removeLineComments(text, {"//", "#"});
QRegularExpressionMatchIterator it = re_poryScriptLabel.globalMatch(text);
while (it.hasNext()) {
@ -516,19 +503,19 @@ QStringList ParseUtil::getGlobalPoryScriptLabels(QString text) {
return poryScriptLabels;
}
QString &ParseUtil::removeStringLiterals(QString &text) {
QString ParseUtil::removeStringLiterals(QString text) {
static const QRegularExpression 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 + "+.*");
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)
removeLineComments(text, commentSymbol);
text = removeLineComments(text, commentSymbol);
return text;
}

View file

@ -63,8 +63,7 @@ void RegionMap::saveTileImages() {
this->region_map_png_path = project->root + "/graphics/pokenav/region_map.png";
pngImage.save(pngPath());
PaletteUtil parser;
parser.writeJASC(project->root + "/graphics/pokenav/region_map.pal", pngImage.colorTable(), 0x70, 0x20);
PaletteUtil::writeJASC(project->root + "/graphics/pokenav/region_map.pal", pngImage.colorTable(), 0x70, 0x20);
}
region_map_png_needs_saving = false;
}
@ -130,7 +129,7 @@ bool RegionMap::readLayout() {
return false;
}
QMap<QString, QString> *qmap = new QMap<QString, QString>;
QMap<QString, QString> qmap;
bool mapNamesQualified = false, mapEntriesQualified = false;
@ -155,7 +154,7 @@ bool RegionMap::readLayout() {
QStringList entry = reAfter.match(line).captured(1).remove(" ").split(",");
QString mapsec = reBefore.match(line).captured(1);
QString insertion = entry[4].remove("sMapName_");
qmap->insert(mapsec, sMapNamesMap.value(insertion));
qmap.insert(mapsec, sMapNamesMap.value(insertion));
mapSecToMapEntry[mapsec] = {
// x y width height name
entry[0].toInt(), entry[1].toInt(), entry[2].toInt(), entry[3].toInt(), insertion
@ -265,7 +264,7 @@ void RegionMap::saveOptions(int id, QString sec, QString name, int x, int y) {
this->map_squares[index].mapsec = sec;
if (!name.isEmpty()) {
this->map_squares[index].map_name = name;
this->project->mapSecToMapHoverName->insert(sec, name);
this->project->mapSecToMapHoverName.insert(sec, name);
QString sName = fixCase(sec);
sMapNamesMap.insert(sName, name);
if (!mapSecToMapEntry.keys().contains(sec)) {

View file

@ -1,9 +0,0 @@
#include "tile.h"
Tile::Tile(int tile, bool xflip, bool yflip, int palette)
{
this->tile = tile;
this->xflip = xflip;
this->yflip = yflip;
this->palette = palette;
}

View file

@ -7,54 +7,56 @@
#include <QPainter>
#include <QImage>
Tileset::Tileset()
{
Tileset::Tileset(const Tileset &other)
: name(other.name),
is_compressed(other.is_compressed),
is_secondary(other.is_secondary),
padding(other.padding),
tiles_label(other.tiles_label),
palettes_label(other.palettes_label),
metatiles_label(other.metatiles_label),
metatiles_path(other.metatiles_path),
callback_label(other.callback_label),
metatile_attrs_label(other.metatile_attrs_label),
metatile_attrs_path(other.metatile_attrs_path),
tilesImagePath(other.tilesImagePath),
tilesImage(other.tilesImage),
palettePaths(other.palettePaths),
tiles(other.tiles),
palettes(other.palettes),
palettePreviews(other.palettePreviews)
{
for (auto *metatile : other.metatiles) {
metatiles.append(new Metatile(*metatile));
}
}
Tileset* Tileset::copy() {
Tileset *copy = new Tileset;
copy->name = this->name;
copy->is_compressed = this->is_compressed;
copy->is_secondary = this->is_secondary;
copy->padding = this->padding;
copy->tiles_label = this->tiles_label;
copy->palettes_label = this->palettes_label;
copy->metatiles_label = this->metatiles_label;
copy->metatiles_path = this->metatiles_path;
copy->callback_label = this->callback_label;
copy->metatile_attrs_label = this->metatile_attrs_label;
copy->metatile_attrs_path = this->metatile_attrs_path;
copy->tilesImage = this->tilesImage.copy();
copy->tilesImagePath = this->tilesImagePath;
for (int i = 0; i < this->palettePaths.length(); i++) {
copy->palettePaths.append(this->palettePaths.at(i));
Tileset &Tileset::operator=(const Tileset &other) {
name = other.name;
is_compressed = other.is_compressed;
is_secondary = other.is_secondary;
padding = other.padding;
tiles_label = other.tiles_label;
palettes_label = other.palettes_label;
metatiles_label = other.metatiles_label;
metatiles_path = other.metatiles_path;
callback_label = other.callback_label;
metatile_attrs_label = other.metatile_attrs_label;
metatile_attrs_path = other.metatile_attrs_path;
tilesImagePath = other.tilesImagePath;
tilesImage = other.tilesImage;
palettePaths = other.palettePaths;
tiles = other.tiles;
palettes = other.palettes;
palettePreviews = other.palettePreviews;
metatiles.clear();
for (auto *metatile : other.metatiles) {
metatiles.append(new Metatile(*metatile));
}
copy->tiles = new QList<QImage>;
for (QImage tile : *this->tiles) {
copy->tiles->append(tile.copy());
}
copy->metatiles = new QList<Metatile*>;
for (Metatile *metatile : *this->metatiles) {
copy->metatiles->append(metatile->copy());
}
copy->palettes = new QList<QList<QRgb>>;
for (QList<QRgb> palette : *this->palettes) {
QList<QRgb> copyPalette;
for (QRgb color : palette) {
copyPalette.append(color);
}
copy->palettes->append(copyPalette);
}
copy->palettePreviews = new QList<QList<QRgb>>;
for (QList<QRgb> palette : *this->palettePreviews) {
QList<QRgb> copyPalette;
for (QRgb color : palette) {
copyPalette.append(color);
}
copy->palettePreviews->append(copyPalette);
}
return copy;
return *this;
}
Tileset* Tileset::getBlockTileset(int metatile_index, Tileset *primaryTileset, Tileset *secondaryTileset) {
@ -68,21 +70,20 @@ Tileset* Tileset::getBlockTileset(int metatile_index, Tileset *primaryTileset, T
Metatile* Tileset::getMetatile(int index, Tileset *primaryTileset, Tileset *secondaryTileset) {
Tileset *tileset = Tileset::getBlockTileset(index, primaryTileset, secondaryTileset);
int local_index = Metatile::getBlockIndex(index);
if (!tileset || !tileset->metatiles) {
if (!tileset) {
return nullptr;
}
Metatile *metatile = tileset->metatiles->value(local_index, nullptr);
return metatile;
return tileset->metatiles.value(local_index, nullptr);
}
bool Tileset::metatileIsValid(uint16_t metatileId, Tileset *primaryTileset, Tileset *secondaryTileset) {
if (metatileId >= Project::getNumMetatilesTotal())
return false;
if (metatileId < Project::getNumMetatilesPrimary() && metatileId >= primaryTileset->metatiles->length())
if (metatileId < Project::getNumMetatilesPrimary() && metatileId >= primaryTileset->metatiles.length())
return false;
if (metatileId >= Project::getNumMetatilesPrimary() + secondaryTileset->metatiles->length())
if (metatileId >= Project::getNumMetatilesPrimary() + secondaryTileset->metatiles.length())
return false;
return true;
@ -92,11 +93,11 @@ QList<QList<QRgb>> Tileset::getBlockPalettes(Tileset *primaryTileset, Tileset *s
QList<QList<QRgb>> palettes;
auto primaryPalettes = useTruePalettes ? primaryTileset->palettes : primaryTileset->palettePreviews;
for (int i = 0; i < Project::getNumPalettesPrimary(); i++) {
palettes.append(primaryPalettes->at(i));
palettes.append(primaryPalettes.at(i));
}
auto secondaryPalettes = useTruePalettes ? secondaryTileset->palettes : secondaryTileset->palettePreviews;
for (int i = Project::getNumPalettesPrimary(); i < Project::getNumPalettesTotal(); i++) {
palettes.append(secondaryPalettes->at(i));
palettes.append(secondaryPalettes.at(i));
}
return palettes;
}
@ -107,8 +108,8 @@ QList<QRgb> Tileset::getPalette(int paletteId, Tileset *primaryTileset, Tileset
? primaryTileset
: secondaryTileset;
auto palettes = useTruePalettes ? tileset->palettes : tileset->palettePreviews;
for (int i = 0; i < palettes->at(paletteId).length(); i++) {
paletteTable.append(palettes->at(paletteId).at(i));
for (int i = 0; i < palettes.at(paletteId).length(); i++) {
paletteTable.append(palettes.at(paletteId).at(i));
}
return paletteTable;
}

View file

@ -316,7 +316,7 @@ void Editor::addNewWildMonGroup(QWidget *window) {
dialog.accept();
}
});
connect(&buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
form.addRow(&buttonBox);
if (dialog.exec() == QDialog::Accepted) {
@ -511,8 +511,8 @@ void Editor::configureEncounterJSON(QWidget *window) {
QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
connect(&buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
connect(&buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
// lambda: Get a QStringList of the existing field names.
auto getFieldNames = [&tempFields]() {
@ -552,8 +552,8 @@ void Editor::configureEncounterJSON(QWidget *window) {
QDialog newNameDialog(nullptr, Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
newNameDialog.setWindowModality(Qt::NonModal);
QDialogButtonBox newFieldButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &newNameDialog);
connect(&newFieldButtonBox, SIGNAL(accepted()), &newNameDialog, SLOT(accept()));
connect(&newFieldButtonBox, SIGNAL(rejected()), &newNameDialog, SLOT(reject()));
connect(&newFieldButtonBox, &QDialogButtonBox::accepted, &newNameDialog, &QDialog::accept);
connect(&newFieldButtonBox, &QDialogButtonBox::rejected, &newNameDialog, &QDialog::reject);
QLineEdit *newNameEdit = new QLineEdit;
newNameEdit->setClearButtonEnabled(true);
@ -726,11 +726,11 @@ void Editor::populateConnectionMapPickers() {
ui->comboBox_EmergeMap->blockSignals(true);
ui->comboBox_ConnectedMap->clear();
ui->comboBox_ConnectedMap->addItems(*project->mapNames);
ui->comboBox_ConnectedMap->addItems(project->mapNames);
ui->comboBox_DiveMap->clear();
ui->comboBox_DiveMap->addItems(*project->mapNames);
ui->comboBox_DiveMap->addItems(project->mapNames);
ui->comboBox_EmergeMap->clear();
ui->comboBox_EmergeMap->addItems(*project->mapNames);
ui->comboBox_EmergeMap->addItems(project->mapNames);
ui->comboBox_ConnectedMap->blockSignals(false);
ui->comboBox_DiveMap->blockSignals(true);
@ -959,7 +959,7 @@ void Editor::onHoveredMapMetatileChanged(const QPoint &pos) {
if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles
&& pos.x() >= 0 && pos.x() < map->getWidth() && pos.y() >= 0 && pos.y() < map->getHeight()) {
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")
.arg(pos.x())
.arg(pos.y())
@ -989,8 +989,8 @@ void Editor::onHoveredMapMovementPermissionChanged(int x, int y) {
if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles
&& x >= 0 && x < map->getWidth() && y >= 0 && y < map->getHeight()) {
int blockIndex = y * map->getWidth() + x;
uint16_t collision = map->layout->blockdata->blocks->at(blockIndex).collision;
uint16_t elevation = map->layout->blockdata->blocks->at(blockIndex).elevation;
uint16_t collision = map->layout->blockdata.at(blockIndex).collision;
uint16_t elevation = map->layout->blockdata.at(blockIndex).elevation;
QString message = QString("X: %1, Y: %2, %3")
.arg(x)
.arg(y)
@ -1320,12 +1320,12 @@ void Editor::displayMetatileSelector() {
scene_metatiles = new QGraphicsScene;
if (!metatile_selector_item) {
metatile_selector_item = new MetatileSelector(8, map);
connect(metatile_selector_item, SIGNAL(hoveredMetatileSelectionChanged(uint16_t)),
this, SLOT(onHoveredMetatileSelectionChanged(uint16_t)));
connect(metatile_selector_item, SIGNAL(hoveredMetatileSelectionCleared()),
this, SLOT(onHoveredMetatileSelectionCleared()));
connect(metatile_selector_item, SIGNAL(selectedMetatilesChanged()),
this, SLOT(onSelectedMetatilesChanged()));
connect(metatile_selector_item, &MetatileSelector::hoveredMetatileSelectionChanged,
this, &Editor::onHoveredMetatileSelectionChanged);
connect(metatile_selector_item, &MetatileSelector::hoveredMetatileSelectionCleared,
this, &Editor::onHoveredMetatileSelectionCleared);
connect(metatile_selector_item, &MetatileSelector::selectedMetatilesChanged,
this, &Editor::onSelectedMetatilesChanged);
metatile_selector_item->select(0);
} else {
metatile_selector_item->setMap(map);
@ -1337,16 +1337,11 @@ void Editor::displayMetatileSelector() {
void Editor::displayMapMetatiles() {
map_item = new MapPixmapItem(map, this->metatile_selector_item, this->settings);
connect(map_item, SIGNAL(mouseEvent(QGraphicsSceneMouseEvent*,MapPixmapItem*)),
this, SLOT(mouseEvent_map(QGraphicsSceneMouseEvent*,MapPixmapItem*)));
connect(map_item, SIGNAL(startPaint(QGraphicsSceneMouseEvent*,MapPixmapItem*)),
this, SLOT(onMapStartPaint(QGraphicsSceneMouseEvent*,MapPixmapItem*)));
connect(map_item, SIGNAL(endPaint(QGraphicsSceneMouseEvent*,MapPixmapItem*)),
this, SLOT(onMapEndPaint(QGraphicsSceneMouseEvent*,MapPixmapItem*)));
connect(map_item, SIGNAL(hoveredMapMetatileChanged(const QPoint&)),
this, SLOT(onHoveredMapMetatileChanged(const QPoint&)));
connect(map_item, SIGNAL(hoveredMapMetatileCleared()),
this, SLOT(onHoveredMapMetatileCleared()));
connect(map_item, &MapPixmapItem::mouseEvent, this, &Editor::mouseEvent_map);
connect(map_item, &MapPixmapItem::startPaint, this, &Editor::onMapStartPaint);
connect(map_item, &MapPixmapItem::endPaint, this, &Editor::onMapEndPaint);
connect(map_item, &MapPixmapItem::hoveredMapMetatileChanged, this, &Editor::onHoveredMapMetatileChanged);
connect(map_item, &MapPixmapItem::hoveredMapMetatileCleared, this, &Editor::onHoveredMapMetatileCleared);
map_item->draw(true);
scene->addItem(map_item);
@ -1366,13 +1361,13 @@ void Editor::displayMapMovementPermissions() {
scene->removeItem(collision_item);
delete collision_item;
}
collision_item = new CollisionPixmapItem(map, this->movement_permissions_selector_item, this->metatile_selector_item, this->settings, &this->collisionOpacity);
connect(collision_item, SIGNAL(mouseEvent(QGraphicsSceneMouseEvent*,CollisionPixmapItem*)),
this, SLOT(mouseEvent_collision(QGraphicsSceneMouseEvent*,CollisionPixmapItem*)));
connect(collision_item, SIGNAL(hoveredMapMovementPermissionChanged(int, int)),
this, SLOT(onHoveredMapMovementPermissionChanged(int, int)));
connect(collision_item, SIGNAL(hoveredMapMovementPermissionCleared()),
this, SLOT(onHoveredMapMovementPermissionCleared()));
collision_item = new CollisionPixmapItem(map, this->movement_permissions_selector_item,
this->metatile_selector_item, this->settings, &this->collisionOpacity);
connect(collision_item, &CollisionPixmapItem::mouseEvent, this, &Editor::mouseEvent_collision);
connect(collision_item, &CollisionPixmapItem::hoveredMapMovementPermissionChanged,
this, &Editor::onHoveredMapMovementPermissionChanged);
connect(collision_item, &CollisionPixmapItem::hoveredMapMovementPermissionCleared,
this, &Editor::onHoveredMapMovementPermissionCleared);
collision_item->draw(true);
scene->addItem(collision_item);
@ -1389,7 +1384,8 @@ void Editor::displayBorderMetatiles() {
selected_border_metatiles_item->draw();
scene_selected_border_metatiles->addItem(selected_border_metatiles_item);
connect(selected_border_metatiles_item, SIGNAL(borderMetatilesChanged()), this, SLOT(onBorderMetatilesChanged()));
connect(selected_border_metatiles_item, &BorderMetatilesPixmapItem::borderMetatilesChanged,
this, &Editor::onBorderMetatilesChanged);
}
void Editor::displayCurrentMetatilesSelection() {
@ -1421,10 +1417,10 @@ void Editor::displayMovementPermissionSelector() {
scene_collision_metatiles = new QGraphicsScene;
if (!movement_permissions_selector_item) {
movement_permissions_selector_item = new MovementPermissionsSelector();
connect(movement_permissions_selector_item, SIGNAL(hoveredMovementPermissionChanged(uint16_t, uint16_t)),
this, SLOT(onHoveredMovementPermissionChanged(uint16_t, uint16_t)));
connect(movement_permissions_selector_item, SIGNAL(hoveredMovementPermissionCleared()),
this, SLOT(onHoveredMovementPermissionCleared()));
connect(movement_permissions_selector_item, &MovementPermissionsSelector::hoveredMovementPermissionChanged,
this, &Editor::onHoveredMovementPermissionChanged);
connect(movement_permissions_selector_item, &MovementPermissionsSelector::hoveredMovementPermissionCleared,
this, &Editor::onHoveredMovementPermissionCleared);
movement_permissions_selector_item->select(0, 3);
}
@ -1540,9 +1536,12 @@ void Editor::createConnectionItem(MapConnection* connection, bool hide) {
connection_edit_item->setY(y);
connection_edit_item->setZValue(-1);
scene->addItem(connection_edit_item);
connect(connection_edit_item, SIGNAL(connectionMoved(MapConnection*)), this, SLOT(onConnectionMoved(MapConnection*)));
connect(connection_edit_item, SIGNAL(connectionItemSelected(ConnectionPixmapItem*)), this, SLOT(onConnectionItemSelected(ConnectionPixmapItem*)));
connect(connection_edit_item, SIGNAL(connectionItemDoubleClicked(ConnectionPixmapItem*)), this, SLOT(onConnectionItemDoubleClicked(ConnectionPixmapItem*)));
connect(connection_edit_item, &ConnectionPixmapItem::connectionMoved,
this, &Editor::onConnectionMoved);
connect(connection_edit_item, &ConnectionPixmapItem::connectionItemSelected,
this, &Editor::onConnectionItemSelected);
connect(connection_edit_item, &ConnectionPixmapItem::connectionItemDoubleClicked,
this, &Editor::onConnectionItemDoubleClicked);
connection_edit_items.append(connection_edit_item);
}
@ -1679,7 +1678,7 @@ void Editor::updateConnectionOffset(int offset) {
}
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));
return;
}
@ -1715,9 +1714,9 @@ void Editor::addNewConnection() {
}
// Don't connect the map to itself.
QString defaultMapName = project->mapNames->first();
QString defaultMapName = project->mapNames.first();
if (defaultMapName == map->name) {
defaultMapName = project->mapNames->value(1);
defaultMapName = project->mapNames.value(1);
}
MapConnection* newConnection = new MapConnection;
@ -1825,7 +1824,7 @@ void Editor::updateEmergeMap(QString mapName) {
}
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));
return;
}
@ -2078,7 +2077,6 @@ bool Editor::startDetachedProcess(const QString &command, const QString &working
logInfo("Executing command: " + command);
QProcess process;
#ifdef Q_OS_WIN
// Windows is WeirdChamp
QStringList arguments = ParseUtil::splitShellCommand(command);
const QString program = arguments.takeFirst();
QFileInfo programFileInfo(program);

View file

@ -40,7 +40,6 @@
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
label_MapRulerStatus(nullptr),
selectedObject(nullptr),
selectedWarp(nullptr),
selectedTrigger(nullptr),
@ -84,6 +83,8 @@ void MainWindow::setWindowDisabled(bool disabled) {
ui->action_Exit->setDisabled(false);
ui->menuHelp->setDisabled(false);
ui->actionAbout_Porymap->setDisabled(false);
ui->actionOpen_Log_File->setDisabled(false);
ui->actionOpen_Config_Folder->setDisabled(false);
if (!disabled)
togglePreferenceSpecificUi();
}
@ -187,11 +188,11 @@ void MainWindow::initCustomUI() {
void MainWindow::initExtraSignals() {
// Right-clicking on items in the map list tree view brings up a context menu.
ui->mapList->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->mapList, SIGNAL(customContextMenuRequested(const QPoint &)),
this, SLOT(onOpenMapListContextMenu(const QPoint &)));
connect(ui->mapList, &QTreeView::customContextMenuRequested,
this, &MainWindow::onOpenMapListContextMenu);
// other signals
connect(ui->newEventToolButton, SIGNAL(newEventAdded(QString)), this, SLOT(addNewEvent(QString)));
connect(ui->newEventToolButton, &NewEventToolButton::newEventAdded, this, &MainWindow::addNewEvent);
connect(ui->tabWidget_EventType, &QTabWidget::currentChanged, this, &MainWindow::eventTabChanged);
// Change pages on wild encounter groups
@ -228,12 +229,12 @@ void MainWindow::initExtraSignals() {
void MainWindow::initEditor() {
this->editor = new Editor(ui);
connect(this->editor, SIGNAL(objectsChanged()), this, SLOT(updateObjects()));
connect(this->editor, SIGNAL(selectedObjectsChanged()), this, SLOT(updateSelectedObjects()));
connect(this->editor, SIGNAL(loadMapRequested(QString, QString)), this, SLOT(onLoadMapRequested(QString, QString)));
connect(this->editor, SIGNAL(warpEventDoubleClicked(QString,QString)), this, SLOT(openWarpMap(QString,QString)));
connect(this->editor, SIGNAL(currentMetatilesSelectionChanged()), this, SLOT(currentMetatilesSelectionChanged()));
connect(this->editor, SIGNAL(wildMonDataChanged()), this, SLOT(onWildMonDataChanged()));
connect(this->editor, &Editor::objectsChanged, this, &MainWindow::updateObjects);
connect(this->editor, &Editor::selectedObjectsChanged, this, &MainWindow::updateSelectedObjects);
connect(this->editor, &Editor::loadMapRequested, this, &MainWindow::onLoadMapRequested);
connect(this->editor, &Editor::warpEventDoubleClicked, this, &MainWindow::openWarpMap);
connect(this->editor, &Editor::currentMetatilesSelectionChanged, this, &MainWindow::currentMetatilesSelectionChanged);
connect(this->editor, &Editor::wildMonDataChanged, this, &MainWindow::onWildMonDataChanged);
connect(this->editor, &Editor::mapRulerStatusChanged, this, &MainWindow::onMapRulerStatusChanged);
connect(ui->toolButton_Open_Scripts, &QToolButton::pressed, this->editor, &Editor::openMapScripts);
connect(ui->actionOpen_Project_in_Text_Editor, &QAction::triggered, this->editor, &Editor::openProjectInTextEditor);
@ -490,9 +491,9 @@ bool MainWindow::openProject(QString dir) {
if (!already_open) {
editor->closeProject();
editor->project = new Project(this);
QObject::connect(editor->project, SIGNAL(reloadProject()), this, SLOT(on_action_Reload_Project_triggered()));
QObject::connect(editor->project, SIGNAL(mapCacheCleared()), this, SLOT(onMapCacheCleared()));
QObject::connect(editor->project, &Project::uncheckMonitorFilesAction, [this] () { ui->actionMonitor_Project_Files->setChecked(false); });
QObject::connect(editor->project, &Project::reloadProject, this, &MainWindow::on_action_Reload_Project_triggered);
QObject::connect(editor->project, &Project::mapCacheCleared, this, &MainWindow::onMapCacheCleared);
QObject::connect(editor->project, &Project::uncheckMonitorFilesAction, [this]() { ui->actionMonitor_Project_Files->setChecked(false); });
on_actionMonitor_Project_Files_triggered(porymapConfig.getMonitorFiles());
editor->project->set_root(dir);
success = loadDataStructures()
@ -539,7 +540,7 @@ QString MainWindow::getDefaultMap() {
if (editor && editor->project) {
QList<QStringList> names = editor->project->groupedMapNames;
if (!names.isEmpty()) {
QString recentMap = porymapConfig.getRecentMap();
QString recentMap = projectConfig.getRecentMap();
if (!recentMap.isNull() && recentMap.length() > 0) {
for (int i = 0; i < names.length(); i++) {
if (names.value(i).contains(recentMap)) {
@ -566,8 +567,8 @@ QString MainWindow::getExistingDirectory(QString dir) {
void MainWindow::on_action_Open_Project_triggered()
{
QString recent = ".";
if (!porymapConfig.getRecentMap().isNull() && porymapConfig.getRecentMap().length() > 0) {
recent = porymapConfig.getRecentMap();
if (!projectConfig.getRecentMap().isEmpty()) {
recent = projectConfig.getRecentMap();
}
QString dir = getExistingDirectory(recent);
if (!dir.isEmpty()) {
@ -622,8 +623,8 @@ bool MainWindow::setMap(QString map_name, bool scrollTreeView) {
showWindowTitle();
connect(editor->map, SIGNAL(mapChanged(Map*)), this, SLOT(onMapChanged(Map *)));
connect(editor->map, SIGNAL(mapNeedsRedrawing()), this, SLOT(onMapNeedsRedrawing()));
connect(editor->map, &Map::mapChanged, this, &MainWindow::onMapChanged);
connect(editor->map, &Map::mapNeedsRedrawing, this, &MainWindow::onMapNeedsRedrawing);
setRecentMap(map_name);
updateMapList();
@ -671,7 +672,7 @@ void MainWindow::refreshMapScene()
void MainWindow::openWarpMap(QString map_name, QString warp_num) {
// 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));
return;
}
@ -709,7 +710,7 @@ void MainWindow::openWarpMap(QString map_name, QString warp_num) {
}
void MainWindow::setRecentMap(QString mapName) {
porymapConfig.setRecentMap(mapName);
projectConfig.setRecentMap(mapName);
}
void MainWindow::displayMapProperties() {
@ -910,11 +911,11 @@ bool MainWindow::loadProjectCombos() {
ui->comboBox_SecondaryTileset->clear();
ui->comboBox_SecondaryTileset->addItems(tilesets.value("secondary"));
ui->comboBox_Weather->clear();
ui->comboBox_Weather->addItems(*project->weatherNames);
ui->comboBox_Weather->addItems(project->weatherNames);
ui->comboBox_BattleScene->clear();
ui->comboBox_BattleScene->addItems(*project->mapBattleScenes);
ui->comboBox_BattleScene->addItems(project->mapBattleScenes);
ui->comboBox_Type->clear();
ui->comboBox_Type->addItems(*project->mapTypes);
ui->comboBox_Type->addItems(project->mapTypes);
return true;
}
@ -946,8 +947,8 @@ void MainWindow::sortMapList() {
switch (mapSortOrder)
{
case MapSortOrder::Group:
for (int i = 0; i < project->groupNames->length(); i++) {
QString group_name = project->groupNames->value(i);
for (int i = 0; i < project->groupNames.length(); i++) {
QString group_name = project->groupNames.value(i);
QStandardItem *group = new QStandardItem;
group->setText(group_name);
group->setIcon(mapFolderIcon);
@ -982,7 +983,7 @@ void MainWindow::sortMapList() {
mapGroupItemsList->append(mapsec);
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);
for (int j = 0; j < names.length(); j++) {
QString map_name = names.value(j);
@ -1014,7 +1015,7 @@ void MainWindow::sortMapList() {
mapGroupItemsList->append(layoutItem);
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);
for (int j = 0; j < names.length(); j++) {
QString map_name = names.value(j);
@ -1065,21 +1066,21 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point)
QMenu* menu = new QMenu(this);
QActionGroup* actions = new QActionGroup(menu);
actions->addAction(menu->addAction("Add New Map to Group"))->setData(groupNum);
connect(actions, SIGNAL(triggered(QAction*)), this, SLOT(onAddNewMapToGroupClick(QAction*)));
connect(actions, &QActionGroup::triggered, this, &MainWindow::onAddNewMapToGroupClick);
menu->exec(QCursor::pos());
} else if (itemType == "map_sec") {
QString secName = selectedItem->data(Qt::UserRole).toString();
QMenu* menu = new QMenu(this);
QActionGroup* actions = new QActionGroup(menu);
actions->addAction(menu->addAction("Add New Map to Area"))->setData(secName);
connect(actions, SIGNAL(triggered(QAction*)), this, SLOT(onAddNewMapToAreaClick(QAction*)));
connect(actions, &QActionGroup::triggered, this, &MainWindow::onAddNewMapToAreaClick);
menu->exec(QCursor::pos());
} else if (itemType == "map_layout") {
QString layoutId = selectedItem->data(MapListUserRoles::TypeRole2).toString();
QMenu* menu = new QMenu(this);
QActionGroup* actions = new QActionGroup(menu);
actions->addAction(menu->addAction("Add New Map with Layout"))->setData(layoutId);
connect(actions, SIGNAL(triggered(QAction*)), this, SLOT(onAddNewMapToLayoutClick(QAction*)));
connect(actions, &QActionGroup::triggered, this, &MainWindow::onAddNewMapToLayoutClick);
menu->exec(QCursor::pos());
}
}
@ -1105,10 +1106,10 @@ void MainWindow::onAddNewMapToLayoutClick(QAction* triggeredAction)
void MainWindow::onNewMapCreated() {
QString newMapName = this->newmapprompt->map->name;
int newMapGroup = this->newmapprompt->group;
Map *newMap_ = this->newmapprompt->map;
Map *newMap = this->newmapprompt->map;
bool existingLayout = this->newmapprompt->existingLayout;
Map *newMap = editor->project->addNewMapToGroup(newMapName, newMapGroup, newMap_, existingLayout);
newMap = editor->project->addNewMapToGroup(newMapName, newMapGroup, newMap, existingLayout);
logInfo(QString("Created a new map named %1.").arg(newMapName));
@ -1131,7 +1132,8 @@ void MainWindow::onNewMapCreated() {
editor->save();// required
}
disconnect(this->newmapprompt, SIGNAL(applied()), this, SLOT(onNewMapCreated()));
disconnect(this->newmapprompt, &NewMapPopup::applied, this, &MainWindow::onNewMapCreated);
delete newMap;
}
void MainWindow::openNewMapPopupWindow(int type, QVariant data) {
@ -1156,9 +1158,8 @@ void MainWindow::openNewMapPopupWindow(int type, QVariant data) {
this->newmapprompt->init(type, 0, QString(), data.toString());
break;
}
connect(this->newmapprompt, SIGNAL(applied()), this, SLOT(onNewMapCreated()));
connect(this->newmapprompt, &QObject::destroyed, [=](QObject *) { this->newmapprompt = nullptr; });
this->newmapprompt->setAttribute(Qt::WA_DeleteOnClose);
connect(this->newmapprompt, &NewMapPopup::applied, this, &MainWindow::onNewMapCreated);
this->newmapprompt->setAttribute(Qt::WA_DeleteOnClose);
}
void MainWindow::on_action_NewMap_triggered() {
@ -1206,65 +1207,58 @@ void MainWindow::on_actionNew_Tileset_triggered() {
}
directory.mkdir(fullDirectoryPath);
directory.mkdir(fullDirectoryPath + "/palettes");
Tileset *newSet = new Tileset();
newSet->name = createTilesetDialog->fullSymbolName;
newSet->tilesImagePath = fullDirectoryPath + "/tiles.png";
newSet->metatiles_path = fullDirectoryPath + "/metatiles.bin";
newSet->metatile_attrs_path = fullDirectoryPath + "/metatile_attributes.bin";
newSet->is_secondary = createTilesetDialog->isSecondary ? "TRUE" : "FALSE";
Tileset newSet;
newSet.name = createTilesetDialog->fullSymbolName;
newSet.tilesImagePath = fullDirectoryPath + "/tiles.png";
newSet.metatiles_path = fullDirectoryPath + "/metatiles.bin";
newSet.metatile_attrs_path = fullDirectoryPath + "/metatile_attributes.bin";
newSet.is_secondary = createTilesetDialog->isSecondary ? "TRUE" : "FALSE";
int numMetaTiles = createTilesetDialog->isSecondary ? (Project::getNumTilesTotal() - Project::getNumTilesPrimary()) : Project::getNumTilesPrimary();
QImage *tilesImage = new QImage(":/images/blank_tileset.png");
editor->project->loadTilesetTiles(newSet, *tilesImage);
newSet->metatiles = new QList<Metatile*>();
QImage tilesImage(":/images/blank_tileset.png");
editor->project->loadTilesetTiles(&newSet, tilesImage);
for(int i = 0; i < numMetaTiles; ++i) {
int tilesPerMetatile = projectConfig.getTripleLayerMetatilesEnabled() ? 12 : 8;
Metatile *mt = new Metatile();
for(int j = 0; j < tilesPerMetatile; ++j){
Tile *tile = new Tile();
Tile tile(0, false, false, 0);
//Create a checkerboard-style dummy tileset
if(((i / 8) % 2) == 0)
tile->tile = ((i % 2) == 0) ? 1 : 2;
tile.tile = ((i % 2) == 0) ? 1 : 2;
else
tile->tile = ((i % 2) == 1) ? 1 : 2;
tile->xflip = false;
tile->yflip = false;
tile->palette = 0;
mt->tiles->append(*tile);
tile.tile = ((i % 2) == 1) ? 1 : 2;
mt->tiles.append(tile);
}
mt->behavior = 0;
mt->layerType = 0;
mt->encounterType = 0;
mt->terrainType = 0;
newSet->metatiles->append(mt);
newSet.metatiles.append(mt);
}
newSet->palettes = new QList<QList<QRgb>>();
newSet->palettePreviews = new QList<QList<QRgb>>();
newSet->palettePaths = *new QList<QString>();
for(int i = 0; i < 16; ++i) {
QList<QRgb> *currentPal = new QList<QRgb>();
QList<QRgb> currentPal;
for(int i = 0; i < 16;++i) {
currentPal->append(qRgb(0,0,0));
currentPal.append(qRgb(0,0,0));
}
newSet->palettes->append(*currentPal);
newSet->palettePreviews->append(*currentPal);
newSet.palettes.append(currentPal);
newSet.palettePreviews.append(currentPal);
QString fileName = QString("%1.pal").arg(i, 2, 10, QLatin1Char('0'));
newSet->palettePaths.append(fullDirectoryPath+"/palettes/" + fileName);
newSet.palettePaths.append(fullDirectoryPath+"/palettes/" + fileName);
}
(*newSet->palettes)[0][1] = qRgb(255,0,255);
(*newSet->palettePreviews)[0][1] = qRgb(255,0,255);
newSet->is_compressed = "TRUE";
newSet->padding = "0";
editor->project->saveTilesetTilesImage(newSet);
editor->project->saveTilesetMetatiles(newSet);
editor->project->saveTilesetMetatileAttributes(newSet);
editor->project->saveTilesetPalettes(newSet);
newSet.palettes[0][1] = qRgb(255,0,255);
newSet.palettePreviews[0][1] = qRgb(255,0,255);
newSet.is_compressed = "TRUE";
newSet.padding = "0";
editor->project->saveTilesetTilesImage(&newSet);
editor->project->saveTilesetMetatiles(&newSet);
editor->project->saveTilesetMetatileAttributes(&newSet);
editor->project->saveTilesetPalettes(&newSet);
//append to tileset specific files
newSet->appendToHeaders(editor->project->root + "/data/tilesets/headers.inc", createTilesetDialog->friendlyName);
newSet->appendToGraphics(editor->project->root + "/data/tilesets/graphics.inc", createTilesetDialog->friendlyName, !createTilesetDialog->isSecondary);
newSet->appendToMetatiles(editor->project->root + "/data/tilesets/metatiles.inc", createTilesetDialog->friendlyName, !createTilesetDialog->isSecondary);
newSet.appendToHeaders(editor->project->root + "/data/tilesets/headers.inc", createTilesetDialog->friendlyName);
newSet.appendToGraphics(editor->project->root + "/data/tilesets/graphics.inc", createTilesetDialog->friendlyName, !createTilesetDialog->isSecondary);
newSet.appendToMetatiles(editor->project->root + "/data/tilesets/metatiles.inc", createTilesetDialog->friendlyName, !createTilesetDialog->isSecondary);
if(!createTilesetDialog->isSecondary) {
this->ui->comboBox_PrimaryTileset->addItem(createTilesetDialog->fullSymbolName);
} else {
@ -1348,10 +1342,10 @@ void MainWindow::drawMapListIcons(QAbstractItemModel *model) {
QVariant data = index.data(Qt::UserRole);
if (!data.isNull()) {
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));
map->setIcon(*mapIcon);
if (editor->project->mapCache->value(map_name)->hasUnsavedChanges()) {
if (editor->project->mapCache.value(map_name)->hasUnsavedChanges()) {
map->setIcon(*mapEditedIcon);
projectHasUnsavedChanges = true;
}
@ -1495,7 +1489,6 @@ void MainWindow::initShortcutsEditor() {
shortcutsEditor = new ShortcutsEditor(this);
connect(shortcutsEditor, &ShortcutsEditor::shortcutsSaved,
this, &MainWindow::applyUserShortcuts);
connect(shortcutsEditor, &QObject::destroyed, [=](QObject *) { shortcutsEditor = nullptr; });
connectSubEditorsToShortcutsEditor();
@ -1559,6 +1552,9 @@ void MainWindow::addNewEvent(QString event_type)
if (editor && editor->project) {
DraggablePixmapItem *object = editor->addNewEvent(event_type);
if (object) {
auto halfSize = ui->graphicsView_Map->size() / 2;
auto centerPos = ui->graphicsView_Map->mapToScene(halfSize.width(), halfSize.height());
object->moveTo(Metatile::coordFromPixmapCoord(centerPos));
updateObjects();
editor->selectMapEvent(object, false);
} else {
@ -1681,7 +1677,7 @@ void MainWindow::updateSelectedObjects() {
if (delta)
editor->map->editHistory.push(new EventMove(QList<Event *>() << item->event, delta, 0, x->getActionId()));
});
connect(item, SIGNAL(xChanged(int)), x, SLOT(setValue(int)));
connect(item, &DraggablePixmapItem::xChanged, x, &NoScrollSpinBox::setValue);
y->setValue(item->event->y());
connect(y, QOverload<int>::of(&QSpinBox::valueChanged), [this, item, y](int value) {
@ -1689,11 +1685,11 @@ void MainWindow::updateSelectedObjects() {
if (delta)
editor->map->editHistory.push(new EventMove(QList<Event *>() << item->event, 0, delta, y->getActionId()));
});
connect(item, SIGNAL(yChanged(int)), y, SLOT(setValue(int)));
connect(item, &DraggablePixmapItem::yChanged, y, &NoScrollSpinBox::setValue);
z->setValue(item->event->elevation());
connect(z, SIGNAL(valueChanged(QString)), item, SLOT(set_elevation(QString)));
connect(item, SIGNAL(elevationChanged(int)), z, SLOT(setValue(int)));
connect(z, &NoScrollSpinBox::textChanged, item, &DraggablePixmapItem::set_elevation);
connect(item, &DraggablePixmapItem::elevationChanged, z, &NoScrollSpinBox::setValue);
QString event_type = item->event->get("event_type");
QString event_group_type = item->event->get("event_group_type");
@ -1716,7 +1712,7 @@ void MainWindow::updateSelectedObjects() {
}
frame->ui->label_spritePixmap->setPixmap(item->event->pixmap);
connect(item, SIGNAL(spriteChanged(QPixmap)), frame->ui->label_spritePixmap, SLOT(setPixmap(QPixmap)));
connect(item, &DraggablePixmapItem::spriteChanged, frame->ui->label_spritePixmap, &QLabel::setPixmap);
frame->ui->sprite->setVisible(false);
@ -1830,19 +1826,19 @@ void MainWindow::updateSelectedObjects() {
}
if (key == "destination_map_name") {
if (!editor->project->mapNames->contains(value)) {
if (!editor->project->mapNames.contains(value)) {
combo->addItem(value);
}
combo->addItems(*editor->project->mapNames);
combo->addItems(editor->project->mapNames);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The destination map name of the warp.");
} else if (key == "destination_warp") {
combo->setToolTip("The warp id on the destination map.");
} else if (key == "item") {
if (!editor->project->itemNames->contains(value)) {
if (!editor->project->itemNames.contains(value)) {
combo->addItem(value);
}
combo->addItems(*editor->project->itemNames);
combo->addItems(editor->project->itemNames);
combo->setCurrentIndex(combo->findText(value));
} else if (key == "quantity") {
spin->setToolTip("The number of items received when the hidden item is picked up.");
@ -1851,27 +1847,27 @@ void MainWindow::updateSelectedObjects() {
} else if (key == "underfoot") {
check->setToolTip("If checked, hidden item can only be picked up using the Itemfinder");
} else if (key == "flag" || key == "event_flag") {
if (!editor->project->flagNames->contains(value)) {
if (!editor->project->flagNames.contains(value)) {
combo->addItem(value);
}
combo->addItems(*editor->project->flagNames);
combo->addItems(editor->project->flagNames);
combo->setCurrentIndex(combo->findText(value));
if (key == "flag")
combo->setToolTip("The flag which is set when the hidden item is picked up.");
else if (key == "event_flag")
combo->setToolTip("The flag which hides the object when set.");
} else if (key == "script_var") {
if (!editor->project->varNames->contains(value)) {
if (!editor->project->varNames.contains(value)) {
combo->addItem(value);
}
combo->addItems(*editor->project->varNames);
combo->addItems(editor->project->varNames);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The variable by which the script is triggered.\n"
"The script is triggered when this variable's value matches 'Var Value'.");
} else if (key == "script_var_value") {
combo->setToolTip("The variable's value which triggers the script.");
} else if (key == "movement_type") {
if (!editor->project->movementTypes->contains(value)) {
if (!editor->project->movementTypes.contains(value)) {
combo->addItem(value);
}
connect(combo, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentTextChanged),
@ -1879,31 +1875,31 @@ void MainWindow::updateSelectedObjects() {
item->event->setFrameFromMovement(editor->project->facingDirections.value(value));
item->updatePixmap();
});
combo->addItems(*editor->project->movementTypes);
combo->addItems(editor->project->movementTypes);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The object's natural movement behavior when\n"
"the player is not interacting with it.");
} else if (key == "weather") {
if (!editor->project->coordEventWeatherNames->contains(value)) {
if (!editor->project->coordEventWeatherNames.contains(value)) {
combo->addItem(value);
}
combo->addItems(*editor->project->coordEventWeatherNames);
combo->addItems(editor->project->coordEventWeatherNames);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The weather that starts when the player steps on this spot.");
} else if (key == "secret_base_id") {
if (!editor->project->secretBaseIds->contains(value)) {
if (!editor->project->secretBaseIds.contains(value)) {
combo->addItem(value);
}
combo->addItems(*editor->project->secretBaseIds);
combo->addItems(editor->project->secretBaseIds);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The secret base id which is inside this secret\n"
"base entrance. Secret base ids are meant to be\n"
"unique to each and every secret base entrance.");
} else if (key == "player_facing_direction") {
if (!editor->project->bgEventFacingDirections->contains(value)) {
if (!editor->project->bgEventFacingDirections.contains(value)) {
combo->addItem(value);
}
combo->addItems(*editor->project->bgEventFacingDirections);
combo->addItems(editor->project->bgEventFacingDirections);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The direction which the player must be facing\n"
"to be able to interact with this event.");
@ -1923,7 +1919,7 @@ void MainWindow::updateSelectedObjects() {
combo->setCompleter(editor->project->getEventScriptLabelCompleter(localScriptLabels));
combo->setToolTip("The script which is executed with this event.");
} else if (key == "trainer_type") {
combo->addItems(*editor->project->trainerTypes);
combo->addItems(editor->project->trainerTypes);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The trainer type of this object event.\n"
"If it is not a trainer, use NONE. SEE ALL DIRECTIONS\n"
@ -1935,10 +1931,10 @@ void MainWindow::updateSelectedObjects() {
} else if (key == "in_connection") {
check->setToolTip("Check if object is positioned in the connection to another map.");
} else if (key == "respawn_map") {
if (!editor->project->mapNames->contains(value)) {
if (!editor->project->mapNames.contains(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.");
} else if (key == "respawn_npc") {
spin->setToolTip("event_object ID of the NPC the player interacts with\n"
@ -2463,7 +2459,6 @@ void MainWindow::showExportMapImageWindow(ImageExporterMode mode) {
delete this->mapImageExporter;
this->mapImageExporter = new MapImageExporter(this, this->editor, mode);
connect(this->mapImageExporter, &QObject::destroyed, [=](QObject *) { this->mapImageExporter = nullptr; });
this->mapImageExporter->setAttribute(Qt::WA_DeleteOnClose);
if (!this->mapImageExporter->isVisible()) {
@ -2487,7 +2482,7 @@ void MainWindow::on_spinBox_ConnectionOffset_valueChanged(int offset)
void MainWindow::on_comboBox_ConnectedMap_currentTextChanged(const QString &mapName)
{
if (editor->project->mapNames->contains(mapName))
if (editor->project->mapNames.contains(mapName))
editor->setConnectionMap(mapName);
}
@ -2515,13 +2510,13 @@ void MainWindow::on_pushButton_ConfigureEncountersJSON_clicked() {
void MainWindow::on_comboBox_DiveMap_currentTextChanged(const QString &mapName)
{
if (editor->project->mapNames->contains(mapName))
if (editor->project->mapNames.contains(mapName))
editor->updateDiveMap(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);
}
@ -2609,14 +2604,14 @@ void MainWindow::on_pushButton_ChangeDimensions_clicked()
errorLabel->setVisible(true);
}
});
connect(&buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
form.addRow(errorLabel);
if (dialog.exec() == QDialog::Accepted) {
Map *map = editor->map;
Blockdata *oldMetatiles = map->layout->blockdata->copy();
Blockdata *oldBorder = map->layout->border->copy();
Blockdata oldMetatiles = map->layout->blockdata;
Blockdata oldBorder = map->layout->border;
QSize oldMapDimensions(map->getWidth(), map->getHeight());
QSize oldBorderDimensions(map->getBorderWidth(), map->getBorderHeight());
QSize newMapDimensions(widthSpinBox->value(), heightSpinBox->value());
@ -2624,11 +2619,11 @@ void MainWindow::on_pushButton_ChangeDimensions_clicked()
if (oldMapDimensions != newMapDimensions || oldBorderDimensions != newBorderDimensions) {
editor->map->setDimensions(newMapDimensions.width(), newMapDimensions.height());
editor->map->setBorderDimensions(newBorderDimensions.width(), newBorderDimensions.height());
editor->map->editHistory.push(new ResizeMap(map,
editor->map->editHistory.push(new ResizeMap(map,
oldMapDimensions, newMapDimensions,
oldMetatiles, map->layout->blockdata->copy(),
oldMetatiles, map->layout->blockdata,
oldBorderDimensions, newBorderDimensions,
oldBorder, map->layout->border->copy()
oldBorder, map->layout->border
));
}
}
@ -2669,8 +2664,7 @@ void MainWindow::on_actionTileset_Editor_triggered()
void MainWindow::initTilesetEditor() {
this->tilesetEditor = new TilesetEditor(this->editor->project, this->editor->map, this);
connect(this->tilesetEditor, SIGNAL(tilesetsSaved(QString, QString)), this, SLOT(onTilesetsSaved(QString, QString)));
connect(this->tilesetEditor, &QObject::destroyed, [=](QObject *) { this->tilesetEditor = nullptr; });
connect(this->tilesetEditor, &TilesetEditor::tilesetsSaved, this, &MainWindow::onTilesetsSaved);
}
void MainWindow::on_toolButton_ExpandAll_clicked()
@ -2694,6 +2688,16 @@ void MainWindow::on_actionAbout_Porymap_triggered()
window->show();
}
void MainWindow::on_actionOpen_Log_File_triggered() {
const QString logPath = getLogPath();
const int lineCount = ParseUtil::textFileLineCount(logPath);
editor->openInTextEditor(logPath, lineCount);
}
void MainWindow::on_actionOpen_Config_Folder_triggered() {
QDesktopServices::openUrl(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
}
void MainWindow::on_actionEdit_Preferences_triggered() {
if (!preferenceEditor) {
preferenceEditor = new PreferenceEditor(this);
@ -2703,7 +2707,6 @@ void MainWindow::on_actionEdit_Preferences_triggered() {
editor, &Editor::maskNonVisibleConnectionTiles);
connect(preferenceEditor, &PreferenceEditor::preferencesSaved,
this, &MainWindow::togglePreferenceSpecificUi);
connect(preferenceEditor, &QObject::destroyed, [=](QObject *) { preferenceEditor = nullptr; });
}
if (!preferenceEditor->isVisible()) {
@ -2818,7 +2821,6 @@ bool MainWindow::initRegionMapEditor() {
return false;
}
connect(this->regionMapEditor, &QObject::destroyed, [=](QObject *) { this->regionMapEditor = nullptr; });
return true;
}

View file

@ -6,11 +6,11 @@
QJSValue MainWindow::getBlock(int x, int y) {
if (!this->editor || !this->editor->map)
return QJSValue();
Block *block = this->editor->map->getBlock(x, y);
if (!block) {
Block block;
if (!this->editor->map->getBlock(x, y, &block)) {
return Scripting::fromBlock(Block());
}
return Scripting::fromBlock(*block);
return Scripting::fromBlock(block);
}
void MainWindow::tryRedrawMapArea(bool forceRedraw) {
@ -26,7 +26,7 @@ void MainWindow::tryCommitMapChanges(bool commitChanges) {
if (map) {
map->editHistory.push(new ScriptEditMap(map,
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
));
}
}
@ -51,21 +51,21 @@ void MainWindow::setBlocksFromSelection(int x, int y, bool forceRedraw, bool com
int MainWindow::getMetatileId(int x, int y) {
if (!this->editor || !this->editor->map)
return 0;
Block *block = this->editor->map->getBlock(x, y);
if (!block) {
Block block;
if (!this->editor->map->getBlock(x, y, &block)) {
return 0;
}
return block->tile;
return block.tile;
}
void MainWindow::setMetatileId(int x, int y, int metatileId, bool forceRedraw, bool commitChanges) {
if (!this->editor || !this->editor->map)
return;
Block *block = this->editor->map->getBlock(x, y);
if (!block) {
Block block;
if (!this->editor->map->getBlock(x, y, &block)) {
return;
}
this->editor->map->setBlock(x, y, Block(metatileId, block->collision, block->elevation));
this->editor->map->setBlock(x, y, Block(metatileId, block.collision, block.elevation));
this->tryCommitMapChanges(commitChanges);
this->tryRedrawMapArea(forceRedraw);
}
@ -73,21 +73,21 @@ void MainWindow::setMetatileId(int x, int y, int metatileId, bool forceRedraw, b
int MainWindow::getCollision(int x, int y) {
if (!this->editor || !this->editor->map)
return 0;
Block *block = this->editor->map->getBlock(x, y);
if (!block) {
Block block;
if (!this->editor->map->getBlock(x, y, &block)) {
return 0;
}
return block->collision;
return block.collision;
}
void MainWindow::setCollision(int x, int y, int collision, bool forceRedraw, bool commitChanges) {
if (!this->editor || !this->editor->map)
return;
Block *block = this->editor->map->getBlock(x, y);
if (!block) {
Block block;
if (!this->editor->map->getBlock(x, y, &block)) {
return;
}
this->editor->map->setBlock(x, y, Block(block->tile, collision, block->elevation));
this->editor->map->setBlock(x, y, Block(block.tile, collision, block.elevation));
this->tryCommitMapChanges(commitChanges);
this->tryRedrawMapArea(forceRedraw);
}
@ -95,21 +95,21 @@ void MainWindow::setCollision(int x, int y, int collision, bool forceRedraw, boo
int MainWindow::getElevation(int x, int y) {
if (!this->editor || !this->editor->map)
return 0;
Block *block = this->editor->map->getBlock(x, y);
if (!block) {
Block block;
if (!this->editor->map->getBlock(x, y, &block)) {
return 0;
}
return block->elevation;
return block.elevation;
}
void MainWindow::setElevation(int x, int y, int elevation, bool forceRedraw, bool commitChanges) {
if (!this->editor || !this->editor->map)
return;
Block *block = this->editor->map->getBlock(x, y);
if (!block) {
Block block;
if (!this->editor->map->getBlock(x, y, &block)) {
return;
}
this->editor->map->setBlock(x, y, Block(block->tile, block->collision, elevation));
this->editor->map->setBlock(x, y, Block(block.tile, block.collision, elevation));
this->tryCommitMapChanges(commitChanges);
this->tryRedrawMapArea(forceRedraw);
}
@ -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) {
if (!this->editor || !this->editor->map)
return;
this->editor->map_item->shift(xDelta, yDelta);
this->editor->map_item->shift(xDelta, yDelta, true);
this->tryCommitMapChanges(commitChanges);
this->tryRedrawMapArea(forceRedraw);
}
@ -260,7 +260,7 @@ void MainWindow::refreshAfterPaletteChange(Tileset *tileset) {
void MainWindow::setTilesetPalette(Tileset *tileset, int paletteIndex, QList<QList<int>> colors) {
if (!this->editor || !this->editor->map || !this->editor->map->layout)
return;
if (paletteIndex >= tileset->palettes->size())
if (paletteIndex >= tileset->palettes.size())
return;
if (colors.size() != 16)
return;
@ -268,8 +268,8 @@ void MainWindow::setTilesetPalette(Tileset *tileset, int paletteIndex, QList<QLi
for (int i = 0; i < 16; i++) {
if (colors[i].size() != 3)
continue;
(*tileset->palettes)[paletteIndex][i] = qRgb(colors[i][0], colors[i][1], colors[i][2]);
(*tileset->palettePreviews)[paletteIndex][i] = qRgb(colors[i][0], colors[i][1], colors[i][2]);
tileset->palettes[paletteIndex][i] = qRgb(colors[i][0], colors[i][1], colors[i][2]);
tileset->palettePreviews[paletteIndex][i] = qRgb(colors[i][0], colors[i][1], colors[i][2]);
}
}
@ -305,22 +305,22 @@ void MainWindow::setSecondaryTilesetPalettes(QList<QList<QList<int>>> palettes)
this->refreshAfterPaletteChange(this->editor->map->layout->tileset_secondary);
}
QJSValue MainWindow::getTilesetPalette(QList<QList<QRgb>> *palettes, int paletteIndex) {
if (paletteIndex >= palettes->size())
QJSValue MainWindow::getTilesetPalette(const QList<QList<QRgb>> &palettes, int paletteIndex) {
if (paletteIndex >= palettes.size())
return QJSValue();
QList<QList<int>> palette;
for (auto color : palettes->value(paletteIndex)) {
for (auto color : palettes.value(paletteIndex)) {
palette.append(QList<int>({qRed(color), qGreen(color), qBlue(color)}));
}
return Scripting::getEngine()->toScriptValue(palette);
}
QJSValue MainWindow::getTilesetPalettes(QList<QList<QRgb>> *palettes) {
QJSValue MainWindow::getTilesetPalettes(const QList<QList<QRgb>> &palettes) {
QList<QList<QList<int>>> outPalettes;
for (int i = 0; i < palettes->size(); i++) {
for (int i = 0; i < palettes.size(); i++) {
QList<QList<int>> colors;
for (auto color : palettes->value(i)) {
for (auto color : palettes.value(i)) {
colors.append(QList<int>({qRed(color), qGreen(color), qBlue(color)}));
}
outPalettes.append(colors);
@ -363,7 +363,7 @@ void MainWindow::refreshAfterPalettePreviewChange() {
void MainWindow::setTilesetPalettePreview(Tileset *tileset, int paletteIndex, QList<QList<int>> colors) {
if (!this->editor || !this->editor->map || !this->editor->map->layout)
return;
if (paletteIndex >= tileset->palettePreviews->size())
if (paletteIndex >= tileset->palettePreviews.size())
return;
if (colors.size() != 16)
return;
@ -371,8 +371,7 @@ void MainWindow::setTilesetPalettePreview(Tileset *tileset, int paletteIndex, QL
for (int i = 0; i < 16; i++) {
if (colors[i].size() != 3)
continue;
auto palettes = tileset->palettePreviews;
(*palettes)[paletteIndex][i] = qRgb(colors[i][0], colors[i][1], colors[i][2]);
tileset->palettePreviews[paletteIndex][i] = qRgb(colors[i][0], colors[i][1], colors[i][2]);
}
}
@ -502,7 +501,7 @@ void MainWindow::setTimeout(QJSValue callback, int milliseconds) {
connect(timer, &QTimer::timeout, [=](){
this->invokeCallback(callback);
});
connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater()));
connect(timer, &QTimer::timeout, timer, &QTimer::deleteLater);
timer->setSingleShot(true);
timer->start(milliseconds);
}

File diff suppressed because it is too large Load diff

View file

@ -61,7 +61,11 @@ void Scripting::invokeCallback(CallbackType type, QJSValueList args) {
QJSValue result = callbackFunction.call(args);
if (result.isError()) {
logError(QString("Module %1 encountered an error when calling '%2'").arg(module.toString()).arg(functionName));
QFileInfo file(result.property("fileName").toString());
logError(QString("Error in custom script '%1' at line %2: '%3'")
.arg(file.fileName())
.arg(result.property("lineNumber").toString())
.arg(result.toString()));
continue;
}
}
@ -90,7 +94,11 @@ void Scripting::invokeAction(QString actionName) {
QJSValue result = callbackFunction.call(QJSValueList());
if (result.isError()) {
logError(QString("Module %1 encountered an error when calling '%2'").arg(module.toString()).arg(functionName));
QFileInfo file(result.property("fileName").toString());
logError(QString("Error in custom script '%1' at line %2: '%3'")
.arg(file.fileName())
.arg(result.property("lineNumber").toString())
.arg(result.toString()));
continue;
}
}

View file

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

View file

@ -45,7 +45,7 @@ void CollisionPixmapItem::paint(QGraphicsSceneMouseEvent *event) {
if (event->type() == QEvent::GraphicsSceneMouseRelease) {
actionId_++;
} else if (map) {
Blockdata *oldCollision = map->layout->blockdata->copy();
Blockdata oldCollision = map->layout->blockdata;
QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
@ -58,19 +58,15 @@ void CollisionPixmapItem::paint(QGraphicsSceneMouseEvent *event) {
this->lockedAxis = MapPixmapItem::Axis::None;
}
Block *block = map->getBlock(pos.x(), pos.y());
if (block) {
block->collision = this->movementPermissionsSelector->getSelectedCollision();
block->elevation = this->movementPermissionsSelector->getSelectedElevation();
map->setBlock(pos.x(), pos.y(), *block, true);
Block block;
if (map->getBlock(pos.x(), pos.y(), &block)) {
block.collision = this->movementPermissionsSelector->getSelectedCollision();
block.elevation = this->movementPermissionsSelector->getSelectedElevation();
map->setBlock(pos.x(), pos.y(), block, true);
}
Blockdata *newCollision = map->layout->blockdata->copy();
if (newCollision->equals(oldCollision)) {
delete newCollision;
delete oldCollision;
} else {
map->editHistory.push(new PaintCollision(map, oldCollision, newCollision, actionId_));
if (map->layout->blockdata != oldCollision) {
map->editHistory.push(new PaintCollision(map, oldCollision, map->layout->blockdata, actionId_));
}
}
}
@ -79,19 +75,15 @@ void CollisionPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) {
if (event->type() == QEvent::GraphicsSceneMouseRelease) {
this->actionId_++;
} else if (map) {
Blockdata *oldCollision = map->layout->blockdata->copy();
Blockdata oldCollision = map->layout->blockdata;
QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
uint16_t collision = this->movementPermissionsSelector->getSelectedCollision();
uint16_t elevation = this->movementPermissionsSelector->getSelectedElevation();
map->floodFillCollisionElevation(pos.x(), pos.y(), collision, elevation);
Blockdata *newCollision = map->layout->blockdata->copy();
if (newCollision->equals(oldCollision)) {
delete newCollision;
delete oldCollision;
} else {
map->editHistory.push(new BucketFillCollision(map, oldCollision, newCollision));
if (map->layout->blockdata != oldCollision) {
map->editHistory.push(new BucketFillCollision(map, oldCollision, map->layout->blockdata));
}
}
}
@ -100,27 +92,23 @@ void CollisionPixmapItem::magicFill(QGraphicsSceneMouseEvent *event) {
if (event->type() == QEvent::GraphicsSceneMouseRelease) {
this->actionId_++;
} else if (map) {
Blockdata *oldCollision = map->layout->blockdata->copy();
Blockdata oldCollision = map->layout->blockdata;
QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
uint16_t collision = this->movementPermissionsSelector->getSelectedCollision();
uint16_t elevation = this->movementPermissionsSelector->getSelectedElevation();
map->magicFillCollisionElevation(pos.x(), pos.y(), collision, elevation);
Blockdata *newCollision = map->layout->blockdata->copy();
if (newCollision->equals(oldCollision)) {
delete newCollision;
delete oldCollision;
} else {
map->editHistory.push(new MagicFillCollision(map, oldCollision, newCollision));
if (map->layout->blockdata != oldCollision) {
map->editHistory.push(new MagicFillCollision(map, oldCollision, map->layout->blockdata));
}
}
}
void CollisionPixmapItem::pick(QGraphicsSceneMouseEvent *event) {
QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
Block *block = map->getBlock(pos.x(), pos.y());
if (block) {
this->movementPermissionsSelector->select(block->collision, block->elevation);
Block block;
if (map->getBlock(pos.x(), pos.y(), &block)) {
this->movementPermissionsSelector->select(block.collision, block.elevation);
}
}
@ -133,6 +121,8 @@ void CollisionPixmapItem::updateMovementPermissionSelection(QGraphicsSceneMouseE
if (pos.y() < 0) pos.setY(0);
if (pos.y() >= map->getHeight()) pos.setY(map->getHeight() - 1);
Block *block = map->getBlock(pos.x(), pos.y());
this->movementPermissionsSelector->select(block->collision, block->elevation);
Block block;
if (map->getBlock(pos.x(), pos.y(), &block)) {
this->movementPermissionsSelector->select(block.collision, block.elevation);
}
}

View file

@ -65,9 +65,16 @@ void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) {
this->editor->selectingEvent = true;
}
void DraggablePixmapItem::move(int x, int y) {
event->setX(event->x() + x);
event->setY(event->y() + y);
void DraggablePixmapItem::move(int dx, int dy) {
event->setX(event->x() + dx);
event->setY(event->y() + dy);
updatePosition();
emitPositionChanged();
}
void DraggablePixmapItem::moveTo(const QPoint &pos) {
event->setX(pos.x());
event->setY(pos.y());
updatePosition();
emitPositionChanged();
}
@ -106,7 +113,7 @@ void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) {
}
else if (this->event->get("event_type") == EventType::SecretBase) {
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) {
emit editor->warpEventDoubleClicked(destMap, "0");
}

View file

@ -26,7 +26,7 @@ QImage getMetatileImage(
metatile_image.fill(Qt::black);
Metatile* metatile = Tileset::getMetatile(tile, primaryTileset, secondaryTileset);
if (!metatile || !metatile->tiles) {
if (!metatile) {
metatile_image.fill(Qt::magenta);
return metatile_image;
}
@ -46,7 +46,7 @@ QImage getMetatileImage(
for (int x = 0; x < 2; x++) {
int l = layerOrder.size() >= numLayers ? layerOrder[layer] : layer;
int bottomLayer = layerOrder.size() >= numLayers ? layerOrder[0] : 0;
Tile tile_ = metatile->tiles->value((y * 2) + x + (l * 4));
Tile tile_ = metatile->tiles.value((y * 2) + x + (l * 4));
QImage tile_image = getTileImage(tile_.tile, primaryTileset, secondaryTileset);
if (tile_image.isNull()) {
// Some metatiles specify tiles that are outside the valid range.
@ -97,10 +97,10 @@ QImage getMetatileImage(
QImage getTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset) {
Tileset *tileset = Tileset::getBlockTileset(tile, primaryTileset, secondaryTileset);
int local_index = Metatile::getBlockIndex(tile);
if (!tileset || !tileset->tiles) {
if (!tileset) {
return QImage();
}
return tileset->tiles->value(local_index, QImage());
return tileset->tiles.value(local_index, QImage());
}
QImage getColoredTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset, QList<QRgb> palette) {

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_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->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) {
Blockdata *backupBlockdata = map->layout->blockdata->copy();
Blockdata oldMetatiles = map->layout->blockdata;
for (int i = 0; i < map->getWidth(); i++)
for (int j = 0; j < map->getHeight(); j++) {
int destX = i + xDelta;
@ -89,20 +90,12 @@ void MapPixmapItem::shift(int xDelta, int yDelta, bool fromScriptCall) {
destY %= map->getHeight();
int blockIndex = j * map->getWidth() + i;
Block srcBlock = backupBlockdata->blocks->at(blockIndex);
Block srcBlock = oldMetatiles.at(blockIndex);
map->setBlock(destX, destY, srcBlock);
}
if (!fromScriptCall) {
Blockdata *newMetatiles = map->layout->blockdata->copy();
if (newMetatiles->equals(backupBlockdata)) {
delete newMetatiles;
delete backupBlockdata;
} else {
map->editHistory.push(new ShiftMetatiles(map, backupBlockdata, newMetatiles, actionId_));
}
} else {
delete backupBlockdata;
if (!fromScriptCall && map->layout->blockdata != oldMetatiles) {
map->editHistory.push(new ShiftMetatiles(map, oldMetatiles, map->layout->blockdata, actionId_));
}
}
@ -124,33 +117,26 @@ void MapPixmapItem::paintNormal(int x, int y, bool fromScriptCall) {
y = initialY + (yDiff / selectionDimensions.y()) * selectionDimensions.y();
// for edit history
Blockdata *oldMetatiles = nullptr;
if (!fromScriptCall) oldMetatiles = map->layout->blockdata->copy();
Blockdata oldMetatiles = !fromScriptCall ? map->layout->blockdata : Blockdata();
for (int i = 0; i < selectionDimensions.x() && i + x < map->getWidth(); i++)
for (int j = 0; j < selectionDimensions.y() && j + y < map->getHeight(); j++) {
int actualX = i + x;
int actualY = j + y;
Block *block = map->getBlock(actualX, actualY);
if (block) {
Block block;
if (map->getBlock(actualX, actualY, &block)) {
int index = j * selectionDimensions.x() + i;
block->tile = selectedMetatiles->at(index);
block.tile = selectedMetatiles->at(index);
if (selectedCollisions && selectedCollisions->length() == selectedMetatiles->length()) {
block->collision = selectedCollisions->at(index).first;
block->elevation = selectedCollisions->at(index).second;
block.collision = selectedCollisions->at(index).first;
block.elevation = selectedCollisions->at(index).second;
}
map->setBlock(actualX, actualY, *block, !fromScriptCall);
map->setBlock(actualX, actualY, block, !fromScriptCall);
}
}
if (!fromScriptCall) {
Blockdata *newMetatiles = map->layout->blockdata->copy();
if (newMetatiles->equals(oldMetatiles)) {
delete newMetatiles;
delete oldMetatiles;
} else {
map->editHistory.push(new PaintMetatile(map, oldMetatiles, newMetatiles, actionId_));
}
if (!fromScriptCall && map->layout->blockdata != oldMetatiles) {
map->editHistory.push(new PaintMetatile(map, oldMetatiles, map->layout->blockdata, actionId_));
}
}
@ -176,7 +162,7 @@ QList<int> MapPixmapItem::smartPathTable = QList<int>({
4, // 1111
});
#define IS_SMART_PATH_TILE(block) (selectedMetatiles->contains(block->tile))
#define IS_SMART_PATH_TILE(block) (selectedMetatiles->contains(block.tile))
void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
QPoint selectionDimensions = this->metatileSelector->getSelectionDimensions();
@ -198,8 +184,7 @@ void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
}
// for edit history
Blockdata *oldMetatiles = nullptr;
if (!fromScriptCall) oldMetatiles = map->layout->blockdata->copy();
Blockdata oldMetatiles = !fromScriptCall ? map->layout->blockdata : Blockdata();
// Fill the region with the open tile.
for (int i = 0; i <= 1; i++)
@ -209,14 +194,14 @@ void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
continue;
int actualX = i + x;
int actualY = j + y;
Block *block = map->getBlock(actualX, actualY);
if (block) {
block->tile = openTile;
Block block;
if (map->getBlock(actualX, actualY, &block)) {
block.tile = openTile;
if (setCollisions) {
block->collision = openTileCollision;
block->elevation = openTileElevation;
block.collision = openTileCollision;
block.elevation = openTileElevation;
}
map->setBlock(actualX, actualY, *block, !fromScriptCall);
map->setBlock(actualX, actualY, block, !fromScriptCall);
}
}
@ -234,43 +219,37 @@ void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
// Ignore tiles that aren't part of the smart path set.
int actualX = i + x;
int actualY = j + y;
Block *block = map->getBlock(actualX, actualY);
if (!block || !IS_SMART_PATH_TILE(block)) {
Block block;
if (!map->getBlock(actualX, actualY, &block) || !IS_SMART_PATH_TILE(block)) {
continue;
}
int id = 0;
Block *top = map->getBlock(actualX, actualY - 1);
Block *right = map->getBlock(actualX + 1, actualY);
Block *bottom = map->getBlock(actualX, actualY + 1);
Block *left = map->getBlock(actualX - 1, actualY);
Block top;
Block right;
Block bottom;
Block left;
// Get marching squares value, to determine which tile to use.
if (top && IS_SMART_PATH_TILE(top))
if (map->getBlock(actualX, actualY - 1, &top) && IS_SMART_PATH_TILE(top))
id += 1;
if (right && IS_SMART_PATH_TILE(right))
if (map->getBlock(actualX + 1, actualY, &right) && IS_SMART_PATH_TILE(right))
id += 2;
if (bottom && IS_SMART_PATH_TILE(bottom))
if (map->getBlock(actualX, actualY + 1, &bottom) && IS_SMART_PATH_TILE(bottom))
id += 4;
if (left && IS_SMART_PATH_TILE(left))
if (map->getBlock(actualX - 1, actualY, &left) && IS_SMART_PATH_TILE(left))
id += 8;
block->tile = selectedMetatiles->at(smartPathTable[id]);
block.tile = selectedMetatiles->at(smartPathTable[id]);
if (setCollisions) {
block->collision = selectedCollisions->at(smartPathTable[id]).first;
block->elevation = selectedCollisions->at(smartPathTable[id]).second;
block.collision = selectedCollisions->at(smartPathTable[id]).first;
block.elevation = selectedCollisions->at(smartPathTable[id]).second;
}
map->setBlock(actualX, actualY, *block, !fromScriptCall);
map->setBlock(actualX, actualY, block, !fromScriptCall);
}
if (!fromScriptCall) {
Blockdata *newMetatiles = map->layout->blockdata->copy();
if (newMetatiles->equals(oldMetatiles)) {
delete newMetatiles;
delete oldMetatiles;
} else {
map->editHistory.push(new PaintMetatile(map, oldMetatiles, newMetatiles, actionId_));
}
if (!fromScriptCall && map->layout->blockdata != oldMetatiles) {
map->editHistory.push(new PaintMetatile(map, oldMetatiles, map->layout->blockdata, actionId_));
}
}
@ -287,7 +266,7 @@ void MapPixmapItem::lockNondominantAxis(QGraphicsSceneMouseEvent *event) {
this->straight_path_initial_x = pos.x();
this->straight_path_initial_y = pos.y();
}
// Only lock an axis when the current position != initial
int xDiff = pos.x() - this->straight_path_initial_x;
int yDiff = pos.y() - this->straight_path_initial_y;
@ -324,8 +303,10 @@ void MapPixmapItem::updateMetatileSelection(QGraphicsSceneMouseEvent *event) {
selection_origin = QPoint(pos.x(), pos.y());
selection.clear();
selection.append(QPoint(pos.x(), pos.y()));
Block *block = map->getBlock(pos.x(), pos.y());
this->metatileSelector->selectFromMap(block->tile, block->collision, block->elevation);
Block block;
if (map->getBlock(pos.x(), pos.y(), &block)) {
this->metatileSelector->selectFromMap(block.tile, block.collision, block.elevation);
}
} else if (event->type() == QEvent::GraphicsSceneMouseMove) {
int x1 = selection_origin.x();
int y1 = selection_origin.y();
@ -345,10 +326,15 @@ void MapPixmapItem::updateMetatileSelection(QGraphicsSceneMouseEvent *event) {
for (QPoint point : selection) {
int x = point.x();
int y = point.y();
metatiles.append(map->getBlock(x, y)->tile);
Block block;
if (map->getBlock(x, y, &block)) {
metatiles.append(block.tile);
}
int blockIndex = y * map->getWidth() + x;
Block block = map->layout->blockdata->blocks->at(blockIndex);
collisions.append(QPair<uint16_t, uint16_t>(block.collision, block.elevation));
block = map->layout->blockdata.at(blockIndex);
auto collision = block.collision;
auto elevation = block.elevation;
collisions.append(QPair<uint16_t, uint16_t>(collision, elevation));
}
this->metatileSelector->setExternalSelection(x2 - x1 + 1, y2 - y1 + 1, metatiles, collisions);
@ -361,11 +347,11 @@ void MapPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) {
actionId_++;
} else {
QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
Block *block = map->getBlock(pos.x(), pos.y());
Block block;
QList<uint16_t> *selectedMetatiles = this->metatileSelector->getSelectedMetatiles();
QPoint selectionDimensions = this->metatileSelector->getSelectionDimensions();
int tile = selectedMetatiles->first();
if (selectedMetatiles->count() > 1 || (block && block->tile != tile)) {
if (selectedMetatiles->count() > 1 || (map->getBlock(pos.x(), pos.y(), &block) && block.tile != tile)) {
bool smartPathsEnabled = event->modifiers() & Qt::ShiftModifier;
if ((this->settings->smartPathsEnabled || smartPathsEnabled) && selectionDimensions.x() == 3 && selectionDimensions.y() == 3)
this->floodFillSmartPath(pos.x(), pos.y());
@ -391,6 +377,7 @@ void MapPixmapItem::magicFill(int x, int y, uint16_t metatileId, bool fromScript
QPoint selectionDimensions(1, 1);
QList<uint16_t> *selectedMetatiles = new QList<uint16_t>({ metatileId });
this->magicFill(x, y, selectionDimensions, selectedMetatiles, nullptr, fromScriptCall);
delete selectedMetatiles;
}
void MapPixmapItem::magicFill(int x, int y, bool fromScriptCall) {
@ -407,22 +394,19 @@ void MapPixmapItem::magicFill(
QList<uint16_t> *selectedMetatiles,
QList<QPair<uint16_t, uint16_t>> *selectedCollisions,
bool fromScriptCall) {
Block *block = map->getBlock(initialX, initialY);
if (block) {
if (selectedMetatiles->length() == 1 && selectedMetatiles->value(0) == block->tile) {
logInfo("early exit");
Block block;
if (map->getBlock(initialX, initialY, &block)) {
if (selectedMetatiles->length() == 1 && selectedMetatiles->value(0) == block.tile) {
return;
}
Blockdata *oldMetatiles = nullptr;
if (!fromScriptCall) oldMetatiles = map->layout->blockdata->copy();
Blockdata oldMetatiles = !fromScriptCall ? map->layout->blockdata : Blockdata();
bool setCollisions = selectedCollisions && selectedCollisions->length() == selectedMetatiles->length();
uint16_t tile = block->tile;
uint16_t tile = block.tile;
for (int y = 0; y < map->getHeight(); y++) {
for (int x = 0; x < map->getWidth(); x++) {
block = map->getBlock(x, y);
if (block && block->tile == tile) {
if (map->getBlock(x, y, &block) && block.tile == tile) {
int xDiff = x - initialX;
int yDiff = y - initialY;
int i = xDiff % selectionDimensions.x();
@ -430,24 +414,18 @@ void MapPixmapItem::magicFill(
if (i < 0) i = selectionDimensions.x() + i;
if (j < 0) j = selectionDimensions.y() + j;
int index = j * selectionDimensions.x() + i;
block->tile = selectedMetatiles->at(index);
block.tile = selectedMetatiles->at(index);
if (setCollisions) {
block->collision = selectedCollisions->at(index).first;
block->elevation = selectedCollisions->at(index).second;
block.collision = selectedCollisions->at(index).first;
block.elevation = selectedCollisions->at(index).second;
}
map->setBlock(x, y, *block, !fromScriptCall);
map->setBlock(x, y, block, !fromScriptCall);
}
}
}
if (!fromScriptCall) {
Blockdata *newMetatiles = map->layout->blockdata->copy();
if (newMetatiles->equals(oldMetatiles)) {
delete newMetatiles;
delete oldMetatiles;
} else {
map->editHistory.push(new MagicFillMetatile(map, oldMetatiles, newMetatiles, actionId_));
}
if (!fromScriptCall && map->layout->blockdata != oldMetatiles) {
map->editHistory.push(new MagicFillMetatile(map, oldMetatiles, map->layout->blockdata, actionId_));
}
}
}
@ -463,6 +441,7 @@ void MapPixmapItem::floodFill(int initialX, int initialY, uint16_t metatileId, b
QPoint selectionDimensions(1, 1);
QList<uint16_t> *selectedMetatiles = new QList<uint16_t>({ metatileId });
this->floodFill(initialX, initialY, selectionDimensions, selectedMetatiles, nullptr, fromScriptCall);
delete selectedMetatiles;
}
void MapPixmapItem::floodFill(
@ -473,28 +452,21 @@ void MapPixmapItem::floodFill(
QList<QPair<uint16_t, uint16_t>> *selectedCollisions,
bool fromScriptCall) {
bool setCollisions = selectedCollisions && selectedCollisions->length() == selectedMetatiles->length();
Blockdata oldMetatiles = !fromScriptCall ? map->layout->blockdata : Blockdata();
int numMetatiles = map->getWidth() * map->getHeight();
bool *visited = new bool[numMetatiles];
for (int i = 0; i < numMetatiles; i++)
visited[i] = false;
Blockdata *oldMetatiles = nullptr;
if (!fromScriptCall) oldMetatiles = map->layout->blockdata->copy();
QSet<int> visited;
QList<QPoint> todo;
todo.append(QPoint(initialX, initialY));
while (todo.length()) {
QPoint point = todo.takeAt(0);
int x = point.x();
int y = point.y();
visited[x + y * map->getWidth()] = true;
Block *block = map->getBlock(x, y);
if (!block) {
Block block;
if (!map->getBlock(x, y, &block)) {
continue;
}
visited.insert(x + y * map->getWidth());
int xDiff = x - initialX;
int yDiff = y - initialY;
int i = xDiff % selectionDimensions.x();
@ -503,44 +475,36 @@ void MapPixmapItem::floodFill(
if (j < 0) j = selectionDimensions.y() + j;
int index = j * selectionDimensions.x() + i;
uint16_t tile = selectedMetatiles->at(index);
uint16_t old_tile = block->tile;
uint16_t old_tile = block.tile;
if (selectedMetatiles->count() != 1 || old_tile != tile) {
block->tile = tile;
block.tile = tile;
if (setCollisions) {
block->collision = selectedCollisions->at(index).first;
block->elevation = selectedCollisions->at(index).second;
block.collision = selectedCollisions->at(index).first;
block.elevation = selectedCollisions->at(index).second;
}
map->setBlock(x, y, *block, !fromScriptCall);
map->setBlock(x, y, block, !fromScriptCall);
}
if (!visited[x + 1 + y * map->getWidth()] && (block = map->getBlock(x + 1, y)) && block->tile == old_tile) {
if (!visited.contains(x + 1 + y * map->getWidth()) && map->getBlock(x + 1, y, &block) && block.tile == old_tile) {
todo.append(QPoint(x + 1, y));
visited[x + 1 + y * map->getWidth()] = true;
visited.insert(x + 1 + y * map->getWidth());
}
if (!visited[x - 1 + y * map->getWidth()] && (block = map->getBlock(x - 1, y)) && block->tile == old_tile) {
if (!visited.contains(x - 1 + y * map->getWidth()) && map->getBlock(x - 1, y, &block) && block.tile == old_tile) {
todo.append(QPoint(x - 1, y));
visited[x - 1 + y * map->getWidth()] = true;
visited.insert(x - 1 + y * map->getWidth());
}
if (!visited[x + (y + 1) * map->getWidth()] && (block = map->getBlock(x, y + 1)) && block->tile == old_tile) {
if (!visited.contains(x + (y + 1) * map->getWidth()) && map->getBlock(x, y + 1, &block) && block.tile == old_tile) {
todo.append(QPoint(x, y + 1));
visited[x + (y + 1) * map->getWidth()] = true;
visited.insert(x + (y + 1) * map->getWidth());
}
if (!visited[x + (y - 1) * map->getWidth()] && (block = map->getBlock(x, y - 1)) && block->tile == old_tile) {
if (!visited.contains(x + (y - 1) * map->getWidth()) && map->getBlock(x, y - 1, &block) && block.tile == old_tile) {
todo.append(QPoint(x, y - 1));
visited[x + (y - 1) * map->getWidth()] = true;
visited.insert(x + (y - 1) * map->getWidth());
}
}
if (!fromScriptCall) {
Blockdata *newMetatiles = map->layout->blockdata->copy();
if (newMetatiles->equals(oldMetatiles)) {
delete newMetatiles;
delete oldMetatiles;
} else {
map->editHistory.push(new BucketFillMetatile(map, oldMetatiles, newMetatiles, actionId_));
}
if (!fromScriptCall && map->layout->blockdata != oldMetatiles) {
map->editHistory.push(new BucketFillMetatile(map, oldMetatiles, map->layout->blockdata, actionId_));
}
delete[] visited;
}
void MapPixmapItem::floodFillSmartPath(int initialX, int initialY, bool fromScriptCall) {
@ -562,8 +526,7 @@ void MapPixmapItem::floodFillSmartPath(int initialX, int initialY, bool fromScri
setCollisions = true;
}
Blockdata *oldMetatiles = nullptr;
if (!fromScriptCall) oldMetatiles = map->layout->blockdata->copy();
Blockdata oldMetatiles = !fromScriptCall ? map->layout->blockdata : Blockdata();
// Flood fill the region with the open tile.
QList<QPoint> todo;
@ -572,116 +535,102 @@ void MapPixmapItem::floodFillSmartPath(int initialX, int initialY, bool fromScri
QPoint point = todo.takeAt(0);
int x = point.x();
int y = point.y();
Block *block = map->getBlock(x, y);
if (!block) {
Block block;
if (!map->getBlock(x, y, &block)) {
continue;
}
uint16_t old_tile = block->tile;
uint16_t old_tile = block.tile;
if (old_tile == openTile) {
continue;
}
block->tile = openTile;
block.tile = openTile;
if (setCollisions) {
block->collision = openTileCollision;
block->elevation = openTileElevation;
block.collision = openTileCollision;
block.elevation = openTileElevation;
}
map->setBlock(x, y, *block, !fromScriptCall);
if ((block = map->getBlock(x + 1, y)) && block->tile == old_tile) {
map->setBlock(x, y, block, !fromScriptCall);
if (map->getBlock(x + 1, y, &block) && block.tile == old_tile) {
todo.append(QPoint(x + 1, y));
}
if ((block = map->getBlock(x - 1, y)) && block->tile == old_tile) {
if (map->getBlock(x - 1, y, &block) && block.tile == old_tile) {
todo.append(QPoint(x - 1, y));
}
if ((block = map->getBlock(x, y + 1)) && block->tile == old_tile) {
if (map->getBlock(x, y + 1, &block) && block.tile == old_tile) {
todo.append(QPoint(x, y + 1));
}
if ((block = map->getBlock(x, y - 1)) && block->tile == old_tile) {
if (map->getBlock(x, y - 1, &block) && block.tile == old_tile) {
todo.append(QPoint(x, y - 1));
}
}
// Go back and resolve the flood-filled edge tiles.
// Mark tiles as visited while we go.
int numMetatiles = map->getWidth() * map->getHeight();
bool *visited = new bool[numMetatiles];
for (int i = 0; i < numMetatiles; i++)
visited[i] = false;
QSet<int> visited;
todo.append(QPoint(initialX, initialY));
while (todo.length()) {
QPoint point = todo.takeAt(0);
int x = point.x();
int y = point.y();
visited[x + y * map->getWidth()] = true;
Block *block = map->getBlock(x, y);
if (!block) {
Block block;
if (!map->getBlock(x, y, &block)) {
continue;
}
visited.insert(x + y * map->getWidth());
int id = 0;
Block *top = map->getBlock(x, y - 1);
Block *right = map->getBlock(x + 1, y);
Block *bottom = map->getBlock(x, y + 1);
Block *left = map->getBlock(x - 1, y);
Block top;
Block right;
Block bottom;
Block left;
// Get marching squares value, to determine which tile to use.
if (top && IS_SMART_PATH_TILE(top))
if (map->getBlock(x, y - 1, &top) && IS_SMART_PATH_TILE(top))
id += 1;
if (right && IS_SMART_PATH_TILE(right))
if (map->getBlock(x + 1, y, &right) && IS_SMART_PATH_TILE(right))
id += 2;
if (bottom && IS_SMART_PATH_TILE(bottom))
if (map->getBlock(x, y + 1, &bottom) && IS_SMART_PATH_TILE(bottom))
id += 4;
if (left && IS_SMART_PATH_TILE(left))
if (map->getBlock(x - 1, y, &left) && IS_SMART_PATH_TILE(left))
id += 8;
block->tile = selectedMetatiles->at(smartPathTable[id]);
block.tile = selectedMetatiles->at(smartPathTable[id]);
if (setCollisions) {
block->collision = selectedCollisions->at(smartPathTable[id]).first;
block->elevation = selectedCollisions->at(smartPathTable[id]).second;
block.collision = selectedCollisions->at(smartPathTable[id]).first;
block.elevation = selectedCollisions->at(smartPathTable[id]).second;
}
map->setBlock(x, y, *block, !fromScriptCall);
map->setBlock(x, y, block, !fromScriptCall);
// Visit neighbors if they are smart-path tiles, and don't revisit any.
if (!visited[x + 1 + y * map->getWidth()] && (block = map->getBlock(x + 1, y)) && IS_SMART_PATH_TILE(block)) {
if (!visited.contains(x + 1 + y * map->getWidth()) && map->getBlock(x + 1, y, &block) && IS_SMART_PATH_TILE(block)) {
todo.append(QPoint(x + 1, y));
visited[x + 1 + y * map->getWidth()] = true;
visited.insert(x + 1 + y * map->getWidth());
}
if (!visited[x - 1 + y * map->getWidth()] && (block = map->getBlock(x - 1, y)) && IS_SMART_PATH_TILE(block)) {
if (!visited.contains(x - 1 + y * map->getWidth()) && map->getBlock(x - 1, y, &block) && IS_SMART_PATH_TILE(block)) {
todo.append(QPoint(x - 1, y));
visited[x - 1 + y * map->getWidth()] = true;
visited.insert(x - 1 + y * map->getWidth());
}
if (!visited[x + (y + 1) * map->getWidth()] && (block = map->getBlock(x, y + 1)) && IS_SMART_PATH_TILE(block)) {
if (!visited.contains(x + (y + 1) * map->getWidth()) && map->getBlock(x, y + 1, &block) && IS_SMART_PATH_TILE(block)) {
todo.append(QPoint(x, y + 1));
visited[x + (y + 1) * map->getWidth()] = true;
visited.insert(x + (y + 1) * map->getWidth());
}
if (!visited[x + (y - 1) * map->getWidth()] && (block = map->getBlock(x, y - 1)) && IS_SMART_PATH_TILE(block)) {
if (!visited.contains(x + (y - 1) * map->getWidth()) && map->getBlock(x, y - 1, &block) && IS_SMART_PATH_TILE(block)) {
todo.append(QPoint(x, y - 1));
visited[x + (y - 1) * map->getWidth()] = true;
visited.insert(x + (y - 1) * map->getWidth());
}
}
if (!fromScriptCall) {
Blockdata *newMetatiles = map->layout->blockdata->copy();
if (newMetatiles->equals(oldMetatiles)) {
delete newMetatiles;
delete oldMetatiles;
} else {
map->editHistory.push(new BucketFillMetatile(map, oldMetatiles, newMetatiles, actionId_));
}
if (!fromScriptCall && map->layout->blockdata != oldMetatiles) {
map->editHistory.push(new BucketFillMetatile(map, oldMetatiles, map->layout->blockdata, actionId_));
}
delete[] visited;
}
void MapPixmapItem::pick(QGraphicsSceneMouseEvent *event) {
QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
Block *block = map->getBlock(pos.x(), pos.y());
if (block) {
this->metatileSelector->selectFromMap(block->tile, block->collision, block->elevation);
Block block;
if (map->getBlock(pos.x(), pos.y(), &block)) {
this->metatileSelector->selectFromMap(block.tile, block.collision, block.elevation);
}
}

View file

@ -25,7 +25,7 @@ void MetatileLayersItem::draw() {
QPainter painter(&pixmap);
int numTiles = isTripleLayerMetatile ? 12 : 8;
for (int i = 0; i < numTiles; i++) {
Tile tile = this->metatile->tiles->at(i);
Tile tile = this->metatile->tiles.at(i);
QImage tileImage = getPalettedTileImage(tile.tile, this->primaryTileset, this->secondaryTileset, tile.palette, true)
.mirrored(tile.xflip, tile.yflip)
.scaled(16, 16);

View file

@ -12,13 +12,12 @@ QPoint MetatileSelector::getSelectionDimensions() {
}
void MetatileSelector::draw() {
if (!this->primaryTileset || !this->primaryTileset->metatiles
|| !this->secondaryTileset || !this->secondaryTileset->metatiles) {
if (!this->primaryTileset || !this->secondaryTileset) {
this->setPixmap(QPixmap());
}
int primaryLength = this->primaryTileset->metatiles->length();
int length_ = primaryLength + this->secondaryTileset->metatiles->length();
int primaryLength = this->primaryTileset->metatiles.length();
int length_ = primaryLength + this->secondaryTileset->metatiles.length();
int height_ = length_ / this->numMetatilesWide;
if (length_ % this->numMetatilesWide != 0) {
height_++;
@ -69,7 +68,7 @@ void MetatileSelector::setTilesets(Tileset *primaryTileset, Tileset *secondaryTi
if (this->externalSelection) {
this->select(0);
} else {
this->select(Project::getNumMetatilesPrimary() + this->secondaryTileset->metatiles->length() - 1);
this->select(Project::getNumMetatilesPrimary() + this->secondaryTileset->metatiles.length() - 1);
}
} else if (this->externalSelection) {
emit selectedMetatilesChanged();
@ -181,10 +180,10 @@ bool MetatileSelector::selectionIsValid() {
uint16_t MetatileSelector::getMetatileId(int x, int y) {
int index = y * this->numMetatilesWide + x;
if (index < this->primaryTileset->metatiles->length()) {
if (index < this->primaryTileset->metatiles.length()) {
return static_cast<uint16_t>(index);
} else {
return static_cast<uint16_t>(Project::getNumMetatilesPrimary() + index - this->primaryTileset->metatiles->length());
return static_cast<uint16_t>(Project::getNumMetatilesPrimary() + index - this->primaryTileset->metatiles.length());
}
}
@ -197,7 +196,7 @@ QPoint MetatileSelector::getMetatileIdCoords(uint16_t metatileId) {
int index = metatileId < Project::getNumMetatilesPrimary()
? metatileId
: metatileId - Project::getNumMetatilesPrimary() + this->primaryTileset->metatiles->length();
: metatileId - Project::getNumMetatilesPrimary() + this->primaryTileset->metatiles.length();
return QPoint(index % this->numMetatilesWide, index / this->numMetatilesWide);
}

View file

@ -7,8 +7,7 @@ NewEventToolButton::NewEventToolButton(QWidget *parent) :
QToolButton(parent)
{
setPopupMode(QToolButton::MenuButtonPopup);
QObject::connect(this, SIGNAL(triggered(QAction*)),
this, SLOT(setDefaultAction(QAction*)));
QObject::connect(this, &NewEventToolButton::triggered, this, &NewEventToolButton::setDefaultAction);
this->init();
}
@ -17,11 +16,11 @@ void NewEventToolButton::init()
// Add a context menu to select different types of map events.
this->newObjectAction = new QAction("New Object", this);
this->newObjectAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newObjectAction, SIGNAL(triggered(bool)), this, SLOT(newObject()));
connect(this->newObjectAction, &QAction::triggered, this, &NewEventToolButton::newObject);
this->newWarpAction = new QAction("New Warp", this);
this->newWarpAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newWarpAction, SIGNAL(triggered(bool)), this, SLOT(newWarp()));
connect(this->newWarpAction, &QAction::triggered, this, &NewEventToolButton::newWarp);
/* // disable this functionality for now
this->newHealLocationAction = new QAction("New Heal Location", this);
@ -31,23 +30,23 @@ void NewEventToolButton::init()
this->newTriggerAction = new QAction("New Trigger", this);
this->newTriggerAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newTriggerAction, SIGNAL(triggered(bool)), this, SLOT(newTrigger()));
connect(this->newTriggerAction, &QAction::triggered, this, &NewEventToolButton::newTrigger);
this->newWeatherTriggerAction = new QAction("New Weather Trigger", this);
this->newWeatherTriggerAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newWeatherTriggerAction, SIGNAL(triggered(bool)), this, SLOT(newWeatherTrigger()));
connect(this->newWeatherTriggerAction, &QAction::triggered, this, &NewEventToolButton::newWeatherTrigger);
this->newSignAction = new QAction("New Sign", this);
this->newSignAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newSignAction, SIGNAL(triggered(bool)), this, SLOT(newSign()));
connect(this->newSignAction, &QAction::triggered, this, &NewEventToolButton::newSign);
this->newHiddenItemAction = new QAction("New Hidden Item", this);
this->newHiddenItemAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newHiddenItemAction, SIGNAL(triggered(bool)), this, SLOT(newHiddenItem()));
connect(this->newHiddenItemAction, &QAction::triggered, this, &NewEventToolButton::newHiddenItem);
this->newSecretBaseAction = new QAction("New Secret Base", this);
this->newSecretBaseAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newSecretBaseAction, SIGNAL(triggered(bool)), this, SLOT(newSecretBase()));
connect(this->newSecretBaseAction, &QAction::triggered, this, &NewEventToolButton::newSecretBase);
QMenu *alignMenu = new QMenu();
alignMenu->addAction(this->newObjectAction);

View file

@ -64,14 +64,31 @@ bool NewMapPopup::checkNewMapDimensions() {
ui->label_NewMap_WarningMessage->clear();
return true;
}
};
}
bool NewMapPopup::checkNewMapGroup() {
group = project->groupNames.indexOf(this->ui->comboBox_NewMap_Group->currentText());
if (group < 0) {
ui->frame_NewMap_Warning->setVisible(true);
QString errorText = QString("Error: The specified map group '%1' does not exist.")
.arg(ui->comboBox_NewMap_Group->currentText());
ui->label_NewMap_WarningMessage->setText(errorText);
ui->label_NewMap_WarningMessage->setWordWrap(true);
return false;
} else {
ui->frame_NewMap_Warning->setVisible(false);
ui->label_NewMap_WarningMessage->clear();
return true;
}
}
void NewMapPopup::connectSignals() {
ui->spinBox_NewMap_Width->setMinimum(1);
ui->spinBox_NewMap_Height->setMinimum(1);
ui->spinBox_NewMap_Width->setMaximum(project->getMaxMapWidth());
ui->spinBox_NewMap_Height->setMaximum(project->getMaxMapHeight());
//ui->icon_NewMap_WarningIcon->setPixmap();
connect(ui->spinBox_NewMap_Width, QOverload<int>::of(&QSpinBox::valueChanged), [=](int){checkNewMapDimensions();});
connect(ui->spinBox_NewMap_Height, QOverload<int>::of(&QSpinBox::valueChanged), [=](int){checkNewMapDimensions();});
@ -89,8 +106,10 @@ void NewMapPopup::setDefaultValues(int groupNum, QString mapSec) {
ui->comboBox_NewMap_Primary_Tileset->addItems(tilesets.value("primary"));
ui->comboBox_NewMap_Secondary_Tileset->addItems(tilesets.value("secondary"));
ui->comboBox_NewMap_Group->addItems(*project->groupNames);
ui->comboBox_NewMap_Group->setCurrentText(project->groupNames->at(groupNum));
ui->comboBox_NewMap_Group->addItems(project->groupNames);
ui->comboBox_NewMap_Group->setCurrentText(project->groupNames.at(groupNum));
ui->comboBox_Song->addItems(project->getSongNames());
if (existingLayout) {
ui->spinBox_NewMap_Width->setValue(project->mapLayouts.value(layoutId)->width.toInt(nullptr, 0));
@ -110,7 +129,7 @@ void NewMapPopup::setDefaultValues(int groupNum, QString mapSec) {
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());
if (!mapSec.isEmpty()) ui->comboBox_NewMap_Location->setCurrentText(mapSec);
ui->checkBox_NewMap_Show_Location->setChecked(true);
@ -165,7 +184,7 @@ void NewMapPopup::setDefaultValues(int groupNum, QString mapSec) {
}
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();
QColor color = Qt::red;
color.setAlpha(25);
@ -177,8 +196,8 @@ void NewMapPopup::on_lineEdit_NewMap_Name_textChanged(const QString &text) {
}
void NewMapPopup::on_pushButton_NewMap_Accept_clicked() {
if (!checkNewMapDimensions()) {
// ignore when map dimensions are invalid
if (!checkNewMapDimensions() || !checkNewMapGroup()) {
// ignore when map dimensions or map group are invalid
return;
}
Map *newMap = new Map;
@ -188,18 +207,18 @@ void NewMapPopup::on_pushButton_NewMap_Accept_clicked() {
// After stripping invalid characters, strip any leading digits.
QString newMapName = this->ui->lineEdit_NewMap_Name->text().remove(QRegularExpression("[^a-zA-Z0-9_]+"));
newMapName.remove(QRegularExpression("^[0-9]*"));
if (project->mapNames->contains(newMapName) || newMapName.isEmpty()) {
if (project->mapNames.contains(newMapName) || newMapName.isEmpty()) {
newMapName = project->getNewMapName();
}
newMap->name = newMapName;
newMap->type = this->ui->comboBox_NewMap_Type->currentText();
newMap->location = this->ui->comboBox_NewMap_Location->currentText();
newMap->song = this->project->defaultSong;
newMap->song = this->ui->comboBox_Song->currentText();
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->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) {
layout = this->project->mapLayouts.value(this->layoutId);
@ -236,7 +255,6 @@ void NewMapPopup::on_pushButton_NewMap_Accept_clicked() {
newMap->floorNumber = this->ui->spinBox_NewMap_Floor_Number->value();
}
group = project->groupNames->indexOf(this->ui->comboBox_NewMap_Group->currentText());
newMap->layout = layout;
newMap->layoutId = layout->id;
if (this->existingLayout) {

View file

@ -151,9 +151,9 @@ void PaletteEditor::refreshColorSliders() {
for (int i = 0; i < 16; i++) {
QRgb color;
if (paletteNum < Project::getNumPalettesPrimary()) {
color = this->primaryTileset->palettes->at(paletteNum).at(i);
color = this->primaryTileset->palettes.at(paletteNum).at(i);
} else {
color = this->secondaryTileset->palettes->at(paletteNum).at(i);
color = this->secondaryTileset->palettes.at(paletteNum).at(i);
}
this->sliders[i][0]->setValue(qRed(color) / 8);
@ -204,8 +204,8 @@ void PaletteEditor::setColor(int colorIndex) {
Tileset *tileset = paletteNum < Project::getNumPalettesPrimary()
? this->primaryTileset
: this->secondaryTileset;
(*tileset->palettes)[paletteNum][colorIndex] = qRgb(red, green, blue);
(*tileset->palettePreviews)[paletteNum][colorIndex] = qRgb(red, green, blue);
tileset->palettes[paletteNum][colorIndex] = qRgb(red, green, blue);
tileset->palettePreviews[paletteNum][colorIndex] = qRgb(red, green, blue);
this->refreshColor(colorIndex);
this->commitEditHistory(paletteNum);
emit this->changedPaletteColor();
@ -255,11 +255,11 @@ void PaletteEditor::setColorsFromHistory(PaletteHistoryItem *history, int palett
for (int i = 0; i < 16; i++) {
if (paletteId < Project::getNumPalettesPrimary()) {
(*this->primaryTileset->palettes)[paletteId][i] = history->colors.at(i);
(*this->primaryTileset->palettePreviews)[paletteId][i] = history->colors.at(i);
this->primaryTileset->palettes[paletteId][i] = history->colors.at(i);
this->primaryTileset->palettePreviews[paletteId][i] = history->colors.at(i);
} else {
(*this->secondaryTileset->palettes)[paletteId][i] = history->colors.at(i);
(*this->secondaryTileset->palettePreviews)[paletteId][i] = history->colors.at(i);
this->secondaryTileset->palettes[paletteId][i] = history->colors.at(i);
this->secondaryTileset->palettePreviews[paletteId][i] = history->colors.at(i);
}
}
@ -279,9 +279,8 @@ void PaletteEditor::on_actionImport_Palette_triggered()
return;
}
PaletteUtil parser;
bool error = false;
QList<QRgb> palette = parser.parse(filepath, &error);
QList<QRgb> palette = PaletteUtil::parse(filepath, &error);
if (error) {
QMessageBox msgBox(this);
msgBox.setText("Failed to import palette.");
@ -307,11 +306,11 @@ void PaletteEditor::on_actionImport_Palette_triggered()
int paletteId = this->ui->spinBox_PaletteId->value();
for (int i = 0; i < 16; i++) {
if (paletteId < Project::getNumPalettesPrimary()) {
(*this->primaryTileset->palettes)[paletteId][i] = palette.at(i);
(*this->primaryTileset->palettePreviews)[paletteId][i] = palette.at(i);
this->primaryTileset->palettes[paletteId][i] = palette.at(i);
this->primaryTileset->palettePreviews[paletteId][i] = palette.at(i);
} else {
(*this->secondaryTileset->palettes)[paletteId][i] = palette.at(i);
(*this->secondaryTileset->palettePreviews)[paletteId][i] = palette.at(i);
this->secondaryTileset->palettes[paletteId][i] = palette.at(i);
this->secondaryTileset->palettePreviews[paletteId][i] = palette.at(i);
}
}

View file

@ -215,7 +215,7 @@ void RegionMapEditor::displayRegionMapLayoutOptions() {
void RegionMapEditor::updateRegionMapLayoutOptions(int index) {
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->blockSignals(false);
}
@ -438,7 +438,7 @@ void RegionMapEditor::onRegionMapLayoutSelectedTileChanged(int index) {
this->currIndex = index;
this->region_map_layout_item->highlightedTile = index;
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->ui->statusbar->showMessage(message);
@ -454,7 +454,7 @@ void RegionMapEditor::onRegionMapLayoutHoveredTileChanged(int index) {
if (x >= 0 && y >= 0) {
message = QString("(%1, %2)").arg(x).arg(y);
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}");
}
}
@ -551,7 +551,7 @@ void RegionMapEditor::on_tabWidget_Region_Map_currentChanged(int index) {
}
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
this->hasUnsavedChanges = true;// sometimes this is called for unknown reasons
}
@ -631,7 +631,7 @@ void RegionMapEditor::on_pushButton_CityMap_add_clicked() {
QString name;
form.addRow(&buttonBox);
connect(&buttonBox, SIGNAL(rejected()), &popup, SLOT(reject()));
connect(&buttonBox, &QDialogButtonBox::rejected, &popup, &QDialog::reject);
connect(&buttonBox, &QDialogButtonBox::accepted, [&popup, &input, &name](){
name = input->text().remove(QRegularExpression("[^a-zA-Z0-9_]+"));
if (!name.isEmpty())
@ -666,8 +666,8 @@ void RegionMapEditor::on_action_RegionMap_Resize_triggered() {
QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &popup);
form.addRow(&buttonBox);
connect(&buttonBox, SIGNAL(rejected()), &popup, SLOT(reject()));
connect(&buttonBox, SIGNAL(accepted()), &popup, SLOT(accept()));
connect(&buttonBox, &QDialogButtonBox::rejected, &popup, &QDialog::reject);
connect(&buttonBox, &QDialogButtonBox::accepted, &popup, &QDialog::accept);
if (popup.exec() == QDialog::Accepted) {
resize(widthSpinBox->value(), heightSpinBox->value());
@ -760,7 +760,7 @@ void RegionMapEditor::on_action_Swap_triggered() {
QString beforeSection, afterSection;
uint8_t oldId, newId;
connect(&buttonBox, SIGNAL(rejected()), &popup, SLOT(reject()));
connect(&buttonBox, &QDialogButtonBox::rejected, &popup, &QDialog::reject);
connect(&buttonBox, &QDialogButtonBox::accepted, [this, &popup, &oldSecBox, &newSecBox,
&beforeSection, &afterSection, &oldId, &newId](){
beforeSection = oldSecBox->currentText();

View file

@ -81,8 +81,8 @@ void TilesetEditor::setTilesets(QString primaryTilesetLabel, QString secondaryTi
Tileset *secondaryTileset = project->getTileset(secondaryTilesetLabel);
if (this->primaryTileset) delete this->primaryTileset;
if (this->secondaryTileset) delete this->secondaryTileset;
this->primaryTileset = primaryTileset->copy();
this->secondaryTileset = secondaryTileset->copy();
this->primaryTileset = new Tileset(*primaryTileset);
this->secondaryTileset = new Tileset(*secondaryTileset);
if (paletteEditor) paletteEditor->setTilesets(this->primaryTileset, this->secondaryTileset);
}
@ -157,12 +157,12 @@ void TilesetEditor::setMetatileLabelValidator() {
void TilesetEditor::initMetatileSelector()
{
this->metatileSelector = new TilesetEditorMetatileSelector(this->primaryTileset, this->secondaryTileset, this->map);
connect(this->metatileSelector, SIGNAL(hoveredMetatileChanged(uint16_t)),
this, SLOT(onHoveredMetatileChanged(uint16_t)));
connect(this->metatileSelector, SIGNAL(hoveredMetatileCleared()),
this, SLOT(onHoveredMetatileCleared()));
connect(this->metatileSelector, SIGNAL(selectedMetatileChanged(uint16_t)),
this, SLOT(onSelectedMetatileChanged(uint16_t)));
connect(this->metatileSelector, &TilesetEditorMetatileSelector::hoveredMetatileChanged,
this, &TilesetEditor::onHoveredMetatileChanged);
connect(this->metatileSelector, &TilesetEditorMetatileSelector::hoveredMetatileCleared,
this, &TilesetEditor::onHoveredMetatileCleared);
connect(this->metatileSelector, &TilesetEditorMetatileSelector::selectedMetatileChanged,
this, &TilesetEditor::onSelectedMetatileChanged);
this->metatilesScene = new QGraphicsScene;
this->metatilesScene->addItem(this->metatileSelector);
@ -175,10 +175,10 @@ void TilesetEditor::initMetatileSelector()
void TilesetEditor::initMetatileLayersItem() {
Metatile *metatile = Tileset::getMetatile(this->metatileSelector->getSelectedMetatile(), this->primaryTileset, this->secondaryTileset);
this->metatileLayersItem = new MetatileLayersItem(metatile, this->primaryTileset, this->secondaryTileset);
connect(this->metatileLayersItem, SIGNAL(tileChanged(int, int)),
this, SLOT(onMetatileLayerTileChanged(int, int)));
connect(this->metatileLayersItem, SIGNAL(selectedTilesChanged(QPoint, int, int)),
this, SLOT(onMetatileLayerSelectionChanged(QPoint, int, int)));
connect(this->metatileLayersItem, &MetatileLayersItem::tileChanged,
this, &TilesetEditor::onMetatileLayerTileChanged);
connect(this->metatileLayersItem, &MetatileLayersItem::selectedTilesChanged,
this, &TilesetEditor::onMetatileLayerSelectionChanged);
this->metatileLayersScene = new QGraphicsScene;
this->metatileLayersScene->addItem(this->metatileLayersItem);
@ -187,13 +187,14 @@ void TilesetEditor::initMetatileLayersItem() {
void TilesetEditor::initTileSelector()
{
this->tileSelector = new TilesetEditorTileSelector(this->primaryTileset, this->secondaryTileset, projectConfig.getTripleLayerMetatilesEnabled());
connect(this->tileSelector, SIGNAL(hoveredTileChanged(uint16_t)),
this, SLOT(onHoveredTileChanged(uint16_t)));
connect(this->tileSelector, SIGNAL(hoveredTileCleared()),
this, SLOT(onHoveredTileCleared()));
connect(this->tileSelector, SIGNAL(selectedTilesChanged()),
this, SLOT(onSelectedTilesChanged()));
this->tileSelector = new TilesetEditorTileSelector(this->primaryTileset, this->secondaryTileset,
projectConfig.getTripleLayerMetatilesEnabled());
connect(this->tileSelector, &TilesetEditorTileSelector::hoveredTileChanged,
this, &TilesetEditor::onHoveredTileChanged);
connect(this->tileSelector, &TilesetEditorTileSelector::hoveredTileCleared,
this, &TilesetEditor::onHoveredTileCleared);
connect(this->tileSelector, &TilesetEditorTileSelector::selectedTilesChanged,
this, &TilesetEditor::onSelectedTilesChanged);
this->tilesScene = new QGraphicsScene;
this->tilesScene->addItem(this->tileSelector);
@ -261,7 +262,7 @@ void TilesetEditor::restoreWindowState() {
}
void TilesetEditor::initMetatileHistory() {
MetatileHistoryItem *commit = new MetatileHistoryItem(0, nullptr, this->metatile->copy());
MetatileHistoryItem *commit = new MetatileHistoryItem(0, nullptr, new Metatile(*metatile));
metatileHistory.push(commit);
}
@ -360,7 +361,7 @@ void TilesetEditor::onSelectedTilesChanged() {
}
void TilesetEditor::onMetatileLayerTileChanged(int x, int y) {
const QList<QPoint> tileCoords = QList<QPoint>{
static const QList<QPoint> tileCoords = QList<QPoint>{
QPoint(0, 0),
QPoint(1, 0),
QPoint(0, 1),
@ -374,7 +375,7 @@ void TilesetEditor::onMetatileLayerTileChanged(int x, int y) {
QPoint(4, 1),
QPoint(5, 1),
};
Metatile *prevMetatile = this->metatile->copy();
Metatile *prevMetatile = new Metatile(*this->metatile);
QPoint dimensions = this->tileSelector->getSelectionDimensions();
QList<Tile> tiles = this->tileSelector->getSelectedTiles();
int selectedTileIndex = 0;
@ -386,11 +387,11 @@ void TilesetEditor::onMetatileLayerTileChanged(int x, int y) {
if (tileIndex < maxTileIndex
&& tileCoords.at(tileIndex).x() >= x
&& tileCoords.at(tileIndex).y() >= y){
Tile *tile = &(*this->metatile->tiles)[tileIndex];
tile->tile = tiles.at(selectedTileIndex).tile;
tile->xflip = tiles.at(selectedTileIndex).xflip;
tile->yflip = tiles.at(selectedTileIndex).yflip;
tile->palette = tiles.at(selectedTileIndex).palette;
Tile &tile = this->metatile->tiles[tileIndex];
tile.tile = tiles.at(selectedTileIndex).tile;
tile.xflip = tiles.at(selectedTileIndex).xflip;
tile.yflip = tiles.at(selectedTileIndex).yflip;
tile.palette = tiles.at(selectedTileIndex).palette;
}
selectedTileIndex++;
}
@ -400,7 +401,8 @@ void TilesetEditor::onMetatileLayerTileChanged(int x, int y) {
this->metatileLayersItem->draw();
this->hasUnsavedChanges = true;
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(), prevMetatile, this->metatile->copy());
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(),
prevMetatile, new Metatile(*this->metatile));
metatileHistory.push(commit);
}
@ -415,7 +417,7 @@ void TilesetEditor::onMetatileLayerSelectionChanged(QPoint selectionOrigin, int
for (int i = 0; i < width; i++) {
int tileIndex = ((x + i) / 2 * 4) + ((y + j) * 2) + ((x + i) % 2);
if (tileIndex < maxTileIndex) {
tiles.append(this->metatile->tiles->at(tileIndex));
tiles.append(this->metatile->tiles.at(tileIndex));
tileIdxs.append(tileIndex);
}
}
@ -464,9 +466,10 @@ void TilesetEditor::on_checkBox_yFlip_stateChanged(int checked)
void TilesetEditor::on_comboBox_metatileBehaviors_activated(const QString &metatileBehavior)
{
if (this->metatile) {
Metatile *prevMetatile = this->metatile->copy();
Metatile *prevMetatile = new Metatile(*this->metatile);
this->metatile->behavior = static_cast<uint8_t>(project->metatileBehaviorMap[metatileBehavior]);
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(), prevMetatile, this->metatile->copy());
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(),
prevMetatile, new Metatile(*this->metatile));
metatileHistory.push(commit);
this->hasUnsavedChanges = true;
}
@ -481,9 +484,10 @@ void TilesetEditor::saveMetatileLabel()
{
// Only commit if the field has changed.
if (this->metatile && this->metatile->label != this->ui->lineEdit_metatileLabel->text()) {
Metatile *prevMetatile = this->metatile->copy();
Metatile *prevMetatile = new Metatile(*this->metatile);
this->metatile->label = this->ui->lineEdit_metatileLabel->text();
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(), prevMetatile, this->metatile->copy());
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(),
prevMetatile, new Metatile(*this->metatile));
metatileHistory.push(commit);
this->hasUnsavedChanges = true;
}
@ -492,9 +496,10 @@ void TilesetEditor::saveMetatileLabel()
void TilesetEditor::on_comboBox_layerType_activated(int layerType)
{
if (this->metatile) {
Metatile *prevMetatile = this->metatile->copy();
Metatile *prevMetatile = new Metatile(*this->metatile);
this->metatile->layerType = static_cast<uint8_t>(layerType);
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(), prevMetatile, this->metatile->copy());
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(),
prevMetatile, new Metatile(*this->metatile));
metatileHistory.push(commit);
this->hasUnsavedChanges = true;
}
@ -503,9 +508,10 @@ void TilesetEditor::on_comboBox_layerType_activated(int layerType)
void TilesetEditor::on_comboBox_encounterType_activated(int encounterType)
{
if (this->metatile) {
Metatile *prevMetatile = this->metatile->copy();
Metatile *prevMetatile = new Metatile(*this->metatile);
this->metatile->encounterType = static_cast<uint8_t>(encounterType);
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(), prevMetatile, this->metatile->copy());
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(),
prevMetatile, new Metatile(*this->metatile));
metatileHistory.push(commit);
this->hasUnsavedChanges = true;
}
@ -514,9 +520,10 @@ void TilesetEditor::on_comboBox_encounterType_activated(int encounterType)
void TilesetEditor::on_comboBox_terrainType_activated(int terrainType)
{
if (this->metatile) {
Metatile *prevMetatile = this->metatile->copy();
Metatile *prevMetatile = new Metatile(*this->metatile);
this->metatile->terrainType = static_cast<uint8_t>(terrainType);
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(), prevMetatile, this->metatile->copy());
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(),
prevMetatile, new Metatile(*this->metatile));
metatileHistory.push(commit);
this->hasUnsavedChanges = true;
}
@ -619,9 +626,8 @@ void TilesetEditor::importTilesetTiles(Tileset *tileset, bool primary) {
return;
}
PaletteUtil parser;
bool error = false;
QList<QRgb> palette = parser.parse(filepath, &error);
QList<QRgb> palette = PaletteUtil::parse(filepath, &error);
if (error) {
QMessageBox msgBox(this);
msgBox.setText("Failed to import palette.");
@ -709,59 +715,49 @@ void TilesetEditor::on_actionChange_Metatiles_Count_triggered()
secondarySpinBox->setMinimum(1);
primarySpinBox->setMaximum(Project::getNumMetatilesPrimary());
secondarySpinBox->setMaximum(Project::getNumMetatilesTotal() - Project::getNumMetatilesPrimary());
primarySpinBox->setValue(this->primaryTileset->metatiles->length());
secondarySpinBox->setValue(this->secondaryTileset->metatiles->length());
primarySpinBox->setValue(this->primaryTileset->metatiles.length());
secondarySpinBox->setValue(this->secondaryTileset->metatiles.length());
form.addRow(new QLabel("Primary Tileset"), primarySpinBox);
form.addRow(new QLabel("Secondary Tileset"), secondarySpinBox);
QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
connect(&buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
connect(&buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
form.addRow(&buttonBox);
if (dialog.exec() == QDialog::Accepted) {
int numPrimaryMetatiles = primarySpinBox->value();
int numSecondaryMetatiles = secondarySpinBox->value();
int numTiles = projectConfig.getTripleLayerMetatilesEnabled() ? 12 : 8;
while (this->primaryTileset->metatiles->length() > numPrimaryMetatiles) {
Metatile *metatile = this->primaryTileset->metatiles->takeLast();
delete metatile;
while (this->primaryTileset->metatiles.length() > numPrimaryMetatiles) {
delete this->primaryTileset->metatiles.takeLast();
}
while (this->primaryTileset->metatiles->length() < numPrimaryMetatiles) {
Tile tile;
tile.palette = 0;
tile.tile = 0;
tile.xflip = false;
tile.yflip = false;
while (this->primaryTileset->metatiles.length() < numPrimaryMetatiles) {
Tile tile(0, false, false, 0);
Metatile *metatile = new Metatile;
metatile->behavior = 0;
metatile->layerType = 0;
metatile->encounterType = 0;
metatile->terrainType = 0;
for (int i = 0; i < numTiles; i++) {
metatile->tiles->append(tile);
metatile->tiles.append(tile);
}
this->primaryTileset->metatiles->append(metatile);
this->primaryTileset->metatiles.append(metatile);
}
while (this->secondaryTileset->metatiles->length() > numSecondaryMetatiles) {
Metatile *metatile = this->secondaryTileset->metatiles->takeLast();
delete metatile;
while (this->secondaryTileset->metatiles.length() > numSecondaryMetatiles) {
delete this->secondaryTileset->metatiles.takeLast();
}
while (this->secondaryTileset->metatiles->length() < numSecondaryMetatiles) {
Tile tile;
tile.palette = 0;
tile.tile = 0;
tile.xflip = 0;
tile.yflip = 0;
while (this->secondaryTileset->metatiles.length() < numSecondaryMetatiles) {
Tile tile(0, false, false, 0);
Metatile *metatile = new Metatile;
metatile->behavior = 0;
metatile->layerType = 0;
metatile->encounterType = 0;
metatile->terrainType = 0;
for (int i = 0; i < numTiles; i++) {
metatile->tiles->append(tile);
metatile->tiles.append(tile);
}
this->secondaryTileset->metatiles->append(metatile);
this->secondaryTileset->metatiles.append(metatile);
}
this->metatileSelector->updateSelectedMetatile();
@ -773,9 +769,12 @@ void TilesetEditor::on_actionChange_Metatiles_Count_triggered()
void TilesetEditor::on_actionChange_Palettes_triggered()
{
if (!this->paletteEditor) {
this->paletteEditor = new PaletteEditor(this->project, this->primaryTileset, this->secondaryTileset, this->paletteId, this);
connect(this->paletteEditor, SIGNAL(changedPaletteColor()), this, SLOT(onPaletteEditorChangedPaletteColor()));
connect(this->paletteEditor, SIGNAL(changedPalette(int)), this, SLOT(onPaletteEditorChangedPalette(int)));
this->paletteEditor = new PaletteEditor(this->project, this->primaryTileset,
this->secondaryTileset, this->paletteId, this);
connect(this->paletteEditor, &PaletteEditor::changedPaletteColor,
this, &TilesetEditor::onPaletteEditorChangedPaletteColor);
connect(this->paletteEditor, &PaletteEditor::changedPalette,
this, &TilesetEditor::onPaletteEditorChangedPalette);
}
if (!this->paletteEditor->isVisible()) {
@ -807,7 +806,7 @@ void TilesetEditor::on_actionUndo_triggered()
Metatile *temp = Tileset::getMetatile(commit->metatileId, this->primaryTileset, this->secondaryTileset);
if (temp) {
this->metatile = temp;
this->metatile->copyInPlace(prev);
*this->metatile = *prev;
this->metatileSelector->select(commit->metatileId);
this->metatileSelector->draw();
this->metatileLayersItem->draw();
@ -824,8 +823,8 @@ void TilesetEditor::on_actionRedo_triggered()
Metatile *temp = Tileset::getMetatile(commit->metatileId, this->primaryTileset, this->secondaryTileset);
if (temp) {
this->metatile = Tileset::getMetatile(commit->metatileId, this->primaryTileset, this->secondaryTileset);
this->metatile->copyInPlace(next);
this->metatile = temp;
*this->metatile = *next;
this->metatileSelector->select(commit->metatileId);
this->metatileSelector->draw();
this->metatileLayersItem->draw();
@ -879,9 +878,8 @@ void TilesetEditor::importTilesetMetatiles(Tileset *tileset, bool primary)
return;
}
MetatileParser parser;
bool error = false;
QList<Metatile*> *metatiles = parser.parse(filepath, &error, primary);
QList<Metatile*> metatiles = MetatileParser::parse(filepath, &error, primary);
if (error) {
QMessageBox msgBox(this);
msgBox.setText("Failed to import metatiles from Advance Map 1.92 .bvd file.");
@ -896,13 +894,14 @@ void TilesetEditor::importTilesetMetatiles(Tileset *tileset, bool primary)
// TODO: This is crude because it makes a history entry for every newly-imported metatile.
// Revisit this when tiles and num metatiles are added to tileset editory history.
int metatileIdBase = primary ? 0 : Project::getNumMetatilesPrimary();
for (int i = 0; i < metatiles->length(); i++) {
if (i >= tileset->metatiles->length()) {
for (int i = 0; i < metatiles.length(); i++) {
if (i >= tileset->metatiles.length()) {
break;
}
Metatile *prevMetatile = tileset->metatiles->at(i)->copy();
MetatileHistoryItem *commit = new MetatileHistoryItem(static_cast<uint16_t>(metatileIdBase + i), prevMetatile, metatiles->at(i)->copy());
Metatile *prevMetatile = new Metatile(*tileset->metatiles.at(i));
MetatileHistoryItem *commit = new MetatileHistoryItem(static_cast<uint16_t>(metatileIdBase + i),
prevMetatile, new Metatile(*metatiles.at(i)));
metatileHistory.push(commit);
}

View file

@ -4,13 +4,12 @@
#include <QPainter>
void TilesetEditorMetatileSelector::draw() {
if (!this->primaryTileset || !this->primaryTileset->metatiles
|| !this->secondaryTileset || !this->secondaryTileset->metatiles) {
if (!this->primaryTileset || !this->secondaryTileset) {
this->setPixmap(QPixmap());
}
int primaryLength = this->primaryTileset->metatiles->length();
int length_ = primaryLength + this->secondaryTileset->metatiles->length();
int primaryLength = this->primaryTileset->metatiles.length();
int length_ = primaryLength + this->secondaryTileset->metatiles.length();
int height_ = length_ / this->numMetatilesWide;
if (length_ % this->numMetatilesWide != 0) {
height_++;
@ -63,7 +62,7 @@ void TilesetEditorMetatileSelector::updateSelectedMetatile() {
if (Tileset::metatileIsValid(metatileId, this->primaryTileset, this->secondaryTileset))
this->selectedMetatile = metatileId;
else
this->selectedMetatile = Project::getNumMetatilesPrimary() + this->secondaryTileset->metatiles->length() - 1;
this->selectedMetatile = Project::getNumMetatilesPrimary() + this->secondaryTileset->metatiles.length() - 1;
emit selectedMetatileChanged(this->selectedMetatile);
}
@ -73,10 +72,10 @@ uint16_t TilesetEditorMetatileSelector::getSelectedMetatile() {
uint16_t TilesetEditorMetatileSelector::getMetatileId(int x, int y) {
int index = y * this->numMetatilesWide + x;
if (index < this->primaryTileset->metatiles->length()) {
if (index < this->primaryTileset->metatiles.length()) {
return static_cast<uint16_t>(index);
} else {
return static_cast<uint16_t>(Project::getNumMetatilesPrimary() + index - this->primaryTileset->metatiles->length());
return static_cast<uint16_t>(Project::getNumMetatilesPrimary() + index - this->primaryTileset->metatiles.length());
}
}
@ -119,10 +118,10 @@ QPoint TilesetEditorMetatileSelector::getMetatileIdCoords(uint16_t metatileId) {
{
// Invalid metatile id.
return QPoint(0, 0);
}
}
int index = metatileId < Project::getNumMetatilesPrimary()
? metatileId
: metatileId - Project::getNumMetatilesPrimary() + this->primaryTileset->metatiles->length();
: metatileId - Project::getNumMetatilesPrimary() + this->primaryTileset->metatiles.length();
return QPoint(index % this->numMetatilesWide, index / this->numMetatilesWide);
}

View file

@ -13,14 +13,13 @@ QPoint TilesetEditorTileSelector::getSelectionDimensions() {
}
void TilesetEditorTileSelector::draw() {
if (!this->primaryTileset || !this->primaryTileset->tiles
|| !this->secondaryTileset || !this->secondaryTileset->tiles) {
if (!this->primaryTileset || !this->secondaryTileset) {
this->setPixmap(QPixmap());
}
int totalTiles = Project::getNumTilesTotal();
int primaryLength = this->primaryTileset->tiles->length();
int secondaryLength = this->secondaryTileset->tiles->length();
int primaryLength = this->primaryTileset->tiles.length();
int secondaryLength = this->secondaryTileset->tiles.length();
int height = totalTiles / this->numTilesWide;
QList<QRgb> palette = Tileset::getPalette(this->paletteId, this->primaryTileset, this->secondaryTileset, true);
QImage image(this->numTilesWide * 16, height * 16, QImage::Format_RGBA8888);
@ -218,12 +217,11 @@ QPoint TilesetEditorTileSelector::getTileCoordsOnWidget(uint16_t tile) {
}
QImage TilesetEditorTileSelector::buildPrimaryTilesIndexedImage() {
if (!this->primaryTileset || !this->primaryTileset->tiles
|| !this->secondaryTileset || !this->secondaryTileset->tiles) {
if (!this->primaryTileset || !this->secondaryTileset) {
return QImage();
}
int primaryLength = this->primaryTileset->tiles->length();
int primaryLength = this->primaryTileset->tiles.length();
int height = qCeil(primaryLength / static_cast<double>(this->numTilesWide));
QImage image(this->numTilesWide * 8, height * 8, QImage::Format_RGBA8888);
@ -254,12 +252,11 @@ QImage TilesetEditorTileSelector::buildPrimaryTilesIndexedImage() {
}
QImage TilesetEditorTileSelector::buildSecondaryTilesIndexedImage() {
if (!this->primaryTileset || !this->primaryTileset->tiles
|| !this->secondaryTileset || !this->secondaryTileset->tiles) {
if (!this->primaryTileset || !this->secondaryTileset) {
return QImage();
}
int secondaryLength = this->secondaryTileset->tiles->length();
int secondaryLength = this->secondaryTileset->tiles.length();
int height = qCeil(secondaryLength / static_cast<double>(this->numTilesWide));
QImage image(this->numTilesWide * 8, height * 8, QImage::Format_RGBA8888);