diff --git a/mapeditor/CMakeLists.txt b/mapeditor/CMakeLists.txt index 2dcfc3345..a0ba173dc 100644 --- a/mapeditor/CMakeLists.txt +++ b/mapeditor/CMakeLists.txt @@ -57,7 +57,7 @@ if(ENABLE_TEMPLATE_EDITOR) templateeditor/graphicelements/CardItem.cpp templateeditor/graphicelements/LineItem.cpp templateeditor/GeometryAlgorithm.cpp - templateeditor/terrainselector.cpp + templateeditor/entitiesselector.cpp templateeditor/factionselector.cpp templateeditor/mineselector.cpp templateeditor/treasureselector.cpp @@ -124,7 +124,7 @@ if(ENABLE_TEMPLATE_EDITOR) templateeditor/graphicelements/CardItem.h templateeditor/graphicelements/LineItem.h templateeditor/GeometryAlgorithm.h - templateeditor/terrainselector.h + templateeditor/entitiesselector.h templateeditor/factionselector.h templateeditor/mineselector.h templateeditor/treasureselector.h @@ -169,7 +169,7 @@ if(ENABLE_TEMPLATE_EDITOR) set(editor_FORMS ${editor_FORMS} templateeditor/templateeditor.ui - templateeditor/terrainselector.ui + templateeditor/entitiesselector.ui templateeditor/factionselector.ui templateeditor/mineselector.ui templateeditor/treasureselector.ui diff --git a/mapeditor/templateeditor/entitiesselector.cpp b/mapeditor/templateeditor/entitiesselector.cpp new file mode 100644 index 000000000..fae8c3a54 --- /dev/null +++ b/mapeditor/templateeditor/entitiesselector.cpp @@ -0,0 +1,135 @@ +/* + * entitiesselector.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 "entitiesselector.h" +#include "ui_entitiesselector.h" + +#include "../../lib/GameLibrary.h" +#include "../../lib/TerrainHandler.h" +#include "../../lib/spells/CSpellHandler.h" +#include "../../lib/CSkillHandler.h" +#include "../../lib/entities/artifact/CArtHandler.h" +#include "../../lib/entities/hero/CHeroHandler.h" + +template +size_t countInVariantSet(const Variant& var, const T& value) { + return std::visit([&](const auto& setRefWrapper) -> size_t { + const auto& setRef = setRefWrapper.get(); + using SetType = std::decay_t; + using ValueType = typename SetType::value_type; + if constexpr (std::is_same_v) { + return setRef.count(value); + } else { + return 0; + } + }, var); +} + +template +void fillListWidgetFromHandler(QListWidget* listWidget, const HandlerType* handler, const VariantSet& entities) +{ + listWidget->clear(); + + for (auto const& objectPtr : handler->objects) + { + auto* item = new QListWidgetItem(QString::fromStdString(objectPtr->getNameTranslated())); + item->setData(Qt::UserRole, QVariant::fromValue(objectPtr->getIndex())); + item->setFlags(item->flags() | Qt::ItemIsUserCheckable); + item->setCheckState(countInVariantSet(entities, objectPtr->getId()) ? Qt::Checked : Qt::Unchecked); + listWidget->addItem(item); + } +} + +template struct overloaded : Ts... { using Ts::operator()...; }; +template overloaded(Ts...) -> overloaded; + +using HandlerVariant = std::variant< + const TerrainTypeHandler*, + const CSpellHandler*, + const CArtHandler*, + const CSkillHandler*, + const CHeroHandler* +>; + +EntitiesSelector::EntitiesSelector(EntityIds & entities) : + ui(new Ui::EntitiesSelector), + entitiesSelected(entities) +{ + ui->setupUi(this); + + setWindowModality(Qt::ApplicationModal); + + HandlerVariant handler; + std::visit(overloaded{ + [&](std::reference_wrapper> terrainSet) { + handler = LIBRARY->terrainTypeHandler.get(); + setWindowTitle(tr("Terrain Selector")); + }, + [&](std::reference_wrapper> spellSet) { + handler = LIBRARY->spellh.get(); + setWindowTitle(tr("Spell Selector")); + }, + [&](std::reference_wrapper> artifactSet) { + handler = LIBRARY->arth.get(); + setWindowTitle(tr("Artifact Selector")); + }, + [&](std::reference_wrapper> secondarySkillSet) { + handler = LIBRARY->skillh.get(); + setWindowTitle(tr("Skill Selector")); + }, + [&](std::reference_wrapper> heroTypeSet) { + handler = LIBRARY->heroh.get(); + setWindowTitle(tr("Hero Type Selector")); + } + }, entitiesSelected); + std::visit([&](auto const* handlerPtr){ + fillListWidgetFromHandler(ui->listWidgetEntities, handlerPtr, entities); + }, handler); + + show(); +} + +void EntitiesSelector::showEntitiesSelector(EntityIds & entities) +{ + auto * dialog = new EntitiesSelector(entities); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->exec(); +} + +void EntitiesSelector::on_buttonBoxResult_accepted() +{ + std::visit([](auto& setRefWrapper) { + setRefWrapper.get().clear(); + }, entitiesSelected); + for(int i = 0; i < ui->listWidgetEntities->count(); ++i) + { + auto * item = ui->listWidgetEntities->item(i); + if(item->checkState() == Qt::Checked) + { + int id = item->data(Qt::UserRole).toInt(); + + std::visit([id](auto& setRefWrapper) { + using SetType = std::decay_t; + using ValueType = typename SetType::value_type; + ValueType value{id}; + setRefWrapper.get().insert(std::move(value)); + }, entitiesSelected); + } + } + + close(); +} + +void EntitiesSelector::on_buttonBoxResult_rejected() +{ + close(); +} diff --git a/mapeditor/templateeditor/entitiesselector.h b/mapeditor/templateeditor/entitiesselector.h new file mode 100644 index 000000000..9b140af26 --- /dev/null +++ b/mapeditor/templateeditor/entitiesselector.h @@ -0,0 +1,39 @@ +/* + * entitiesselector.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 + +#include "../StdInc.h" +#include "../../lib/constants/EntityIdentifiers.h" + +namespace Ui { +class EntitiesSelector; +} + +using EntityIds = std::variant>, std::reference_wrapper>, std::reference_wrapper>, std::reference_wrapper>, std::reference_wrapper>>; + +class EntitiesSelector : public QDialog +{ + Q_OBJECT + +public: + explicit EntitiesSelector(EntityIds & entities); + + static void showEntitiesSelector(EntityIds & entities); + +private slots: + void on_buttonBoxResult_accepted(); + void on_buttonBoxResult_rejected(); + +private: + Ui::EntitiesSelector *ui; + + EntityIds & entitiesSelected; +}; diff --git a/mapeditor/templateeditor/terrainselector.ui b/mapeditor/templateeditor/entitiesselector.ui similarity index 71% rename from mapeditor/templateeditor/terrainselector.ui rename to mapeditor/templateeditor/entitiesselector.ui index 28b2a9881..406fda1d9 100644 --- a/mapeditor/templateeditor/terrainselector.ui +++ b/mapeditor/templateeditor/entitiesselector.ui @@ -1,7 +1,7 @@ - TerrainSelector - + EntitiesSelector + 0 @@ -11,18 +11,18 @@ - Select Terrains + Select Entities - + - Select Terrains + Select Entities - + diff --git a/mapeditor/templateeditor/templateeditor.cpp b/mapeditor/templateeditor/templateeditor.cpp index efc0b7a18..66b81ce0b 100644 --- a/mapeditor/templateeditor/templateeditor.cpp +++ b/mapeditor/templateeditor/templateeditor.cpp @@ -12,7 +12,7 @@ #include "ui_templateeditor.h" #include "graphicelements/CardItem.h" #include "graphicelements/LineItem.h" -#include "terrainselector.h" +#include "entitiesselector.h" #include "factionselector.h" #include "mineselector.h" #include "treasureselector.h" @@ -1012,12 +1012,14 @@ void TemplateEditor::on_pushButtonConnectionAdd_clicked() void TemplateEditor::on_pushButtonOpenTerrainTypes_clicked() { - TerrainSelector::showTerrainSelector(templates[selectedTemplate]->getZones().at(selectedZone)->terrainTypes); + EntityIds entitiesVariant = std::ref(templates[selectedTemplate]->getZones().at(selectedZone)->terrainTypes); + EntitiesSelector::showEntitiesSelector(entitiesVariant); } void TemplateEditor::on_pushButtonOpenBannedTerrainTypes_clicked() { - TerrainSelector::showTerrainSelector(templates[selectedTemplate]->getZones().at(selectedZone)->bannedTerrains); + EntityIds entitiesVariant = std::ref(templates[selectedTemplate]->getZones().at(selectedZone)->bannedTerrains); + EntitiesSelector::showEntitiesSelector(entitiesVariant); } void TemplateEditor::on_pushButtonAllowedTowns_clicked() @@ -1062,3 +1064,27 @@ void TemplateEditor::on_pushButtonCustomObjects_clicked() //TODO: Implement dialog QMessageBox::critical(this, tr("Error"), tr("Not implemented yet!")); } + +void TemplateEditor::on_pushButtonEntitiesBannedSpells_clicked() +{ + EntityIds entitiesVariant = std::ref(templates[selectedTemplate]->bannedSpells); + EntitiesSelector::showEntitiesSelector(entitiesVariant); +} + +void TemplateEditor::on_pushButtonEntitiesBannedArtifacts_clicked() +{ + EntityIds entitiesVariant = std::ref(templates[selectedTemplate]->bannedArtifacts); + EntitiesSelector::showEntitiesSelector(entitiesVariant); +} + +void TemplateEditor::on_pushButtonEntitiesBannedSkills_clicked() +{ + EntityIds entitiesVariant = std::ref(templates[selectedTemplate]->bannedSkills); + EntitiesSelector::showEntitiesSelector(entitiesVariant); +} + +void TemplateEditor::on_pushButtonEntitiesBannedHeroes_clicked() +{ + EntityIds entitiesVariant = std::ref(templates[selectedTemplate]->bannedHeroes); + EntitiesSelector::showEntitiesSelector(entitiesVariant); +} diff --git a/mapeditor/templateeditor/templateeditor.h b/mapeditor/templateeditor/templateeditor.h index 59fa56264..1770a1233 100644 --- a/mapeditor/templateeditor/templateeditor.h +++ b/mapeditor/templateeditor/templateeditor.h @@ -95,6 +95,10 @@ private slots: void on_pushButtonTreasure_clicked(); void on_pushButtonMines_clicked(); void on_pushButtonCustomObjects_clicked(); + void on_pushButtonEntitiesBannedSpells_clicked(); + void on_pushButtonEntitiesBannedArtifacts_clicked(); + void on_pushButtonEntitiesBannedSkills_clicked(); + void on_pushButtonEntitiesBannedHeroes_clicked(); private: bool getAnswerAboutUnsavedChanges(); diff --git a/mapeditor/templateeditor/templateeditor.ui b/mapeditor/templateeditor/templateeditor.ui index 721fe58ea..e5b328003 100644 --- a/mapeditor/templateeditor/templateeditor.ui +++ b/mapeditor/templateeditor/templateeditor.ui @@ -200,15 +200,15 @@ - 1 + 0 0 - -148 + -316 449 - 662 + 830 @@ -496,6 +496,43 @@ + + + + Entities + + + + + + Banned Spells + + + + + + + Banned Artifacts + + + + + + + Banned Skills + + + + + + + Banned Heroes + + + + + + @@ -515,7 +552,7 @@ 0 - -980 + 0 449 1494 diff --git a/mapeditor/templateeditor/terrainselector.cpp b/mapeditor/templateeditor/terrainselector.cpp deleted file mode 100644 index 7394443a5..000000000 --- a/mapeditor/templateeditor/terrainselector.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * terrainselector.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 "terrainselector.h" -#include "ui_terrainselector.h" - -#include "../../lib/GameLibrary.h" -#include "../../lib/TerrainHandler.h" - -TerrainSelector::TerrainSelector(std::set & terrains) : - ui(new Ui::TerrainSelector), - terrainsSelected(terrains) -{ - ui->setupUi(this); - - setWindowTitle(tr("Terrain Selector")); - - setWindowModality(Qt::ApplicationModal); - - for(auto const & objectPtr : LIBRARY->terrainTypeHandler->objects) - { - auto * item = new QListWidgetItem(QString::fromStdString(objectPtr->getNameTranslated())); - item->setData(Qt::UserRole, QVariant::fromValue(objectPtr->getIndex())); - item->setFlags(item->flags() | Qt::ItemIsUserCheckable); - item->setCheckState(terrains.count(objectPtr->getId()) ? Qt::Checked : Qt::Unchecked); - ui->listWidgetTerrains->addItem(item); - } - - show(); -} - -void TerrainSelector::showTerrainSelector(std::set & terrains) -{ - auto * dialog = new TerrainSelector(terrains); - dialog->setAttribute(Qt::WA_DeleteOnClose); - dialog->exec(); -} - -void TerrainSelector::on_buttonBoxResult_accepted() -{ - terrainsSelected.clear(); - for(int i = 0; i < ui->listWidgetTerrains->count(); ++i) - { - auto * item = ui->listWidgetTerrains->item(i); - if(item->checkState() == Qt::Checked) - terrainsSelected.insert(item->data(Qt::UserRole).toInt()); - } - - close(); -} - -void TerrainSelector::on_buttonBoxResult_rejected() -{ - close(); -} diff --git a/mapeditor/templateeditor/terrainselector.h b/mapeditor/templateeditor/terrainselector.h deleted file mode 100644 index 0e264d8f7..000000000 --- a/mapeditor/templateeditor/terrainselector.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * terrainselector.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 - -#include "../StdInc.h" -#include "../../lib/constants/EntityIdentifiers.h" - -namespace Ui { -class TerrainSelector; -} - -class TerrainSelector : public QDialog -{ - Q_OBJECT - -public: - explicit TerrainSelector(std::set & terrains); - - static void showTerrainSelector(std::set & terrains); - -private slots: - void on_buttonBoxResult_accepted(); - void on_buttonBoxResult_rejected(); - -private: - Ui::TerrainSelector *ui; - - std::set & terrainsSelected; -};