| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- /*
- * towneventdialog.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 "townbuildingswidget.h"
- #include "towneventdialog.h"
- #include "ui_towneventdialog.h"
- #include "mapeditorroles.h"
- #include "../../lib/entities/building/CBuilding.h"
- #include "../../lib/entities/faction/CTownHandler.h"
- #include "../../lib/constants/NumericConstants.h"
- #include "../../lib/constants/StringConstants.h"
- static const int FIRST_DAY_FOR_EVENT = 1;
- static const int LAST_DAY_FOR_EVENT = 999;
- static const int MAXIMUM_EVENT_REPEAT_AFTER = 999;
- static const int MAXIMUM_GOLD_CHANGE = 999999;
- static const int MAXIMUM_RESOURCE_CHANGE = 999;
- static const int GOLD_STEP = 100;
- static const int RESOURCE_STEP = 1;
- static const int MAXIMUM_CREATURES_CHANGE = 999999;
- TownEventDialog::TownEventDialog(CGTownInstance & t, QListWidgetItem * item, QWidget * parent) :
- QDialog(parent),
- ui(new Ui::TownEventDialog),
- town(t),
- townEventListItem(item)
- {
- ui->setupUi(this);
- ui->buildingsTree->setModel(&buildingsModel);
- params = townEventListItem->data(MapEditorRoles::TownEventRole).toMap();
- ui->eventFirstOccurrence->setMinimum(FIRST_DAY_FOR_EVENT);
- ui->eventFirstOccurrence->setMaximum(LAST_DAY_FOR_EVENT);
- ui->eventRepeatAfter->setMaximum(MAXIMUM_EVENT_REPEAT_AFTER);
- ui->eventNameText->setText(params.value("name").toString());
- ui->eventMessageText->setPlainText(params.value("message").toString());
- ui->eventAffectsCpu->setChecked(params.value("computerAffected").toBool());
- ui->eventAffectsHuman->setChecked(params.value("humanAffected").toBool());
- ui->eventFirstOccurrence->setValue(params.value("firstOccurrence").toInt()+1);
- ui->eventRepeatAfter->setValue(params.value("nextOccurrence").toInt());
- initPlayers();
- initResources();
- initBuildings();
- initCreatures();
- }
- TownEventDialog::~TownEventDialog()
- {
- delete ui;
- }
- void TownEventDialog::initPlayers()
- {
- for (int i = 0; i < PlayerColor::PLAYER_LIMIT_I; ++i)
- {
- bool isAffected = (1 << i) & params.value("players").toInt();
- auto * item = new QListWidgetItem(QString::fromStdString(GameConstants::PLAYER_COLOR_NAMES[i]));
- item->setData(MapEditorRoles::PlayerIDRole, QVariant::fromValue(i));
- item->setCheckState(isAffected ? Qt::Checked : Qt::Unchecked);
- ui->playersAffected->addItem(item);
- }
- }
- void TownEventDialog::initResources()
- {
- ui->resourcesTable->setRowCount(GameConstants::RESOURCE_QUANTITY);
- auto resourcesMap = params.value("resources").toMap();
- for (int i = 0; i < GameConstants::RESOURCE_QUANTITY; ++i)
- {
- auto name = QString::fromStdString(GameConstants::RESOURCE_NAMES[i]);
- auto * item = new QTableWidgetItem();
- item->setFlags(item->flags() & ~Qt::ItemIsEditable);
- item->setText(name);
- ui->resourcesTable->setItem(i, 0, item);
- int val = resourcesMap.value(name).toInt();
- auto * edit = new QSpinBox(ui->resourcesTable);
- edit->setMaximum(i == GameResID::GOLD ? MAXIMUM_GOLD_CHANGE : MAXIMUM_RESOURCE_CHANGE);
- edit->setMinimum(i == GameResID::GOLD ? -MAXIMUM_GOLD_CHANGE : -MAXIMUM_RESOURCE_CHANGE);
- edit->setSingleStep(i == GameResID::GOLD ? GOLD_STEP : RESOURCE_STEP);
- edit->setValue(val);
- ui->resourcesTable->setCellWidget(i, 1, edit);
- }
- }
- void TownEventDialog::initBuildings()
- {
- auto * ctown = town.town;
- if (!ctown)
- ctown = VLC->townh->randomTown;
- if (!ctown)
- throw std::runtime_error("No Town defined for type selected");
- auto allBuildings = ctown->getAllBuildings();
- while (!allBuildings.empty())
- {
- addBuilding(*ctown, *allBuildings.begin(), allBuildings);
- }
- ui->buildingsTree->resizeColumnToContents(0);
- connect(&buildingsModel, &QStandardItemModel::itemChanged, this, &TownEventDialog::onItemChanged);
- }
- QStandardItem * TownEventDialog::addBuilding(const CTown& ctown, BuildingID buildingId, std::set<si32>& remaining)
- {
- auto bId = buildingId.num;
- const CBuilding * building = ctown.buildings.at(buildingId);
- QString name = QString::fromStdString(building->getNameTranslated());
- if (name.isEmpty())
- name = QString::fromStdString(defaultBuildingIdConversion(buildingId));
- QList<QStandardItem *> checks;
- checks << new QStandardItem(name);
- checks.back()->setData(bId, MapEditorRoles::BuildingIDRole);
- checks << new QStandardItem;
- checks.back()->setCheckable(true);
- checks.back()->setCheckState(params["buildings"].toList().contains(bId) ? Qt::Checked : Qt::Unchecked);
- checks.back()->setData(bId, MapEditorRoles::BuildingIDRole);
- if (building->getBase() == buildingId)
- {
- buildingsModel.appendRow(checks);
- }
- else
- {
- QStandardItem * parent = getBuildingParentFromTreeModel(building, buildingsModel);
- if (!parent)
- parent = addBuilding(ctown, building->upgrade.getNum(), remaining);
- parent->appendRow(checks);
- }
- remaining.erase(bId);
- return checks.front();
- }
- void TownEventDialog::initCreatures()
- {
- auto creatures = params.value("creatures").toList();
- auto * ctown = town.town;
- for (int i = 0; i < GameConstants::CREATURES_PER_TOWN; ++i)
- {
- QString creatureNames;
- if (!ctown)
- {
- creatureNames.append(tr("Creature level %1 / Creature level %1 Upgrade").arg(i + 1));
- }
- else
- {
- auto creaturesOnLevel = ctown->creatures.at(i);
- for (auto& creature : creaturesOnLevel)
- {
- auto cre = VLC->creatures()->getById(creature);
- auto creatureName = QString::fromStdString(cre->getNameSingularTranslated());
- creatureNames.append(creatureNames.isEmpty() ? creatureName : " / " + creatureName);
- }
- }
- auto * item = new QTableWidgetItem();
- item->setFlags(item->flags() & ~Qt::ItemIsEditable);
- item->setText(creatureNames);
- ui->creaturesTable->setItem(i, 0, item);
- auto creatureNumber = creatures.size() > i ? creatures.at(i).toInt() : 0;
- auto * edit = new QSpinBox(ui->creaturesTable);
- edit->setValue(creatureNumber);
- edit->setMaximum(MAXIMUM_CREATURES_CHANGE);
- ui->creaturesTable->setCellWidget(i, 1, edit);
- }
- ui->creaturesTable->resizeColumnToContents(0);
- }
- void TownEventDialog::on_TownEventDialog_finished(int result)
- {
- QVariantMap descriptor;
- descriptor["name"] = ui->eventNameText->text();
- descriptor["message"] = ui->eventMessageText->toPlainText();
- descriptor["humanAffected"] = QVariant::fromValue(ui->eventAffectsHuman->isChecked());
- descriptor["computerAffected"] = QVariant::fromValue(ui->eventAffectsCpu->isChecked());
- descriptor["firstOccurrence"] = QVariant::fromValue(ui->eventFirstOccurrence->value()-1);
- descriptor["nextOccurrence"] = QVariant::fromValue(ui->eventRepeatAfter->value());
- descriptor["players"] = playersToVariant();
- descriptor["resources"] = resourcesToVariant();
- descriptor["buildings"] = buildingsToVariant();
- descriptor["creatures"] = creaturesToVariant();
- townEventListItem->setData(MapEditorRoles::TownEventRole, descriptor);
- auto itemText = tr("Day %1 - %2").arg(ui->eventFirstOccurrence->value(), 3).arg(ui->eventNameText->text());
- townEventListItem->setText(itemText);
- }
- QVariant TownEventDialog::playersToVariant()
- {
- int players = 0;
- for (int i = 0; i < ui->playersAffected->count(); ++i)
- {
- auto * item = ui->playersAffected->item(i);
- if (item->checkState() == Qt::Checked)
- players |= 1 << i;
- }
- return QVariant::fromValue(players);
- }
- QVariantMap TownEventDialog::resourcesToVariant()
- {
- auto res = params.value("resources").toMap();
- for (int i = 0; i < GameConstants::RESOURCE_QUANTITY; ++i)
- {
- auto * itemType = ui->resourcesTable->item(i, 0);
- auto * itemQty = static_cast<QSpinBox *> (ui->resourcesTable->cellWidget(i, 1));
- res[itemType->text()] = QVariant::fromValue(itemQty->value());
- }
- return res;
- }
- QVariantList TownEventDialog::buildingsToVariant()
- {
- return getBuildingVariantsFromModel(buildingsModel, 1, Qt::Checked);
- }
- QVariantList TownEventDialog::creaturesToVariant()
- {
- QVariantList creaturesList;
- for (int i = 0; i < GameConstants::CREATURES_PER_TOWN; ++i)
- {
- auto * item = static_cast<QSpinBox *>(ui->creaturesTable->cellWidget(i, 1));
- creaturesList.push_back(item->value());
- }
- return creaturesList;
- }
- void TownEventDialog::on_okButton_clicked()
- {
- close();
- }
- void TownEventDialog::setRowColumnCheckState(const QStandardItem * item, int column, Qt::CheckState checkState) {
- auto sibling = item->model()->sibling(item->row(), column, item->index());
- buildingsModel.itemFromIndex(sibling)->setCheckState(checkState);
- }
- void TownEventDialog::onItemChanged(const QStandardItem * item)
- {
- disconnect(&buildingsModel, &QStandardItemModel::itemChanged, this, &TownEventDialog::onItemChanged);
- auto rowFirstColumnIndex = item->model()->sibling(item->row(), 0, item->index());
- QStandardItem * nextRow = buildingsModel.itemFromIndex(rowFirstColumnIndex);
- if (item->checkState() == Qt::Checked) {
- while (nextRow) {
- setRowColumnCheckState(nextRow,item->column(), Qt::Checked);
- nextRow = nextRow->parent();
- }
- }
- else if (item->checkState() == Qt::Unchecked) {
- std::vector<QStandardItem *> stack;
- stack.push_back(nextRow);
- do
- {
- nextRow = stack.back();
- stack.pop_back();
- setRowColumnCheckState(nextRow, item->column(), Qt::Unchecked);
- if (nextRow->hasChildren()) {
- for (int i = 0; i < nextRow->rowCount(); ++i) {
- stack.push_back(nextRow->child(i, 0));
- }
- }
- } while(!stack.empty());
- }
- connect(&buildingsModel, &QStandardItemModel::itemChanged, this, &TownEventDialog::onItemChanged);
- }
|