diff --git a/editor.cpp b/editor.cpp index 4a56cdb3..3c374ebc 100755 --- a/editor.cpp +++ b/editor.cpp @@ -4,6 +4,8 @@ #include #include +bool selectingEvent = false; + Editor::Editor(Ui::MainWindow* ui) { this->ui = ui; @@ -469,6 +471,8 @@ void Editor::displayMapEvents() { delete events_group; } + selected_events->clear(); + events_group = new EventGroup; scene->addItem(events_group); @@ -484,8 +488,7 @@ void Editor::displayMapEvents() { } DraggablePixmapItem *Editor::addMapEvent(Event *event) { - DraggablePixmapItem *object = new DraggablePixmapItem(event); - object->editor = this; + DraggablePixmapItem *object = new DraggablePixmapItem(event, this); events_group->addToGroup(object); return object; } @@ -808,16 +811,22 @@ void Editor::updateDiveEmergeMap(QString mapName, QString direction) { void Editor::updatePrimaryTileset(QString tilesetLabel) { - map->layout->tileset_primary_label = tilesetLabel; - map->layout->tileset_primary = project->getTileset(tilesetLabel); - emit tilesetChanged(map->name); + if (map->layout->tileset_primary_label != tilesetLabel) + { + map->layout->tileset_primary_label = tilesetLabel; + map->layout->tileset_primary = project->getTileset(tilesetLabel); + emit tilesetChanged(map->name); + } } void Editor::updateSecondaryTileset(QString tilesetLabel) { - map->layout->tileset_secondary_label = tilesetLabel; - map->layout->tileset_secondary = project->getTileset(tilesetLabel); - emit tilesetChanged(map->name); + if (map->layout->tileset_secondary_label != tilesetLabel) + { + map->layout->tileset_secondary_label = tilesetLabel; + map->layout->tileset_secondary = project->getTileset(tilesetLabel); + emit tilesetChanged(map->name); + } } void MetatilesPixmapItem::paintTileChanged(Map *map) { @@ -1471,9 +1480,11 @@ void CollisionPixmapItem::pick(QGraphicsSceneMouseEvent *event) { void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) { active = true; - clicking = true; last_x = (mouse->pos().x() + this->pos().x()) / 16; last_y = (mouse->pos().y() + this->pos().y()) / 16; + this->editor->selectMapEvent(this, mouse->modifiers() & Qt::ControlModifier); + this->editor->updateSelectedEvents(); + selectingEvent = true; //qDebug() << QString("(%1, %2)").arg(event->get("x")).arg(event->get("y")); } @@ -1489,7 +1500,6 @@ void DraggablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouse) { int x = (mouse->pos().x() + this->pos().x()) / 16; int y = (mouse->pos().y() + this->pos().y()) / 16; if (x != last_x || y != last_y) { - clicking = false; if (editor->selected_events->contains(this)) { for (DraggablePixmapItem *item : *editor->selected_events) { item->move(x - last_x, y - last_y); @@ -1505,13 +1515,15 @@ void DraggablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouse) { } void DraggablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouse) { - if (clicking) { - this->editor->selectMapEvent(this, mouse->modifiers() & Qt::ControlModifier); - this->editor->updateSelectedEvents(); - } active = false; } +void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouse) { + if (this->event->get("event_type") == EventType::Warp) { + emit editor->warpEventDoubleClicked(this->event->get("destination_map_name"), this->event->get("destination_warp")); + } +} + QList *Editor::getObjects() { QList *list = new QList; for (Event *event : map->getAllEvents()) { @@ -1532,7 +1544,7 @@ void Editor::redrawObject(DraggablePixmapItem *item) { if (selected_events && selected_events->contains(item)) { QImage image = item->pixmap().toImage(); QPainter painter(&image); - painter.setPen(QColor(250, 100, 25)); + painter.setPen(QColor(250, 0, 255)); painter.drawRect(0, 0, image.width() - 1, image.height() - 1); painter.end(); item->setPixmap(QPixmap::fromImage(image)); @@ -1589,39 +1601,19 @@ void Editor::deleteEvent(Event *event) { //updateSelectedObjects(); } -// dunno how to detect bubbling. QMouseEvent::isAccepted seems to always be true -// check if selected_events changed instead. this has the side effect of deselecting -// when you click on a selected event, since selected_events doesn't change. - -QList selected_events_test; -bool clicking = false; - +// It doesn't seem to be possible to prevent the mousePress event +// from triggering both event's DraggablePixmapItem and the background mousePress. +// Since the DraggablePixmapItem's event fires first, we can set a temp +// variable "selectingEvent" so that we can detect whether or not the user +// is clicking on the background instead of an event. void Editor::objectsView_onMousePress(QMouseEvent *event) { - clicking = true; - selected_events_test = *selected_events; -} - -void Editor::objectsView_onMouseMove(QMouseEvent *event) { - clicking = false; -} - -void Editor::objectsView_onMouseRelease(QMouseEvent *event) { - if (clicking) { - if (selected_events_test.length()) { - if (selected_events_test.length() == selected_events->length()) { - bool deselect = true; - for (int i = 0; i < selected_events_test.length(); i++) { - if (selected_events_test.at(i) != selected_events->at(i)) { - deselect = false; - break; - } - } - if (deselect) { - selected_events->clear(); - updateSelectedEvents(); - } - } - } - clicking = false; + bool multiSelect = event->modifiers() & Qt::ControlModifier; + if (!selectingEvent && !multiSelect && selected_events->length() > 1) { + DraggablePixmapItem *first = selected_events->first(); + selected_events->clear(); + selected_events->append(first); + updateSelectedEvents(); } + + selectingEvent = false; } diff --git a/editor.h b/editor.h index c096d1a5..ba51c4aa 100755 --- a/editor.h +++ b/editor.h @@ -138,6 +138,7 @@ signals: void selectedObjectsChanged(); void loadMapRequested(QString, QString); void tilesetChanged(QString); + void warpEventDoubleClicked(QString mapName, QString warpNum); }; @@ -150,13 +151,12 @@ public: Editor *editor = NULL; Event *event = NULL; QGraphicsItemAnimation *pos_anim = NULL; - DraggablePixmapItem(Event *event_) : QGraphicsPixmapItem(event_->pixmap) { + DraggablePixmapItem(Event *event_, Editor *editor_) : QGraphicsPixmapItem(event_->pixmap) { event = event_; + editor = editor_; updatePosition(); } bool active; - bool right_click; - bool clicking; int last_x; int last_y; void updatePosition() { @@ -229,6 +229,7 @@ protected: void mousePressEvent(QGraphicsSceneMouseEvent*); void mouseMoveEvent(QGraphicsSceneMouseEvent*); void mouseReleaseEvent(QGraphicsSceneMouseEvent*); + void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*); }; class EventGroup : public QGraphicsItemGroup { diff --git a/event.cpp b/event.cpp index 6b47972e..e26b4540 100755 --- a/event.cpp +++ b/event.cpp @@ -43,13 +43,13 @@ Event* Event::createNewObjectEvent() event->put("event_group_type", "object_event_group"); event->put("event_type", EventType::Object); event->put("sprite", "EVENT_OBJ_GFX_BOY_1"); - event->put("behavior", "1"); + event->put("movement_type", "MOVEMENT_TYPE_LOOK_AROUND"); event->put("radius_x", 0); event->put("radius_y", 0); event->put("script_label", "NULL"); event->put("event_flag", "0"); event->put("replacement", "0"); - event->put("trainer_see_type", "0"); + event->put("is_trainer", "FALSE"); event->put("sight_radius_tree_id", 0); return event; } @@ -89,7 +89,7 @@ Event* Event::createNewSignEvent() Event *event = new Event; event->put("event_group_type", "bg_event_group"); event->put("event_type", EventType::Sign); - event->put("player_facing_direction", "0"); + event->put("player_facing_direction", "BG_EVENT_PLAYER_FACING_ANY"); event->put("script_label", "NULL"); return event; } @@ -109,7 +109,7 @@ Event* Event::createNewSecretBaseEvent() Event *event = new Event; event->put("event_group_type", "bg_event_group"); event->put("event_type", EventType::SecretBase); - event->put("secret_base_map", "SECRET_BASE_RED_CAVE2_1"); + event->put("secret_base_id", "SECRET_BASE_RED_CAVE2_1"); return event; } @@ -127,10 +127,10 @@ QString Event::buildObjectEventMacro(int item_index) text += QString(", %1").arg(x); text += QString(", %1").arg(y); text += QString(", %1").arg(this->get("elevation")); - text += QString(", %1").arg(this->get("behavior")); + text += QString(", %1").arg(this->get("movement_type")); text += QString(", %1").arg(radius_x); text += QString(", %1").arg(radius_y); - text += QString(", %1").arg(this->get("trainer_see_type")); + text += QString(", %1").arg(this->get("is_trainer")); text += QString(", %1").arg(this->get("sight_radius_tree_id")); text += QString(", %1").arg(this->get("script_label")); text += QString(", %1").arg(this->get("event_flag")); @@ -156,10 +156,8 @@ QString Event::buildCoordScriptEventMacro() text += QString("\tcoord_event %1").arg(this->get("x")); text += QString(", %1").arg(this->get("y")); text += QString(", %1").arg(this->get("elevation")); - text += QString(", 0"); text += QString(", %1").arg(this->get("script_var")); text += QString(", %1").arg(this->get("script_var_value")); - text += QString(", 0"); text += QString(", %1").arg(this->get("script_label")); text += "\n"; return text; @@ -183,7 +181,6 @@ QString Event::buildSignEventMacro() text += QString(", %1").arg(this->get("y")); text += QString(", %1").arg(this->get("elevation")); text += QString(", %1").arg(this->get("player_facing_direction")); - text += QString(", 0"); text += QString(", %1").arg(this->get("script_label")); text += "\n"; return text; @@ -207,7 +204,7 @@ QString Event::buildSecretBaseEventMacro() text += QString("\tbg_secret_base_event %1").arg(this->get("x")); text += QString(", %1").arg(this->get("y")); text += QString(", %1").arg(this->get("elevation")); - text += QString(", %1").arg(this->get("secret_base_map")); + text += QString(", %1").arg(this->get("secret_base_id")); text += "\n"; return text; } diff --git a/graphicsview.cpp b/graphicsview.cpp index 361ec3a9..02204103 100755 --- a/graphicsview.cpp +++ b/graphicsview.cpp @@ -10,14 +10,8 @@ void GraphicsView::mousePressEvent(QMouseEvent *event) { void GraphicsView::mouseMoveEvent(QMouseEvent *event) { QGraphicsView::mouseMoveEvent(event); - if (editor) { - editor->objectsView_onMouseMove(event); - } } void GraphicsView::mouseReleaseEvent(QMouseEvent *event) { QGraphicsView::mouseReleaseEvent(event); - if (editor) { - editor->objectsView_onMouseRelease(event); - } } diff --git a/mainwindow.cpp b/mainwindow.cpp index 87254a63..038e829b 100755 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -37,6 +37,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(editor, SIGNAL(selectedObjectsChanged()), this, SLOT(updateSelectedObjects())); connect(editor, SIGNAL(loadMapRequested(QString, QString)), this, SLOT(onLoadMapRequested(QString, QString))); connect(editor, SIGNAL(tilesetChanged(QString)), this, SLOT(onTilesetChanged(QString))); + connect(editor, SIGNAL(warpEventDoubleClicked(QString,QString)), this, SLOT(openWarpMap(QString,QString))); on_toolButton_Paint_clicked(); @@ -196,6 +197,39 @@ void MainWindow::redrawMapScene() ui->graphicsView_Elevation->setFixedSize(editor->elevation_metatiles_item->pixmap().width() + 2, editor->elevation_metatiles_item->pixmap().height() + 2); } +void MainWindow::openWarpMap(QString map_name, QString warp_num) { + // Ensure valid destination map name. + if (!editor->project->mapNames->contains(map_name)) { + qDebug() << QString("Invalid warp destination map name '%1'").arg(map_name); + return; + } + + // Ensure valid destination warp number. + bool ok; + int warpNum = warp_num.toInt(&ok, 0); + if (!ok) { + qDebug() << QString("Invalid warp number '%1' for destination map '%2'").arg(warp_num).arg(map_name); + return; + } + + // Open the destination map, and select the target warp event. + setMap(map_name); + QList warp_events = editor->map->events["warp_event_group"]; + if (warp_events.length() > warpNum) { + Event *warp_event = warp_events.at(warpNum); + QList *all_events = editor->getObjects(); + for (DraggablePixmapItem *item : *all_events) { + if (item->event == warp_event) { + editor->selected_events->clear(); + editor->selected_events->append(item); + editor->updateSelectedEvents(); + } + } + + delete all_events; + } +} + void MainWindow::setRecentMap(QString map_name) { QSettings settings; QString key = "project:" + editor->project->root; @@ -210,7 +244,7 @@ void MainWindow::setRecentMap(QString map_name) { void MainWindow::displayMapProperties() { ui->comboBox_Song->clear(); ui->comboBox_Location->clear(); - ui->comboBox_Visibility->clear(); + ui->checkBox_Visibility->setChecked(false); ui->comboBox_Weather->clear(); ui->comboBox_Type->clear(); ui->comboBox_BattleScene->clear(); @@ -229,7 +263,7 @@ void MainWindow::displayMapProperties() { ui->comboBox_Song->addItems(songs); ui->comboBox_Song->setCurrentText(map->song); - ui->comboBox_Location->addItems(project->getLocations()); + ui->comboBox_Location->addItems(*project->regionMapSections); ui->comboBox_Location->setCurrentText(map->location); QMap tilesets = project->getTilesets(); @@ -238,16 +272,15 @@ void MainWindow::displayMapProperties() { ui->comboBox_SecondaryTileset->addItems(tilesets.value("secondary")); ui->comboBox_SecondaryTileset->setCurrentText(map->layout->tileset_secondary_label); - ui->comboBox_Visibility->addItems(project->getVisibilities()); - ui->comboBox_Visibility->setCurrentText(map->visibility); + ui->checkBox_Visibility->setChecked(map->requiresFlash.toInt() > 0 || map->requiresFlash == "TRUE"); - ui->comboBox_Weather->addItems(project->getWeathers()); + ui->comboBox_Weather->addItems(*project->weatherNames); ui->comboBox_Weather->setCurrentText(map->weather); - ui->comboBox_Type->addItems(project->getMapTypes()); + ui->comboBox_Type->addItems(*project->mapTypes); ui->comboBox_Type->setCurrentText(map->type); - ui->comboBox_BattleScene->addItems(project->getBattleScenes()); + ui->comboBox_BattleScene->addItems(*project->mapBattleScenes); ui->comboBox_BattleScene->setCurrentText(map->battle_scene); ui->checkBox_ShowLocation->setChecked(map->show_location.toInt() > 0 || map->show_location == "TRUE"); @@ -267,10 +300,10 @@ void MainWindow::on_comboBox_Location_activated(const QString &location) } } -void MainWindow::on_comboBox_Visibility_activated(const QString &visibility) +void MainWindow::on_comboBox_Visibility_activated(const QString &requiresFlash) { if (editor && editor->map) { - editor->map->visibility = visibility; + editor->map->requiresFlash = requiresFlash; } } @@ -295,6 +328,17 @@ void MainWindow::on_comboBox_BattleScene_activated(const QString &battle_scene) } } +void MainWindow::on_checkBox_Visibility_clicked(bool checked) +{ + if (editor && editor->map) { + if (checked) { + editor->map->requiresFlash = "TRUE"; + } else { + editor->map->requiresFlash = "FALSE"; + } + } +} + void MainWindow::on_checkBox_ShowLocation_clicked(bool checked) { if (editor && editor->map) { @@ -310,9 +354,17 @@ void MainWindow::loadDataStructures() { Project *project = editor->project; project->readMapLayoutsTable(); project->readAllMapLayouts(); + project->readRegionMapSections(); project->readItemNames(); project->readFlagNames(); project->readVarNames(); + project->readMovementTypes(); + project->readMapTypes(); + project->readMapBattleScenes(); + project->readWeatherNames(); + project->readCoordEventWeatherNames(); + project->readSecretBaseIds(); + project->readBgEventFacingDirections(); project->readMapsWithConnections(); } @@ -544,12 +596,19 @@ void MainWindow::addNewEvent(QString event_type) // Should probably just pass layout and let the editor work it out void MainWindow::updateSelectedObjects() { - QList *all_events = editor->getObjects(); - QList *events = all_events; + QList *events = NULL; if (editor->selected_events && editor->selected_events->length()) { events = editor->selected_events; + } else { + events = new QList; + if (all_events && all_events->length()) { + DraggablePixmapItem *selectedEvent = all_events->first(); + editor->selected_events->append(selectedEvent); + editor->redrawObject(selectedEvent); + events->append(selectedEvent); + } } QMap event_obj_gfx_constants = editor->project->getEventObjGfxConstants(); @@ -597,11 +656,10 @@ void MainWindow::updateSelectedObjects() { QMap field_labels; field_labels["script_label"] = "Script"; field_labels["event_flag"] = "Event Flag"; - field_labels["replacement"] = "Replacement"; - field_labels["behavior"] = "Behavior"; + field_labels["movement_type"] = "Movement"; field_labels["radius_x"] = "Movement Radius X"; field_labels["radius_y"] = "Movement Radius Y"; - field_labels["trainer_see_type"] = "Trainer See Type"; + field_labels["is_trainer"] = "Trainer"; field_labels["sight_radius_tree_id"] = "Sight Radius / Berry Tree ID"; field_labels["destination_warp"] = "Destination Warp"; field_labels["destination_map_name"] = "Destination Map"; @@ -613,7 +671,7 @@ void MainWindow::updateSelectedObjects() { field_labels["item_unknown6"] = "Unknown 6"; field_labels["weather"] = "Weather"; field_labels["flag"] = "Flag"; - field_labels["secret_base_map"] = "Secret Base Map"; + field_labels["secret_base_id"] = "Secret Base Id"; QStringList fields; @@ -634,13 +692,12 @@ void MainWindow::updateSelectedObjects() { //connect(item, SIGNAL(scriptChanged(QString)), frame->ui->comboBox_script, SLOT(setValue(QString))); */ - fields << "behavior"; + fields << "movement_type"; fields << "radius_x"; fields << "radius_y"; fields << "script_label"; fields << "event_flag"; - fields << "replacement"; - fields << "trainer_see_type"; + fields << "is_trainer"; fields << "sight_radius_tree_id"; } else if (event_type == EventType::Warp) { @@ -664,37 +721,96 @@ void MainWindow::updateSelectedObjects() { fields << "flag"; } else if (event_type == EventType::SecretBase) { - fields << "secret_base_map"; + fields << "secret_base_id"; } for (QString key : fields) { + QString value = item->event->get(key); QWidget *widget = new QWidget(frame); QFormLayout *fl = new QFormLayout(widget); fl->setContentsMargins(9, 0, 9, 0); - QComboBox *combo = new QComboBox(widget); + + // is_trainer is the only non-combobox item. + if (key == "is_trainer") { + QCheckBox *checkbox = new QCheckBox(widget); + checkbox->setEnabled(true); + checkbox->setChecked(value.toInt() != 0 && value != "FALSE"); + checkbox->setToolTip("Whether or not this object is trainer."); + fl->addRow(new QLabel(field_labels[key], widget), checkbox); + widget->setLayout(fl); + frame->layout()->addWidget(widget); + connect(checkbox, &QCheckBox::stateChanged, [=](int state) { + QString isTrainer = state == Qt::Checked ? "TRUE" : "FALSE"; + item->event->put("is_trainer", isTrainer); + }); + continue; + } + + NoScrollComboBox *combo = new NoScrollComboBox(widget); combo->setEditable(true); - QString value = item->event->get(key); if (key == "destination_map_name") { if (!editor->project->mapNames->contains(value)) { combo->addItem(value); } combo->addItems(*editor->project->mapNames); + 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)) { combo->addItem(value); } combo->addItems(*editor->project->itemNames); - } else if (key == "flag") { + } else if (key == "flag" || key == "event_flag") { if (!editor->project->flagNames->contains(value)) { combo->addItem(value); } combo->addItems(*editor->project->flagNames); + 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)) { combo->addItem(value); } combo->addItems(*editor->project->varNames); + combo->setToolTip("The variable by which the script is triggered. 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)) { + combo->addItem(value); + } + combo->addItems(*editor->project->movementTypes); + combo->setToolTip("The object's natural movement behavior when the player is not interacting with it."); + } else if (key == "weather") { + if (!editor->project->coordEventWeatherNames->contains(value)) { + combo->addItem(value); + } + combo->addItems(*editor->project->coordEventWeatherNames); + 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)) { + combo->addItem(value); + } + combo->addItems(*editor->project->secretBaseIds); + combo->setToolTip("The secret base id which is inside this secret base entrance. Secret base ids are meant to be unique to each and every secret base entrance."); + } else if (key == "player_facing_direction") { + if (!editor->project->bgEventFacingDirections->contains(value)) { + combo->addItem(value); + } + combo->addItems(*editor->project->bgEventFacingDirections); + combo->setToolTip("The direction which the player must be facing to be able to interact with this event."); + } else if (key == "radius_x") { + combo->setToolTip("The maximum number of metatiles this object is allowed to move left or right during its normal movement behavior actions."); + } else if (key == "radius_y") { + combo->setToolTip("The maximum number of metatiles this object is allowed to move up or down during its normal movement behavior actions."); + } else if (key == "script_label") { + combo->setToolTip("The script which is executed with this event."); + } else if (key == "sight_radius_tree_id") { + combo->setToolTip("The maximum sight range of a trainer, OR the unique id of the berry tree."); } else { combo->addItem(value); } diff --git a/mainwindow.h b/mainwindow.h index 04b4cdb6..f7a3fe0e 100755 --- a/mainwindow.h +++ b/mainwindow.h @@ -32,6 +32,7 @@ private slots: void on_action_Open_Project_triggered(); void on_mapList_activated(const QModelIndex &index); void on_action_Save_Project_triggered(); + void openWarpMap(QString map_name, QString warp_num); void undo(); void redo(); @@ -98,6 +99,8 @@ private slots: void on_checkBox_smartPaths_stateChanged(int selected); + void on_checkBox_Visibility_clicked(bool checked); + private: Ui::MainWindow *ui; QStandardItemModel *mapListModel; diff --git a/mainwindow.ui b/mainwindow.ui index 59f41023..1c0ab3c7 100755 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -69,6 +69,9 @@ false + + + :/icons/map.ico:/icons/map.ico @@ -76,6 +79,9 @@ Map + + <html><head/><body><p>Edit the map layout.</p><p>Select metatiles or collision attributes from the right panel, and paint them onto the map.</p></body></html> + 0 @@ -164,6 +170,9 @@ true + + <html><head/><body><p>Pencil</p><p>Click and drag to draw on the map.</p></body></html> + Paint @@ -187,6 +196,9 @@ true + + <html><head/><body><p>Pointer</p><p>Does nothing</p></body></html> + Select @@ -201,6 +213,9 @@ + + <html><head/><body><p>Flood Fill</p><p>Fills all similar tiles in a region with the selected metatiles or collision attributes</p></body></html> + Fill @@ -215,6 +230,9 @@ + + <html><head/><body><p>Eye Dropper</p><p>Click to select a metatile or collision attribute.</p></body></html> + Dropper @@ -229,6 +247,9 @@ + + <html><head/><body><p>Smart-path mode allows easier drawing of paths. If a 3x3 metatile block is selcted in the right panel, then smart path mode will automatically form a pathway using those selected blocks.</p><p>When smart-path mode is <span style=" font-weight:600;">not</span> enabled, clicking and dragging a selection will tile it in a grid.</p></body></html> + margin-left: 10px @@ -239,6 +260,9 @@ + + <html><head/><body><p>Toggles a grid over the map's metatile boundaries.</p></body></html> + @@ -262,6 +286,9 @@ + + <html><head/><body><p>Change a map layout's width and height.</p></body></html> + Change Dimensions @@ -490,7 +517,13 @@ - + + + Qt::StrongFocus + + + <html><head/><body><p>Primary Tileset</p><p>Defines the first 0x200 metatiles available for the map.</p></body></html> + true @@ -504,7 +537,13 @@ - + + + Qt::StrongFocus + + + <html><head/><body><p>Secondary Tileset</p><p>Defines the second 0x200 metatiles available for the map.</p></body></html> + true @@ -574,6 +613,9 @@ 48 + + <html><head/><body><p>The border is a 2x2 metatile which is repeated outside of the map layout's boundary. Draw on this border area to modify it.</p></body></html> + QFrame::StyledPanel @@ -846,7 +888,10 @@ true - Objects + Events + + + <html><head/><body><p>Edit the map's events.</p><p>View and modify objects, warps, signs, etc.</p></body></html> @@ -1107,6 +1152,9 @@ 32 + + <html><head/><body><p>Add a new event to the map.</p></body></html> + New Object @@ -1133,6 +1181,9 @@ 32 + + <html><head/><body><p>Delete the selected event from the map.</p></body></html> + Delete @@ -1172,7 +1223,7 @@ - Attributes + Header @@ -1182,211 +1233,146 @@ 10 10 - 301 - 251 + 381 + 311 + + + 0 + 0 + + QFrame::StyledPanel QFrame::Raised - - - - 20 - 30 - 47 - 21 - + + + 12 - - Song - - - - - - 20 - 60 - 47 - 21 - - - - Location - - - - - - 20 - 90 - 47 - 21 - - - - Visibility - - - - - - 20 - 120 - 47 - 21 - - - - Weather - - - - - - 20 - 150 - 47 - 21 - - - - Type - - - - - - 20 - 180 - 101 - 21 - - - - Show location name - - - - - - 20 - 210 - 81 - 21 - - - - Battle scene - - - - - - 80 - 60 - 211 - 22 - - - - true - - - - - - 80 - 90 - 211 - 22 - - - - true - - - - - - 80 - 30 - 211 - 22 - - - - true - - - - - - 80 - 120 - 211 - 22 - - - - true - - - - - - 80 - 150 - 211 - 22 - - - - true - - - - - - 90 - 210 - 201 - 22 - - - - true - - - - - - 130 - 180 - 161 - 21 - - - - - - - - - - 0 - 0 - 47 - 13 - - - - Header - - + + + + Song + + + + + + + <html><head/><body><p>The default background music for this map.</p></body></html> + + + true + + + + + + + Location + + + + + + + <html><head/><body><p>The section of the region map which the map is grouped under. This also determines the name of the map that is display when the player enters it.</p></body></html> + + + true + + + + + + + Requires Flash + + + + + + + Weather + + + + + + + <html><head/><body><p>The default weather for this map.</p></body></html> + + + true + + + + + + + Type + + + + + + + <html><head/><body><p>The map type is a general attribute, which is used for many different things. For example. it determines whether biking or running is allowed.</p></body></html> + + + true + + + + + + + Show Location Name + + + + + + + <html><head/><body><p>Whether or not to display the location name when the player enters the map.</p></body></html> + + + + + + + + + + Battle scene + + + + + + + <html><head/><body><p>Determines the type of battle scene graphics to use.</p></body></html> + + + true + + + + + + + <html><head/><body><p>Whether or not the map is dark and requires Flash to illuminate.</p></body></html> + + + + + + + @@ -1480,6 +1466,9 @@ 0 + + <html><head/><body><p>Add a new connection.</p></body></html> + @@ -1492,6 +1481,9 @@ + + <html><head/><body><p>Remove the currently-selected connection.</p></body></html> + @@ -1540,6 +1532,9 @@ 0 + + <html><head/><body><p>If enabled, connections will automatically be updated on the connected map.</p></body></html> + Mirror @@ -1602,6 +1597,9 @@ + + <html><head/><body><p>The direction of the connection.</p></body></html> + up @@ -1649,6 +1647,9 @@ + + <html><head/><body><p>The destination map name of the connection.</p></body></html> + true @@ -1663,6 +1664,9 @@ + + <html><head/><body><p>The number of metatiles to offset the connection.</p></body></html> + -999 @@ -1840,6 +1844,9 @@ + + <html><head/><body><p>Destination map name when using <span style=" font-weight:600;">Dive</span>. If empty, no such connection will exist.</p></body></html> + true @@ -1854,6 +1861,9 @@ + + <html><head/><body><p>Destination map name when emerging using <span style=" font-weight:600;">Dive</span>. If empty, no such connection will exist.</p></body></html> + true @@ -1989,6 +1999,11 @@ QToolButton
neweventtoolbutton.h
+ + NoScrollComboBox + QComboBox +
noscrollcombobox.h
+
diff --git a/map.h b/map.h index 1270ce3b..e634f556 100755 --- a/map.h +++ b/map.h @@ -127,7 +127,7 @@ public: QString song; QString layout_id; QString location; - QString visibility; + QString requiresFlash; QString weather; QString type; QString unknown; diff --git a/noscrollcombobox.cpp b/noscrollcombobox.cpp new file mode 100644 index 00000000..723289d9 --- /dev/null +++ b/noscrollcombobox.cpp @@ -0,0 +1,15 @@ +#include "noscrollcombobox.h" + +NoScrollComboBox::NoScrollComboBox(QWidget *parent) + : QComboBox(parent) +{ + // Don't let scrolling hijack focus. + setFocusPolicy(Qt::StrongFocus); +} + +void NoScrollComboBox::wheelEvent(QWheelEvent *event) +{ + // Only allow scrolling to modify contents when it explicitly has focus. + if (hasFocus()) + QComboBox::wheelEvent(event); +} diff --git a/noscrollcombobox.h b/noscrollcombobox.h new file mode 100644 index 00000000..1291c7e9 --- /dev/null +++ b/noscrollcombobox.h @@ -0,0 +1,17 @@ +#ifndef NOSCROLLCOMBOBOX_H +#define NOSCROLLCOMBOBOX_H + +#include + +class NoScrollComboBox : public QComboBox +{ + Q_OBJECT + +public: + explicit NoScrollComboBox(QWidget *parent = nullptr); + void wheelEvent(QWheelEvent *event); + +private: +}; + +#endif // NOSCROLLCOMBOBOX_H diff --git a/noscrollspinbox.cpp b/noscrollspinbox.cpp new file mode 100644 index 00000000..026a145c --- /dev/null +++ b/noscrollspinbox.cpp @@ -0,0 +1,16 @@ +#include "noscrollspinbox.h" + +NoScrollSpinBox::NoScrollSpinBox(QWidget *parent) + : QSpinBox(parent) +{ + // Don't let scrolling hijack focus. + setFocusPolicy(Qt::StrongFocus); +} + +void NoScrollSpinBox::wheelEvent(QWheelEvent *event) +{ + // Only allow scrolling to modify contents when it explicitly has focus. + if (hasFocus()) + QSpinBox::wheelEvent(event); +} + diff --git a/noscrollspinbox.h b/noscrollspinbox.h new file mode 100644 index 00000000..d9361f6f --- /dev/null +++ b/noscrollspinbox.h @@ -0,0 +1,17 @@ +#ifndef NOSCROLLSPINBOX_H +#define NOSCROLLSPINBOX_H + +#include + +class NoScrollSpinBox : public QSpinBox +{ + Q_OBJECT + +public: + explicit NoScrollSpinBox(QWidget *parent = nullptr); + void wheelEvent(QWheelEvent *event); + +private: +}; + +#endif // NOSCROLLSPINBOX_H diff --git a/objectpropertiesframe.ui b/objectpropertiesframe.ui index c11aaa6d..5ff1fa32 100755 --- a/objectpropertiesframe.ui +++ b/objectpropertiesframe.ui @@ -105,7 +105,13 @@
- + + + Qt::StrongFocus + + + <html><head/><body><p>The X coordinate of this object.</p></body></html> + -32768 @@ -129,7 +135,13 @@ - + + + Qt::StrongFocus + + + <html><head/><body><p>The Y coordinate of this object.</p></body></html> + -32768 @@ -153,7 +165,13 @@ - + + + Qt::StrongFocus + + + <html><head/><body><p>The elevation of this object.</p></body></html> + 15 @@ -210,7 +228,7 @@ - + true @@ -220,6 +238,12 @@ 0 + + Qt::StrongFocus + + + <html><head/><body><p>The sprite graphics to use for this object.</p></body></html> + true @@ -239,6 +263,18 @@
+ + + NoScrollComboBox + QComboBox +
noscrollcombobox.h
+
+ + NoScrollSpinBox + QSpinBox +
noscrollspinbox.h
+
+
spinBox_x spinBox_y diff --git a/pretmap.pro b/pretmap.pro index 5e722c11..96014047 100755 --- a/pretmap.pro +++ b/pretmap.pro @@ -25,7 +25,9 @@ SOURCES += main.cpp\ objectpropertiesframe.cpp \ graphicsview.cpp \ parseutil.cpp \ - neweventtoolbutton.cpp + neweventtoolbutton.cpp \ + noscrollcombobox.cpp \ + noscrollspinbox.cpp HEADERS += mainwindow.h \ project.h \ @@ -39,7 +41,9 @@ HEADERS += mainwindow.h \ objectpropertiesframe.h \ graphicsview.h \ parseutil.h \ - neweventtoolbutton.h + neweventtoolbutton.h \ + noscrollcombobox.h \ + noscrollspinbox.h FORMS += mainwindow.ui \ objectpropertiesframe.ui diff --git a/project.cpp b/project.cpp index 68b7a742..fd352dfa 100755 --- a/project.cpp +++ b/project.cpp @@ -17,9 +17,17 @@ Project::Project() groupNames = new QStringList; map_groups = new QMap; mapNames = new QStringList; + regionMapSections = new QStringList; itemNames = new QStringList; flagNames = new QStringList; varNames = new QStringList; + movementTypes = new QStringList; + mapTypes = new QStringList; + mapBattleScenes = new QStringList; + weatherNames = new QStringList; + coordEventWeatherNames = new QStringList; + secretBaseIds = new QStringList; + bgEventFacingDirections = new QStringList; map_cache = new QMap; mapConstantsToMapNames = new QMap; mapNamesToMapConstants = new QMap; @@ -164,7 +172,7 @@ void Project::readMapHeader(Map* map) { map->song = header->value(4); map->layout_id = header->value(5); map->location = header->value(6); - map->visibility = header->value(7); + map->requiresFlash = header->value(7); map->weather = header->value(8); map->type = header->value(9); map->unknown = header->value(10); @@ -179,13 +187,13 @@ void Project::setNewMapHeader(Map* map, int mapIndex) { map->connections_label = "0x0"; map->song = "MUS_DAN02"; map->layout_id = QString("%1").arg(mapIndex); - map->location = "0"; - map->visibility = "0"; - map->weather = "2"; - map->type = "1"; + map->location = "MAPSEC_LITTLEROOT_TOWN"; + map->requiresFlash = "FALSE"; + map->weather = "WEATHER_SUNNY"; + map->type = "MAP_TYPE_TOWN"; map->unknown = "0"; - map->show_location = "1"; - map->battle_scene = "0"; + map->show_location = "TRUE"; + map->battle_scene = "MAP_BATTLE_SCENE_NORMAL"; } void Project::saveMapHeader(Map *map) { @@ -207,7 +215,7 @@ void Project::saveMapHeader(Map *map) { text += QString("\t.2byte %1\n").arg(map->song); text += QString("\t.2byte %1\n").arg(map->layout_id); text += QString("\t.byte %1\n").arg(map->location); - text += QString("\t.byte %1\n").arg(map->visibility); + text += QString("\t.byte %1\n").arg(map->requiresFlash); text += QString("\t.byte %1\n").arg(map->weather); text += QString("\t.byte %1\n").arg(map->type); text += QString("\t.2byte %1\n").arg(map->unknown); @@ -982,15 +990,6 @@ QList* Project::parseAsm(QString text) { return parser->parseAsm(text); } -QStringList Project::getLocations() { - // TODO - QStringList names; - for (int i = 0; i < 88; i++) { - names.append(QString("%1").arg(i)); - } - return names; -} - QStringList Project::getVisibilities() { // TODO QStringList names; @@ -1041,31 +1040,10 @@ QMap Project::getTilesets() { return allTilesets; } -QStringList Project::getWeathers() { - // TODO - QStringList names; - for (int i = 0; i < 16; i++) { - names.append(QString("%1").arg(i)); - } - return names; -} - -QStringList Project::getMapTypes() { - // TODO - QStringList names; - for (int i = 0; i < 16; i++) { - names.append(QString("%1").arg(i)); - } - return names; -} - -QStringList Project::getBattleScenes() { - // TODO - QStringList names; - for (int i = 0; i < 16; i++) { - names.append(QString("%1").arg(i)); - } - return names; +void Project::readRegionMapSections() { + QString filepath = root + "/include/constants/region_map_sections.h"; + QStringList prefixes = (QStringList() << "MAPSEC_"); + readCDefinesSorted(filepath, prefixes, regionMapSections); } void Project::readItemNames() { @@ -1086,6 +1064,48 @@ void Project::readVarNames() { readCDefinesSorted(filepath, prefixes, varNames); } +void Project::readMovementTypes() { + QString filepath = root + "/include/constants/event_object_movement_constants.h"; + QStringList prefixes = (QStringList() << "MOVEMENT_TYPE_"); + readCDefinesSorted(filepath, prefixes, movementTypes); +} + +void Project::readMapTypes() { + QString filepath = root + "/include/constants/map_types.h"; + QStringList prefixes = (QStringList() << "MAP_TYPE_"); + readCDefinesSorted(filepath, prefixes, mapTypes); +} + +void Project::readMapBattleScenes() { + QString filepath = root + "/include/constants/map_types.h"; + QStringList prefixes = (QStringList() << "MAP_BATTLE_SCENE_"); + readCDefinesSorted(filepath, prefixes, mapBattleScenes); +} + +void Project::readWeatherNames() { + QString filepath = root + "/include/constants/weather.h"; + QStringList prefixes = (QStringList() << "WEATHER_"); + readCDefinesSorted(filepath, prefixes, weatherNames); +} + +void Project::readCoordEventWeatherNames() { + QString filepath = root + "/include/constants/weather.h"; + QStringList prefixes = (QStringList() << "COORD_EVENT_WEATHER_"); + readCDefinesSorted(filepath, prefixes, coordEventWeatherNames); +} + +void Project::readSecretBaseIds() { + QString filepath = root + "/include/constants/secret_bases.h"; + QStringList prefixes = (QStringList() << "SECRET_BASE_"); + readCDefinesSorted(filepath, prefixes, secretBaseIds); +} + +void Project::readBgEventFacingDirections() { + QString filepath = root + "/include/constants/bg_event_constants.h"; + QStringList prefixes = (QStringList() << "BG_EVENT_PLAYER_FACING_"); + readCDefinesSorted(filepath, prefixes, bgEventFacingDirections); +} + void Project::readCDefinesSorted(QString filepath, QStringList prefixes, QStringList* definesToSet) { QString text = readTextFile(filepath); if (!text.isNull()) { @@ -1098,6 +1118,8 @@ void Project::readCDefinesSorted(QString filepath, QStringList prefixes, QString definesInverse.insert(defines[defineName], defineName); } *definesToSet = definesInverse.values(); + } else { + qDebug() << "Failed to read C defines file: " << filepath; } } @@ -1319,10 +1341,10 @@ void Project::readMapEvents(Map *map) { object->put("x", command.value(i++).toInt(nullptr, 0)); object->put("y", command.value(i++).toInt(nullptr, 0)); object->put("elevation", command.value(i++)); - object->put("behavior", command.value(i++)); + object->put("movement_type", command.value(i++)); object->put("radius_x", command.value(i++).toInt(nullptr, 0)); object->put("radius_y", command.value(i++).toInt(nullptr, 0)); - object->put("trainer_see_type", command.value(i++)); + object->put("is_trainer", command.value(i++)); object->put("sight_radius_tree_id", command.value(i++)); object->put("script_label", command.value(i++)); object->put("event_flag", command.value(i++)); @@ -1363,12 +1385,6 @@ void Project::readMapEvents(Map *map) { if (command.value(0) == "coord_event") { Event *coord = new Event; coord->put("map_name", map->name); - bool old_macro = false; - if (command.length() >= 9) { - command.removeAt(7); - command.removeAt(4); - old_macro = true; - } int i = 1; coord->put("x", command.value(i++)); coord->put("y", command.value(i++)); @@ -1376,9 +1392,6 @@ void Project::readMapEvents(Map *map) { coord->put("script_var", command.value(i++)); coord->put("script_var_value", command.value(i++)); coord->put("script_label", command.value(i++)); - //coord_unknown3 - //coord_unknown4 - coord->put("event_group_type", "coord_event_group"); coord->put("event_type", EventType::CoordScript); map->events["coord_event_group"].append(coord); @@ -1407,7 +1420,6 @@ void Project::readMapEvents(Map *map) { bg->put("y", command.value(i++)); bg->put("elevation", command.value(i++)); bg->put("player_facing_direction", command.value(i++)); - i++; bg->put("script_label", command.value(i++)); //sign_unknown7 bg->put("event_group_type", "bg_event_group"); @@ -1432,7 +1444,7 @@ void Project::readMapEvents(Map *map) { bg->put("x", command.value(i++)); bg->put("y", command.value(i++)); bg->put("elevation", command.value(i++)); - bg->put("secret_base_map", command.value(i++)); + bg->put("secret_base_id", command.value(i++)); bg->put("event_group_type", "bg_event_group"); bg->put("event_type", EventType::SecretBase); map->events["bg_event_group"].append(bg); diff --git a/project.h b/project.h index 18ab4282..90796295 100755 --- a/project.h +++ b/project.h @@ -23,9 +23,17 @@ public: QList mapLayoutsTableMaster; QMap mapLayouts; QMap mapLayoutsMaster; + QStringList *regionMapSections = NULL; QStringList *itemNames = NULL; QStringList *flagNames = NULL; QStringList *varNames = NULL; + QStringList *movementTypes = NULL; + QStringList *mapTypes = NULL; + QStringList *mapBattleScenes = NULL; + QStringList *weatherNames = NULL; + QStringList *coordEventWeatherNames = NULL; + QStringList *secretBaseIds = NULL; + QStringList *bgEventFacingDirections = NULL; QStringList mapsWithConnections; QMap *map_cache; @@ -72,15 +80,19 @@ public: QList* parseAsm(QString text); QStringList getSongNames(); - QStringList getLocations(); QStringList getVisibilities(); QMap getTilesets(); - QStringList getWeathers(); - QStringList getMapTypes(); - QStringList getBattleScenes(); + void readRegionMapSections(); void readItemNames(); void readFlagNames(); void readVarNames(); + void readMovementTypes(); + void readMapTypes(); + void readMapBattleScenes(); + void readWeatherNames(); + void readCoordEventWeatherNames(); + void readSecretBaseIds(); + void readBgEventFacingDirections(); void loadEventPixmaps(QList objects); QMap getEventObjGfxConstants();