mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
map editor: Allow to customize town events
This commit is contained in:
parent
7aca2efb35
commit
5578346dac
@ -1207,6 +1207,22 @@ void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
{
|
||||
handler.serializeIdArray( "possibleSpells", possibleSpells);
|
||||
handler.serializeIdArray( "obligatorySpells", obligatorySpells);
|
||||
|
||||
if (handler.saving)
|
||||
{
|
||||
auto eventsHandler = handler.enterArray("events");
|
||||
std::vector<CCastleEvent> temp(events.begin(), events.end());
|
||||
eventsHandler.serializeStruct(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto eventsHandler = handler.enterArray("events");
|
||||
std::vector<CCastleEvent> temp;
|
||||
eventsHandler.serializeStruct(temp);
|
||||
events.clear();
|
||||
events.insert(events.begin(), temp.begin(), temp.end());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,8 @@ set(editor_SRCS
|
||||
validator.cpp
|
||||
inspector/inspector.cpp
|
||||
inspector/townbuildingswidget.cpp
|
||||
inspector/townevent.cpp
|
||||
inspector/towneventswidget.cpp
|
||||
inspector/townspellswidget.cpp
|
||||
inspector/armywidget.cpp
|
||||
inspector/messagewidget.cpp
|
||||
@ -71,6 +73,8 @@ set(editor_HEADERS
|
||||
validator.h
|
||||
inspector/inspector.h
|
||||
inspector/townbuildingswidget.h
|
||||
inspector/townevent.h
|
||||
inspector/towneventswidget.h
|
||||
inspector/townspellswidget.h
|
||||
inspector/armywidget.h
|
||||
inspector/messagewidget.h
|
||||
@ -100,6 +104,8 @@ set(editor_FORMS
|
||||
playerparams.ui
|
||||
validator.ui
|
||||
inspector/townbuildingswidget.ui
|
||||
inspector/townevent.ui
|
||||
inspector/towneventswidget.ui
|
||||
inspector/townspellswidget.ui
|
||||
inspector/armywidget.ui
|
||||
inspector/messagewidget.ui
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "../lib/constants/StringConstants.h"
|
||||
|
||||
#include "townbuildingswidget.h"
|
||||
#include "towneventswidget.h"
|
||||
#include "townspellswidget.h"
|
||||
#include "armywidget.h"
|
||||
#include "messagewidget.h"
|
||||
@ -344,6 +345,7 @@ void Inspector::updateProperties(CGTownInstance * o)
|
||||
auto * delegate = new TownBuildingsDelegate(*o);
|
||||
addProperty("Buildings", PropertyEditorPlaceholder(), delegate, false);
|
||||
addProperty("Spells", PropertyEditorPlaceholder(), new TownSpellsDelegate(*o), false);
|
||||
addProperty("Events", PropertyEditorPlaceholder(), new TownEventsDelegate(*o, controller), false);
|
||||
}
|
||||
|
||||
void Inspector::updateProperties(CGArtifact * o)
|
||||
|
320
mapeditor/inspector/townevent.cpp
Normal file
320
mapeditor/inspector/townevent.cpp
Normal file
@ -0,0 +1,320 @@
|
||||
/*
|
||||
* townevent.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 "townevent.h"
|
||||
#include "ui_townevent.h"
|
||||
#include "../../lib/constants/NumericConstants.h"
|
||||
#include "../../lib/constants/StringConstants.h"
|
||||
|
||||
TownEvent::TownEvent(CGTownInstance & t, QListWidgetItem * item, QWidget * parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::TownEvent),
|
||||
town(t),
|
||||
item(item)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->buildingsTree->setModel(&buildingsModel);
|
||||
|
||||
params = item->data(Qt::UserRole).toMap();
|
||||
ui->eventFirstOccurrence->setMinimum(1);
|
||||
ui->eventFirstOccurrence->setMaximum(999);
|
||||
ui->eventRepeatAfter->setMaximum(999);
|
||||
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();
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
TownEvent::~TownEvent()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void TownEvent::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(Qt::UserRole, QVariant::fromValue(i));
|
||||
item->setCheckState(isAffected ? Qt::Checked : Qt::Unchecked);
|
||||
ui->playersAffected->addItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
void TownEvent::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]);
|
||||
int val = resourcesMap.value(name).toInt();
|
||||
ui->resourcesTable->setItem(i, 0, new QTableWidgetItem(name));
|
||||
|
||||
QSpinBox * edit = new QSpinBox(ui->resourcesTable);
|
||||
edit->setMaximum(i == GameResID::GOLD ? 999999 : 999);
|
||||
edit->setMinimum(i == GameResID::GOLD ? -999999 : -999);
|
||||
edit->setSingleStep(i == GameResID::GOLD ? 100 : 1);
|
||||
edit->setValue(val);
|
||||
|
||||
ui->resourcesTable->setCellWidget(i, 1, edit);
|
||||
}
|
||||
}
|
||||
|
||||
void TownEvent::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, &TownEvent::onItemChanged);
|
||||
}
|
||||
|
||||
QStandardItem * TownEvent::addBuilding(const CTown& ctown, BuildingID buildingId, std::set<si32>& remaining)
|
||||
{
|
||||
auto bId = buildingId.num;
|
||||
const CBuilding * building = ctown.buildings.at(buildingId);
|
||||
if (!building)
|
||||
{
|
||||
remaining.erase(bId);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString name = tr(building->getNameTranslated().c_str());
|
||||
|
||||
if (name.isEmpty())
|
||||
name = QString::fromStdString(defaultBuildingIdConversion(buildingId));
|
||||
|
||||
QList<QStandardItem *> checks;
|
||||
|
||||
checks << new QStandardItem(name);
|
||||
checks.back()->setData(bId, Qt::UserRole);
|
||||
|
||||
checks << new QStandardItem;
|
||||
checks.back()->setCheckable(true);
|
||||
checks.back()->setCheckState(params["buildings"].toList().contains(bId) ? Qt::Checked : Qt::Unchecked);
|
||||
checks.back()->setData(bId, Qt::UserRole);
|
||||
|
||||
if (building->getBase() == buildingId)
|
||||
{
|
||||
buildingsModel.appendRow(checks);
|
||||
}
|
||||
else
|
||||
{
|
||||
QStandardItem * parent = nullptr;
|
||||
std::vector<QModelIndex> stack;
|
||||
stack.push_back(QModelIndex());
|
||||
while (!parent && !stack.empty())
|
||||
{
|
||||
auto pindex = stack.back();
|
||||
stack.pop_back();
|
||||
for (int i = 0; i < buildingsModel.rowCount(pindex); ++i)
|
||||
{
|
||||
QModelIndex index = buildingsModel.index(i, 0, pindex);
|
||||
if (building->upgrade.getNum() == buildingsModel.itemFromIndex(index)->data(Qt::UserRole).toInt())
|
||||
{
|
||||
parent = buildingsModel.itemFromIndex(index);
|
||||
break;
|
||||
}
|
||||
if (buildingsModel.hasChildren(index))
|
||||
stack.push_back(index);
|
||||
}
|
||||
}
|
||||
|
||||
if (!parent)
|
||||
parent = addBuilding(ctown, building->upgrade.getNum(), remaining);
|
||||
|
||||
if (!parent)
|
||||
{
|
||||
remaining.erase(bId);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
parent->appendRow(checks);
|
||||
}
|
||||
|
||||
remaining.erase(bId);
|
||||
return checks.front();
|
||||
}
|
||||
|
||||
void TownEvent::initCreatures()
|
||||
{
|
||||
auto creatures = params.value("creatures").toList();
|
||||
auto * ctown = town.town;
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
QString creatureNames;
|
||||
if (!ctown)
|
||||
{
|
||||
creatureNames.append(QString("Creature %1 / Creature %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;
|
||||
QSpinBox* edit = new QSpinBox(ui->creaturesTable);
|
||||
edit->setValue(creatureNumber);
|
||||
edit->setMaximum(999999);
|
||||
ui->creaturesTable->setCellWidget(i, 1, edit);
|
||||
|
||||
}
|
||||
ui->creaturesTable->resizeColumnToContents(0);
|
||||
}
|
||||
|
||||
void TownEvent::on_TownEvent_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();
|
||||
|
||||
item->setData(Qt::UserRole, descriptor);
|
||||
auto itemText = QString::fromStdString("Day %1 - %2").arg(ui->eventFirstOccurrence->value(), 3).arg(ui->eventNameText->text());
|
||||
item->setText(itemText);
|
||||
}
|
||||
|
||||
QVariant TownEvent::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 TownEvent::resourcesToVariant()
|
||||
{
|
||||
auto res = item->data(Qt::UserRole).toMap().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 TownEvent::buildingsToVariant()
|
||||
{
|
||||
QVariantList buildingsList;
|
||||
std::vector<QModelIndex> stack;
|
||||
stack.push_back(QModelIndex());
|
||||
while (!stack.empty())
|
||||
{
|
||||
auto pindex = stack.back();
|
||||
stack.pop_back();
|
||||
for (int i = 0; i < buildingsModel.rowCount(pindex); ++i)
|
||||
{
|
||||
QModelIndex index = buildingsModel.index(i, 1, pindex);
|
||||
if (auto * item = buildingsModel.itemFromIndex(index))
|
||||
if (item->checkState() == Qt::Checked)
|
||||
buildingsList.push_back(item->data(Qt::UserRole));
|
||||
index = buildingsModel.index(i, 0, pindex);
|
||||
if (buildingsModel.hasChildren(index))
|
||||
stack.push_back(index);
|
||||
}
|
||||
}
|
||||
return buildingsList;
|
||||
}
|
||||
|
||||
QVariantList TownEvent::creaturesToVariant()
|
||||
{
|
||||
QVariantList creaturesList;
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
auto * item = static_cast<QSpinBox *>(ui->creaturesTable->cellWidget(i, 1));
|
||||
creaturesList.push_back(item->value());
|
||||
}
|
||||
return creaturesList;
|
||||
}
|
||||
|
||||
void TownEvent::on_okButton_clicked()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void TownEvent::setRowColumnCheckState(QStandardItem * item, int column, Qt::CheckState checkState) {
|
||||
auto sibling = item->model()->sibling(item->row(), column, item->index());
|
||||
buildingsModel.itemFromIndex(sibling)->setCheckState(checkState);
|
||||
}
|
||||
|
||||
void TownEvent::onItemChanged(QStandardItem * item)
|
||||
{
|
||||
disconnect(&buildingsModel, &QStandardItemModel::itemChanged, this, &TownEvent::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);
|
||||
while (!stack.empty()) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
connect(&buildingsModel, &QStandardItemModel::itemChanged, this, &TownEvent::onItemChanged);
|
||||
}
|
53
mapeditor/inspector/townevent.h
Normal file
53
mapeditor/inspector/townevent.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* townevent.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 "../StdInc.h"
|
||||
#include <QDialog>
|
||||
#include "../lib/mapObjects/CGTownInstance.h"
|
||||
|
||||
namespace Ui {
|
||||
class TownEvent;
|
||||
}
|
||||
|
||||
class TownEvent : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TownEvent(CGTownInstance & town, QListWidgetItem * item, QWidget * parent);
|
||||
~TownEvent();
|
||||
|
||||
|
||||
private slots:
|
||||
void onItemChanged(QStandardItem * item);
|
||||
void on_TownEvent_finished(int result);
|
||||
void on_okButton_clicked();
|
||||
void setRowColumnCheckState(QStandardItem * item, int column, Qt::CheckState checkState);
|
||||
|
||||
private:
|
||||
void initPlayers();
|
||||
void initResources();
|
||||
void initBuildings();
|
||||
void initCreatures();
|
||||
|
||||
QVariant playersToVariant();
|
||||
QVariantMap resourcesToVariant();
|
||||
QVariantList buildingsToVariant();
|
||||
QVariantList creaturesToVariant();
|
||||
|
||||
QStandardItem * addBuilding(const CTown & ctown, BuildingID bId, std::set<si32> & remaining);
|
||||
|
||||
Ui::TownEvent * ui;
|
||||
CGTownInstance & town;
|
||||
QListWidgetItem * item;
|
||||
QMap<QString, QVariant> params;
|
||||
mutable QStandardItemModel buildingsModel;
|
||||
};
|
263
mapeditor/inspector/townevent.ui
Normal file
263
mapeditor/inspector/townevent.ui
Normal file
@ -0,0 +1,263 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TownEvent</class>
|
||||
<widget class="QDialog" name="TownEvent">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>693</width>
|
||||
<height>525</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Town event</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="generalTab">
|
||||
<attribute name="title">
|
||||
<string>General</string>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="verticalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>9</x>
|
||||
<y>9</y>
|
||||
<width>511</width>
|
||||
<height>351</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="eventNameText">
|
||||
<property name="placeholderText">
|
||||
<string>Event name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="eventMessageText">
|
||||
<property name="placeholderText">
|
||||
<string>Type event message text</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>370</y>
|
||||
<width>511</width>
|
||||
<height>61</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="eventFirstOccurrenceText">
|
||||
<property name="text">
|
||||
<string>Day of first occurrence</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="eventFirstOccurrence"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="eventRepeatAfterText">
|
||||
<property name="text">
|
||||
<string>Repeat after (0 = no repeat)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="eventRepeatAfter"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="verticalLayoutWidget_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>529</x>
|
||||
<y>9</y>
|
||||
<width>141</width>
|
||||
<height>421</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="playersAffectedText">
|
||||
<property name="text">
|
||||
<string>Affected players</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="playersAffected">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="eventAffectsHuman">
|
||||
<property name="text">
|
||||
<string>affects human</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="eventAffectsCpu">
|
||||
<property name="text">
|
||||
<string>affects AI</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="resourcesTab">
|
||||
<attribute name="title">
|
||||
<string>Resources</string>
|
||||
</attribute>
|
||||
<widget class="QTableWidget" name="resourcesTable">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>661</width>
|
||||
<height>421</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column/>
|
||||
<column/>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="buildingsTab">
|
||||
<attribute name="title">
|
||||
<string>Buildings</string>
|
||||
</attribute>
|
||||
<widget class="QTreeView" name="buildingsTree">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>661</width>
|
||||
<height>421</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="creaturesTab">
|
||||
<attribute name="title">
|
||||
<string>Creatures</string>
|
||||
</attribute>
|
||||
<widget class="QTableWidget" name="creaturesTable">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>661</width>
|
||||
<height>421</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="rowCount">
|
||||
<number>7</number>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<row/>
|
||||
<row/>
|
||||
<row/>
|
||||
<row/>
|
||||
<row/>
|
||||
<row/>
|
||||
<row/>
|
||||
<column/>
|
||||
<column/>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="okButton">
|
||||
<property name="text">
|
||||
<string>OK</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
179
mapeditor/inspector/towneventswidget.cpp
Normal file
179
mapeditor/inspector/towneventswidget.cpp
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* towneventswidget.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 "towneventswidget.h"
|
||||
#include "ui_towneventswidget.h"
|
||||
#include "townevent.h"
|
||||
#include "mapsettings/eventsettings.h"
|
||||
#include "../../lib/constants/NumericConstants.h"
|
||||
#include "../../lib/constants/StringConstants.h"
|
||||
|
||||
TownEventsWidget::TownEventsWidget(CGTownInstance & town, QWidget * parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::TownEventsWidget),
|
||||
town(town)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
TownEventsWidget::~TownEventsWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QVariant toVariant(const std::set<BuildingID> & buildings)
|
||||
{
|
||||
QVariantList result;
|
||||
for (auto b : buildings)
|
||||
result.push_back(QVariant::fromValue(b.num));
|
||||
return result;
|
||||
}
|
||||
|
||||
QVariant toVariant(const std::vector<si32> & creatures)
|
||||
{
|
||||
QVariantList result;
|
||||
for (auto c : creatures)
|
||||
result.push_back(QVariant::fromValue(c));
|
||||
return result;
|
||||
}
|
||||
|
||||
std::set<BuildingID> buildingsFromVariant(const QVariant& v)
|
||||
{
|
||||
std::set<BuildingID> result;
|
||||
for (auto r : v.toList()) {
|
||||
result.insert(BuildingID(r.toInt()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<si32> creaturesFromVariant(const QVariant& v)
|
||||
{
|
||||
std::vector<si32> result;
|
||||
for (auto r : v.toList()) {
|
||||
result.push_back(r.toInt());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QVariant toVariant(const CCastleEvent& event)
|
||||
{
|
||||
QVariantMap result;
|
||||
result["name"] = QString::fromStdString(event.name);
|
||||
result["message"] = QString::fromStdString(event.message.toString());
|
||||
result["players"] = QVariant::fromValue(event.players);
|
||||
result["humanAffected"] = QVariant::fromValue(event.humanAffected);
|
||||
result["computerAffected"] = QVariant::fromValue(event.computerAffected);
|
||||
result["firstOccurrence"] = QVariant::fromValue(event.firstOccurrence);
|
||||
result["nextOccurrence"] = QVariant::fromValue(event.nextOccurrence);
|
||||
result["resources"] = toVariant(event.resources);
|
||||
result["buildings"] = toVariant(event.buildings);
|
||||
result["creatures"] = toVariant(event.creatures);
|
||||
|
||||
return QVariant(result);
|
||||
}
|
||||
|
||||
CCastleEvent eventFromVariant(CMapHeader& map, CGTownInstance& town, const QVariant& variant)
|
||||
{
|
||||
CCastleEvent result;
|
||||
auto v = variant.toMap();
|
||||
result.name = v.value("name").toString().toStdString();
|
||||
result.message.appendTextID(mapRegisterLocalizedString("map", map, TextIdentifier("town", town.instanceName, "event", result.name, "message"), v.value("message").toString().toStdString()));
|
||||
result.players = v.value("players").toInt();
|
||||
result.humanAffected = v.value("humanAffected").toInt();
|
||||
result.computerAffected = v.value("computerAffected").toInt();
|
||||
result.firstOccurrence = v.value("firstOccurrence").toInt();
|
||||
result.nextOccurrence = v.value("nextOccurrence").toInt();
|
||||
result.resources = resourcesFromVariant(v.value("resources"));
|
||||
result.buildings = buildingsFromVariant(v.value("buildings"));
|
||||
result.creatures = creaturesFromVariant(v.value("creatures"));
|
||||
return result;
|
||||
}
|
||||
|
||||
void TownEventsWidget::obtainData()
|
||||
{
|
||||
for (const auto & event : town.events)
|
||||
{
|
||||
auto eventName = QString::fromStdString(event.name);
|
||||
auto itemText = QString::fromStdString("Day %1 - %2").arg(event.firstOccurrence+1, 3).arg(eventName);
|
||||
|
||||
auto * item = new QListWidgetItem(itemText);
|
||||
item->setData(Qt::UserRole, toVariant(event));
|
||||
ui->eventsList->addItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
void TownEventsWidget::commitChanges(MapController& controller)
|
||||
{
|
||||
town.events.clear();
|
||||
for (int i = 0; i < ui->eventsList->count(); ++i)
|
||||
{
|
||||
const auto * item = ui->eventsList->item(i);
|
||||
town.events.push_back(eventFromVariant(*controller.map(), town, item->data(Qt::UserRole)));
|
||||
}
|
||||
}
|
||||
|
||||
void TownEventsWidget::on_timedEventAdd_clicked()
|
||||
{
|
||||
CCastleEvent event;
|
||||
event.name = tr("New event").toStdString();
|
||||
auto* item = new QListWidgetItem(QString::fromStdString(event.name));
|
||||
item->setData(Qt::UserRole, toVariant(event));
|
||||
ui->eventsList->addItem(item);
|
||||
on_eventsList_itemActivated(item);
|
||||
}
|
||||
|
||||
void TownEventsWidget::on_timedEventRemove_clicked()
|
||||
{
|
||||
if (auto* item = ui->eventsList->currentItem())
|
||||
ui->eventsList->takeItem(ui->eventsList->row(item));
|
||||
}
|
||||
|
||||
void TownEventsWidget::on_eventsList_itemActivated(QListWidgetItem* item)
|
||||
{
|
||||
new TownEvent(town, item, parentWidget());
|
||||
}
|
||||
|
||||
void TownEventsWidget::onItemChanged(QStandardItem * item)
|
||||
{
|
||||
}
|
||||
|
||||
TownEventsDelegate::TownEventsDelegate(CGTownInstance & town, MapController & c) : town(town), controller(c), QStyledItemDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
QWidget* TownEventsDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const
|
||||
{
|
||||
return new TownEventsWidget(town, parent);;
|
||||
}
|
||||
|
||||
void TownEventsDelegate::setEditorData(QWidget * editor, const QModelIndex & index) const
|
||||
{
|
||||
if (auto * ed = qobject_cast<TownEventsWidget *>(editor))
|
||||
{
|
||||
ed->obtainData();
|
||||
}
|
||||
else
|
||||
{
|
||||
QStyledItemDelegate::setEditorData(editor, index);
|
||||
}
|
||||
}
|
||||
|
||||
void TownEventsDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const
|
||||
{
|
||||
if (auto * ed = qobject_cast<TownEventsWidget *>(editor))
|
||||
{
|
||||
ed->commitChanges(controller);
|
||||
}
|
||||
else
|
||||
{
|
||||
QStyledItemDelegate::setModelData(editor, model, index);
|
||||
}
|
||||
}
|
59
mapeditor/inspector/towneventswidget.h
Normal file
59
mapeditor/inspector/towneventswidget.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* towneventswidget.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 "../StdInc.h"
|
||||
#include <QDialog>
|
||||
#include "../lib/mapping/CMapDefines.h"
|
||||
#include "../lib/mapObjects/CGTownInstance.h"
|
||||
#include "../mapcontroller.h"
|
||||
|
||||
namespace Ui {
|
||||
class TownEventsWidget;
|
||||
}
|
||||
|
||||
class TownEventsWidget : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TownEventsWidget(CGTownInstance &, QWidget * parent = nullptr);
|
||||
~TownEventsWidget();
|
||||
|
||||
void obtainData();
|
||||
void commitChanges(MapController & controller);
|
||||
private slots:
|
||||
void onItemChanged(QStandardItem * item);
|
||||
void on_timedEventAdd_clicked();
|
||||
void on_timedEventRemove_clicked();
|
||||
void on_eventsList_itemActivated(QListWidgetItem * item);
|
||||
|
||||
private:
|
||||
|
||||
Ui::TownEventsWidget * ui;
|
||||
CGTownInstance & town;
|
||||
};
|
||||
|
||||
class TownEventsDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QStyledItemDelegate::QStyledItemDelegate;
|
||||
|
||||
TownEventsDelegate(CGTownInstance &, MapController &);
|
||||
|
||||
QWidget* createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
|
||||
void setEditorData(QWidget * editor, const QModelIndex & index) const override;
|
||||
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override;
|
||||
|
||||
private:
|
||||
CGTownInstance & town;
|
||||
MapController & controller;
|
||||
};
|
93
mapeditor/inspector/towneventswidget.ui
Normal file
93
mapeditor/inspector/towneventswidget.ui
Normal file
@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TownEventsWidget</class>
|
||||
<widget class="QDialog" name="TownEventsWidget">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>691</width>
|
||||
<height>462</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>400</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Town events</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="timedEventText">
|
||||
<property name="text">
|
||||
<string>Timed events</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="timedEventAdd">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>90</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="timedEventRemove">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>90</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="eventsList">
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -15,6 +15,9 @@ namespace Ui {
|
||||
class EventSettings;
|
||||
}
|
||||
|
||||
QVariant toVariant(const TResources & resources);
|
||||
TResources resourcesFromVariant(const QVariant & v);
|
||||
|
||||
class EventSettings : public AbstractSettings
|
||||
{
|
||||
Q_OBJECT
|
||||
|
Loading…
Reference in New Issue
Block a user