mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-25 22:42:04 +02:00
campaign editor
This commit is contained in:
@@ -431,6 +431,10 @@ std::unique_ptr<CMap> CampaignState::getMap(CampaignScenarioID scenarioId, IGame
|
|||||||
std::string scenarioName = getFilename().substr(0, getFilename().find('.'));
|
std::string scenarioName = getFilename().substr(0, getFilename().find('.'));
|
||||||
boost::to_lower(scenarioName);
|
boost::to_lower(scenarioName);
|
||||||
scenarioName += ':' + std::to_string(scenarioId.getNum());
|
scenarioName += ':' + std::to_string(scenarioId.getNum());
|
||||||
|
|
||||||
|
if(!mapPieces.count(scenarioId) || !mapPieces.find(scenarioId)->second.size())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
const auto & mapContent = mapPieces.find(scenarioId)->second;
|
const auto & mapContent = mapPieces.find(scenarioId)->second;
|
||||||
auto result = mapService.loadMap(mapContent.data(), mapContent.size(), scenarioName, getModName(), getEncoding(), cb);
|
auto result = mapService.loadMap(mapContent.data(), mapContent.size(), scenarioName, getModName(), getEncoding(), cb);
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ class IGameCallback;
|
|||||||
|
|
||||||
class DLL_LINKAGE CampaignRegions
|
class DLL_LINKAGE CampaignRegions
|
||||||
{
|
{
|
||||||
|
// Campaign editor
|
||||||
|
friend class CampaignEditor;
|
||||||
|
friend class CampaignProperties;
|
||||||
|
friend class ScenarioProperties;
|
||||||
|
|
||||||
std::string campPrefix;
|
std::string campPrefix;
|
||||||
std::vector<std::string> campSuffix;
|
std::vector<std::string> campSuffix;
|
||||||
std::string campBackground;
|
std::string campBackground;
|
||||||
@@ -85,6 +90,11 @@ class DLL_LINKAGE CampaignHeader : public boost::noncopyable
|
|||||||
friend class CampaignHandler;
|
friend class CampaignHandler;
|
||||||
friend class Campaign;
|
friend class Campaign;
|
||||||
|
|
||||||
|
// Campaign editor
|
||||||
|
friend class CampaignEditor;
|
||||||
|
friend class CampaignProperties;
|
||||||
|
friend class ScenarioProperties;
|
||||||
|
|
||||||
CampaignVersion version = CampaignVersion::NONE;
|
CampaignVersion version = CampaignVersion::NONE;
|
||||||
CampaignRegions campaignRegions;
|
CampaignRegions campaignRegions;
|
||||||
MetaString name;
|
MetaString name;
|
||||||
@@ -251,6 +261,11 @@ class DLL_LINKAGE Campaign : public CampaignHeader, public Serializeable
|
|||||||
{
|
{
|
||||||
friend class CampaignHandler;
|
friend class CampaignHandler;
|
||||||
|
|
||||||
|
// Campaign editor
|
||||||
|
friend class CampaignEditor;
|
||||||
|
friend class CampaignProperties;
|
||||||
|
friend class ScenarioProperties;
|
||||||
|
|
||||||
std::map<CampaignScenarioID, CampaignScenario> scenarios;
|
std::map<CampaignScenarioID, CampaignScenario> scenarios;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -273,6 +288,12 @@ public:
|
|||||||
class DLL_LINKAGE CampaignState : public Campaign
|
class DLL_LINKAGE CampaignState : public Campaign
|
||||||
{
|
{
|
||||||
friend class CampaignHandler;
|
friend class CampaignHandler;
|
||||||
|
|
||||||
|
// Campaign editor
|
||||||
|
friend class CampaignEditor;
|
||||||
|
friend class CampaignProperties;
|
||||||
|
friend class ScenarioProperties;
|
||||||
|
|
||||||
using ScenarioPoolType = std::vector<JsonNode>;
|
using ScenarioPoolType = std::vector<JsonNode>;
|
||||||
using CampaignPoolType = std::map<CampaignScenarioID, ScenarioPoolType>;
|
using CampaignPoolType = std::map<CampaignScenarioID, ScenarioPoolType>;
|
||||||
using GlobalPoolType = std::map<HeroTypeID, JsonNode>;
|
using GlobalPoolType = std::map<HeroTypeID, JsonNode>;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "CCreatureHandler.h"
|
#include "CCreatureHandler.h"
|
||||||
#include "CCreatureSet.h"
|
#include "CCreatureSet.h"
|
||||||
#include "entities/faction/CFaction.h"
|
#include "entities/faction/CFaction.h"
|
||||||
|
#include "entities/hero/CHero.h"
|
||||||
#include "texts/CGeneralTextHandler.h"
|
#include "texts/CGeneralTextHandler.h"
|
||||||
#include "CSkillHandler.h"
|
#include "CSkillHandler.h"
|
||||||
#include "GameConstants.h"
|
#include "GameConstants.h"
|
||||||
@@ -350,6 +351,11 @@ void MetaString::appendName(const ArtifactID & id)
|
|||||||
appendTextID(id.toEntity(LIBRARY)->getNameTextID());
|
appendTextID(id.toEntity(LIBRARY)->getNameTextID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetaString::appendName(const HeroTypeID & id)
|
||||||
|
{
|
||||||
|
appendTextID(id.toEntity(LIBRARY)->getNameTextID());
|
||||||
|
}
|
||||||
|
|
||||||
void MetaString::appendName(const SpellID & id)
|
void MetaString::appendName(const SpellID & id)
|
||||||
{
|
{
|
||||||
appendTextID(id.toEntity(LIBRARY)->getNameTextID());
|
appendTextID(id.toEntity(LIBRARY)->getNameTextID());
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ class SecondarySkill;
|
|||||||
class SpellID;
|
class SpellID;
|
||||||
class FactionID;
|
class FactionID;
|
||||||
class GameResID;
|
class GameResID;
|
||||||
|
class HeroTypeID;
|
||||||
using TQuantity = si32;
|
using TQuantity = si32;
|
||||||
|
|
||||||
/// Strings classes that can be used as replacement in MetaString
|
/// Strings classes that can be used as replacement in MetaString
|
||||||
@@ -78,6 +79,7 @@ public:
|
|||||||
void appendNumber(int64_t value);
|
void appendNumber(int64_t value);
|
||||||
|
|
||||||
void appendName(const ArtifactID& id);
|
void appendName(const ArtifactID& id);
|
||||||
|
void appendName(const HeroTypeID& id);
|
||||||
void appendName(const SpellID& id);
|
void appendName(const SpellID& id);
|
||||||
void appendName(const PlayerColor& id);
|
void appendName(const PlayerColor& id);
|
||||||
void appendName(const CreatureID & id, TQuantity count);
|
void appendName(const CreatureID & id, TQuantity count);
|
||||||
|
|||||||
@@ -69,18 +69,20 @@ namespace BitmapHandler
|
|||||||
it = (int)size - 256 * 3;
|
it = (int)size - 256 * 3;
|
||||||
for(int i = 0; i < 256; i++)
|
for(int i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
char bytes[3];
|
unsigned char bytes[4];
|
||||||
bytes[0] = pcx[it++];
|
bytes[0] = pcx[it++];
|
||||||
bytes[1] = pcx[it++];
|
bytes[1] = pcx[it++];
|
||||||
bytes[2] = pcx[it++];
|
bytes[2] = pcx[it++];
|
||||||
colorTable.append(qRgb(bytes[0], bytes[1], bytes[2]));
|
bytes[3] = (bytes[0] == 0 && bytes[1] == 255 && bytes[2] == 255) ? 0 : 255;
|
||||||
|
|
||||||
|
colorTable.append(qRgba(bytes[0], bytes[1], bytes[2], bytes[3]));
|
||||||
}
|
}
|
||||||
image.setColorTable(colorTable);
|
image.setColorTable(colorTable);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QImage image(pcx + it, width, height, width * 3, QImage::Format_RGB888);
|
QImage image(pcx + it, width, height, width * 3, QImage::Format_BGR888);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,12 @@ set(editor_SRCS
|
|||||||
inspector/PickObjectDelegate.cpp
|
inspector/PickObjectDelegate.cpp
|
||||||
inspector/portraitwidget.cpp
|
inspector/portraitwidget.cpp
|
||||||
resourceExtractor/ResourceConverter.cpp
|
resourceExtractor/ResourceConverter.cpp
|
||||||
|
helper.cpp
|
||||||
|
campaigneditor/campaigneditor.cpp
|
||||||
|
campaigneditor/campaignproperties.cpp
|
||||||
|
campaigneditor/scenarioproperties.cpp
|
||||||
|
campaigneditor/startingbonus.cpp
|
||||||
|
campaigneditor/campaignview.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(editor_HEADERS
|
set(editor_HEADERS
|
||||||
@@ -87,6 +93,12 @@ set(editor_HEADERS
|
|||||||
inspector/baseinspectoritemdelegate.h
|
inspector/baseinspectoritemdelegate.h
|
||||||
resourceExtractor/ResourceConverter.h
|
resourceExtractor/ResourceConverter.h
|
||||||
mapeditorroles.h
|
mapeditorroles.h
|
||||||
|
helper.h
|
||||||
|
campaigneditor/campaigneditor.h
|
||||||
|
campaigneditor/campaignproperties.h
|
||||||
|
campaigneditor/scenarioproperties.h
|
||||||
|
campaigneditor/startingbonus.h
|
||||||
|
campaigneditor/campaignview.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(editor_FORMS
|
set(editor_FORMS
|
||||||
@@ -118,6 +130,10 @@ set(editor_FORMS
|
|||||||
inspector/heroskillswidget.ui
|
inspector/heroskillswidget.ui
|
||||||
inspector/herospellwidget.ui
|
inspector/herospellwidget.ui
|
||||||
inspector/portraitwidget.ui
|
inspector/portraitwidget.ui
|
||||||
|
campaigneditor/campaigneditor.ui
|
||||||
|
campaigneditor/campaignproperties.ui
|
||||||
|
campaigneditor/scenarioproperties.ui
|
||||||
|
campaigneditor/startingbonus.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
set(editor_RESOURCES
|
set(editor_RESOURCES
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "../Global.h"
|
#include "../Global.h"
|
||||||
|
|
||||||
#define VCMI_EDITOR_NAME "VCMI Map Editor"
|
#define VCMI_EDITOR_NAME "VCMI Map Editor"
|
||||||
|
#define VCMI_CAMP_EDITOR_NAME "VCMI Campaign Editor"
|
||||||
|
|
||||||
#include <QtWidgets>
|
#include <QtWidgets>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|||||||
251
mapeditor/campaigneditor/campaigneditor.cpp
Normal file
251
mapeditor/campaigneditor/campaigneditor.cpp
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
/*
|
||||||
|
* campaigneditor.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 "campaigneditor.h"
|
||||||
|
#include "ui_campaigneditor.h"
|
||||||
|
|
||||||
|
#include "campaignproperties.h"
|
||||||
|
#include "scenarioproperties.h"
|
||||||
|
|
||||||
|
#include "../BitmapHandler.h"
|
||||||
|
#include "../helper.h"
|
||||||
|
|
||||||
|
#include "../../lib/VCMIDirs.h"
|
||||||
|
#include "../../lib/json/JsonNode.h"
|
||||||
|
#include "../../lib/campaign/CampaignState.h"
|
||||||
|
#include "../../lib/mapping/CMap.h"
|
||||||
|
|
||||||
|
CampaignEditor::CampaignEditor():
|
||||||
|
ui(new Ui::CampaignEditor),
|
||||||
|
selectedScenario(CampaignScenarioID::NONE)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
setWindowIcon(QIcon{":/icons/menu-game.png"});
|
||||||
|
ui->actionOpen->setIcon(QIcon{":/icons/document-open.png"});
|
||||||
|
ui->actionSave->setIcon(QIcon{":/icons/document-save.png"});
|
||||||
|
ui->actionNew->setIcon(QIcon{":/icons/document-new.png"});
|
||||||
|
ui->actionScenarioProperties->setIcon(QIcon{":/icons/menu-settings.png"});
|
||||||
|
ui->actionCampaignProperties->setIcon(QIcon{":/icons/menu-mods.png"});
|
||||||
|
|
||||||
|
campaignScene.reset(new CampaignScene());
|
||||||
|
ui->campaignView->setScene(campaignScene.get());
|
||||||
|
|
||||||
|
redraw();
|
||||||
|
|
||||||
|
setTitle();
|
||||||
|
|
||||||
|
setWindowModality(Qt::ApplicationModal);
|
||||||
|
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
CampaignEditor::~CampaignEditor()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignEditor::redraw()
|
||||||
|
{
|
||||||
|
ui->actionSave->setEnabled(campaignState != nullptr);
|
||||||
|
ui->actionSave_as->setEnabled(campaignState != nullptr);
|
||||||
|
ui->actionScenarioProperties->setEnabled(campaignState != nullptr && campaignState->scenarios.count(selectedScenario));
|
||||||
|
ui->actionCampaignProperties->setEnabled(campaignState != nullptr);
|
||||||
|
|
||||||
|
if(!campaignState)
|
||||||
|
return;
|
||||||
|
|
||||||
|
campaignScene->clear();
|
||||||
|
|
||||||
|
auto background = BitmapHandler::loadBitmap(campaignState->getRegions().getBackgroundName().getName());
|
||||||
|
campaignScene->addItem(new QGraphicsPixmapItem(QPixmap::fromImage(background)));
|
||||||
|
for (auto & s : campaignState->scenarios)
|
||||||
|
{
|
||||||
|
auto scenario = s.first;
|
||||||
|
auto color = campaignState->scenarios.at(scenario).regionColor;
|
||||||
|
auto image = BitmapHandler::loadBitmap(campaignState->getRegions().getAvailableName(scenario, color).getName());
|
||||||
|
if(selectedScenario == scenario)
|
||||||
|
image = BitmapHandler::loadBitmap(campaignState->getRegions().getSelectedName(scenario, color).getName());
|
||||||
|
else if(campaignState->scenarios.at(scenario).mapName == "")
|
||||||
|
image = BitmapHandler::loadBitmap(campaignState->getRegions().getConqueredName(scenario, color).getName());
|
||||||
|
auto pixmap = new ClickablePixmapItem(QPixmap::fromImage(image), [this, scenario]()
|
||||||
|
{
|
||||||
|
bool redrawRequired = selectedScenario != scenario;
|
||||||
|
selectedScenario = scenario;
|
||||||
|
|
||||||
|
if(redrawRequired)
|
||||||
|
redraw();
|
||||||
|
}, [this, scenario]()
|
||||||
|
{
|
||||||
|
if(ScenarioProperties::showScenarioProperties(campaignState, scenario))
|
||||||
|
changed();
|
||||||
|
redraw();
|
||||||
|
}, [this, scenario](QGraphicsSceneContextMenuEvent * event)
|
||||||
|
{
|
||||||
|
QMenu contextMenu(this);
|
||||||
|
QAction *actionScenarioProperties = contextMenu.addAction(tr("Scenario editor"));
|
||||||
|
actionScenarioProperties->setIcon(ui->actionScenarioProperties->icon());
|
||||||
|
connect(actionScenarioProperties, &QAction::triggered, this, [this, scenario]() {
|
||||||
|
if(ScenarioProperties::showScenarioProperties(campaignState, scenario))
|
||||||
|
changed();
|
||||||
|
redraw();
|
||||||
|
});
|
||||||
|
contextMenu.exec(event->screenPos());
|
||||||
|
});
|
||||||
|
auto pos = campaignState->getRegions().getPosition(scenario);
|
||||||
|
pixmap->setPos(pos.x, pos.y);
|
||||||
|
pixmap->setToolTip(QString::fromStdString(campaignState->scenarios.at(scenario).mapName));
|
||||||
|
campaignScene->addItem(pixmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->campaignView->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CampaignEditor::getAnswerAboutUnsavedChanges()
|
||||||
|
{
|
||||||
|
if(unsaved)
|
||||||
|
{
|
||||||
|
auto sure = QMessageBox::question(this, tr("Confirmation"), tr("Unsaved changes will be lost, are you sure?"));
|
||||||
|
if(sure == QMessageBox::No)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignEditor::setTitle()
|
||||||
|
{
|
||||||
|
QFileInfo fileInfo(filename);
|
||||||
|
QString title = QString("%1%2 - %3 (%4)").arg(fileInfo.fileName(), unsaved ? "*" : "", VCMI_CAMP_EDITOR_NAME, GameConstants::VCMI_VERSION.c_str());
|
||||||
|
setWindowTitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignEditor::changed()
|
||||||
|
{
|
||||||
|
unsaved = true;
|
||||||
|
setTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CampaignEditor::saveCampaign()
|
||||||
|
{
|
||||||
|
if(campaignState->mapPieces.size() != campaignState->campaignRegions.regions.size())
|
||||||
|
{
|
||||||
|
QMessageBox::critical(nullptr, tr("Maps missing"), tr("Not all Regions have a map. Please add them in Scenario Properties."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Helper::saveCampaign(campaignState, filename);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignEditor::showCampaignEditor()
|
||||||
|
{
|
||||||
|
auto * dialog = new CampaignEditor();
|
||||||
|
|
||||||
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignEditor::on_actionOpen_triggered()
|
||||||
|
{
|
||||||
|
if(!getAnswerAboutUnsavedChanges())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto filenameSelect = QFileDialog::getOpenFileName(this, tr("Open map"),
|
||||||
|
QString::fromStdString(VCMIDirs::get().userDataPath().make_preferred().string()),
|
||||||
|
tr("All supported campaigns (*.vcmp *.h3c);;VCMI campaigns(*.vcmp);;HoMM3 campaigns(*.h3c)"));
|
||||||
|
if(filenameSelect.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
campaignState = Helper::openCampaignInternal(filenameSelect);
|
||||||
|
selectedScenario = *campaignState->allScenarios().begin();
|
||||||
|
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignEditor::on_actionSave_as_triggered()
|
||||||
|
{
|
||||||
|
if(!campaignState)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto filenameSelect = QFileDialog::getSaveFileName(this, tr("Save campaign"), "", tr("VCMI campaigns (*.vcmp)"));
|
||||||
|
|
||||||
|
if(filenameSelect.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QFileInfo fileInfo(filenameSelect);
|
||||||
|
|
||||||
|
if(fileInfo.suffix().toLower() != "vcmp")
|
||||||
|
filenameSelect += ".vcmp";
|
||||||
|
|
||||||
|
filename = filenameSelect;
|
||||||
|
if(saveCampaign())
|
||||||
|
unsaved = false;
|
||||||
|
setTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignEditor::on_actionNew_triggered()
|
||||||
|
{
|
||||||
|
if(!getAnswerAboutUnsavedChanges())
|
||||||
|
return;
|
||||||
|
|
||||||
|
campaignState = std::make_unique<CampaignState>();
|
||||||
|
campaignState->campaignRegions = CampaignRegions::getLegacy(0);
|
||||||
|
for (int i = 0; i < campaignState->campaignRegions.regions.size(); i++)
|
||||||
|
{
|
||||||
|
CampaignScenario s;
|
||||||
|
s.travelOptions.startOptions = CampaignStartOptions::START_BONUS;
|
||||||
|
campaignState->scenarios.emplace(CampaignScenarioID(i), s);
|
||||||
|
}
|
||||||
|
campaignState->modName = "mapEditor";
|
||||||
|
|
||||||
|
changed();
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignEditor::on_actionSave_triggered()
|
||||||
|
{
|
||||||
|
if(!campaignState)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(filename.isNull())
|
||||||
|
on_actionSave_as_triggered();
|
||||||
|
else if(saveCampaign())
|
||||||
|
unsaved = false;
|
||||||
|
setTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignEditor::on_actionCampaignProperties_triggered()
|
||||||
|
{
|
||||||
|
if(!campaignState)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(CampaignProperties::showCampaignProperties(campaignState))
|
||||||
|
changed();
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignEditor::on_actionScenarioProperties_triggered()
|
||||||
|
{
|
||||||
|
if(!campaignState || selectedScenario == CampaignScenarioID::NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(ScenarioProperties::showScenarioProperties(campaignState, selectedScenario))
|
||||||
|
changed();
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignEditor::closeEvent(QCloseEvent *event)
|
||||||
|
{
|
||||||
|
if(getAnswerAboutUnsavedChanges())
|
||||||
|
QDialog::closeEvent(event);
|
||||||
|
else
|
||||||
|
event->ignore();
|
||||||
|
}
|
||||||
60
mapeditor/campaigneditor/campaigneditor.h
Normal file
60
mapeditor/campaigneditor/campaigneditor.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* campaigneditor.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 <QDialog>
|
||||||
|
|
||||||
|
#include "campaignview.h"
|
||||||
|
|
||||||
|
#include "../StdInc.h"
|
||||||
|
#include "../../lib/constants/EntityIdentifiers.h"
|
||||||
|
|
||||||
|
class CampaignState;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class CampaignEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CampaignEditor : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CampaignEditor();
|
||||||
|
~CampaignEditor();
|
||||||
|
|
||||||
|
void redraw();
|
||||||
|
|
||||||
|
static void showCampaignEditor();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_actionOpen_triggered();
|
||||||
|
void on_actionSave_as_triggered();
|
||||||
|
void on_actionNew_triggered();
|
||||||
|
void on_actionSave_triggered();
|
||||||
|
void on_actionCampaignProperties_triggered();
|
||||||
|
void on_actionScenarioProperties_triggered();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool getAnswerAboutUnsavedChanges();
|
||||||
|
void setTitle();
|
||||||
|
void changed();
|
||||||
|
bool saveCampaign();
|
||||||
|
|
||||||
|
void closeEvent(QCloseEvent *event) override;
|
||||||
|
|
||||||
|
Ui::CampaignEditor *ui;
|
||||||
|
|
||||||
|
std::unique_ptr<CampaignScene> campaignScene;
|
||||||
|
|
||||||
|
QString filename;
|
||||||
|
bool unsaved = false;
|
||||||
|
CampaignScenarioID selectedScenario;
|
||||||
|
std::shared_ptr<CampaignState> campaignState;
|
||||||
|
};
|
||||||
157
mapeditor/campaigneditor/campaigneditor.ui
Normal file
157
mapeditor/campaigneditor/campaigneditor.ui
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>CampaignEditor</class>
|
||||||
|
<widget class="QDialog" name="CampaignEditor">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>820</width>
|
||||||
|
<height>720</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>VCMI Campaign Editor</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="Spacing" stdset="0">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
<widget class="QMenu" name="menuFile">
|
||||||
|
<property name="title">
|
||||||
|
<string>File</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionNew"/>
|
||||||
|
<addaction name="actionOpen"/>
|
||||||
|
<addaction name="actionSave"/>
|
||||||
|
<addaction name="actionSave_as"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuEdit">
|
||||||
|
<property name="title">
|
||||||
|
<string>Edit</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionCampaignProperties"/>
|
||||||
|
<addaction name="actionScenarioProperties"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuFile"/>
|
||||||
|
<addaction name="menuEdit"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolBar" name="toolBar">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Toolbar</string>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin" stdset="0">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin" stdset="0">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionNew"/>
|
||||||
|
<addaction name="actionOpen"/>
|
||||||
|
<addaction name="actionSave"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionCampaignProperties"/>
|
||||||
|
<addaction name="actionScenarioProperties"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="CampaignView" name="campaignView">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="mouseTracking">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
<action name="actionOpen">
|
||||||
|
<property name="text">
|
||||||
|
<string>Open</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string notr="true">Ctrl+O</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSave">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string notr="true">Ctrl+S</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNew">
|
||||||
|
<property name="text">
|
||||||
|
<string>New</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string notr="true">Ctrl+N</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSave_as">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save as...</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Shift+S</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCampaignProperties">
|
||||||
|
<property name="text">
|
||||||
|
<string>Campaign Properties</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Campaign Properties</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string notr="true">Ctrl+Enter</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionScenarioProperties">
|
||||||
|
<property name="text">
|
||||||
|
<string>Scenario Properties</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Scenario Properties</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string notr="true">Enter</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>CampaignView</class>
|
||||||
|
<extends>QGraphicsView</extends>
|
||||||
|
<header>campaigneditor/campaignview.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
193
mapeditor/campaigneditor/campaignproperties.cpp
Normal file
193
mapeditor/campaigneditor/campaignproperties.cpp
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
* campaignproperties.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 "campaignproperties.h"
|
||||||
|
#include "ui_campaignproperties.h"
|
||||||
|
|
||||||
|
#include "../../lib/GameLibrary.h"
|
||||||
|
#include "../../lib/texts/CGeneralTextHandler.h"
|
||||||
|
#include "../../lib/campaign/CampaignState.h"
|
||||||
|
#include "../../lib/constants/StringConstants.h"
|
||||||
|
|
||||||
|
CampaignProperties::CampaignProperties(std::shared_ptr<CampaignState> campaignState):
|
||||||
|
ui(new Ui::CampaignProperties),
|
||||||
|
campaignState(campaignState),
|
||||||
|
regions(campaignState->campaignRegions)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
setWindowTitle(tr("Campaign Properties"));
|
||||||
|
|
||||||
|
setWindowModality(Qt::ApplicationModal);
|
||||||
|
|
||||||
|
ui->lineEditName->setText(QString::fromStdString(campaignState->name.toString()));
|
||||||
|
ui->textEditDescription->setText(QString::fromStdString(campaignState->description.toString()));
|
||||||
|
ui->lineEditAuthor->setText(QString::fromStdString(campaignState->author.toString()));
|
||||||
|
ui->lineEditAuthorContact->setText(QString::fromStdString(campaignState->authorContact.toString()));
|
||||||
|
ui->dateTimeEditCreationDateTime->setDateTime(QDateTime::fromSecsSinceEpoch(campaignState->creationDateTime));
|
||||||
|
ui->lineEditCampaignVersion->setText(QString::fromStdString(campaignState->campaignVersion.toString()));
|
||||||
|
ui->lineEditMusic->setText(QString::fromStdString(campaignState->music.getName()));
|
||||||
|
ui->checkBoxScenarioDifficulty->setChecked(campaignState->difficultyChosenByPlayer);
|
||||||
|
|
||||||
|
for (int i = 0; i < 20; i++)
|
||||||
|
ui->comboBoxRegionPreset->insertItem(i, QString::fromStdString(LIBRARY->generaltexth->translate("core.camptext.names", i)));
|
||||||
|
ui->comboBoxRegionPreset->insertItem(20, tr("Custom"));
|
||||||
|
ui->comboBoxRegionPreset->setCurrentIndex(20);
|
||||||
|
|
||||||
|
loadRegion();
|
||||||
|
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
CampaignProperties::~CampaignProperties()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CampaignProperties::showCampaignProperties(std::shared_ptr<CampaignState> campaignState)
|
||||||
|
{
|
||||||
|
if(!campaignState)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto * dialog = new CampaignProperties(campaignState);
|
||||||
|
|
||||||
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
return dialog->exec() == QDialog::Accepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignProperties::on_buttonBox_clicked(QAbstractButton * button)
|
||||||
|
{
|
||||||
|
if(button == ui->buttonBox->button(QDialogButtonBox::Ok))
|
||||||
|
{
|
||||||
|
if(!saveRegion())
|
||||||
|
return;
|
||||||
|
campaignState->name = MetaString::createFromRawString(ui->lineEditName->text().toStdString());
|
||||||
|
campaignState->description = MetaString::createFromRawString(ui->textEditDescription->toPlainText().toStdString());
|
||||||
|
campaignState->author = MetaString::createFromRawString(ui->lineEditAuthor->text().toStdString());
|
||||||
|
campaignState->authorContact = MetaString::createFromRawString(ui->lineEditAuthorContact->text().toStdString());
|
||||||
|
campaignState->creationDateTime = ui->dateTimeEditCreationDateTime->dateTime().toSecsSinceEpoch();
|
||||||
|
campaignState->campaignVersion = MetaString::createFromRawString(ui->lineEditCampaignVersion->text().toStdString());
|
||||||
|
campaignState->music = AudioPath::builtin(ui->lineEditMusic->text().toStdString());
|
||||||
|
campaignState->difficultyChosenByPlayer = ui->checkBoxScenarioDifficulty->isChecked();
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignProperties::on_comboBoxRegionPreset_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
if(ui->comboBoxRegionPreset->count() == 21 && ui->comboBoxRegionPreset->currentIndex() != 20)
|
||||||
|
regions = CampaignRegions::getLegacy(ui->comboBoxRegionPreset->currentIndex());
|
||||||
|
|
||||||
|
loadRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignProperties::on_pushButtonRegionAdd_clicked()
|
||||||
|
{
|
||||||
|
int row = ui->tableWidgetRegions->rowCount();
|
||||||
|
ui->tableWidgetRegions->insertRow(row);
|
||||||
|
ui->tableWidgetRegions->setItem(row, 0, new QTableWidgetItem("INFIX"));
|
||||||
|
ui->tableWidgetRegions->setItem(row, 1, new QTableWidgetItem(QString::number(0)));
|
||||||
|
ui->tableWidgetRegions->setItem(row, 2, new QTableWidgetItem(QString::number(0)));
|
||||||
|
ui->tableWidgetRegions->setItem(row, 3, new QTableWidgetItem(QString::number(-1)));
|
||||||
|
ui->tableWidgetRegions->setItem(row, 4, new QTableWidgetItem(QString::number(-1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignProperties::on_pushButtonRegionRemove_clicked()
|
||||||
|
{
|
||||||
|
int rows = ui->tableWidgetRegions->rowCount() - 1;
|
||||||
|
ui->tableWidgetRegions->removeRow(rows);
|
||||||
|
ui->tableWidgetRegions->setRowCount(rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CampaignProperties::loadRegion()
|
||||||
|
{
|
||||||
|
ui->lineEditBackground->setText(QString::fromStdString(regions.campBackground.empty() ? regions.campPrefix + "_BG" : regions.campBackground));
|
||||||
|
ui->lineEditSuffix1->setText(QString::fromStdString(regions.campSuffix.size() ? regions.campSuffix[0] : "En"));
|
||||||
|
ui->lineEditSuffix2->setText(QString::fromStdString(regions.campSuffix.size() ? regions.campSuffix[1] : "Se"));
|
||||||
|
ui->lineEditSuffix3->setText(QString::fromStdString(regions.campSuffix.size() ? regions.campSuffix[2] : "Co"));
|
||||||
|
ui->lineEditPrefix->setText(QString::fromStdString(regions.campPrefix));
|
||||||
|
ui->spinBoxColorSuffixLength->setValue(regions.colorSuffixLength);
|
||||||
|
|
||||||
|
ui->tableWidgetRegions->clearContents();
|
||||||
|
ui->tableWidgetRegions->setRowCount(0);
|
||||||
|
ui->tableWidgetRegions->setColumnCount(5);
|
||||||
|
ui->tableWidgetRegions->setHorizontalHeaderLabels({tr("Infix"), tr("X"), tr("Y"), tr("Label Pos X"), tr("Label Pos Y")});
|
||||||
|
for (int i = 0; i < regions.regions.size(); ++i)
|
||||||
|
{
|
||||||
|
ui->tableWidgetRegions->insertRow(ui->tableWidgetRegions->rowCount());
|
||||||
|
ui->tableWidgetRegions->setItem(i, 0, new QTableWidgetItem(QString::fromStdString(regions.regions[i].infix)));
|
||||||
|
ui->tableWidgetRegions->setItem(i, 1, new QTableWidgetItem(QString::number(regions.regions[i].pos.x)));
|
||||||
|
ui->tableWidgetRegions->setItem(i, 2, new QTableWidgetItem(QString::number(regions.regions[i].pos.y)));
|
||||||
|
ui->tableWidgetRegions->setItem(i, 3, new QTableWidgetItem(QString::number(regions.regions[i].labelPos.has_value() ? (*regions.regions[i].labelPos).x : -1)));
|
||||||
|
ui->tableWidgetRegions->setItem(i, 4, new QTableWidgetItem(QString::number(regions.regions[i].labelPos.has_value() ? (*regions.regions[i].labelPos).y : -1)));
|
||||||
|
}
|
||||||
|
ui->tableWidgetRegions->resizeColumnsToContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CampaignProperties::saveRegion()
|
||||||
|
{
|
||||||
|
regions.campBackground = ui->lineEditBackground->text().toStdString();
|
||||||
|
if(regions.campSuffix.size() == 3)
|
||||||
|
{
|
||||||
|
regions.campSuffix[0] = ui->lineEditSuffix1->text().toStdString();
|
||||||
|
regions.campSuffix[1] = ui->lineEditSuffix2->text().toStdString();
|
||||||
|
regions.campSuffix[2] = ui->lineEditSuffix3->text().toStdString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regions.campSuffix.push_back(ui->lineEditSuffix1->text().toStdString());
|
||||||
|
regions.campSuffix.push_back(ui->lineEditSuffix2->text().toStdString());
|
||||||
|
regions.campSuffix.push_back(ui->lineEditSuffix3->text().toStdString());
|
||||||
|
}
|
||||||
|
regions.campPrefix = ui->lineEditPrefix->text().toStdString();
|
||||||
|
regions.colorSuffixLength = ui->spinBoxColorSuffixLength->value();
|
||||||
|
|
||||||
|
regions.regions.clear();
|
||||||
|
for (int i = 0; i < ui->tableWidgetRegions->rowCount(); ++i)
|
||||||
|
{
|
||||||
|
CampaignRegions::RegionDescription rd;
|
||||||
|
|
||||||
|
rd.infix = ui->tableWidgetRegions->item(i, 0)->text().toStdString();
|
||||||
|
rd.pos.x = ui->tableWidgetRegions->item(i, 1)->text().toInt();
|
||||||
|
rd.pos.y = ui->tableWidgetRegions->item(i, 2)->text().toInt();
|
||||||
|
auto labelX = ui->tableWidgetRegions->item(i, 3)->text().toInt();
|
||||||
|
auto labelY = ui->tableWidgetRegions->item(i, 4)->text().toInt();
|
||||||
|
if(labelX == -1 || labelY == -1)
|
||||||
|
rd.labelPos = std::nullopt;
|
||||||
|
else
|
||||||
|
Point(labelX, labelY);
|
||||||
|
|
||||||
|
regions.regions.push_back(rd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(campaignState->campaignRegions.regions.size() > regions.regions.size())
|
||||||
|
{
|
||||||
|
QMessageBox::StandardButton reply;
|
||||||
|
reply = QMessageBox::question(this, tr("Fewer Scenarios"), tr("New Region setup supports fewer scenarios than before. Some will removed. Continue?"), QMessageBox::Yes|QMessageBox::No);
|
||||||
|
if (reply != QMessageBox::Yes)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
campaignState->campaignRegions = regions;
|
||||||
|
|
||||||
|
while(campaignState->scenarios.size() < campaignState->campaignRegions.regions.size())
|
||||||
|
campaignState->scenarios.emplace(CampaignScenarioID(std::prev(campaignState->scenarios.end())->first + 1), CampaignScenario());
|
||||||
|
while(campaignState->scenarios.size() > campaignState->campaignRegions.regions.size())
|
||||||
|
{
|
||||||
|
auto elem = std::prev(campaignState->scenarios.end());
|
||||||
|
campaignState->mapPieces.erase(elem->first);
|
||||||
|
campaignState->scenarios.erase(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
46
mapeditor/campaigneditor/campaignproperties.h
Normal file
46
mapeditor/campaigneditor/campaignproperties.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* campaignproperties.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 <QDialog>
|
||||||
|
|
||||||
|
#include "../../lib/campaign/CampaignState.h"
|
||||||
|
|
||||||
|
class CampaignState;
|
||||||
|
class QAbstractButton;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class CampaignProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CampaignProperties : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CampaignProperties(std::shared_ptr<CampaignState> campaignState);
|
||||||
|
~CampaignProperties();
|
||||||
|
|
||||||
|
static bool showCampaignProperties(std::shared_ptr<CampaignState> campaignState);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_buttonBox_clicked(QAbstractButton * button);
|
||||||
|
void on_comboBoxRegionPreset_currentIndexChanged(int index);
|
||||||
|
void on_pushButtonRegionAdd_clicked();
|
||||||
|
void on_pushButtonRegionRemove_clicked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::CampaignProperties *ui;
|
||||||
|
|
||||||
|
std::shared_ptr<CampaignState> campaignState;
|
||||||
|
CampaignRegions regions;
|
||||||
|
|
||||||
|
void loadRegion();
|
||||||
|
bool saveRegion();
|
||||||
|
};
|
||||||
332
mapeditor/campaigneditor/campaignproperties.ui
Normal file
332
mapeditor/campaigneditor/campaignproperties.ui
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>CampaignProperties</class>
|
||||||
|
<widget class="QDialog" name="CampaignProperties">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>499</width>
|
||||||
|
<height>580</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Campaign Properties</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tabGeneral">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<attribute name="title">
|
||||||
|
<string>General</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelName">
|
||||||
|
<property name="text">
|
||||||
|
<string>Campaign name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditName"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelDescription">
|
||||||
|
<property name="text">
|
||||||
|
<string>Campaign description</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTextEdit" name="textEditDescription"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelAuthor">
|
||||||
|
<property name="text">
|
||||||
|
<string>Author</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditAuthor"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelAuthorContact">
|
||||||
|
<property name="text">
|
||||||
|
<string>Author contact (e.g. e-mail)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditAuthorContact"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelCreationDateTime">
|
||||||
|
<property name="text">
|
||||||
|
<string>Campaign creation date</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDateTimeEdit" name="dateTimeEditCreationDateTime"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelCampaignVersion">
|
||||||
|
<property name="text">
|
||||||
|
<string>Campaign version</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditCampaignVersion"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelMusic">
|
||||||
|
<property name="text">
|
||||||
|
<string>Music</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditMusic"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxScenarioDifficulty">
|
||||||
|
<property name="text">
|
||||||
|
<string>Scenario difficulty is user selectable</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabRegions">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Regions</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelRegionPreset">
|
||||||
|
<property name="text">
|
||||||
|
<string>Regions Preset</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxRegionPreset"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelBackground">
|
||||||
|
<property name="text">
|
||||||
|
<string>Background</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditBackground"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelSuffix">
|
||||||
|
<property name="text">
|
||||||
|
<string>Suffix</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditSuffix1"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditSuffix2"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditSuffix3"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelPrefix">
|
||||||
|
<property name="text">
|
||||||
|
<string>Prefix</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditPrefix"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelColorSuffixLength">
|
||||||
|
<property name="text">
|
||||||
|
<string>Color suffix length</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spinBoxColorSuffixLength">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelRegions">
|
||||||
|
<property name="text">
|
||||||
|
<string>Regions</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QTableWidget" name="tableWidgetRegions"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonRegionAdd">
|
||||||
|
<property name="text">
|
||||||
|
<string>Add</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonRegionRemove">
|
||||||
|
<property name="text">
|
||||||
|
<string>Remove</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabMisc">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Misc</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelLoadingBackground">
|
||||||
|
<property name="text">
|
||||||
|
<string>Loading background image</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditLoadingBackground"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelVideoRim">
|
||||||
|
<property name="text">
|
||||||
|
<string>Video rim image</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditVideoRim"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelIntroVideo">
|
||||||
|
<property name="text">
|
||||||
|
<string>Intro video</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditIntroVideo"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelOutroVideo">
|
||||||
|
<property name="text">
|
||||||
|
<string>Outro video</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditOutroVideo"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
48
mapeditor/campaigneditor/campaignview.cpp
Normal file
48
mapeditor/campaigneditor/campaignview.cpp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* campaignview.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 "campaignview.h"
|
||||||
|
|
||||||
|
CampaignScene::CampaignScene():
|
||||||
|
QGraphicsScene(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CampaignView::CampaignView(QWidget * parent):
|
||||||
|
QGraphicsView(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ClickablePixmapItem::ClickablePixmapItem(const QPixmap &pixmap, std::function<void()> clickedCallback, std::function<void()> doubleClickedCallback, std::function<void(QGraphicsSceneContextMenuEvent *)> contextMenuCallback):
|
||||||
|
QGraphicsPixmapItem(pixmap),
|
||||||
|
clickedCallback(clickedCallback),
|
||||||
|
doubleClickedCallback(doubleClickedCallback),
|
||||||
|
contextMenuCallback(contextMenuCallback)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClickablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||||
|
{
|
||||||
|
if(clickedCallback)
|
||||||
|
clickedCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClickablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
|
||||||
|
{
|
||||||
|
if(doubleClickedCallback)
|
||||||
|
doubleClickedCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClickablePixmapItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
||||||
|
{
|
||||||
|
if(contextMenuCallback)
|
||||||
|
contextMenuCallback(event);
|
||||||
|
}
|
||||||
44
mapeditor/campaigneditor/campaignview.h
Normal file
44
mapeditor/campaigneditor/campaignview.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* campaignview.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 <QGraphicsView>
|
||||||
|
#include <QGraphicsPixmapItem>
|
||||||
|
|
||||||
|
class CampaignScene : public QGraphicsScene
|
||||||
|
{
|
||||||
|
Q_OBJECT;
|
||||||
|
public:
|
||||||
|
CampaignScene();
|
||||||
|
};
|
||||||
|
|
||||||
|
class CampaignView : public QGraphicsView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
CampaignView(QWidget * parent);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ClickablePixmapItem : public QGraphicsPixmapItem {
|
||||||
|
public:
|
||||||
|
ClickablePixmapItem(const QPixmap &pixmap, std::function<void()> clickedCallback, std::function<void()> doubleClickedCallback, std::function<void(QGraphicsSceneContextMenuEvent *)> contextMenuCallback);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<void()> clickedCallback;
|
||||||
|
std::function<void()> doubleClickedCallback;
|
||||||
|
std::function<void(QGraphicsSceneContextMenuEvent *)> contextMenuCallback;
|
||||||
|
};
|
||||||
529
mapeditor/campaigneditor/scenarioproperties.cpp
Normal file
529
mapeditor/campaigneditor/scenarioproperties.cpp
Normal file
@@ -0,0 +1,529 @@
|
|||||||
|
/*
|
||||||
|
* scenarioproperties.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 "scenarioproperties.h"
|
||||||
|
#include "ui_scenarioproperties.h"
|
||||||
|
#include "startingbonus.h"
|
||||||
|
|
||||||
|
#include "../../lib/GameLibrary.h"
|
||||||
|
#include "../../lib/CArtHandler.h"
|
||||||
|
#include "../../lib/CCreatureHandler.h"
|
||||||
|
#include "../../lib/texts/CGeneralTextHandler.h"
|
||||||
|
#include "../../lib/entities/hero/CHeroHandler.h"
|
||||||
|
#include "../../lib/campaign/CampaignState.h"
|
||||||
|
#include "../../lib/mapping/CMap.h"
|
||||||
|
#include "../../lib/constants/StringConstants.h"
|
||||||
|
|
||||||
|
ScenarioProperties::ScenarioProperties(std::shared_ptr<CampaignState> campaignState, CampaignScenarioID scenario):
|
||||||
|
ui(new Ui::ScenarioProperties),
|
||||||
|
campaignState(campaignState),
|
||||||
|
map(campaignState->getMap(scenario, nullptr)),
|
||||||
|
scenario(scenario)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
setWindowTitle(tr("Scenario Properties"));
|
||||||
|
|
||||||
|
setWindowModality(Qt::ApplicationModal);
|
||||||
|
|
||||||
|
ui->lineEditRegionName->setText(getRegionChar(scenario.getNum()));
|
||||||
|
ui->plainTextEditRightClickText->setPlainText(QString::fromStdString(campaignState->scenarios.at(scenario).regionText.toString()));
|
||||||
|
|
||||||
|
for(int i = 0, index = 0; i < PlayerColor::PLAYER_LIMIT_I; ++i)
|
||||||
|
{
|
||||||
|
MetaString str;
|
||||||
|
str.appendName(PlayerColor(i));
|
||||||
|
ui->comboBoxRegionColor->addItem(QString::fromStdString(str.toString()), QVariant(i));
|
||||||
|
if(i == campaignState->scenarios.at(scenario).regionColor)
|
||||||
|
ui->comboBoxRegionColor->setCurrentIndex(index);
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0, index = 0; i < 5; ++i)
|
||||||
|
{
|
||||||
|
ui->comboBoxDefaultDifficulty->addItem(QString::fromStdString(LIBRARY->generaltexth->arraytxt[142 + i]), QVariant(i));
|
||||||
|
if(i == campaignState->scenarios.at(scenario).difficulty)
|
||||||
|
ui->comboBoxDefaultDifficulty->setCurrentIndex(index);
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < scenario.getNum(); ++i)
|
||||||
|
{
|
||||||
|
auto tmpScenario = CampaignScenarioID(i);
|
||||||
|
auto * item = new QListWidgetItem(getRegionChar(tmpScenario.getNum()) + " - " + QString::fromStdString(campaignState->scenarios.at(tmpScenario).mapName));
|
||||||
|
item->setData(Qt::UserRole, QVariant::fromValue(i));
|
||||||
|
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||||
|
item->setCheckState(campaignState->scenarios.at(scenario).preconditionRegions.count(tmpScenario) ? Qt::Checked : Qt::Unchecked);
|
||||||
|
ui->listWidgetPrerequisites->addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->checkBoxPrologueEnabled->setChecked(campaignState->scenarios.at(scenario).prolog.hasPrologEpilog);
|
||||||
|
ui->lineEditPrologueVideo->setText(QString::fromStdString(campaignState->scenarios.at(scenario).prolog.prologVideo.getName()));
|
||||||
|
ui->lineEditPrologueMusic->setText(QString::fromStdString(campaignState->scenarios.at(scenario).prolog.prologMusic.getName()));
|
||||||
|
ui->lineEditPrologueVoice->setText(QString::fromStdString(campaignState->scenarios.at(scenario).prolog.prologVoice.getName()));
|
||||||
|
ui->plainTextEditPrologueText->setPlainText(QString::fromStdString(campaignState->scenarios.at(scenario).prolog.prologText.toString()));
|
||||||
|
ui->checkBoxEpilogueEnabled->setChecked(campaignState->scenarios.at(scenario).epilog.hasPrologEpilog);
|
||||||
|
ui->lineEditEpilogueVideo->setText(QString::fromStdString(campaignState->scenarios.at(scenario).epilog.prologVideo.getName()));
|
||||||
|
ui->lineEditEpilogueMusic->setText(QString::fromStdString(campaignState->scenarios.at(scenario).epilog.prologMusic.getName()));
|
||||||
|
ui->lineEditEpilogueVoice->setText(QString::fromStdString(campaignState->scenarios.at(scenario).epilog.prologVoice.getName()));
|
||||||
|
ui->plainTextEditEpilogueText->setPlainText(QString::fromStdString(campaignState->scenarios.at(scenario).epilog.prologText.toString()));
|
||||||
|
|
||||||
|
ui->checkBoxCrossoverExperience->setChecked(campaignState->scenarios.at(scenario).travelOptions.whatHeroKeeps.experience);
|
||||||
|
ui->checkBoxCrossoverPrimarySkills->setChecked(campaignState->scenarios.at(scenario).travelOptions.whatHeroKeeps.primarySkills);
|
||||||
|
ui->checkBoxCrossoverSecondarySkills->setChecked(campaignState->scenarios.at(scenario).travelOptions.whatHeroKeeps.secondarySkills);
|
||||||
|
ui->checkBoxCrossoverSpells->setChecked(campaignState->scenarios.at(scenario).travelOptions.whatHeroKeeps.spells);
|
||||||
|
ui->checkBoxCrossoverArtifacts->setChecked(campaignState->scenarios.at(scenario).travelOptions.whatHeroKeeps.artifacts);
|
||||||
|
|
||||||
|
ui->radioButtonStartingOptionBonus->setChecked(campaignState->scenarios.at(scenario).travelOptions.startOptions == CampaignStartOptions::START_BONUS);
|
||||||
|
ui->radioButtonStartingOptionHeroCrossover->setChecked(campaignState->scenarios.at(scenario).travelOptions.startOptions == CampaignStartOptions::HERO_CROSSOVER);
|
||||||
|
ui->radioButtonStartingOptionStartingHero->setChecked(campaignState->scenarios.at(scenario).travelOptions.startOptions == CampaignStartOptions::HERO_OPTIONS);
|
||||||
|
|
||||||
|
for(auto const & objectPtr : LIBRARY->arth->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(campaignState->scenarios.at(scenario).travelOptions.artifactsKeptByHero.count(objectPtr->getId()) ? Qt::Checked : Qt::Unchecked);
|
||||||
|
ui->listWidgetCrossoverArtifacts->addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto const & objectPtr : LIBRARY->creh->objects)
|
||||||
|
{
|
||||||
|
auto * item = new QListWidgetItem(QString::fromStdString(objectPtr->getNameSingularTranslated()));
|
||||||
|
item->setData(Qt::UserRole, QVariant::fromValue(objectPtr->getIndex()));
|
||||||
|
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||||
|
item->setCheckState(campaignState->scenarios.at(scenario).travelOptions.monstersKeptByHero.count(objectPtr->getId()) ? Qt::Checked : Qt::Unchecked);
|
||||||
|
ui->listWidgetCrossoverCreatures->addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->tabWidgetStartOptions->tabBar()->hide();
|
||||||
|
ui->tabWidgetStartOptions->setStyleSheet("QTabWidget::pane { border: 0; }");
|
||||||
|
|
||||||
|
ui->tableWidgetStartingCrossover->setColumnCount(2);
|
||||||
|
|
||||||
|
LIBRARY->heroTypes()->forEach([this](const HeroType * hero, bool &)
|
||||||
|
{
|
||||||
|
heroSelection.emplace(hero->getId().getNum(), hero->getNameTranslated());
|
||||||
|
});
|
||||||
|
heroSelection.emplace(0xFFFD, tr("Strongest").toStdString());
|
||||||
|
heroSelection.emplace(0xFFFE, tr("Generated").toStdString());
|
||||||
|
heroSelection.emplace(0xFFFF, tr("Random").toStdString());
|
||||||
|
|
||||||
|
reloadMapRelatedUi();
|
||||||
|
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
ScenarioProperties::~ScenarioProperties()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScenarioProperties::reloadMapRelatedUi()
|
||||||
|
{
|
||||||
|
map = campaignState->getMap(scenario, nullptr);
|
||||||
|
|
||||||
|
ui->lineEditMapFile->setText(QString::fromStdString(campaignState->scenarios.at(scenario).mapName));
|
||||||
|
ui->lineEditScenarioName->setText(map ? QString::fromStdString(map->name.toString()) : tr("No map"));
|
||||||
|
if(!map)
|
||||||
|
ui->lineEditScenarioName->setStyleSheet("background-color: red;");
|
||||||
|
else
|
||||||
|
ui->lineEditScenarioName->setStyleSheet("");
|
||||||
|
|
||||||
|
ui->pushButtonExport->setEnabled(map != nullptr);
|
||||||
|
ui->pushButtonRemove->setEnabled(map != nullptr);
|
||||||
|
|
||||||
|
ui->radioButtonStartingOptionHeroCrossover->setEnabled(scenario.getNum() > 0);
|
||||||
|
bool allowSelectingStartHero = false;
|
||||||
|
if(map != nullptr)
|
||||||
|
for(auto & player : map->players)
|
||||||
|
if(player.generateHeroAtMainTown)
|
||||||
|
allowSelectingStartHero = true;
|
||||||
|
ui->radioButtonStartingOptionStartingHero->setEnabled(allowSelectingStartHero);
|
||||||
|
|
||||||
|
ui->tabPrologueEpilogue->setEnabled(map != nullptr);
|
||||||
|
ui->tabCrossover->setEnabled(map != nullptr);
|
||||||
|
ui->tabStarting->setEnabled(map != nullptr);
|
||||||
|
|
||||||
|
ui->comboBoxDefaultDifficulty->setEnabled(map != nullptr);
|
||||||
|
ui->listWidgetPrerequisites->setEnabled(map != nullptr);
|
||||||
|
ui->plainTextEditRightClickText->setEnabled(map != nullptr);
|
||||||
|
|
||||||
|
ui->tableWidgetStartingCrossover->clearContents();
|
||||||
|
ui->tableWidgetStartingCrossover->setRowCount(0);
|
||||||
|
ui->listWidgetStartingBonusOption->clear();
|
||||||
|
|
||||||
|
if(map != nullptr)
|
||||||
|
{
|
||||||
|
std::vector<PlayerColor> selectableColors;
|
||||||
|
for(int i = 0; i < map->players.size(); i++)
|
||||||
|
if(map->players[i].canHumanPlay)
|
||||||
|
selectableColors.push_back(PlayerColor(i));
|
||||||
|
|
||||||
|
ui->comboBoxStartingBonusPlayerPosition->clear();
|
||||||
|
for(int i = 0; i < PlayerColor::PLAYER_LIMIT_I; ++i)
|
||||||
|
{
|
||||||
|
if(!vstd::contains(selectableColors, PlayerColor(i)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MetaString str;
|
||||||
|
str.appendRawString((tr("Player") + " ").toStdString());
|
||||||
|
str.appendNumber(i + 1);
|
||||||
|
str.appendRawString(" (");
|
||||||
|
str.appendName(PlayerColor(i));
|
||||||
|
str.appendRawString(")");
|
||||||
|
ui->comboBoxStartingBonusPlayerPosition->addItem(QString::fromStdString(str.toString()), QVariant(i));
|
||||||
|
}
|
||||||
|
int index = ui->comboBoxStartingBonusPlayerPosition->findData(campaignState->scenarios.at(scenario).travelOptions.playerColor.getNum());
|
||||||
|
if(index != -1)
|
||||||
|
ui->comboBoxStartingBonusPlayerPosition->setCurrentIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(campaignState->scenarios.at(scenario).travelOptions.startOptions == CampaignStartOptions::HERO_CROSSOVER || campaignState->scenarios.at(scenario).travelOptions.startOptions == CampaignStartOptions::HERO_OPTIONS)
|
||||||
|
{
|
||||||
|
if(campaignState->scenarios.at(scenario).travelOptions.startOptions == CampaignStartOptions::HERO_OPTIONS)
|
||||||
|
on_radioButtonStartingOptionStartingHero_toggled();
|
||||||
|
else
|
||||||
|
on_radioButtonStartingOptionHeroCrossover_toggled();
|
||||||
|
|
||||||
|
for(int i = 0; i < campaignState->scenarios.at(scenario).travelOptions.bonusesToChoose.size(); i++)
|
||||||
|
{
|
||||||
|
auto bonus = campaignState->scenarios.at(scenario).travelOptions.bonusesToChoose[i];
|
||||||
|
|
||||||
|
ui->tableWidgetStartingCrossover->insertRow(i);
|
||||||
|
QComboBox* comboBoxOption = new QComboBox();
|
||||||
|
if(campaignState->scenarios.at(scenario).travelOptions.startOptions == CampaignStartOptions::HERO_OPTIONS)
|
||||||
|
{
|
||||||
|
for(auto & hero : heroSelection)
|
||||||
|
comboBoxOption->addItem(QString::fromStdString(hero.second), hero.first);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < scenario.getNum(); ++i)
|
||||||
|
{
|
||||||
|
auto tmpScenario = CampaignScenarioID(i);
|
||||||
|
auto text = getRegionChar(tmpScenario.getNum()) + " - " + QString::fromStdString(campaignState->scenarios.at(tmpScenario).mapName);
|
||||||
|
comboBoxOption->addItem(text, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox* comboBoxPlayer = new QComboBox();
|
||||||
|
for(int i = 0; i < ui->comboBoxStartingBonusPlayerPosition->count(); ++i) // copy from player dropdown
|
||||||
|
comboBoxPlayer->addItem(ui->comboBoxStartingBonusPlayerPosition->itemText(i), ui->comboBoxStartingBonusPlayerPosition->itemData(i));
|
||||||
|
|
||||||
|
// set selected
|
||||||
|
int index = comboBoxPlayer->findData(bonus.info1);
|
||||||
|
if(index != -1)
|
||||||
|
comboBoxPlayer->setCurrentIndex(index);
|
||||||
|
index = comboBoxOption->findData(bonus.info2);
|
||||||
|
if(index != -1)
|
||||||
|
comboBoxOption->setCurrentIndex(index);
|
||||||
|
|
||||||
|
ui->tableWidgetStartingCrossover->setCellWidget(i, 0, comboBoxOption);
|
||||||
|
ui->tableWidgetStartingCrossover->setCellWidget(i, 1, comboBoxPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->tableWidgetStartingCrossover->resizeColumnsToContents();
|
||||||
|
}
|
||||||
|
else if(campaignState->scenarios.at(scenario).travelOptions.startOptions == CampaignStartOptions::START_BONUS)
|
||||||
|
{
|
||||||
|
ui->listWidgetStartingBonusOption->clear();
|
||||||
|
for(auto & bonus : campaignState->scenarios.at(scenario).travelOptions.bonusesToChoose)
|
||||||
|
{
|
||||||
|
QListWidgetItem * item = new QListWidgetItem(StartingBonus::getBonusListTitle(bonus, map));
|
||||||
|
item->setData(Qt::UserRole, QVariant::fromValue(bonus));
|
||||||
|
ui->listWidgetStartingBonusOption->addItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reloadEnableState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScenarioProperties::reloadEnableState()
|
||||||
|
{
|
||||||
|
ui->pushButtonStartingAdd->setEnabled(ui->tableWidgetStartingCrossover->rowCount() < 3 && ui->listWidgetStartingBonusOption->count() < 3);
|
||||||
|
ui->pushButtonStartingRemove->setEnabled(ui->tableWidgetStartingCrossover->rowCount() > 0 || ui->listWidgetStartingBonusOption->count() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScenarioProperties::showScenarioProperties(std::shared_ptr<CampaignState> campaignState, CampaignScenarioID scenario)
|
||||||
|
{
|
||||||
|
if(!campaignState || scenario == CampaignScenarioID::NONE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto * dialog = new ScenarioProperties(campaignState, scenario);
|
||||||
|
|
||||||
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
return dialog->exec() == QDialog::Accepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ScenarioProperties::on_buttonBox_clicked(QAbstractButton * button)
|
||||||
|
{
|
||||||
|
if(button == ui->buttonBox->button(QDialogButtonBox::Ok))
|
||||||
|
{
|
||||||
|
campaignState->scenarios.at(scenario).regionText = MetaString::createFromRawString(ui->plainTextEditRightClickText->toPlainText().toStdString());
|
||||||
|
|
||||||
|
campaignState->scenarios.at(scenario).regionColor = ui->comboBoxRegionColor->currentData().toInt();
|
||||||
|
campaignState->scenarios.at(scenario).difficulty = ui->comboBoxDefaultDifficulty->currentData().toInt();
|
||||||
|
|
||||||
|
campaignState->scenarios.at(scenario).prolog.hasPrologEpilog = ui->checkBoxPrologueEnabled->isChecked();
|
||||||
|
campaignState->scenarios.at(scenario).prolog.prologVideo = VideoPath::builtin(ui->lineEditPrologueVideo->text().toStdString());
|
||||||
|
campaignState->scenarios.at(scenario).prolog.prologMusic = AudioPath::builtin(ui->lineEditPrologueMusic->text().toStdString());
|
||||||
|
campaignState->scenarios.at(scenario).prolog.prologVoice = AudioPath::builtin(ui->lineEditPrologueVoice->text().toStdString());
|
||||||
|
campaignState->scenarios.at(scenario).prolog.prologText = MetaString::createFromRawString(ui->plainTextEditPrologueText->toPlainText().toStdString());
|
||||||
|
campaignState->scenarios.at(scenario).epilog.hasPrologEpilog = ui->checkBoxEpilogueEnabled->isChecked();
|
||||||
|
campaignState->scenarios.at(scenario).epilog.prologVideo = VideoPath::builtin(ui->lineEditEpilogueVideo->text().toStdString());
|
||||||
|
campaignState->scenarios.at(scenario).epilog.prologMusic = AudioPath::builtin(ui->lineEditEpilogueMusic->text().toStdString());
|
||||||
|
campaignState->scenarios.at(scenario).epilog.prologVoice = AudioPath::builtin(ui->lineEditEpilogueVoice->text().toStdString());
|
||||||
|
campaignState->scenarios.at(scenario).epilog.prologText = MetaString::createFromRawString(ui->plainTextEditEpilogueText->toPlainText().toStdString());
|
||||||
|
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.whatHeroKeeps.experience = ui->checkBoxCrossoverExperience->isChecked();
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.whatHeroKeeps.primarySkills = ui->checkBoxCrossoverPrimarySkills->isChecked();
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.whatHeroKeeps.secondarySkills = ui->checkBoxCrossoverSecondarySkills->isChecked();
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.whatHeroKeeps.spells = ui->checkBoxCrossoverSpells->isChecked();
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.whatHeroKeeps.artifacts = ui->checkBoxCrossoverArtifacts->isChecked();
|
||||||
|
|
||||||
|
CampaignStartOptions startOption = CampaignStartOptions::NONE;
|
||||||
|
if(ui->radioButtonStartingOptionBonus->isChecked())
|
||||||
|
startOption = CampaignStartOptions::START_BONUS;
|
||||||
|
else if(ui->radioButtonStartingOptionHeroCrossover->isChecked())
|
||||||
|
startOption = CampaignStartOptions::HERO_CROSSOVER;
|
||||||
|
else if(ui->radioButtonStartingOptionStartingHero->isChecked())
|
||||||
|
startOption = CampaignStartOptions::HERO_OPTIONS;
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.startOptions = startOption;
|
||||||
|
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.artifactsKeptByHero.clear();
|
||||||
|
for(int i = 0; i < ui->listWidgetCrossoverArtifacts->count(); ++i)
|
||||||
|
{
|
||||||
|
auto * item = ui->listWidgetCrossoverArtifacts->item(i);
|
||||||
|
if(item->checkState() == Qt::Checked)
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.artifactsKeptByHero.emplace(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.monstersKeptByHero.clear();
|
||||||
|
for(int i = 0; i < ui->listWidgetCrossoverCreatures->count(); ++i)
|
||||||
|
{
|
||||||
|
auto * item = ui->listWidgetCrossoverCreatures->item(i);
|
||||||
|
if(item->checkState() == Qt::Checked)
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.monstersKeptByHero.emplace(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
campaignState->scenarios.at(scenario).preconditionRegions.clear();
|
||||||
|
for(int i = 0; i < ui->listWidgetPrerequisites->count(); ++i)
|
||||||
|
{
|
||||||
|
auto * item = ui->listWidgetPrerequisites->item(i);
|
||||||
|
if(item->checkState() == Qt::Checked)
|
||||||
|
campaignState->scenarios.at(scenario).preconditionRegions.emplace(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.bonusesToChoose.clear();
|
||||||
|
if(ui->radioButtonStartingOptionBonus->isChecked())
|
||||||
|
{
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.playerColor = PlayerColor(ui->comboBoxStartingBonusPlayerPosition->currentData().toInt());
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.bonusesToChoose.clear();
|
||||||
|
for (int i = 0; i < ui->listWidgetStartingBonusOption->count(); ++i) {
|
||||||
|
QListWidgetItem *item = ui->listWidgetStartingBonusOption->item(i);
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.bonusesToChoose.push_back(item->data(Qt::UserRole).value<CampaignBonus>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(ui->radioButtonStartingOptionHeroCrossover->isChecked() || ui->radioButtonStartingOptionStartingHero->isChecked())
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ui->tableWidgetStartingCrossover->rowCount(); ++i)
|
||||||
|
{
|
||||||
|
CampaignBonus bonus;
|
||||||
|
bonus.type = ui->radioButtonStartingOptionHeroCrossover->isChecked() ? CampaignBonusType::HEROES_FROM_PREVIOUS_SCENARIO : CampaignBonusType::HERO;
|
||||||
|
QComboBox* comboBoxOption = qobject_cast<QComboBox*>(ui->tableWidgetStartingCrossover->cellWidget(i, 0));
|
||||||
|
QComboBox* comboBoxPlayer = qobject_cast<QComboBox*>(ui->tableWidgetStartingCrossover->cellWidget(i, 1));
|
||||||
|
bonus.info1 = comboBoxPlayer->currentData().toInt();
|
||||||
|
bonus.info2 = comboBoxOption->currentData().toInt();
|
||||||
|
campaignState->scenarios.at(scenario).travelOptions.bonusesToChoose.push_back(bonus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScenarioProperties::on_pushButtonCreatureTypeAll_clicked()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < ui->listWidgetCrossoverCreatures->count(); ++i)
|
||||||
|
ui->listWidgetCrossoverCreatures->item(i)->setCheckState(Qt::CheckState::Checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScenarioProperties::on_pushButtonCreatureTypeNone_clicked()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < ui->listWidgetCrossoverCreatures->count(); ++i)
|
||||||
|
ui->listWidgetCrossoverCreatures->item(i)->setCheckState(Qt::CheckState::Unchecked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScenarioProperties::on_pushButtonImport_clicked()
|
||||||
|
{
|
||||||
|
auto filename = QFileDialog::getOpenFileName(this, tr("Open map"), "", tr("All supported maps (*.vmap *.h3m);;VCMI maps(*.vmap);;HoMM3 maps(*.h3m)"));
|
||||||
|
if(filename.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QFile file(filename);
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
|
QMessageBox::critical(nullptr, tr("Error"), tr("Could not open the file."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray fileData = file.readAll();
|
||||||
|
std::vector<uint8_t> byteArray(fileData.begin(), fileData.end());
|
||||||
|
campaignState->mapPieces[scenario] = byteArray;
|
||||||
|
|
||||||
|
QFileInfo fileInfo(filename);
|
||||||
|
QString baseName = fileInfo.fileName();
|
||||||
|
campaignState->scenarios.at(scenario).mapName = baseName.toStdString();
|
||||||
|
|
||||||
|
reloadMapRelatedUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScenarioProperties::on_pushButtonExport_clicked()
|
||||||
|
{
|
||||||
|
auto mapName = QString::fromStdString(campaignState->scenarios.at(scenario).mapName);
|
||||||
|
bool isVmap = mapName.toLower().endsWith(".vmap");
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(nullptr, tr("Save map"), mapName, isVmap ? tr("VCMI maps (*.vmap);") : tr("HoMM3 maps (*.h3m);"));
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QFile file(fileName);
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::WriteOnly)) {
|
||||||
|
QMessageBox::critical(nullptr, tr("Error"), tr("Could not open the file."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto byteArray = campaignState->mapPieces[scenario];
|
||||||
|
QByteArray fileData(reinterpret_cast<const char*>(byteArray.data()), byteArray.size());
|
||||||
|
|
||||||
|
file.write(fileData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScenarioProperties::on_pushButtonRemove_clicked()
|
||||||
|
{
|
||||||
|
campaignState->mapPieces.erase(scenario);
|
||||||
|
campaignState->scenarios.at(scenario).mapName = "";
|
||||||
|
reloadMapRelatedUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScenarioProperties::on_radioButtonStartingOptionBonus_toggled()
|
||||||
|
{
|
||||||
|
ui->tabWidgetStartOptions->setCurrentIndex(0);
|
||||||
|
ui->listWidgetStartingBonusOption->clear();
|
||||||
|
ui->pushButtonStartingEdit->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScenarioProperties::on_radioButtonStartingOptionHeroCrossover_toggled()
|
||||||
|
{
|
||||||
|
ui->tabWidgetStartOptions->setCurrentIndex(1);
|
||||||
|
ui->tableWidgetStartingCrossover->clearContents();
|
||||||
|
ui->tableWidgetStartingCrossover->setRowCount(0);
|
||||||
|
ui->tableWidgetStartingCrossover->setHorizontalHeaderLabels({tr("Source scenario"), tr("Player position")});
|
||||||
|
ui->tableWidgetStartingCrossover->resizeColumnsToContents();
|
||||||
|
ui->pushButtonStartingEdit->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScenarioProperties::on_radioButtonStartingOptionStartingHero_toggled()
|
||||||
|
{
|
||||||
|
ui->tabWidgetStartOptions->setCurrentIndex(1);
|
||||||
|
ui->tableWidgetStartingCrossover->clearContents();
|
||||||
|
ui->tableWidgetStartingCrossover->setRowCount(0);
|
||||||
|
ui->tableWidgetStartingCrossover->setHorizontalHeaderLabels({tr("Hero"), tr("Player position")});
|
||||||
|
ui->tableWidgetStartingCrossover->resizeColumnsToContents();
|
||||||
|
ui->pushButtonStartingEdit->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScenarioProperties::on_pushButtonStartingAdd_clicked()
|
||||||
|
{
|
||||||
|
if(ui->radioButtonStartingOptionHeroCrossover->isChecked() || ui->radioButtonStartingOptionStartingHero->isChecked())
|
||||||
|
{
|
||||||
|
int row = ui->tableWidgetStartingCrossover->rowCount();
|
||||||
|
ui->tableWidgetStartingCrossover->insertRow(row);
|
||||||
|
|
||||||
|
QComboBox* comboBoxOption = new QComboBox();
|
||||||
|
if(ui->radioButtonStartingOptionStartingHero->isChecked())
|
||||||
|
{
|
||||||
|
for(auto & hero : heroSelection)
|
||||||
|
comboBoxOption->addItem(QString::fromStdString(hero.second), hero.first);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < scenario.getNum(); ++i)
|
||||||
|
{
|
||||||
|
auto tmpScenario = CampaignScenarioID(i);
|
||||||
|
auto text = getRegionChar(tmpScenario.getNum()) + " - " + QString::fromStdString(campaignState->scenarios.at(tmpScenario).mapName);
|
||||||
|
comboBoxOption->addItem(text, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QComboBox* comboBoxPlayer = new QComboBox();
|
||||||
|
for(int i = 0; i < ui->comboBoxStartingBonusPlayerPosition->count(); ++i) // copy from player dropdown
|
||||||
|
comboBoxPlayer->addItem(ui->comboBoxStartingBonusPlayerPosition->itemText(i), ui->comboBoxStartingBonusPlayerPosition->itemData(i));
|
||||||
|
|
||||||
|
ui->tableWidgetStartingCrossover->setCellWidget(row, 0, comboBoxOption);
|
||||||
|
ui->tableWidgetStartingCrossover->setCellWidget(row, 1, comboBoxPlayer);
|
||||||
|
|
||||||
|
ui->tableWidgetStartingCrossover->resizeColumnsToContents();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CampaignBonus bonus;
|
||||||
|
bonus.type = CampaignBonusType::SPELL;
|
||||||
|
if(StartingBonus::showStartingBonus(PlayerColor(ui->comboBoxStartingBonusPlayerPosition->currentData().toInt()), map, bonus))
|
||||||
|
{
|
||||||
|
QListWidgetItem * item = new QListWidgetItem(StartingBonus::getBonusListTitle(bonus, map));
|
||||||
|
item->setData(Qt::UserRole, QVariant::fromValue(bonus));
|
||||||
|
ui->listWidgetStartingBonusOption->addItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reloadEnableState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScenarioProperties::on_pushButtonStartingEdit_clicked()
|
||||||
|
{
|
||||||
|
if(ui->radioButtonStartingOptionBonus->isChecked())
|
||||||
|
{
|
||||||
|
QList<QListWidgetItem *> selectedItems = ui->listWidgetStartingBonusOption->selectedItems();
|
||||||
|
QListWidgetItem * item = selectedItems.takeFirst();
|
||||||
|
|
||||||
|
CampaignBonus bonus = item->data(Qt::UserRole).value<CampaignBonus>();
|
||||||
|
if(StartingBonus::showStartingBonus(PlayerColor(ui->comboBoxStartingBonusPlayerPosition->currentData().toInt()), map, bonus))
|
||||||
|
{
|
||||||
|
item->setText(StartingBonus::getBonusListTitle(bonus, map));
|
||||||
|
item->setData(Qt::UserRole, QVariant::fromValue(bonus));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScenarioProperties::on_pushButtonStartingRemove_clicked()
|
||||||
|
{
|
||||||
|
if(ui->radioButtonStartingOptionHeroCrossover->isChecked() || ui->radioButtonStartingOptionStartingHero->isChecked())
|
||||||
|
{
|
||||||
|
int rows = ui->tableWidgetStartingCrossover->rowCount() - 1;
|
||||||
|
ui->tableWidgetStartingCrossover->removeRow(rows);
|
||||||
|
ui->tableWidgetStartingCrossover->setRowCount(rows);
|
||||||
|
|
||||||
|
ui->tableWidgetStartingCrossover->resizeColumnsToContents();
|
||||||
|
}
|
||||||
|
else if(ui->radioButtonStartingOptionBonus->isChecked())
|
||||||
|
{
|
||||||
|
QList<QListWidgetItem *> selectedItems = ui->listWidgetStartingBonusOption->selectedItems();
|
||||||
|
for (QListWidgetItem *item : selectedItems)
|
||||||
|
delete ui->listWidgetStartingBonusOption->takeItem(ui->listWidgetStartingBonusOption->row(item));
|
||||||
|
}
|
||||||
|
reloadEnableState();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ScenarioProperties::getRegionChar(int no)
|
||||||
|
{
|
||||||
|
return QString(static_cast<char>('A' + no));
|
||||||
|
}
|
||||||
65
mapeditor/campaigneditor/scenarioproperties.h
Normal file
65
mapeditor/campaigneditor/scenarioproperties.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* scenarioproperties.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 <QDialog>
|
||||||
|
|
||||||
|
#include "lib/constants/EntityIdentifiers.h"
|
||||||
|
#include "lib/campaign/CampaignState.h"
|
||||||
|
|
||||||
|
class CMap;
|
||||||
|
class CampaignState;
|
||||||
|
class QAbstractButton;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ScenarioProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(CampaignBonus)
|
||||||
|
|
||||||
|
class ScenarioProperties : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ScenarioProperties(std::shared_ptr<CampaignState> campaignState, CampaignScenarioID scenario);
|
||||||
|
~ScenarioProperties();
|
||||||
|
|
||||||
|
static bool showScenarioProperties(std::shared_ptr<CampaignState> campaignState, CampaignScenarioID scenario);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_buttonBox_clicked(QAbstractButton * button);
|
||||||
|
void on_pushButtonCreatureTypeAll_clicked();
|
||||||
|
void on_pushButtonCreatureTypeNone_clicked();
|
||||||
|
|
||||||
|
void on_pushButtonImport_clicked();
|
||||||
|
void on_pushButtonExport_clicked();
|
||||||
|
void on_pushButtonRemove_clicked();
|
||||||
|
|
||||||
|
void on_radioButtonStartingOptionBonus_toggled();
|
||||||
|
void on_radioButtonStartingOptionHeroCrossover_toggled();
|
||||||
|
void on_radioButtonStartingOptionStartingHero_toggled();
|
||||||
|
|
||||||
|
void on_pushButtonStartingAdd_clicked();
|
||||||
|
void on_pushButtonStartingEdit_clicked();
|
||||||
|
void on_pushButtonStartingRemove_clicked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::ScenarioProperties *ui;
|
||||||
|
|
||||||
|
std::shared_ptr<CMap> map;
|
||||||
|
std::shared_ptr<CampaignState> campaignState;
|
||||||
|
CampaignScenarioID scenario;
|
||||||
|
|
||||||
|
std::map<int, std::string> heroSelection;
|
||||||
|
|
||||||
|
void reloadMapRelatedUi();
|
||||||
|
void reloadEnableState();
|
||||||
|
QString getRegionChar(int no);
|
||||||
|
};
|
||||||
569
mapeditor/campaigneditor/scenarioproperties.ui
Normal file
569
mapeditor/campaigneditor/scenarioproperties.ui
Normal file
@@ -0,0 +1,569 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ScenarioProperties</class>
|
||||||
|
<widget class="QDialog" name="ScenarioProperties">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>499</width>
|
||||||
|
<height>660</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Scenario Properties</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tabGeneral">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<attribute name="title">
|
||||||
|
<string>General</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelRegionName">
|
||||||
|
<property name="text">
|
||||||
|
<string>Region name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditRegionName">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelRegionColor">
|
||||||
|
<property name="text">
|
||||||
|
<string>Region color</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxRegionColor"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelScenarioName">
|
||||||
|
<property name="text">
|
||||||
|
<string>Scenario name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditScenarioName">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelMapFIle">
|
||||||
|
<property name="text">
|
||||||
|
<string>Map file</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditMapFile">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonImport">
|
||||||
|
<property name="text">
|
||||||
|
<string>Import...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonExport">
|
||||||
|
<property name="text">
|
||||||
|
<string>Export...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonRemove">
|
||||||
|
<property name="text">
|
||||||
|
<string>Remove</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelDefaultDifficulty">
|
||||||
|
<property name="text">
|
||||||
|
<string>Default difficulty</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxDefaultDifficulty"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelPrerequisites">
|
||||||
|
<property name="text">
|
||||||
|
<string>Prerequisites</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="listWidgetPrerequisites"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelRIghtClickText">
|
||||||
|
<property name="text">
|
||||||
|
<string>Region right-click text</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="plainTextEditRightClickText"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabPrologueEpilogue">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Prologue/Epilogue</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBoxPrologue">
|
||||||
|
<property name="title">
|
||||||
|
<string>Prologue</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxPrologueEnabled">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enabled</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelPrologueVideo">
|
||||||
|
<property name="text">
|
||||||
|
<string>Video</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditPrologueVideo"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelPrologueMusic">
|
||||||
|
<property name="text">
|
||||||
|
<string>Music</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditPrologueMusic"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelPrologueVoice">
|
||||||
|
<property name="text">
|
||||||
|
<string>Voice</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditPrologueVoice"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelPrologueText">
|
||||||
|
<property name="text">
|
||||||
|
<string>Text</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="plainTextEditPrologueText"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBoxEpilogue">
|
||||||
|
<property name="title">
|
||||||
|
<string>Epilogue</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxEpilogueEnabled">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enabled</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelEpilogueVideo">
|
||||||
|
<property name="text">
|
||||||
|
<string>Video</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditEpilogueVideo"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelEpilogueMusic">
|
||||||
|
<property name="text">
|
||||||
|
<string>Music</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditEpilogueMusic"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelEpilogueVoice">
|
||||||
|
<property name="text">
|
||||||
|
<string>Voice</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEditEpilogueVoice"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelEpilogueText">
|
||||||
|
<property name="text">
|
||||||
|
<string>Text</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="plainTextEditEpilogueText"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabCrossover">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Crossover</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBoxCrossoverHeroes">
|
||||||
|
<property name="title">
|
||||||
|
<string>Crossover heroes retain</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxCrossoverExperience">
|
||||||
|
<property name="text">
|
||||||
|
<string>Experience</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxCrossoverPrimarySkills">
|
||||||
|
<property name="text">
|
||||||
|
<string>Primary skills</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxCrossoverSecondarySkills">
|
||||||
|
<property name="text">
|
||||||
|
<string>Secondary skills</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxCrossoverSpells">
|
||||||
|
<property name="text">
|
||||||
|
<string>Spells</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxCrossoverArtifacts">
|
||||||
|
<property name="text">
|
||||||
|
<string>Artifacts</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="listWidgetCrossoverCreatures">
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollMode">
|
||||||
|
<enum>QAbstractItemView::ScrollPerItem</enum>
|
||||||
|
</property>
|
||||||
|
<property name="isWrapping" stdset="0">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="layoutMode">
|
||||||
|
<enum>QListView::Batched</enum>
|
||||||
|
</property>
|
||||||
|
<property name="batchSize">
|
||||||
|
<number>30</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonCreatureTypeAll">
|
||||||
|
<property name="text">
|
||||||
|
<string>All</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonCreatureTypeNone">
|
||||||
|
<property name="text">
|
||||||
|
<string>None</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBoxArtifacts">
|
||||||
|
<property name="title">
|
||||||
|
<string>Crossover artifacts</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="listWidgetCrossoverArtifacts">
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollMode">
|
||||||
|
<enum>QAbstractItemView::ScrollPerItem</enum>
|
||||||
|
</property>
|
||||||
|
<property name="isWrapping" stdset="0">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="layoutMode">
|
||||||
|
<enum>QListView::Batched</enum>
|
||||||
|
</property>
|
||||||
|
<property name="batchSize">
|
||||||
|
<number>30</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabStarting">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Starting</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelStartingOption">
|
||||||
|
<property name="text">
|
||||||
|
<string>Starting options are</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonStartingOptionBonus">
|
||||||
|
<property name="text">
|
||||||
|
<string>Starting bonus options</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonStartingOptionHeroCrossover">
|
||||||
|
<property name="text">
|
||||||
|
<string>Hero crossover options</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonStartingOptionStartingHero">
|
||||||
|
<property name="text">
|
||||||
|
<string>Starting hero options</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidgetStartOptions">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tabBonus">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Bonus</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelStartingBonusPlayerPosition">
|
||||||
|
<property name="text">
|
||||||
|
<string>Player position</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxStartingBonusPlayerPosition"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelStartingBonusOption">
|
||||||
|
<property name="text">
|
||||||
|
<string>Starting bonus option</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="listWidgetStartingBonusOption"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabCrossoverStartingHero">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Crossover/ Starting hero</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableWidget" name="tableWidgetStartingCrossover"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonStartingAdd">
|
||||||
|
<property name="text">
|
||||||
|
<string>Add...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonStartingEdit">
|
||||||
|
<property name="text">
|
||||||
|
<string>Edit...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButtonStartingRemove">
|
||||||
|
<property name="text">
|
||||||
|
<string>Remove</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
370
mapeditor/campaigneditor/startingbonus.cpp
Normal file
370
mapeditor/campaigneditor/startingbonus.cpp
Normal file
@@ -0,0 +1,370 @@
|
|||||||
|
/*
|
||||||
|
* startingbonus.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 "startingbonus.h"
|
||||||
|
#include "ui_startingbonus.h"
|
||||||
|
|
||||||
|
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||||
|
#include "../../lib/mapObjects/CGTownInstance.h"
|
||||||
|
#include "../../lib/campaign/CampaignState.h"
|
||||||
|
#include "../../lib/entities/building/CBuilding.h"
|
||||||
|
#include "../../lib/entities/hero/CHero.h"
|
||||||
|
#include "../../lib/mapping/CMap.h"
|
||||||
|
#include "../../lib/CArtHandler.h"
|
||||||
|
#include "../../lib/CSkillHandler.h"
|
||||||
|
#include "../../lib/CCreatureHandler.h"
|
||||||
|
#include "../../lib/spells/CSpellHandler.h"
|
||||||
|
|
||||||
|
StartingBonus::StartingBonus(PlayerColor color, std::shared_ptr<CMap> map, CampaignBonus bonus):
|
||||||
|
ui(new Ui::StartingBonus),
|
||||||
|
bonus(bonus),
|
||||||
|
map(map),
|
||||||
|
color(color)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
setWindowTitle(tr("Edit Starting Bonus"));
|
||||||
|
|
||||||
|
setWindowModality(Qt::ApplicationModal);
|
||||||
|
|
||||||
|
ui->tabWidget->tabBar()->hide();
|
||||||
|
ui->tabWidget->setStyleSheet("QTabWidget::pane { border: 0; }");
|
||||||
|
|
||||||
|
initControls();
|
||||||
|
|
||||||
|
loadBonus();
|
||||||
|
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
StartingBonus::~StartingBonus()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartingBonus::initControls()
|
||||||
|
{
|
||||||
|
std::map<int, std::string> heroSelection;
|
||||||
|
for(auto & hero : map->heroesOnMap)
|
||||||
|
if(hero->getOwner() == color || color == PlayerColor::CANNOT_DETERMINE)
|
||||||
|
heroSelection.emplace(hero->getHeroTypeID(), hero->getNameTranslated());
|
||||||
|
heroSelection.emplace(0xFFFD, tr("Strongest").toStdString());
|
||||||
|
heroSelection.emplace(0xFFFE, tr("Generated").toStdString());
|
||||||
|
heroSelection.emplace(0xFFFF, tr("Random").toStdString());
|
||||||
|
|
||||||
|
for(auto & hero : heroSelection)
|
||||||
|
{
|
||||||
|
ui->comboBoxSpellRecipient->addItem(QString::fromStdString(hero.second), QVariant(hero.first));
|
||||||
|
ui->comboBoxCreatureRecipient->addItem(QString::fromStdString(hero.second), QVariant(hero.first));
|
||||||
|
ui->comboBoxArtifactRecipient->addItem(QString::fromStdString(hero.second), QVariant(hero.first));
|
||||||
|
ui->comboBoxSpellScrollRecipient->addItem(QString::fromStdString(hero.second), QVariant(hero.first));
|
||||||
|
ui->comboBoxPrimarySkillRecipient->addItem(QString::fromStdString(hero.second), QVariant(hero.first));
|
||||||
|
ui->comboBoxSecondarySkillRecipient->addItem(QString::fromStdString(hero.second), QVariant(hero.first));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto const & objectPtr : LIBRARY->spellh->objects)
|
||||||
|
{
|
||||||
|
ui->comboBoxSpellSpell->addItem(QString::fromStdString(objectPtr->getNameTranslated()), QVariant(objectPtr->getId()));
|
||||||
|
ui->comboBoxSpellScrollSpell->addItem(QString::fromStdString(objectPtr->getNameTranslated()), QVariant(objectPtr->getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto const & objectPtr : LIBRARY->creh->objects)
|
||||||
|
ui->comboBoxCreatureCreatureType->addItem(QString::fromStdString(objectPtr->getNameSingularTranslated()), QVariant(objectPtr->getId()));
|
||||||
|
|
||||||
|
if(map->players[color].hasMainTown)
|
||||||
|
for(auto & town : map->towns)
|
||||||
|
if(town->pos == map->players[color].posOfMainTown)
|
||||||
|
{
|
||||||
|
for(auto & building : town->getTown()->buildings)
|
||||||
|
ui->comboBoxBuildingBuilding->addItem(QString::fromStdString(building.second->getNameTranslated()), QVariant(building.first.getNum()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto const & objectPtr : LIBRARY->arth->objects)
|
||||||
|
if(!vstd::contains(std::vector<ArtifactID>({
|
||||||
|
ArtifactID::SPELL_SCROLL,
|
||||||
|
ArtifactID::SPELLBOOK,
|
||||||
|
ArtifactID::GRAIL,
|
||||||
|
ArtifactID::AMMO_CART,
|
||||||
|
ArtifactID::BALLISTA,
|
||||||
|
ArtifactID::CATAPULT,
|
||||||
|
ArtifactID::FIRST_AID_TENT,
|
||||||
|
}), objectPtr->getId()))
|
||||||
|
ui->comboBoxArtifactArtifact->addItem(QString::fromStdString(objectPtr->getNameTranslated()), QVariant(objectPtr->getId()));
|
||||||
|
|
||||||
|
for(auto const & objectPtr : LIBRARY->skillh->objects)
|
||||||
|
ui->comboBoxSecondarySkillSecondarySkill->addItem(QString::fromStdString(objectPtr->getNameTranslated()), QVariant(objectPtr->getId()));
|
||||||
|
|
||||||
|
ui->comboBoxSecondarySkillMastery->addItem(tr("Basic"), QVariant(0));
|
||||||
|
ui->comboBoxSecondarySkillMastery->addItem(tr("Advanced"), QVariant(1));
|
||||||
|
ui->comboBoxSecondarySkillMastery->addItem(tr("Expert"), QVariant(2));
|
||||||
|
|
||||||
|
ui->comboBoxResourceResourceType->addItem(tr("Wood"), QVariant(0));
|
||||||
|
ui->comboBoxResourceResourceType->addItem(tr("Mercury"), QVariant(1));
|
||||||
|
ui->comboBoxResourceResourceType->addItem(tr("Ore"), QVariant(2));
|
||||||
|
ui->comboBoxResourceResourceType->addItem(tr("Sulfur"), QVariant(3));
|
||||||
|
ui->comboBoxResourceResourceType->addItem(tr("Crystal"), QVariant(4));
|
||||||
|
ui->comboBoxResourceResourceType->addItem(tr("Gems"), QVariant(5));
|
||||||
|
ui->comboBoxResourceResourceType->addItem(tr("Gold"), QVariant(6));
|
||||||
|
ui->comboBoxResourceResourceType->addItem(tr("Common (Wood and Ore)"), QVariant(0xFD));
|
||||||
|
ui->comboBoxResourceResourceType->addItem(tr("Rare (Mercury, Sulfur, Crystal, Gems)"), QVariant(0xFE));
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartingBonus::loadBonus()
|
||||||
|
{
|
||||||
|
auto setComboBoxValue = [](QComboBox * comboBox, QVariant data){
|
||||||
|
int index = comboBox->findData(data);
|
||||||
|
if(index != -1)
|
||||||
|
comboBox->setCurrentIndex(index);
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (bonus.type)
|
||||||
|
{
|
||||||
|
case CampaignBonusType::SPELL:
|
||||||
|
ui->radioButtonSpell->setChecked(true);
|
||||||
|
on_radioButtonSpell_toggled();
|
||||||
|
setComboBoxValue(ui->comboBoxSpellRecipient, bonus.info1);
|
||||||
|
setComboBoxValue(ui->comboBoxSpellSpell, bonus.info2);
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::MONSTER:
|
||||||
|
ui->radioButtonCreature->setChecked(true);
|
||||||
|
on_radioButtonCreature_toggled();
|
||||||
|
setComboBoxValue(ui->comboBoxCreatureRecipient, bonus.info1);
|
||||||
|
setComboBoxValue(ui->comboBoxCreatureCreatureType, bonus.info2);
|
||||||
|
ui->spinBoxCreatureQuantity->setValue(bonus.info3);
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::BUILDING:
|
||||||
|
ui->radioButtonBuilding->setChecked(true);
|
||||||
|
on_radioButtonBuilding_toggled();
|
||||||
|
setComboBoxValue(ui->comboBoxBuildingBuilding, bonus.info1);
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::ARTIFACT:
|
||||||
|
ui->radioButtonArtifact->setChecked(true);
|
||||||
|
on_radioButtonArtifact_toggled();
|
||||||
|
setComboBoxValue(ui->comboBoxArtifactRecipient, bonus.info1);
|
||||||
|
setComboBoxValue(ui->comboBoxArtifactArtifact, bonus.info2);
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::SPELL_SCROLL:
|
||||||
|
ui->radioButtonSpellScroll->setChecked(true);
|
||||||
|
on_radioButtonSpellScroll_toggled();
|
||||||
|
setComboBoxValue(ui->comboBoxSpellScrollRecipient, bonus.info1);
|
||||||
|
setComboBoxValue(ui->comboBoxSpellScrollSpell, bonus.info2);
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::PRIMARY_SKILL:
|
||||||
|
ui->radioButtonPrimarySkill->setChecked(true);
|
||||||
|
on_radioButtonPrimarySkill_toggled();
|
||||||
|
setComboBoxValue(ui->comboBoxPrimarySkillRecipient, bonus.info1);
|
||||||
|
ui->spinBoxPrimarySkillAttack->setValue((bonus.info2 >> 0) & 0xff);
|
||||||
|
ui->spinBoxPrimarySkillDefense->setValue((bonus.info2 >> 8) & 0xff);
|
||||||
|
ui->spinBoxPrimarySkillSpell->setValue((bonus.info2 >> 16) & 0xff);
|
||||||
|
ui->spinBoxPrimarySkillKnowledge->setValue((bonus.info2 >> 24) & 0xff);
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::SECONDARY_SKILL:
|
||||||
|
ui->radioButtonSecondarySkill->setChecked(true);
|
||||||
|
on_radioButtonSecondarySkill_toggled();
|
||||||
|
setComboBoxValue(ui->comboBoxSecondarySkillRecipient, bonus.info1);
|
||||||
|
setComboBoxValue(ui->comboBoxSecondarySkillSecondarySkill, bonus.info2);
|
||||||
|
setComboBoxValue(ui->comboBoxSecondarySkillMastery, bonus.info3);
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::RESOURCE:
|
||||||
|
ui->radioButtonResource->setChecked(true);
|
||||||
|
on_radioButtonResource_toggled();
|
||||||
|
setComboBoxValue(ui->comboBoxResourceResourceType, bonus.info1);
|
||||||
|
ui->spinBoxResourceQuantity->setValue(bonus.info2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartingBonus::saveBonus()
|
||||||
|
{
|
||||||
|
if(ui->radioButtonSpell->isChecked())
|
||||||
|
bonus.type = CampaignBonusType::SPELL;
|
||||||
|
else if(ui->radioButtonCreature->isChecked())
|
||||||
|
bonus.type = CampaignBonusType::MONSTER;
|
||||||
|
else if(ui->radioButtonBuilding->isChecked())
|
||||||
|
bonus.type = CampaignBonusType::BUILDING;
|
||||||
|
else if(ui->radioButtonArtifact->isChecked())
|
||||||
|
bonus.type = CampaignBonusType::ARTIFACT;
|
||||||
|
else if(ui->radioButtonSpellScroll->isChecked())
|
||||||
|
bonus.type = CampaignBonusType::SPELL_SCROLL;
|
||||||
|
else if(ui->radioButtonPrimarySkill->isChecked())
|
||||||
|
bonus.type = CampaignBonusType::PRIMARY_SKILL;
|
||||||
|
else if(ui->radioButtonSecondarySkill->isChecked())
|
||||||
|
bonus.type = CampaignBonusType::SECONDARY_SKILL;
|
||||||
|
else if(ui->radioButtonResource->isChecked())
|
||||||
|
bonus.type = CampaignBonusType::RESOURCE;
|
||||||
|
|
||||||
|
bonus.info1 = 0;
|
||||||
|
bonus.info2 = 0;
|
||||||
|
bonus.info3 = 0;
|
||||||
|
|
||||||
|
switch (bonus.type)
|
||||||
|
{
|
||||||
|
case CampaignBonusType::SPELL:
|
||||||
|
bonus.info1 = ui->comboBoxSpellRecipient->currentData().toInt();
|
||||||
|
bonus.info2 = ui->comboBoxSpellSpell->currentData().toInt();
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::MONSTER:
|
||||||
|
bonus.info1 = ui->comboBoxCreatureRecipient->currentData().toInt();
|
||||||
|
bonus.info2 = ui->comboBoxCreatureCreatureType->currentData().toInt();
|
||||||
|
bonus.info3 = ui->spinBoxCreatureQuantity->value();
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::BUILDING:
|
||||||
|
bonus.info1 = ui->comboBoxBuildingBuilding->currentData().toInt();
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::ARTIFACT:
|
||||||
|
bonus.info1 = ui->comboBoxArtifactRecipient->currentData().toInt();
|
||||||
|
bonus.info2 = ui->comboBoxArtifactArtifact->currentData().toInt();
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::SPELL_SCROLL:
|
||||||
|
bonus.info1 = ui->comboBoxSpellScrollRecipient->currentData().toInt();
|
||||||
|
bonus.info2 = ui->comboBoxSpellScrollSpell->currentData().toInt();
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::PRIMARY_SKILL:
|
||||||
|
bonus.info1 = ui->comboBoxPrimarySkillRecipient->currentData().toInt();
|
||||||
|
bonus.info2 |= ui->spinBoxPrimarySkillAttack->value() << 0;
|
||||||
|
bonus.info2 |= ui->spinBoxPrimarySkillDefense->value() << 8;
|
||||||
|
bonus.info2 |= ui->spinBoxPrimarySkillSpell->value() << 16;
|
||||||
|
bonus.info2 |= ui->spinBoxPrimarySkillKnowledge->value() << 24;
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::SECONDARY_SKILL:
|
||||||
|
bonus.info1 = ui->comboBoxSecondarySkillRecipient->currentData().toInt();
|
||||||
|
bonus.info2 = ui->comboBoxSecondarySkillSecondarySkill->currentData().toInt();
|
||||||
|
bonus.info3 = ui->comboBoxSecondarySkillMastery->currentData().toInt();
|
||||||
|
break;
|
||||||
|
case CampaignBonusType::RESOURCE:
|
||||||
|
bonus.info1 = ui->comboBoxResourceResourceType->currentData().toInt();
|
||||||
|
bonus.info2 = ui->spinBoxResourceQuantity->value();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartingBonus::on_buttonBox_clicked(QAbstractButton * button)
|
||||||
|
{
|
||||||
|
if(button == ui->buttonBox->button(QDialogButtonBox::Ok))
|
||||||
|
{
|
||||||
|
saveBonus();
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StartingBonus::showStartingBonus(PlayerColor color, std::shared_ptr<CMap> map, CampaignBonus & bonus)
|
||||||
|
{
|
||||||
|
auto * dialog = new StartingBonus(color, map, bonus);
|
||||||
|
|
||||||
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
auto result = dialog->exec();
|
||||||
|
|
||||||
|
if(result == QDialog::Accepted)
|
||||||
|
bonus = dialog->bonus;
|
||||||
|
|
||||||
|
return result == QDialog::Accepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString StartingBonus::getBonusListTitle(CampaignBonus bonus, std::shared_ptr<CMap> map)
|
||||||
|
{
|
||||||
|
auto getHeroName = [](int id){
|
||||||
|
MetaString tmp;
|
||||||
|
if(0xFFFD)
|
||||||
|
tmp.appendRawString(tr("strongest hero").toStdString());
|
||||||
|
else if(0xFFFE)
|
||||||
|
tmp.appendRawString(tr("generated hero").toStdString());
|
||||||
|
else if(0xFFFF)
|
||||||
|
tmp.appendRawString(tr("random hero").toStdString());
|
||||||
|
else
|
||||||
|
tmp.appendName(HeroTypeID(id));
|
||||||
|
return QString::fromStdString(tmp.toString());
|
||||||
|
};
|
||||||
|
auto getSpellName = [](int id){
|
||||||
|
MetaString tmp;
|
||||||
|
tmp.appendName(SpellID(id));
|
||||||
|
return QString::fromStdString(tmp.toString());
|
||||||
|
};
|
||||||
|
auto getMonsterName = [](int id, int amount){
|
||||||
|
MetaString tmp;
|
||||||
|
tmp.appendName(CreatureID(id), amount);
|
||||||
|
return QString::fromStdString(tmp.toString());
|
||||||
|
};
|
||||||
|
auto getArtifactName = [](int id){
|
||||||
|
MetaString tmp;
|
||||||
|
tmp.appendName(ArtifactID(id));
|
||||||
|
return QString::fromStdString(tmp.toString());
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (bonus.type)
|
||||||
|
{
|
||||||
|
case CampaignBonusType::SPELL:
|
||||||
|
return tr("%1 spell for %2").arg(getSpellName(bonus.info2)).arg(getHeroName(bonus.info1));
|
||||||
|
case CampaignBonusType::MONSTER:
|
||||||
|
return tr("%1 %2 for %3").arg(bonus.info3).arg(getMonsterName(bonus.info2, bonus.info3)).arg(getHeroName(bonus.info1));
|
||||||
|
case CampaignBonusType::BUILDING:
|
||||||
|
return tr("Building");
|
||||||
|
case CampaignBonusType::ARTIFACT:
|
||||||
|
return tr("%1 artifact for %2").arg(getArtifactName(bonus.info2)).arg(getHeroName(bonus.info1));
|
||||||
|
case CampaignBonusType::SPELL_SCROLL:
|
||||||
|
return tr("%1 spell scroll for %2").arg(getSpellName(bonus.info2)).arg(getHeroName(bonus.info1));
|
||||||
|
case CampaignBonusType::PRIMARY_SKILL:
|
||||||
|
return tr("Primary skill (Attack: %1, Defense: %2, Spell: %3, Knowledge: %4) for %5").arg((bonus.info2 >> 0) & 0xff).arg((bonus.info2 >> 8) & 0xff).arg((bonus.info2 >> 16) & 0xff).arg((bonus.info2 >> 24) & 0xff).arg(getHeroName(bonus.info1));
|
||||||
|
case CampaignBonusType::SECONDARY_SKILL:
|
||||||
|
return tr("Secondary skill");
|
||||||
|
case CampaignBonusType::RESOURCE:
|
||||||
|
return tr("Resource");
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartingBonus::on_radioButtonSpell_toggled()
|
||||||
|
{
|
||||||
|
ui->tabWidget->setCurrentIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartingBonus::on_radioButtonCreature_toggled()
|
||||||
|
{
|
||||||
|
ui->tabWidget->setCurrentIndex(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartingBonus::on_radioButtonBuilding_toggled()
|
||||||
|
{
|
||||||
|
ui->tabWidget->setCurrentIndex(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartingBonus::on_radioButtonArtifact_toggled()
|
||||||
|
{
|
||||||
|
ui->tabWidget->setCurrentIndex(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartingBonus::on_radioButtonSpellScroll_toggled()
|
||||||
|
{
|
||||||
|
ui->tabWidget->setCurrentIndex(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartingBonus::on_radioButtonPrimarySkill_toggled()
|
||||||
|
{
|
||||||
|
ui->tabWidget->setCurrentIndex(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartingBonus::on_radioButtonSecondarySkill_toggled()
|
||||||
|
{
|
||||||
|
ui->tabWidget->setCurrentIndex(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartingBonus::on_radioButtonResource_toggled()
|
||||||
|
{
|
||||||
|
ui->tabWidget->setCurrentIndex(7);
|
||||||
|
}
|
||||||
|
|
||||||
55
mapeditor/campaigneditor/startingbonus.h
Normal file
55
mapeditor/campaigneditor/startingbonus.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* startingbonus.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 <QDialog>
|
||||||
|
|
||||||
|
#include "lib/constants/EntityIdentifiers.h"
|
||||||
|
#include "lib/campaign/CampaignState.h"
|
||||||
|
|
||||||
|
struct CampaignBonus;
|
||||||
|
class CMap;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class StartingBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
class StartingBonus : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit StartingBonus(PlayerColor color, std::shared_ptr<CMap> map, CampaignBonus bonus);
|
||||||
|
~StartingBonus();
|
||||||
|
|
||||||
|
static bool showStartingBonus(PlayerColor color, std::shared_ptr<CMap> map, CampaignBonus & bonus);
|
||||||
|
static QString getBonusListTitle(CampaignBonus bonus, std::shared_ptr<CMap> map);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_radioButtonSpell_toggled();
|
||||||
|
void on_radioButtonCreature_toggled();
|
||||||
|
void on_radioButtonBuilding_toggled();
|
||||||
|
void on_radioButtonArtifact_toggled();
|
||||||
|
void on_radioButtonSpellScroll_toggled();
|
||||||
|
void on_radioButtonPrimarySkill_toggled();
|
||||||
|
void on_radioButtonSecondarySkill_toggled();
|
||||||
|
void on_radioButtonResource_toggled();
|
||||||
|
void on_buttonBox_clicked(QAbstractButton * button);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::StartingBonus *ui;
|
||||||
|
|
||||||
|
CampaignBonus bonus;
|
||||||
|
std::shared_ptr<CMap> map;
|
||||||
|
PlayerColor color;
|
||||||
|
|
||||||
|
void initControls();
|
||||||
|
void loadBonus();
|
||||||
|
void saveBonus();
|
||||||
|
};
|
||||||
468
mapeditor/campaigneditor/startingbonus.ui
Normal file
468
mapeditor/campaigneditor/startingbonus.ui
Normal file
@@ -0,0 +1,468 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>StartingBonus</class>
|
||||||
|
<widget class="QDialog" name="StartingBonus">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>499</width>
|
||||||
|
<height>644</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Scenario Properties</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelSelBonusType">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select a bonus type</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonSpell">
|
||||||
|
<property name="text">
|
||||||
|
<string>Spell</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonCreature">
|
||||||
|
<property name="text">
|
||||||
|
<string>Creature</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonBuilding">
|
||||||
|
<property name="text">
|
||||||
|
<string>Building</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonArtifact">
|
||||||
|
<property name="text">
|
||||||
|
<string>Artifact</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonSpellScroll">
|
||||||
|
<property name="text">
|
||||||
|
<string>Spell scroll</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonPrimarySkill">
|
||||||
|
<property name="text">
|
||||||
|
<string>Primary skill</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonSecondarySkill">
|
||||||
|
<property name="text">
|
||||||
|
<string>Secondary skill</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonResource">
|
||||||
|
<property name="text">
|
||||||
|
<string>Resource</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tabSpell">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Spell</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelSpellRecipient">
|
||||||
|
<property name="text">
|
||||||
|
<string>Recipient</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxSpellRecipient"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelSpellSpell">
|
||||||
|
<property name="text">
|
||||||
|
<string>Spell</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxSpellSpell"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabCreature">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Creature</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelCreatureRecipient">
|
||||||
|
<property name="text">
|
||||||
|
<string>Recipient</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxCreatureRecipient"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelCreatureCreatureType">
|
||||||
|
<property name="text">
|
||||||
|
<string>Creature type</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxCreatureCreatureType"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelCreatureQuantity">
|
||||||
|
<property name="text">
|
||||||
|
<string>Quantity</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spinBoxCreatureQuantity"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabBuilding">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Building</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelBuildingBuilding">
|
||||||
|
<property name="text">
|
||||||
|
<string>Building</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxBuildingBuilding"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabArtifact">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Artifact</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelArtifactRecipient">
|
||||||
|
<property name="text">
|
||||||
|
<string>Recipient</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxArtifactRecipient"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelArtifactArtifact">
|
||||||
|
<property name="text">
|
||||||
|
<string>Artifact</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxArtifactArtifact"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabSpellScroll">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Spell scroll</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelSpellScrollRecipient">
|
||||||
|
<property name="text">
|
||||||
|
<string>Recipient</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxSpellScrollRecipient"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelSpellScrollSpell">
|
||||||
|
<property name="text">
|
||||||
|
<string>Spell</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxSpellScrollSpell"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabPrimarySkill">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Primary skill</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelPrimarySkillRecipient">
|
||||||
|
<property name="text">
|
||||||
|
<string>Recipient</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxPrimarySkillRecipient"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelPrimarySkillAttack">
|
||||||
|
<property name="text">
|
||||||
|
<string>Attack skill</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spinBoxPrimarySkillAttack"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelPrimarySkillDefense">
|
||||||
|
<property name="text">
|
||||||
|
<string>Defense skill</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spinBoxPrimarySkillDefense"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelPrimarySkillSpell">
|
||||||
|
<property name="text">
|
||||||
|
<string>Spell power</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spinBoxPrimarySkillSpell"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelPrimarySkillKnowledge">
|
||||||
|
<property name="text">
|
||||||
|
<string>Knowledge</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spinBoxPrimarySkillKnowledge"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_6">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabSecondarySkill">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Scondary skill</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelSecondarySkillRecipient">
|
||||||
|
<property name="text">
|
||||||
|
<string>Recipient</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxSecondarySkillRecipient"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelSecondarySkillSecondarySkill">
|
||||||
|
<property name="text">
|
||||||
|
<string>Secondary skill</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxSecondarySkillSecondarySkill"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelSecondarySkillMastery">
|
||||||
|
<property name="text">
|
||||||
|
<string>Mastery</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxSecondarySkillMastery"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_7">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabResource">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Resource</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelResourceResourceType">
|
||||||
|
<property name="text">
|
||||||
|
<string>Resource type</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxResourceResourceType"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelResourceQuantity">
|
||||||
|
<property name="text">
|
||||||
|
<string>Quantity</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spinBoxResourceQuantity"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_8">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
109
mapeditor/helper.cpp
Normal file
109
mapeditor/helper.cpp
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* helper.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 "helper.h"
|
||||||
|
#include "mapcontroller.h"
|
||||||
|
|
||||||
|
#include "../lib/filesystem/Filesystem.h"
|
||||||
|
#include "../lib/filesystem/CMemoryBuffer.h"
|
||||||
|
#include "../lib/filesystem/CFilesystemLoader.h"
|
||||||
|
#include "../lib/filesystem/CZipSaver.h"
|
||||||
|
#include "../lib/campaign/CampaignHandler.h"
|
||||||
|
#include "../lib/mapping/CMapService.h"
|
||||||
|
#include "../lib/mapping/CMap.h"
|
||||||
|
#include "../lib/mapping/CMap.h"
|
||||||
|
#include "../lib/mapping/MapFormatJson.h"
|
||||||
|
#include "../lib/modding/ModIncompatibility.h"
|
||||||
|
|
||||||
|
std::unique_ptr<CMap> Helper::openMapInternal(const QString & filenameSelect)
|
||||||
|
{
|
||||||
|
QFileInfo fi(filenameSelect);
|
||||||
|
std::string fname = fi.fileName().toStdString();
|
||||||
|
std::string fdir = fi.dir().path().toStdString();
|
||||||
|
|
||||||
|
ResourcePath resId("MAPEDITOR/" + fname, EResType::MAP);
|
||||||
|
|
||||||
|
//addFilesystem takes care about memory deallocation if case of failure, no memory leak here
|
||||||
|
auto * mapEditorFilesystem = new CFilesystemLoader("MAPEDITOR/", fdir, 0);
|
||||||
|
CResourceHandler::removeFilesystem("local", "mapEditor");
|
||||||
|
CResourceHandler::addFilesystem("local", "mapEditor", mapEditorFilesystem);
|
||||||
|
|
||||||
|
if(!CResourceHandler::get("mapEditor")->existsResource(resId))
|
||||||
|
throw std::runtime_error("Cannot open map from this folder");
|
||||||
|
|
||||||
|
CMapService mapService;
|
||||||
|
if(auto header = mapService.loadMapHeader(resId))
|
||||||
|
{
|
||||||
|
auto missingMods = CMapService::verifyMapHeaderMods(*header);
|
||||||
|
ModIncompatibility::ModList modList;
|
||||||
|
for(const auto & m : missingMods)
|
||||||
|
modList.push_back(m.second.name);
|
||||||
|
|
||||||
|
if(!modList.empty())
|
||||||
|
throw ModIncompatibility(modList);
|
||||||
|
|
||||||
|
return mapService.loadMap(resId, nullptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::runtime_error("Corrupted map");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<CampaignState> Helper::openCampaignInternal(const QString & filenameSelect)
|
||||||
|
{
|
||||||
|
QFileInfo fi(filenameSelect);
|
||||||
|
std::string fname = fi.fileName().toStdString();
|
||||||
|
std::string fdir = fi.dir().path().toStdString();
|
||||||
|
|
||||||
|
ResourcePath resId("MAPEDITOR/" + fname, EResType::CAMPAIGN);
|
||||||
|
|
||||||
|
//addFilesystem takes care about memory deallocation if case of failure, no memory leak here
|
||||||
|
auto * mapEditorFilesystem = new CFilesystemLoader("MAPEDITOR/", fdir, 0);
|
||||||
|
CResourceHandler::removeFilesystem("local", "mapEditor");
|
||||||
|
CResourceHandler::addFilesystem("local", "mapEditor", mapEditorFilesystem);
|
||||||
|
|
||||||
|
if(!CResourceHandler::get("mapEditor")->existsResource(resId))
|
||||||
|
throw std::runtime_error("Cannot open campaign from this folder");
|
||||||
|
if(auto campaign = CampaignHandler::getCampaign(resId.getName()))
|
||||||
|
return campaign;
|
||||||
|
else
|
||||||
|
throw std::runtime_error("Corrupted campaign");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Helper::saveCampaign(std::shared_ptr<CampaignState> campaignState, const QString & filename)
|
||||||
|
{
|
||||||
|
auto jsonCampaign = CampaignHandler::writeHeaderToJson(*campaignState);
|
||||||
|
|
||||||
|
std::shared_ptr<CIOApi> io(new CDefaultIOApi());
|
||||||
|
auto saver = std::make_shared<CZipSaver>(io, filename.toStdString());
|
||||||
|
for(auto & scenario : campaignState->allScenarios())
|
||||||
|
{
|
||||||
|
auto map = campaignState->getMap(scenario, nullptr);
|
||||||
|
MapController::repairMap(map.get());
|
||||||
|
CMemoryBuffer serializeBuffer;
|
||||||
|
{
|
||||||
|
CMapSaverJson jsonSaver(&serializeBuffer);
|
||||||
|
jsonSaver.saveMap(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mapName = boost::algorithm::to_lower_copy(campaignState->scenario(scenario).mapName);
|
||||||
|
if(!boost::ends_with(mapName, ".vmap"))
|
||||||
|
mapName = boost::replace_all_copy(mapName, ".h3m", std::string("")) + ".vmap";
|
||||||
|
|
||||||
|
auto stream = saver->addFile(mapName);
|
||||||
|
stream->write(reinterpret_cast<const ui8 *>(serializeBuffer.getBuffer().data()), serializeBuffer.getSize());
|
||||||
|
|
||||||
|
jsonCampaign["scenarios"].Vector().push_back(CampaignHandler::writeScenarioToJson(campaignState->scenario(scenario)));
|
||||||
|
jsonCampaign["scenarios"].Vector().back()["map"].String() = mapName;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto jsonCampaignStr = jsonCampaign.toString();
|
||||||
|
saver->addFile("header.json")->write(reinterpret_cast<const ui8 *>(jsonCampaignStr.data()), jsonCampaignStr.length());
|
||||||
|
}
|
||||||
21
mapeditor/helper.h
Normal file
21
mapeditor/helper.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* helper.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
|
||||||
|
|
||||||
|
class CMap;
|
||||||
|
class CampaignState;
|
||||||
|
|
||||||
|
namespace Helper
|
||||||
|
{
|
||||||
|
std::unique_ptr<CMap> openMapInternal(const QString &);
|
||||||
|
std::shared_ptr<CampaignState> openCampaignInternal(const QString &);
|
||||||
|
void saveCampaign(std::shared_ptr<CampaignState> campaignState, const QString & filename);
|
||||||
|
}
|
||||||
@@ -25,14 +25,11 @@
|
|||||||
#include "../lib/CConfigHandler.h"
|
#include "../lib/CConfigHandler.h"
|
||||||
#include "../lib/CConsoleHandler.h"
|
#include "../lib/CConsoleHandler.h"
|
||||||
#include "../lib/filesystem/Filesystem.h"
|
#include "../lib/filesystem/Filesystem.h"
|
||||||
#include "../lib/filesystem/CMemoryBuffer.h"
|
|
||||||
#include "../lib/GameConstants.h"
|
#include "../lib/GameConstants.h"
|
||||||
#include "../lib/campaign/CampaignHandler.h"
|
#include "../lib/campaign/CampaignHandler.h"
|
||||||
#include "../lib/mapObjectConstructors/AObjectTypeHandler.h"
|
#include "../lib/mapObjectConstructors/AObjectTypeHandler.h"
|
||||||
#include "../lib/mapObjectConstructors/CObjectClassesHandler.h"
|
#include "../lib/mapObjectConstructors/CObjectClassesHandler.h"
|
||||||
#include "../lib/mapObjects/ObjectTemplate.h"
|
#include "../lib/mapObjects/ObjectTemplate.h"
|
||||||
#include "../lib/mapping/CMapService.h"
|
|
||||||
#include "../lib/mapping/CMap.h"
|
|
||||||
#include "../lib/mapping/CMapEditManager.h"
|
#include "../lib/mapping/CMapEditManager.h"
|
||||||
#include "../lib/mapping/MapFormat.h"
|
#include "../lib/mapping/MapFormat.h"
|
||||||
#include "../lib/mapping/MapFormatJson.h"
|
#include "../lib/mapping/MapFormatJson.h"
|
||||||
@@ -40,7 +37,6 @@
|
|||||||
#include "../lib/RoadHandler.h"
|
#include "../lib/RoadHandler.h"
|
||||||
#include "../lib/RiverHandler.h"
|
#include "../lib/RiverHandler.h"
|
||||||
#include "../lib/TerrainHandler.h"
|
#include "../lib/TerrainHandler.h"
|
||||||
#include "../lib/filesystem/CFilesystemLoader.h"
|
|
||||||
|
|
||||||
#include "maphandler.h"
|
#include "maphandler.h"
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
@@ -51,6 +47,8 @@
|
|||||||
#include "mapsettings/translations.h"
|
#include "mapsettings/translations.h"
|
||||||
#include "playersettings.h"
|
#include "playersettings.h"
|
||||||
#include "validator.h"
|
#include "validator.h"
|
||||||
|
#include "helper.h"
|
||||||
|
#include "campaigneditor/campaigneditor.h"
|
||||||
|
|
||||||
QJsonValue jsonFromPixmap(const QPixmap &p)
|
QJsonValue jsonFromPixmap(const QPixmap &p)
|
||||||
{
|
{
|
||||||
@@ -237,6 +235,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
|||||||
ui->actionZoom_in->setIcon(QIcon{":/icons/zoom_plus.png"});
|
ui->actionZoom_in->setIcon(QIcon{":/icons/zoom_plus.png"});
|
||||||
ui->actionZoom_out->setIcon(QIcon{":/icons/zoom_minus.png"});
|
ui->actionZoom_out->setIcon(QIcon{":/icons/zoom_minus.png"});
|
||||||
ui->actionZoom_reset->setIcon(QIcon{":/icons/zoom_zero.png"});
|
ui->actionZoom_reset->setIcon(QIcon{":/icons/zoom_zero.png"});
|
||||||
|
ui->actionCampaignEditor->setIcon(QIcon{":/icons/mapeditor.64x64.png"});
|
||||||
|
|
||||||
loadUserSettings(); //For example window size
|
loadUserSettings(); //For example window size
|
||||||
setTitle();
|
setTitle();
|
||||||
@@ -363,65 +362,11 @@ void MainWindow::initializeMap(bool isNew)
|
|||||||
onPlayersChanged();
|
onPlayersChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CMap> MainWindow::openMapInternal(const QString & filenameSelect)
|
|
||||||
{
|
|
||||||
QFileInfo fi(filenameSelect);
|
|
||||||
std::string fname = fi.fileName().toStdString();
|
|
||||||
std::string fdir = fi.dir().path().toStdString();
|
|
||||||
|
|
||||||
ResourcePath resId("MAPEDITOR/" + fname, EResType::MAP);
|
|
||||||
|
|
||||||
//addFilesystem takes care about memory deallocation if case of failure, no memory leak here
|
|
||||||
auto * mapEditorFilesystem = new CFilesystemLoader("MAPEDITOR/", fdir, 0);
|
|
||||||
CResourceHandler::removeFilesystem("local", "mapEditor");
|
|
||||||
CResourceHandler::addFilesystem("local", "mapEditor", mapEditorFilesystem);
|
|
||||||
|
|
||||||
if(!CResourceHandler::get("mapEditor")->existsResource(resId))
|
|
||||||
throw std::runtime_error("Cannot open map from this folder");
|
|
||||||
|
|
||||||
CMapService mapService;
|
|
||||||
if(auto header = mapService.loadMapHeader(resId))
|
|
||||||
{
|
|
||||||
auto missingMods = CMapService::verifyMapHeaderMods(*header);
|
|
||||||
ModIncompatibility::ModList modList;
|
|
||||||
for(const auto & m : missingMods)
|
|
||||||
modList.push_back(m.second.name);
|
|
||||||
|
|
||||||
if(!modList.empty())
|
|
||||||
throw ModIncompatibility(modList);
|
|
||||||
|
|
||||||
return mapService.loadMap(resId, nullptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw std::runtime_error("Corrupted map");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<CampaignState> MainWindow::openCampaignInternal(const QString & filenameSelect)
|
|
||||||
{
|
|
||||||
QFileInfo fi(filenameSelect);
|
|
||||||
std::string fname = fi.fileName().toStdString();
|
|
||||||
std::string fdir = fi.dir().path().toStdString();
|
|
||||||
|
|
||||||
ResourcePath resId("MAPEDITOR/" + fname, EResType::CAMPAIGN);
|
|
||||||
|
|
||||||
//addFilesystem takes care about memory deallocation if case of failure, no memory leak here
|
|
||||||
auto * mapEditorFilesystem = new CFilesystemLoader("MAPEDITOR/", fdir, 0);
|
|
||||||
CResourceHandler::removeFilesystem("local", "mapEditor");
|
|
||||||
CResourceHandler::addFilesystem("local", "mapEditor", mapEditorFilesystem);
|
|
||||||
|
|
||||||
if(!CResourceHandler::get("mapEditor")->existsResource(resId))
|
|
||||||
throw std::runtime_error("Cannot open campaign from this folder");
|
|
||||||
if(auto campaign = CampaignHandler::getCampaign(resId.getName()))
|
|
||||||
return campaign;
|
|
||||||
else
|
|
||||||
throw std::runtime_error("Corrupted campaign");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::openMap(const QString & filenameSelect)
|
bool MainWindow::openMap(const QString & filenameSelect)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
controller.setMap(openMapInternal(filenameSelect));
|
controller.setMap(Helper::openMapInternal(filenameSelect));
|
||||||
}
|
}
|
||||||
catch(const ModIncompatibility & e)
|
catch(const ModIncompatibility & e)
|
||||||
{
|
{
|
||||||
@@ -623,6 +568,14 @@ void MainWindow::on_actionSave_as_triggered()
|
|||||||
saveMap();
|
saveMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionCampaignEditor_triggered()
|
||||||
|
{
|
||||||
|
if(!getAnswerAboutUnsavedChanges())
|
||||||
|
return;
|
||||||
|
|
||||||
|
hide();
|
||||||
|
CampaignEditor::showCampaignEditor();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionNew_triggered()
|
void MainWindow::on_actionNew_triggered()
|
||||||
{
|
{
|
||||||
@@ -1382,7 +1335,7 @@ void MainWindow::on_actionh3m_converter_triggered()
|
|||||||
for(auto & m : mapFiles)
|
for(auto & m : mapFiles)
|
||||||
{
|
{
|
||||||
CMapService mapService;
|
CMapService mapService;
|
||||||
auto map = openMapInternal(m);
|
auto map = Helper::openMapInternal(m);
|
||||||
controller.repairMap(map.get());
|
controller.repairMap(map.get());
|
||||||
mapService.saveMap(map, (saveDirectory + '/' + QFileInfo(m).completeBaseName() + ".vmap").toStdString());
|
mapService.saveMap(map, (saveDirectory + '/' + QFileInfo(m).completeBaseName() + ".vmap").toStdString());
|
||||||
}
|
}
|
||||||
@@ -1411,35 +1364,9 @@ void MainWindow::on_actionh3c_converter_triggered()
|
|||||||
QFileInfo fileInfo(campaignFileDest);
|
QFileInfo fileInfo(campaignFileDest);
|
||||||
if(fileInfo.suffix().toLower() != "vcmp")
|
if(fileInfo.suffix().toLower() != "vcmp")
|
||||||
campaignFileDest += ".vcmp";
|
campaignFileDest += ".vcmp";
|
||||||
auto campaign = openCampaignInternal(campaignFile);
|
auto campaign = Helper::openCampaignInternal(campaignFile);
|
||||||
|
|
||||||
auto jsonCampaign = CampaignHandler::writeHeaderToJson(*campaign);
|
Helper::saveCampaign(campaign, campaignFileDest);
|
||||||
|
|
||||||
std::shared_ptr<CIOApi> io(new CDefaultIOApi());
|
|
||||||
auto saver = std::make_shared<CZipSaver>(io, campaignFileDest.toStdString());
|
|
||||||
for(auto & scenario : campaign->allScenarios())
|
|
||||||
{
|
|
||||||
CMapService mapService;
|
|
||||||
auto map = campaign->getMap(scenario, nullptr);
|
|
||||||
controller.repairMap(map.get());
|
|
||||||
CMemoryBuffer serializeBuffer;
|
|
||||||
{
|
|
||||||
CMapSaverJson jsonSaver(&serializeBuffer);
|
|
||||||
jsonSaver.saveMap(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto mapName = boost::algorithm::to_lower_copy(campaign->scenario(scenario).mapName);
|
|
||||||
mapName = boost::replace_all_copy(mapName, ".h3m", std::string("")) + ".vmap";
|
|
||||||
|
|
||||||
auto stream = saver->addFile(mapName);
|
|
||||||
stream->write(reinterpret_cast<const ui8 *>(serializeBuffer.getBuffer().data()), serializeBuffer.getSize());
|
|
||||||
|
|
||||||
jsonCampaign["scenarios"].Vector().push_back(CampaignHandler::writeScenarioToJson(campaign->scenario(scenario)));
|
|
||||||
jsonCampaign["scenarios"].Vector().back()["map"].String() = mapName;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto jsonCampaignStr = jsonCampaign.toString();
|
|
||||||
saver->addFile("header.json")->write(reinterpret_cast<const ui8 *>(jsonCampaignStr.data()), jsonCampaignStr.length());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionLock_triggered()
|
void MainWindow::on_actionLock_triggered()
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ class ObjectBrowser;
|
|||||||
class ObjectBrowserProxyModel;
|
class ObjectBrowserProxyModel;
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
class CMap;
|
|
||||||
class CampaignState;
|
|
||||||
class CConsoleHandler;
|
class CConsoleHandler;
|
||||||
class CBasicLogConfigurator;
|
class CBasicLogConfigurator;
|
||||||
class CGObjectInstance;
|
class CGObjectInstance;
|
||||||
@@ -42,9 +40,6 @@ class MainWindow : public QMainWindow
|
|||||||
#endif
|
#endif
|
||||||
std::unique_ptr<CBasicLogConfigurator> logConfig;
|
std::unique_ptr<CBasicLogConfigurator> logConfig;
|
||||||
|
|
||||||
std::unique_ptr<CMap> openMapInternal(const QString &);
|
|
||||||
std::shared_ptr<CampaignState> openCampaignInternal(const QString &);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainWindow(QWidget *parent = nullptr);
|
explicit MainWindow(QWidget *parent = nullptr);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
@@ -75,6 +70,8 @@ private slots:
|
|||||||
|
|
||||||
void on_actionSave_as_triggered();
|
void on_actionSave_as_triggered();
|
||||||
|
|
||||||
|
void on_actionCampaignEditor_triggered();
|
||||||
|
|
||||||
void on_actionNew_triggered();
|
void on_actionNew_triggered();
|
||||||
|
|
||||||
void on_actionLevel_triggered();
|
void on_actionLevel_triggered();
|
||||||
|
|||||||
@@ -70,6 +70,9 @@
|
|||||||
<addaction name="actionSave"/>
|
<addaction name="actionSave"/>
|
||||||
<addaction name="actionSave_as"/>
|
<addaction name="actionSave_as"/>
|
||||||
<addaction name="actionExport"/>
|
<addaction name="actionExport"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionCampaignEditor"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="actionh3m_converter"/>
|
<addaction name="actionh3m_converter"/>
|
||||||
<addaction name="actionh3c_converter"/>
|
<addaction name="actionh3c_converter"/>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -144,6 +147,8 @@
|
|||||||
<addaction name="actionOpenRecent"/>
|
<addaction name="actionOpenRecent"/>
|
||||||
<addaction name="actionSave"/>
|
<addaction name="actionSave"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionCampaignEditor"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="actionUndo"/>
|
<addaction name="actionUndo"/>
|
||||||
<addaction name="actionRedo"/>
|
<addaction name="actionRedo"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
@@ -1065,6 +1070,14 @@
|
|||||||
<string>Ctrl+Shift+S</string>
|
<string>Ctrl+Shift+S</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionCampaignEditor">
|
||||||
|
<property name="text">
|
||||||
|
<string>Campaign editor</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Campaign editor</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
<action name="actionLevel">
|
<action name="actionLevel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>View underground</string>
|
<string>View underground</string>
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ void MapController::repairMap()
|
|||||||
repairMap(map());
|
repairMap(map());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapController::repairMap(CMap * map) const
|
void MapController::repairMap(CMap * map)
|
||||||
{
|
{
|
||||||
if(!map)
|
if(!map)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public:
|
|||||||
void setMap(std::unique_ptr<CMap>);
|
void setMap(std::unique_ptr<CMap>);
|
||||||
void initObstaclePainters(CMap * map);
|
void initObstaclePainters(CMap * map);
|
||||||
|
|
||||||
void repairMap(CMap * map) const;
|
static void repairMap(CMap * map);
|
||||||
void repairMap();
|
void repairMap();
|
||||||
|
|
||||||
const std::unique_ptr<CMap> & getMapUniquePtr() const; //to be used for map saving
|
const std::unique_ptr<CMap> & getMapUniquePtr() const; //to be used for map saving
|
||||||
|
|||||||
Reference in New Issue
Block a user