Files
vcmi/mapeditor/campaigneditor/campaigneditor.cpp
T
2025-04-10 21:04:24 +02:00

254 lines
6.8 KiB
C++

/*
* 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 ? "*" : "", tr("VCMI Campaign Editor"), GameConstants::VCMI_VERSION.c_str());
setWindowTitle(title);
}
void CampaignEditor::changed()
{
unsaved = true;
setTitle();
}
bool CampaignEditor::saveCampaign()
{
if(campaignState->mapPieces.size() != campaignState->campaignRegions.regions.size())
{
auto reply = QMessageBox::question(nullptr, tr("Maps missing"), tr("Not all regions have a map. Do you want to continue?"), QMessageBox::Yes|QMessageBox::No);
if (reply != QMessageBox::Yes)
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";
campaignState->creationDateTime = std::time(nullptr);
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();
}