Merge branch 'master' into new-map-config
This commit is contained in:
commit
07f1dd7a62
10 changed files with 43003 additions and 19 deletions
|
@ -162,6 +162,7 @@ public:
|
||||||
this->newMapElevation = 3;
|
this->newMapElevation = 3;
|
||||||
this->newMapBorderMetatileIds = DEFAULT_BORDER_RSE;
|
this->newMapBorderMetatileIds = DEFAULT_BORDER_RSE;
|
||||||
this->prefabFilepath = QString();
|
this->prefabFilepath = QString();
|
||||||
|
this->prefabImportPrompted = false;
|
||||||
this->customScripts.clear();
|
this->customScripts.clear();
|
||||||
this->readKeys.clear();
|
this->readKeys.clear();
|
||||||
}
|
}
|
||||||
|
@ -205,7 +206,9 @@ public:
|
||||||
void setCustomScripts(QList<QString> scripts);
|
void setCustomScripts(QList<QString> scripts);
|
||||||
QList<QString> getCustomScripts();
|
QList<QString> getCustomScripts();
|
||||||
void setPrefabFilepath(QString filepath);
|
void setPrefabFilepath(QString filepath);
|
||||||
QString getPrefabFilepath();
|
QString getPrefabFilepath(bool setIfEmpty);
|
||||||
|
void setPrefabImportPrompted(bool prompted);
|
||||||
|
bool getPrefabImportPrompted();
|
||||||
protected:
|
protected:
|
||||||
virtual QString getConfigFilepath() override;
|
virtual QString getConfigFilepath() override;
|
||||||
virtual void parseConfigKeyValue(QString key, QString value) override;
|
virtual void parseConfigKeyValue(QString key, QString value) override;
|
||||||
|
@ -234,6 +237,7 @@ private:
|
||||||
QList<QString> customScripts;
|
QList<QString> customScripts;
|
||||||
QStringList readKeys;
|
QStringList readKeys;
|
||||||
QString prefabFilepath;
|
QString prefabFilepath;
|
||||||
|
bool prefabImportPrompted;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ProjectConfig projectConfig;
|
extern ProjectConfig projectConfig;
|
||||||
|
|
|
@ -33,6 +33,7 @@ class MetatileSelector: public SelectablePixmapItem {
|
||||||
public:
|
public:
|
||||||
MetatileSelector(int numMetatilesWide, Map *map): SelectablePixmapItem(16, 16) {
|
MetatileSelector(int numMetatilesWide, Map *map): SelectablePixmapItem(16, 16) {
|
||||||
this->externalSelection = false;
|
this->externalSelection = false;
|
||||||
|
this->prefabSelection = false;
|
||||||
this->numMetatilesWide = numMetatilesWide;
|
this->numMetatilesWide = numMetatilesWide;
|
||||||
this->map = map;
|
this->map = map;
|
||||||
this->primaryTileset = map->layout->tileset_primary;
|
this->primaryTileset = map->layout->tileset_primary;
|
||||||
|
@ -46,7 +47,7 @@ public:
|
||||||
bool selectFromMap(uint16_t metatileId, uint16_t collision, uint16_t elevation);
|
bool selectFromMap(uint16_t metatileId, uint16_t collision, uint16_t elevation);
|
||||||
void setTilesets(Tileset*, Tileset*);
|
void setTilesets(Tileset*, Tileset*);
|
||||||
MetatileSelection getMetatileSelection();
|
MetatileSelection getMetatileSelection();
|
||||||
void setDirectSelection(MetatileSelection selection);
|
void setPrefabSelection(MetatileSelection selection);
|
||||||
void setExternalSelection(int, int, QList<uint16_t>, QList<QPair<uint16_t, uint16_t>>);
|
void setExternalSelection(int, int, QList<uint16_t>, QList<QPair<uint16_t, uint16_t>>);
|
||||||
QPoint getMetatileIdCoordsOnWidget(uint16_t);
|
QPoint getMetatileIdCoordsOnWidget(uint16_t);
|
||||||
void setMap(Map*);
|
void setMap(Map*);
|
||||||
|
@ -60,6 +61,7 @@ protected:
|
||||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent*);
|
void hoverLeaveEvent(QGraphicsSceneHoverEvent*);
|
||||||
private:
|
private:
|
||||||
bool externalSelection;
|
bool externalSelection;
|
||||||
|
bool prefabSelection;
|
||||||
int numMetatilesWide;
|
int numMetatilesWide;
|
||||||
Map *map;
|
Map *map;
|
||||||
int externalSelectionWidth;
|
int externalSelectionWidth;
|
||||||
|
|
|
@ -23,6 +23,7 @@ public:
|
||||||
void initPrefabUI(MetatileSelector *selector, QWidget *prefabWidget, QLabel *emptyPrefabLabel, Map *map);
|
void initPrefabUI(MetatileSelector *selector, QWidget *prefabWidget, QLabel *emptyPrefabLabel, Map *map);
|
||||||
void addPrefab(MetatileSelection selection, Map *map, QString name);
|
void addPrefab(MetatileSelection selection, Map *map, QString name);
|
||||||
void updatePrefabUi(Map *map);
|
void updatePrefabUi(Map *map);
|
||||||
|
void handlePrefabImport();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MetatileSelector *selector;
|
MetatileSelector *selector;
|
||||||
|
|
|
@ -3,5 +3,8 @@
|
||||||
<file>text/region_map_default_emerald.json</file>
|
<file>text/region_map_default_emerald.json</file>
|
||||||
<file>text/region_map_default_firered.json</file>
|
<file>text/region_map_default_firered.json</file>
|
||||||
<file>text/region_map_default_ruby.json</file>
|
<file>text/region_map_default_ruby.json</file>
|
||||||
|
<file>text/prefabs_default_emerald.json</file>
|
||||||
|
<file>text/prefabs_default_firered.json</file>
|
||||||
|
<file>text/prefabs_default_ruby.json</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
19429
resources/text/prefabs_default_emerald.json
Normal file
19429
resources/text/prefabs_default_emerald.json
Normal file
File diff suppressed because it is too large
Load diff
11712
resources/text/prefabs_default_firered.json
Normal file
11712
resources/text/prefabs_default_firered.json
Normal file
File diff suppressed because it is too large
Load diff
11732
resources/text/prefabs_default_ruby.json
Normal file
11732
resources/text/prefabs_default_ruby.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -504,6 +504,8 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
|
||||||
}
|
}
|
||||||
} else if (key == "prefabs_filepath") {
|
} else if (key == "prefabs_filepath") {
|
||||||
this->prefabFilepath = value;
|
this->prefabFilepath = value;
|
||||||
|
} else if (key == "prefabs_import_prompted") {
|
||||||
|
setConfigBool(key, &this->prefabImportPrompted, value);
|
||||||
} else {
|
} else {
|
||||||
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
|
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
|
||||||
}
|
}
|
||||||
|
@ -549,6 +551,7 @@ QMap<QString, QString> ProjectConfig::getKeyValueMap() {
|
||||||
map.insert("new_map_border_metatiles", metatiles.join(","));
|
map.insert("new_map_border_metatiles", metatiles.join(","));
|
||||||
map.insert("custom_scripts", this->customScripts.join(","));
|
map.insert("custom_scripts", this->customScripts.join(","));
|
||||||
map.insert("prefabs_filepath", this->prefabFilepath);
|
map.insert("prefabs_filepath", this->prefabFilepath);
|
||||||
|
map.insert("prefabs_import_prompted", QString::number(this->prefabImportPrompted));
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -776,14 +779,22 @@ void ProjectConfig::setPrefabFilepath(QString filepath) {
|
||||||
this->save();
|
this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ProjectConfig::getPrefabFilepath() {
|
QString ProjectConfig::getPrefabFilepath(bool setIfEmpty) {
|
||||||
if (this->prefabFilepath.isEmpty()) {
|
if (setIfEmpty && this->prefabFilepath.isEmpty()) {
|
||||||
// Default to the <projectroot>/prefabs.json, if no path exists.
|
this->setPrefabFilepath("prefabs.json");
|
||||||
this->setPrefabFilepath(QDir(this->projectDir).filePath("prefabs.json"));
|
|
||||||
}
|
}
|
||||||
return this->prefabFilepath;
|
return this->prefabFilepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectConfig::setPrefabImportPrompted(bool prompted) {
|
||||||
|
this->prefabImportPrompted = prompted;
|
||||||
|
this->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProjectConfig::getPrefabImportPrompted() {
|
||||||
|
return this->prefabImportPrompted;
|
||||||
|
}
|
||||||
|
|
||||||
ShortcutsConfig shortcutsConfig;
|
ShortcutsConfig shortcutsConfig;
|
||||||
|
|
||||||
QString ShortcutsConfig::getConfigFilepath() {
|
QString ShortcutsConfig::getConfigFilepath() {
|
||||||
|
|
|
@ -36,7 +36,7 @@ void MetatileSelector::draw() {
|
||||||
painter.end();
|
painter.end();
|
||||||
this->setPixmap(QPixmap::fromImage(image));
|
this->setPixmap(QPixmap::fromImage(image));
|
||||||
|
|
||||||
if (!this->externalSelection || (this->externalSelectionWidth == 1 && this->externalSelectionHeight == 1)) {
|
if (!this->prefabSelection && (!this->externalSelection || (this->externalSelectionWidth == 1 && this->externalSelectionHeight == 1))) {
|
||||||
this->drawSelection();
|
this->drawSelection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,13 @@ void MetatileSelector::draw() {
|
||||||
bool MetatileSelector::select(uint16_t metatileId) {
|
bool MetatileSelector::select(uint16_t metatileId) {
|
||||||
if (!Tileset::metatileIsValid(metatileId, this->primaryTileset, this->secondaryTileset)) return false;
|
if (!Tileset::metatileIsValid(metatileId, this->primaryTileset, this->secondaryTileset)) return false;
|
||||||
this->externalSelection = false;
|
this->externalSelection = false;
|
||||||
|
this->prefabSelection = false;
|
||||||
|
this->selection = MetatileSelection{
|
||||||
|
QPoint(1, 1),
|
||||||
|
false,
|
||||||
|
QList<MetatileSelectionItem>({MetatileSelectionItem{true, metatileId}}),
|
||||||
|
QList<CollisionSelectionItem>(),
|
||||||
|
};
|
||||||
QPoint coords = this->getMetatileIdCoords(metatileId);
|
QPoint coords = this->getMetatileIdCoords(metatileId);
|
||||||
SelectablePixmapItem::select(coords.x(), coords.y(), 0, 0);
|
SelectablePixmapItem::select(coords.x(), coords.y(), 0, 0);
|
||||||
this->updateSelectedMetatiles();
|
this->updateSelectedMetatiles();
|
||||||
|
@ -73,6 +80,7 @@ MetatileSelection MetatileSelector::getMetatileSelection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetatileSelector::setExternalSelection(int width, int height, QList<uint16_t> metatiles, QList<QPair<uint16_t, uint16_t>> collisions) {
|
void MetatileSelector::setExternalSelection(int width, int height, QList<uint16_t> metatiles, QList<QPair<uint16_t, uint16_t>> collisions) {
|
||||||
|
this->prefabSelection = false;
|
||||||
this->externalSelection = true;
|
this->externalSelection = true;
|
||||||
this->externalSelectionWidth = width;
|
this->externalSelectionWidth = width;
|
||||||
this->externalSelectionHeight = height;
|
this->externalSelectionHeight = height;
|
||||||
|
@ -95,8 +103,9 @@ void MetatileSelector::setExternalSelection(int width, int height, QList<uint16_
|
||||||
emit selectedMetatilesChanged();
|
emit selectedMetatilesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetatileSelector::setDirectSelection(MetatileSelection selection) {
|
void MetatileSelector::setPrefabSelection(MetatileSelection selection) {
|
||||||
this->externalSelection = false;
|
this->externalSelection = false;
|
||||||
|
this->prefabSelection = true;
|
||||||
this->externalSelectedMetatiles.clear();
|
this->externalSelectedMetatiles.clear();
|
||||||
this->selection = selection;
|
this->selection = selection;
|
||||||
this->draw();
|
this->draw();
|
||||||
|
@ -142,6 +151,7 @@ void MetatileSelector::hoverLeaveEvent(QGraphicsSceneHoverEvent*) {
|
||||||
|
|
||||||
void MetatileSelector::updateSelectedMetatiles() {
|
void MetatileSelector::updateSelectedMetatiles() {
|
||||||
this->externalSelection = false;
|
this->externalSelection = false;
|
||||||
|
this->prefabSelection = false;
|
||||||
this->selection.metatileItems.clear();
|
this->selection.metatileItems.clear();
|
||||||
this->selection.collisionItems.clear();
|
this->selection.collisionItems.clear();
|
||||||
this->selection.hasCollision = false;
|
this->selection.hasCollision = false;
|
||||||
|
|
|
@ -21,17 +21,18 @@ using OrderedJsonDoc = poryjson::JsonDoc;
|
||||||
|
|
||||||
void Prefab::loadPrefabs() {
|
void Prefab::loadPrefabs() {
|
||||||
this->items.clear();
|
this->items.clear();
|
||||||
QString filepath = projectConfig.getPrefabFilepath();
|
QString filepath = projectConfig.getPrefabFilepath(false);
|
||||||
if (filepath.isEmpty()) return;
|
if (filepath.isEmpty()) return;
|
||||||
|
|
||||||
ParseUtil parser;
|
ParseUtil parser;
|
||||||
QJsonDocument prefabDoc;
|
QJsonDocument prefabDoc;
|
||||||
|
QFileInfo info(filepath);
|
||||||
|
if (info.isRelative()) {
|
||||||
|
filepath = QDir::cleanPath(projectConfig.getProjectDir() + QDir::separator() + filepath);
|
||||||
|
}
|
||||||
if (!QFile::exists(filepath) || !parser.tryParseJsonFile(&prefabDoc, filepath)) {
|
if (!QFile::exists(filepath) || !parser.tryParseJsonFile(&prefabDoc, filepath)) {
|
||||||
QString relativePath = QDir::cleanPath(projectConfig.getProjectDir() + QDir::separator() + filepath);
|
logError(QString("Failed to read prefab data from %1").arg(filepath));
|
||||||
if (!parser.tryParseJsonFile(&prefabDoc, relativePath)) {
|
return;
|
||||||
logError(QString("Failed to prefab data from %1").arg(filepath));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonArray prefabs = prefabDoc.array();
|
QJsonArray prefabs = prefabDoc.array();
|
||||||
|
@ -84,11 +85,22 @@ void Prefab::loadPrefabs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Prefab::savePrefabs() {
|
void Prefab::savePrefabs() {
|
||||||
QString filepath = projectConfig.getPrefabFilepath();
|
QString filepath = projectConfig.getPrefabFilepath(true);
|
||||||
if (filepath.isEmpty()) return;
|
if (filepath.isEmpty()) return;
|
||||||
|
|
||||||
|
QFileInfo info(filepath);
|
||||||
|
if (info.isRelative()) {
|
||||||
|
filepath = QDir::cleanPath(projectConfig.getProjectDir() + QDir::separator() + filepath);
|
||||||
|
}
|
||||||
QFile prefabsFile(filepath);
|
QFile prefabsFile(filepath);
|
||||||
if (!prefabsFile.open(QIODevice::WriteOnly)) {
|
if (!prefabsFile.open(QIODevice::WriteOnly)) {
|
||||||
logError(QString("Error: Could not open %1 for writing").arg(filepath));
|
logError(QString("Error: Could not open %1 for writing").arg(filepath));
|
||||||
|
QMessageBox messageBox;
|
||||||
|
messageBox.setText("Failed to save prefabs file!");
|
||||||
|
messageBox.setInformativeText(QString("Could not open \"%1\" for writing").arg(filepath));
|
||||||
|
messageBox.setDetailedText("Any created prefabs will not be available next time Porymap is opened. Please fix your prefabs_filepath in the Porymap project config file.");
|
||||||
|
messageBox.setIcon(QMessageBox::Warning);
|
||||||
|
messageBox.exec();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,13 +118,15 @@ void Prefab::savePrefabs() {
|
||||||
int index = y * item.selection.dimensions.x() + x;
|
int index = y * item.selection.dimensions.x() + x;
|
||||||
auto metatileItem = item.selection.metatileItems.at(index);
|
auto metatileItem = item.selection.metatileItems.at(index);
|
||||||
if (metatileItem.enabled) {
|
if (metatileItem.enabled) {
|
||||||
auto collisionItem = item.selection.collisionItems.at(index);
|
|
||||||
OrderedJson::object metatileObj;
|
OrderedJson::object metatileObj;
|
||||||
metatileObj["x"] = x;
|
metatileObj["x"] = x;
|
||||||
metatileObj["y"] = y;
|
metatileObj["y"] = y;
|
||||||
metatileObj["metatile_id"] = metatileItem.metatileId;
|
metatileObj["metatile_id"] = metatileItem.metatileId;
|
||||||
metatileObj["collision"] = collisionItem.collision;
|
if (item.selection.hasCollision && index < item.selection.collisionItems.size()) {
|
||||||
metatileObj["elevation"] = collisionItem.elevation;
|
auto collisionItem = item.selection.collisionItems.at(index);
|
||||||
|
metatileObj["collision"] = collisionItem.collision;
|
||||||
|
metatileObj["elevation"] = collisionItem.elevation;
|
||||||
|
}
|
||||||
metatiles.push_back(metatileObj);
|
metatiles.push_back(metatileObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,6 +159,7 @@ void Prefab::initPrefabUI(MetatileSelector *selector, QWidget *prefabWidget, QLa
|
||||||
this->selector = selector;
|
this->selector = selector;
|
||||||
this->prefabWidget = prefabWidget;
|
this->prefabWidget = prefabWidget;
|
||||||
this->emptyPrefabLabel = emptyPrefabLabel;
|
this->emptyPrefabLabel = emptyPrefabLabel;
|
||||||
|
this->handlePrefabImport();
|
||||||
this->loadPrefabs();
|
this->loadPrefabs();
|
||||||
this->updatePrefabUi(map);
|
this->updatePrefabUi(map);
|
||||||
}
|
}
|
||||||
|
@ -194,7 +209,7 @@ void Prefab::updatePrefabUi(Map *map) {
|
||||||
|
|
||||||
// Clicking on the prefab graphics item selects it for painting.
|
// Clicking on the prefab graphics item selects it for painting.
|
||||||
QObject::connect(frame->ui->graphicsView_Prefab, &ClickableGraphicsView::clicked, [this, item](){
|
QObject::connect(frame->ui->graphicsView_Prefab, &ClickableGraphicsView::clicked, [this, item](){
|
||||||
selector->setDirectSelection(item.selection);
|
selector->setPrefabSelection(item.selection);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Clicking the delete button removes it from the list of known prefabs and updates the UI.
|
// Clicking the delete button removes it from the list of known prefabs and updates the UI.
|
||||||
|
@ -254,4 +269,69 @@ void Prefab::addPrefab(MetatileSelection selection, Map *map, QString name) {
|
||||||
this->updatePrefabUi(map);
|
this->updatePrefabUi(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Prefab::handlePrefabImport() {
|
||||||
|
BaseGameVersion version = projectConfig.getBaseGameVersion();
|
||||||
|
// Ensure we have default prefabs for the project's game version.
|
||||||
|
if (version != BaseGameVersion::pokeruby && version != BaseGameVersion::pokeemerald && version != BaseGameVersion::pokefirered)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Exit early if the user has already setup prefabs.
|
||||||
|
if (!projectConfig.getPrefabFilepath(false).isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Exit early if the user has already gone through this import prompt before.
|
||||||
|
if (projectConfig.getPrefabImportPrompted())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Display a dialog box to the user, asking if the default prefabs should be imported
|
||||||
|
// into their project.
|
||||||
|
QMessageBox::StandardButton prompt =
|
||||||
|
QMessageBox::question(nullptr,
|
||||||
|
"Import Default Prefabs",
|
||||||
|
QString("Would you like to import the default prefabs for %1? This will create a file called 'prefabs.json' in your project directory.")
|
||||||
|
.arg(projectConfig.getBaseGameVersionString()),
|
||||||
|
QMessageBox::Yes | QMessageBox::No);
|
||||||
|
|
||||||
|
if (prompt == QMessageBox::Yes) {
|
||||||
|
// Sets up the default prefabs.json filepath.
|
||||||
|
QString filepath = projectConfig.getPrefabFilepath(true);
|
||||||
|
|
||||||
|
QFileInfo info(filepath);
|
||||||
|
if (info.isRelative()) {
|
||||||
|
filepath = QDir::cleanPath(projectConfig.getProjectDir() + QDir::separator() + filepath);
|
||||||
|
}
|
||||||
|
QFile prefabsFile(filepath);
|
||||||
|
if (!prefabsFile.open(QIODevice::WriteOnly)) {
|
||||||
|
projectConfig.setPrefabFilepath(QString());
|
||||||
|
|
||||||
|
logError(QString("Error: Could not open %1 for writing").arg(filepath));
|
||||||
|
QMessageBox messageBox;
|
||||||
|
messageBox.setText("Failed to import default prefabs file!");
|
||||||
|
messageBox.setInformativeText(QString("Could not open \"%1\" for writing").arg(filepath));
|
||||||
|
messageBox.setIcon(QMessageBox::Warning);
|
||||||
|
messageBox.exec();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseUtil parser;
|
||||||
|
QString content;
|
||||||
|
switch (version) {
|
||||||
|
case BaseGameVersion::pokeruby:
|
||||||
|
content = parser.readTextFile(":/text/prefabs_default_ruby.json");
|
||||||
|
break;
|
||||||
|
case BaseGameVersion::pokefirered:
|
||||||
|
content = parser.readTextFile(":/text/prefabs_default_firered.json");
|
||||||
|
break;
|
||||||
|
case BaseGameVersion::pokeemerald:
|
||||||
|
content = parser.readTextFile(":/text/prefabs_default_emerald.json");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
prefabsFile.write(content.toUtf8());
|
||||||
|
prefabsFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
projectConfig.setPrefabImportPrompted(true);
|
||||||
|
}
|
||||||
|
|
||||||
Prefab prefab;
|
Prefab prefab;
|
||||||
|
|
Loading…
Reference in a new issue