mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-25 22:42:04 +02:00
Merge pull request #5909 from Laserlicht/template_editor_object
Template editor - object & townHints selection
This commit is contained in:
@@ -18,6 +18,7 @@ struct DLL_LINKAGE CompoundMapObjectID
|
||||
si32 primaryID;
|
||||
si32 secondaryID;
|
||||
|
||||
CompoundMapObjectID() : primaryID(0), secondaryID(0) {}
|
||||
CompoundMapObjectID(si32 primID, si32 secID) : primaryID(primID), secondaryID(secID) {};
|
||||
|
||||
bool operator<(const CompoundMapObjectID& other) const
|
||||
|
||||
@@ -16,6 +16,10 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class DLL_LINKAGE ObjectConfig
|
||||
{
|
||||
#ifdef ENABLE_TEMPLATE_EDITOR
|
||||
friend class ObjectSelector;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
enum class EObjectCategory
|
||||
|
||||
@@ -61,6 +61,8 @@ if(ENABLE_TEMPLATE_EDITOR)
|
||||
templateeditor/factionselector.cpp
|
||||
templateeditor/mineselector.cpp
|
||||
templateeditor/treasureselector.cpp
|
||||
templateeditor/objectselector.cpp
|
||||
templateeditor/townhintselector.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -128,6 +130,8 @@ if(ENABLE_TEMPLATE_EDITOR)
|
||||
templateeditor/factionselector.h
|
||||
templateeditor/mineselector.h
|
||||
templateeditor/treasureselector.h
|
||||
templateeditor/objectselector.h
|
||||
templateeditor/townhintselector.h
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -173,6 +177,8 @@ if(ENABLE_TEMPLATE_EDITOR)
|
||||
templateeditor/factionselector.ui
|
||||
templateeditor/mineselector.ui
|
||||
templateeditor/treasureselector.ui
|
||||
templateeditor/objectselector.ui
|
||||
templateeditor/townhintselector.ui
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -988,7 +988,7 @@ void MainWindow::on_actionLevel_triggered()
|
||||
|
||||
void MainWindow::on_actionUndo_triggered()
|
||||
{
|
||||
QString str("Undo clicked");
|
||||
QString str(tr("Undo clicked"));
|
||||
statusBar()->showMessage(str, 1000);
|
||||
|
||||
if (controller.map())
|
||||
@@ -999,7 +999,7 @@ void MainWindow::on_actionUndo_triggered()
|
||||
|
||||
void MainWindow::on_actionRedo_triggered()
|
||||
{
|
||||
QString str("Redo clicked");
|
||||
QString str(tr("Redo clicked"));
|
||||
displayStatus(str);
|
||||
|
||||
if (controller.map())
|
||||
@@ -1010,7 +1010,7 @@ void MainWindow::on_actionRedo_triggered()
|
||||
|
||||
void MainWindow::on_actionPass_triggered(bool checked)
|
||||
{
|
||||
QString str("Passability clicked");
|
||||
QString str(tr("Passability clicked"));
|
||||
displayStatus(str);
|
||||
|
||||
if(controller.map())
|
||||
@@ -1023,7 +1023,7 @@ void MainWindow::on_actionPass_triggered(bool checked)
|
||||
|
||||
void MainWindow::on_actionGrid_triggered(bool checked)
|
||||
{
|
||||
QString str("Grid clicked");
|
||||
QString str(tr("Grid clicked"));
|
||||
displayStatus(str);
|
||||
|
||||
if(controller.map())
|
||||
@@ -1104,7 +1104,7 @@ void MainWindow::on_filter_textChanged(const QString &arg1)
|
||||
|
||||
void MainWindow::on_actionFill_triggered()
|
||||
{
|
||||
QString str("Fill clicked");
|
||||
QString str(tr("Fill clicked"));
|
||||
displayStatus(str);
|
||||
|
||||
if(!controller.map())
|
||||
|
||||
321
mapeditor/templateeditor/objectselector.cpp
Normal file
321
mapeditor/templateeditor/objectselector.cpp
Normal file
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* objectselector.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
|
||||
#include "objectselector.h"
|
||||
#include "ui_objectselector.h"
|
||||
|
||||
#include "../mainwindow.h"
|
||||
#include "../mapcontroller.h"
|
||||
|
||||
#include "../../lib/mapping/CMap.h"
|
||||
#include "../../lib/rmg/ObjectConfig.h"
|
||||
#include "../../lib/GameLibrary.h"
|
||||
#include "../../lib/mapObjects/CGObjectInstance.h"
|
||||
#include "../../lib/mapObjectConstructors/AObjectTypeHandler.h"
|
||||
#include "../../lib/mapObjectConstructors/CObjectClassesHandler.h"
|
||||
|
||||
ObjectSelector::ObjectSelector(ObjectConfig & obj) :
|
||||
ui(new Ui::ObjectSelector),
|
||||
obj(obj),
|
||||
advObjects(getAdventureMapItems())
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
setWindowTitle(tr("Object Selector"));
|
||||
|
||||
setWindowModality(Qt::ApplicationModal);
|
||||
|
||||
fillBannedObjectCategories();
|
||||
fillBannedObjects();
|
||||
fillCustomObjects();
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
QMainWindow* getMainWindow()
|
||||
{
|
||||
foreach (QWidget *w, qApp->topLevelWidgets())
|
||||
if (QMainWindow* mainWin = qobject_cast<QMainWindow*>(w))
|
||||
return mainWin;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::map<CompoundMapObjectID, QString> ObjectSelector::getAdventureMapItems()
|
||||
{
|
||||
std::map<CompoundMapObjectID, QString> objects;
|
||||
auto& controller = qobject_cast<MainWindow *>(getMainWindow())->controller;
|
||||
|
||||
auto knownObjects = LIBRARY->objtypeh->knownObjects();
|
||||
for(auto & id : knownObjects)
|
||||
{
|
||||
auto knownSubObjects = LIBRARY->objtypeh->knownSubObjects(id);
|
||||
for(auto & subId : knownSubObjects)
|
||||
{
|
||||
auto objId = CompoundMapObjectID(id, subId);
|
||||
auto factory = LIBRARY->objtypeh->getHandlerFor(id, subId);
|
||||
auto templates = factory->getTemplates();
|
||||
|
||||
QString name{};
|
||||
try
|
||||
{
|
||||
auto templ = templates.at(0);
|
||||
auto temporaryObj(factory->create(controller.getCallback(), templ));
|
||||
QString translated = QString::fromStdString(temporaryObj->getObjectName().c_str());
|
||||
name = translated;
|
||||
}
|
||||
catch(...) {}
|
||||
|
||||
if(name.isEmpty())
|
||||
{
|
||||
auto subGroupName = QString::fromStdString(LIBRARY->objtypeh->getObjectName(id, subId));
|
||||
name = subGroupName;
|
||||
}
|
||||
|
||||
if(!name.isEmpty())
|
||||
objects[objId] = name;
|
||||
}
|
||||
}
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
void ObjectSelector::fillBannedObjectCategories()
|
||||
{
|
||||
ui->tableWidgetBannedObjectCategories->setColumnCount(2);
|
||||
ui->tableWidgetBannedObjectCategories->setRowCount(obj.bannedObjectCategories.size() + 1);
|
||||
ui->tableWidgetBannedObjectCategories->setHorizontalHeaderLabels({tr("Category"), tr("Action")});
|
||||
|
||||
auto addRow = [this](ObjectConfig::EObjectCategory category, int row){
|
||||
std::map<ObjectConfig::EObjectCategory, QString> values = {
|
||||
{ ObjectConfig::EObjectCategory::OTHER, tr("Other") },
|
||||
{ ObjectConfig::EObjectCategory::ALL, tr("All") },
|
||||
{ ObjectConfig::EObjectCategory::NONE, tr("None") },
|
||||
{ ObjectConfig::EObjectCategory::CREATURE_BANK, tr("Creature bank") },
|
||||
{ ObjectConfig::EObjectCategory::BONUS, tr("Bonus") },
|
||||
{ ObjectConfig::EObjectCategory::DWELLING, tr("Dwelling") },
|
||||
{ ObjectConfig::EObjectCategory::RESOURCE, tr("Resource") },
|
||||
{ ObjectConfig::EObjectCategory::RESOURCE_GENERATOR, tr("Resource generator") },
|
||||
{ ObjectConfig::EObjectCategory::SPELL_SCROLL, tr("Spell scroll") },
|
||||
{ ObjectConfig::EObjectCategory::RANDOM_ARTIFACT, tr("Random artifact") },
|
||||
{ ObjectConfig::EObjectCategory::PANDORAS_BOX, tr("Pandoras box") },
|
||||
{ ObjectConfig::EObjectCategory::QUEST_ARTIFACT, tr("Quest artifact") },
|
||||
{ ObjectConfig::EObjectCategory::SEER_HUT, tr("Seer hut") }
|
||||
};
|
||||
QComboBox *combo = new QComboBox();
|
||||
for(auto & item : values)
|
||||
combo->addItem(item.second, QVariant(static_cast<int>(item.first)));
|
||||
|
||||
int index = combo->findData(static_cast<int>(category));
|
||||
if (index != -1)
|
||||
combo->setCurrentIndex(index);
|
||||
|
||||
ui->tableWidgetBannedObjectCategories->setCellWidget(row, 0, combo);
|
||||
|
||||
auto deleteButton = new QPushButton(tr("Delete"));
|
||||
ui->tableWidgetBannedObjectCategories->setCellWidget(row, 1, deleteButton);
|
||||
connect(deleteButton, &QPushButton::clicked, this, [this, deleteButton]() {
|
||||
for (int r = 0; r < ui->tableWidgetBannedObjectCategories->rowCount(); ++r) {
|
||||
if (ui->tableWidgetBannedObjectCategories->cellWidget(r, 1) == deleteButton) {
|
||||
ui->tableWidgetBannedObjectCategories->removeRow(r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
for (int row = 0; row < obj.bannedObjectCategories.size(); ++row)
|
||||
addRow(obj.bannedObjectCategories[row], row);
|
||||
|
||||
auto addButton = new QPushButton("Add");
|
||||
ui->tableWidgetBannedObjectCategories->setCellWidget(ui->tableWidgetBannedObjectCategories->rowCount() - 1, 1, addButton);
|
||||
connect(addButton, &QPushButton::clicked, this, [this, addRow]() {
|
||||
ui->tableWidgetBannedObjectCategories->insertRow(ui->tableWidgetBannedObjectCategories->rowCount() - 1);
|
||||
addRow(ObjectConfig::EObjectCategory::ALL, ui->tableWidgetBannedObjectCategories->rowCount() - 2);
|
||||
});
|
||||
|
||||
ui->tableWidgetBannedObjectCategories->resizeColumnsToContents();
|
||||
ui->tableWidgetBannedObjectCategories->setColumnWidth(0, 300);
|
||||
}
|
||||
|
||||
void ObjectSelector::getBannedObjectCategories()
|
||||
{
|
||||
obj.bannedObjectCategories.clear();
|
||||
for (int row = 0; row < ui->tableWidgetBannedObjectCategories->rowCount() - 1; ++row)
|
||||
{
|
||||
auto val = static_cast<ObjectConfig::EObjectCategory>(static_cast<QComboBox *>(ui->tableWidgetBannedObjectCategories->cellWidget(row, 0))->currentData().toInt());
|
||||
if(vstd::contains(obj.bannedObjectCategories, val))
|
||||
obj.bannedObjectCategories.push_back(val);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectSelector::fillBannedObjects()
|
||||
{
|
||||
ui->tableWidgetBannedObjects->setColumnCount(2);
|
||||
ui->tableWidgetBannedObjects->setRowCount(obj.bannedObjects.size() + 1);
|
||||
ui->tableWidgetBannedObjects->setHorizontalHeaderLabels({tr("Object"), tr("Action")});
|
||||
|
||||
auto addRow = [this](CompoundMapObjectID obj, int row){
|
||||
QComboBox *combo = new QComboBox();
|
||||
for(auto & item : advObjects)
|
||||
combo->addItem(item.second, QVariant::fromValue(item.first));
|
||||
|
||||
int index = combo->findData(QVariant::fromValue(obj));
|
||||
if (index != -1)
|
||||
combo->setCurrentIndex(index);
|
||||
|
||||
combo->setEditable(true);
|
||||
QCompleter* completer = new QCompleter(combo);
|
||||
completer->setModel(combo->model());
|
||||
completer->setCompletionMode(QCompleter::PopupCompletion);
|
||||
completer->setFilterMode(Qt::MatchContains);
|
||||
combo->setCompleter(completer);
|
||||
|
||||
ui->tableWidgetBannedObjects->setCellWidget(row, 0, combo);
|
||||
|
||||
auto deleteButton = new QPushButton(tr("Delete"));
|
||||
ui->tableWidgetBannedObjects->setCellWidget(row, 1, deleteButton);
|
||||
connect(deleteButton, &QPushButton::clicked, this, [this, deleteButton]() {
|
||||
for (int r = 0; r < ui->tableWidgetBannedObjects->rowCount(); ++r) {
|
||||
if (ui->tableWidgetBannedObjects->cellWidget(r, 1) == deleteButton) {
|
||||
ui->tableWidgetBannedObjects->removeRow(r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
for (int row = 0; row < obj.bannedObjects.size(); ++row)
|
||||
addRow(obj.bannedObjects[row], row);
|
||||
|
||||
auto addButton = new QPushButton("Add");
|
||||
ui->tableWidgetBannedObjects->setCellWidget(ui->tableWidgetBannedObjects->rowCount() - 1, 1, addButton);
|
||||
connect(addButton, &QPushButton::clicked, this, [this, addRow]() {
|
||||
ui->tableWidgetBannedObjects->insertRow(ui->tableWidgetBannedObjects->rowCount() - 1);
|
||||
addRow((*advObjects.begin()).first, ui->tableWidgetBannedObjects->rowCount() - 2);
|
||||
});
|
||||
|
||||
ui->tableWidgetBannedObjects->resizeColumnsToContents();
|
||||
ui->tableWidgetBannedObjects->setColumnWidth(0, 300);
|
||||
}
|
||||
|
||||
void ObjectSelector::getBannedObjects()
|
||||
{
|
||||
obj.bannedObjects.clear();
|
||||
for (int row = 0; row < ui->tableWidgetBannedObjects->rowCount() - 1; ++row)
|
||||
{
|
||||
auto val = static_cast<QComboBox *>(ui->tableWidgetBannedObjects->cellWidget(row, 0))->currentData().value<CompoundMapObjectID>();
|
||||
obj.bannedObjects.push_back(val);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectSelector::fillCustomObjects()
|
||||
{
|
||||
ui->tableWidgetObjects->setColumnCount(5);
|
||||
ui->tableWidgetObjects->setRowCount(obj.customObjects.size() + 1);
|
||||
ui->tableWidgetObjects->setHorizontalHeaderLabels({tr("Object"), tr("Value"), tr("Probability"), tr("Max per zone"), tr("Action")});
|
||||
|
||||
auto addRow = [this](CompoundMapObjectID obj, ui32 value, ui16 probability, ui32 maxPerZone, int row){
|
||||
QComboBox *combo = new QComboBox();
|
||||
for(auto & item : advObjects)
|
||||
combo->addItem(item.second, QVariant::fromValue(item.first));
|
||||
|
||||
int index = combo->findData(QVariant::fromValue(obj));
|
||||
if (index != -1)
|
||||
combo->setCurrentIndex(index);
|
||||
|
||||
combo->setEditable(true);
|
||||
QCompleter* completer = new QCompleter(combo);
|
||||
completer->setModel(combo->model());
|
||||
completer->setCompletionMode(QCompleter::PopupCompletion);
|
||||
completer->setFilterMode(Qt::MatchContains);
|
||||
combo->setCompleter(completer);
|
||||
|
||||
ui->tableWidgetObjects->setCellWidget(row, 0, combo);
|
||||
|
||||
QSpinBox *spinValue = new QSpinBox();
|
||||
spinValue->setRange(0, 10000);
|
||||
spinValue->setValue(value);
|
||||
ui->tableWidgetObjects->setCellWidget(row, 1, spinValue);
|
||||
|
||||
QSpinBox *spinProbability = new QSpinBox();
|
||||
spinProbability->setRange(0, 1000);
|
||||
spinProbability->setValue(probability);
|
||||
ui->tableWidgetObjects->setCellWidget(row, 2, spinProbability);
|
||||
|
||||
QSpinBox *spinMaxPerZone = new QSpinBox();
|
||||
spinMaxPerZone->setRange(0, 100);
|
||||
spinMaxPerZone->setValue(maxPerZone);
|
||||
ui->tableWidgetObjects->setCellWidget(row, 3, spinMaxPerZone);
|
||||
|
||||
auto deleteButton = new QPushButton(tr("Delete"));
|
||||
ui->tableWidgetObjects->setCellWidget(row, 4, deleteButton);
|
||||
connect(deleteButton, &QPushButton::clicked, this, [this, deleteButton]() {
|
||||
for (int r = 0; r < ui->tableWidgetObjects->rowCount(); ++r) {
|
||||
if (ui->tableWidgetObjects->cellWidget(r, 4) == deleteButton) {
|
||||
ui->tableWidgetObjects->removeRow(r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
for (int row = 0; row < obj.customObjects.size(); ++row)
|
||||
addRow(obj.customObjects[row].getCompoundID(), obj.customObjects[row].value, obj.customObjects[row].probability, obj.customObjects[row].maxPerZone, row);
|
||||
|
||||
auto addButton = new QPushButton("Add");
|
||||
ui->tableWidgetObjects->setCellWidget(ui->tableWidgetObjects->rowCount() - 1, 4, addButton);
|
||||
connect(addButton, &QPushButton::clicked, this, [this, addRow]() {
|
||||
ui->tableWidgetObjects->insertRow(ui->tableWidgetObjects->rowCount() - 1);
|
||||
addRow((*advObjects.begin()).first, 0, 0, 1, ui->tableWidgetObjects->rowCount() - 2);
|
||||
});
|
||||
|
||||
ui->tableWidgetObjects->resizeColumnsToContents();
|
||||
ui->tableWidgetObjects->setColumnWidth(0, 300);
|
||||
}
|
||||
|
||||
void ObjectSelector::getCustomObjects()
|
||||
{
|
||||
obj.customObjects.clear();
|
||||
for (int row = 0; row < ui->tableWidgetObjects->rowCount() - 1; ++row)
|
||||
{
|
||||
auto id = static_cast<QComboBox *>(ui->tableWidgetObjects->cellWidget(row, 0))->currentData().value<CompoundMapObjectID>();
|
||||
auto value = static_cast<QSpinBox *>(ui->tableWidgetObjects->cellWidget(row, 1))->value();
|
||||
auto probability = static_cast<QSpinBox *>(ui->tableWidgetObjects->cellWidget(row, 2))->value();
|
||||
auto maxPerZone = static_cast<QSpinBox *>(ui->tableWidgetObjects->cellWidget(row, 3))->value();
|
||||
auto info = ObjectInfo(id);
|
||||
info.value = value;
|
||||
info.probability = probability;
|
||||
info.maxPerZone = maxPerZone;
|
||||
obj.customObjects.push_back(info);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectSelector::showObjectSelector(ObjectConfig & obj)
|
||||
{
|
||||
auto * dialog = new ObjectSelector(obj);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->exec();
|
||||
}
|
||||
|
||||
void ObjectSelector::on_buttonBoxResult_accepted()
|
||||
{
|
||||
getBannedObjectCategories();
|
||||
getBannedObjects();
|
||||
getCustomObjects();
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
void ObjectSelector::on_buttonBoxResult_rejected()
|
||||
{
|
||||
close();
|
||||
}
|
||||
48
mapeditor/templateeditor/objectselector.h
Normal file
48
mapeditor/templateeditor/objectselector.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* objectselector.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include <QWidget>
|
||||
|
||||
#include "../../lib/rmg/CRmgTemplate.h"
|
||||
|
||||
Q_DECLARE_METATYPE(CompoundMapObjectID);
|
||||
|
||||
namespace Ui {
|
||||
class ObjectSelector;
|
||||
}
|
||||
|
||||
class ObjectSelector : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ObjectSelector(ObjectConfig & obj);
|
||||
|
||||
static void showObjectSelector(ObjectConfig & obj);
|
||||
|
||||
private slots:
|
||||
void on_buttonBoxResult_accepted();
|
||||
void on_buttonBoxResult_rejected();
|
||||
|
||||
private:
|
||||
Ui::ObjectSelector *ui;
|
||||
|
||||
ObjectConfig & obj;
|
||||
|
||||
std::map<CompoundMapObjectID, QString> advObjects;
|
||||
std::map<CompoundMapObjectID, QString> getAdventureMapItems();
|
||||
|
||||
void fillBannedObjectCategories();
|
||||
void getBannedObjectCategories();
|
||||
void fillBannedObjects();
|
||||
void getBannedObjects();
|
||||
void fillCustomObjects();
|
||||
void getCustomObjects();
|
||||
};
|
||||
58
mapeditor/templateeditor/objectselector.ui
Normal file
58
mapeditor/templateeditor/objectselector.ui
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ObjectSelector</class>
|
||||
<widget class="QDialog" name="ObjectSelector">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>750</width>
|
||||
<height>480</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Select Objects</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelObjects">
|
||||
<property name="text">
|
||||
<string>Objects</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidgetObjects"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelBannedObjects">
|
||||
<property name="text">
|
||||
<string>Banned Objects</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidgetBannedObjects"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelBannedObjectCategories">
|
||||
<property name="text">
|
||||
<string>Banned Object Categories</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidgetBannedObjectCategories"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBoxResult">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "factionselector.h"
|
||||
#include "mineselector.h"
|
||||
#include "treasureselector.h"
|
||||
#include "objectselector.h"
|
||||
#include "townhintselector.h"
|
||||
#include "GeometryAlgorithm.h"
|
||||
|
||||
#include "../helper.h"
|
||||
@@ -1032,8 +1034,7 @@ void TemplateEditor::on_pushButtonBannedTowns_clicked()
|
||||
|
||||
void TemplateEditor::on_pushButtonTownHints_clicked()
|
||||
{
|
||||
//TODO: Implement dialog
|
||||
QMessageBox::critical(this, tr("Error"), tr("Not implemented yet!"));
|
||||
TownHintSelector::showTownHintSelector(templates[selectedTemplate]->getZones().at(selectedZone)->townHints);
|
||||
}
|
||||
|
||||
void TemplateEditor::on_pushButtonAllowedMonsters_clicked()
|
||||
@@ -1059,6 +1060,5 @@ void TemplateEditor::on_pushButtonMines_clicked()
|
||||
|
||||
void TemplateEditor::on_pushButtonCustomObjects_clicked()
|
||||
{
|
||||
//TODO: Implement dialog
|
||||
QMessageBox::critical(this, tr("Error"), tr("Not implemented yet!"));
|
||||
ObjectSelector::showObjectSelector(templates[selectedTemplate]->getZones().at(selectedZone)->objectConfig);
|
||||
}
|
||||
|
||||
156
mapeditor/templateeditor/townhintselector.cpp
Normal file
156
mapeditor/templateeditor/townhintselector.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* townhintselector.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
|
||||
#include "townhintselector.h"
|
||||
#include "ui_townhintselector.h"
|
||||
|
||||
enum modes { UNKNOWN, LIKE_ZONE, NOT_LIKE_ZONE, RELATED_TO_ZONE_TERRAIN };
|
||||
|
||||
TownHintSelector::TownHintSelector(std::vector<rmg::ZoneOptions::CTownHints> & townHints) :
|
||||
ui(new Ui::TownHintSelector),
|
||||
townHints(townHints)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
setWindowTitle(tr("Town hint Selector"));
|
||||
|
||||
setWindowModality(Qt::ApplicationModal);
|
||||
|
||||
ui->tableWidgetTownHints->setColumnCount(3);
|
||||
ui->tableWidgetTownHints->setRowCount(townHints.size() + 1);
|
||||
ui->tableWidgetTownHints->setHorizontalHeaderLabels({tr("Type"), tr("Value"), tr("Action")});
|
||||
|
||||
std::map<modes, QString> values = {
|
||||
{ LIKE_ZONE, tr("Like Zone") },
|
||||
{ NOT_LIKE_ZONE, tr("Not like zone (comma separated)") },
|
||||
{ RELATED_TO_ZONE_TERRAIN, tr("Related to zone terrain") }
|
||||
};
|
||||
|
||||
auto addRow = [this, values](int mode, std::vector<TRmgTemplateZoneId> zones, int row){
|
||||
QComboBox *combo = new QComboBox();
|
||||
for(auto & item : values)
|
||||
combo->addItem(item.second, QVariant(static_cast<int>(item.first)));
|
||||
|
||||
int index = combo->findData(static_cast<int>(mode));
|
||||
if (index != -1)
|
||||
combo->setCurrentIndex(index);
|
||||
|
||||
ui->tableWidgetTownHints->setCellWidget(row, 0, combo);
|
||||
|
||||
std::vector<std::string> values(zones.size());
|
||||
std::transform(zones.begin(), zones.end(), values.begin(), [](const int val) { return std::to_string(val); });
|
||||
std::string valuesText = boost::algorithm::join(values, ",");
|
||||
|
||||
QLineEdit *lineEdit = new QLineEdit;
|
||||
QRegularExpression regex("^\\d+(,\\d+)*$");
|
||||
QRegularExpressionValidator *validator = new QRegularExpressionValidator(regex, lineEdit);
|
||||
lineEdit->setValidator(validator);
|
||||
lineEdit->setText(QString::fromStdString(valuesText));
|
||||
ui->tableWidgetTownHints->setCellWidget(row, 1, lineEdit);
|
||||
|
||||
auto deleteButton = new QPushButton(tr("Delete"));
|
||||
ui->tableWidgetTownHints->setCellWidget(row, 2, deleteButton);
|
||||
connect(deleteButton, &QPushButton::clicked, this, [this, deleteButton]() {
|
||||
for (int r = 0; r < ui->tableWidgetTownHints->rowCount(); ++r) {
|
||||
if (ui->tableWidgetTownHints->cellWidget(r, 2) == deleteButton) {
|
||||
ui->tableWidgetTownHints->removeRow(r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
for (int row = 0; row < townHints.size(); ++row)
|
||||
{
|
||||
int mode = UNKNOWN;
|
||||
std::vector<TRmgTemplateZoneId> zones;
|
||||
if(townHints[row].likeZone != rmg::ZoneOptions::NO_ZONE)
|
||||
{
|
||||
mode = LIKE_ZONE;
|
||||
zones = { townHints[row].likeZone };
|
||||
}
|
||||
else if(!townHints[row].notLikeZone.empty())
|
||||
{
|
||||
mode = NOT_LIKE_ZONE;
|
||||
zones = townHints[row].notLikeZone;
|
||||
|
||||
}
|
||||
else if(townHints[row].relatedToZoneTerrain != rmg::ZoneOptions::NO_ZONE)
|
||||
{
|
||||
mode = RELATED_TO_ZONE_TERRAIN;
|
||||
zones = { townHints[row].relatedToZoneTerrain };
|
||||
|
||||
}
|
||||
|
||||
assert(mode != UNKNOWN);
|
||||
|
||||
addRow(mode, zones, row);
|
||||
}
|
||||
|
||||
auto addButton = new QPushButton("Add");
|
||||
ui->tableWidgetTownHints->setCellWidget(ui->tableWidgetTownHints->rowCount() - 1, 2, addButton);
|
||||
connect(addButton, &QPushButton::clicked, this, [this, addRow]() {
|
||||
ui->tableWidgetTownHints->insertRow(ui->tableWidgetTownHints->rowCount() - 1);
|
||||
addRow(LIKE_ZONE, std::vector<TRmgTemplateZoneId>({ 0 }), ui->tableWidgetTownHints->rowCount() - 2);
|
||||
});
|
||||
|
||||
ui->tableWidgetTownHints->resizeColumnsToContents();
|
||||
ui->tableWidgetTownHints->setColumnWidth(0, 300);
|
||||
ui->tableWidgetTownHints->setColumnWidth(1, 150);
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
void TownHintSelector::showTownHintSelector(std::vector<rmg::ZoneOptions::CTownHints> & townHints)
|
||||
{
|
||||
auto * dialog = new TownHintSelector(townHints);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->exec();
|
||||
}
|
||||
|
||||
void TownHintSelector::on_buttonBoxResult_accepted()
|
||||
{
|
||||
townHints.clear();
|
||||
for (int row = 0; row < ui->tableWidgetTownHints->rowCount() - 1; ++row) // iterate over all rows except the add button row
|
||||
{
|
||||
auto mode = static_cast<modes>(static_cast<QComboBox *>(ui->tableWidgetTownHints->cellWidget(row, 0))->currentData().toInt());
|
||||
auto text = static_cast<QLineEdit *>(ui->tableWidgetTownHints->cellWidget(row, 1))->text().toStdString();
|
||||
std::vector<std::string> values;
|
||||
boost::split(values, text, boost::is_any_of(","));
|
||||
if (!values.empty() && values.back().empty()) // remove "no number" after last comma; other cases are covered by regex
|
||||
values.pop_back();
|
||||
std::vector<int> numValues(values.size());
|
||||
std::transform(values.begin(), values.end(), numValues.begin(), [](const std::string& str) { return std::stoi(str); });
|
||||
|
||||
rmg::ZoneOptions::CTownHints hint;
|
||||
switch (mode)
|
||||
{
|
||||
case LIKE_ZONE:
|
||||
hint.likeZone = numValues.at(0);
|
||||
break;
|
||||
case NOT_LIKE_ZONE:
|
||||
hint.notLikeZone = numValues;
|
||||
break;
|
||||
case RELATED_TO_ZONE_TERRAIN:
|
||||
hint.relatedToZoneTerrain = numValues.at(0);
|
||||
break;
|
||||
}
|
||||
townHints.push_back(hint);
|
||||
}
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
void TownHintSelector::on_buttonBoxResult_rejected()
|
||||
{
|
||||
close();
|
||||
}
|
||||
36
mapeditor/templateeditor/townhintselector.h
Normal file
36
mapeditor/templateeditor/townhintselector.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* townhintselector.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include <QWidget>
|
||||
|
||||
#include "../../lib/rmg/CRmgTemplate.h"
|
||||
|
||||
namespace Ui {
|
||||
class TownHintSelector;
|
||||
}
|
||||
|
||||
class TownHintSelector : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TownHintSelector(std::vector<rmg::ZoneOptions::CTownHints> & townHints);
|
||||
|
||||
static void showTownHintSelector(std::vector<rmg::ZoneOptions::CTownHints> & townHints);
|
||||
|
||||
private slots:
|
||||
void on_buttonBoxResult_accepted();
|
||||
void on_buttonBoxResult_rejected();
|
||||
|
||||
private:
|
||||
Ui::TownHintSelector *ui;
|
||||
|
||||
std::vector<rmg::ZoneOptions::CTownHints> & townHints;
|
||||
};
|
||||
38
mapeditor/templateeditor/townhintselector.ui
Normal file
38
mapeditor/templateeditor/townhintselector.ui
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TownHintSelector</class>
|
||||
<widget class="QDialog" name="townHintSelector">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>600</width>
|
||||
<height>329</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Select Town hints</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelTownHints">
|
||||
<property name="text">
|
||||
<string>Town hints</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidgetTownHints"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBoxResult">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -47,7 +47,7 @@ TreasureSelector::TreasureSelector(std::vector<CTreasureInfo> & treasures) :
|
||||
spinBoxDensity->setValue(density);
|
||||
ui->tableWidgetTreasures->setCellWidget(row, 2, spinBoxDensity);
|
||||
|
||||
auto deleteButton = new QPushButton("Delete");
|
||||
auto deleteButton = new QPushButton(tr("Delete"));
|
||||
ui->tableWidgetTreasures->setCellWidget(row, 3, deleteButton);
|
||||
connect(deleteButton, &QPushButton::clicked, this, [this, deleteButton]() {
|
||||
for (int r = 0; r < ui->tableWidgetTreasures->rowCount(); ++r) {
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
<message>
|
||||
<location filename="../campaigneditor/campaignproperties.ui" line="120"/>
|
||||
<source>Regions Preset</source>
|
||||
<translation>Regionan-Voreinstellung</translation>
|
||||
<translation>Regionen-Voreinstellung</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../campaigneditor/campaignproperties.ui" line="137"/>
|
||||
@@ -3383,7 +3383,7 @@ Fügen Sie sie zu den erforderlichen Mods unter Karte → Allgemeine Einstellung
|
||||
<message>
|
||||
<location filename="../templateeditor/templateeditor.ui" line="1110"/>
|
||||
<source>Banned towns</source>
|
||||
<translation>Verbotene STädte</translation>
|
||||
<translation>Verbotene Städte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../templateeditor/templateeditor.ui" line="1117"/>
|
||||
|
||||
Reference in New Issue
Block a user