#include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include #include "../lib/VCMIDirs.h" #include "../lib/VCMI_Lib.h" #include "../lib/logging/CBasicLogConfigurator.h" #include "../lib/CConfigHandler.h" #include "../lib/filesystem/Filesystem.h" #include "../lib/GameConstants.h" #include "../lib/mapping/CMapService.h" #include "../lib/mapping/CMap.h" #include "../lib/Terrain.h" #include "../lib/mapObjects/CObjectClassesHandler.h" #include "CGameInfo.h" #include "maphandler.h" #include "graphics.h" #include "windownewmap.h" static CBasicLogConfigurator * logConfig; void init() { loadDLLClasses(); const_cast(CGI)->setFromLib(); logGlobal->info("Initializing VCMI_Lib"); } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->mapView->setMain(this); //configure logging const boost::filesystem::path logPath = VCMIDirs::get().userCachePath() / "VCMI_Editor_log.txt"; console = new CConsoleHandler(); logConfig = new CBasicLogConfigurator(logPath, console); logConfig->configureDefault(); logGlobal->info("The log file will be saved to %s", logPath); //init preinitDLL(::console); settings.init(); // Initialize logging based on settings logConfig->configure(); logGlobal->debug("settings = %s", settings.toJsonNode().toJson()); // Some basic data validation to produce better error messages in cases of incorrect install auto testFile = [](std::string filename, std::string message) -> bool { if (CResourceHandler::get()->existsResource(ResourceID(filename))) return true; logGlobal->error("Error: %s was not found!", message); return false; }; if(!testFile("DATA/HELP.TXT", "Heroes III data") || !testFile("MODS/VCMI/MOD.JSON", "VCMI data")) { QApplication::quit(); } conf.init(); logGlobal->info("Loading settings"); CGI = new CGameInfo(); //contains all global informations about game (texts, lodHandlers, map handler etc.) init(); graphics = new Graphics(); // should be before curh->init() graphics->load();//must be after Content loading but should be in main thread if(!testFile("DATA/new-menu/Background.png", "Cannot find file")) { QApplication::quit(); } //now let's try to draw auto resPath = *CResourceHandler::get()->getResourceName(ResourceID("DATA/new-menu/Background.png")); scenes[0] = new MapScene(this, 0); scenes[1] = new MapScene(this, 1); ui->mapView->setScene(scenes[0]); sceneMini = new QGraphicsScene(this); ui->minimapView->setScene(sceneMini); scenes[0]->addPixmap(QPixmap(QString::fromStdString(resPath.native()))); //loading objects loadObjectsTree(); show(); setStatusMessage("privet"); } MainWindow::~MainWindow() { delete ui; } void MainWindow::setStatusMessage(const QString & status) { statusBar()->showMessage(status); } void MainWindow::reloadMap(int level) { MapHandler mapHandler(map.get()); for(int j = 0; j < map->height; ++j) { for(int i = 0; i < map->width; ++i) { mapHandler.drawTerrainTile(i, j, level); mapHandler.drawObjects(i, j, level); } } auto mapSizePx = mapHandler.surface.rect(); float ratio = std::fmin(mapSizePx.width() / 192., mapSizePx.height() / 192.); minimap = mapHandler.surface; minimap.setDevicePixelRatio(ratio); scenes[level]->updateViews(mapHandler.surface); //sceneMini->clear(); //sceneMini->addPixmap(minimap); } CMap * MainWindow::getMap() { return map.get(); } void MainWindow::setMapRaw(std::unique_ptr cmap) { map = std::move(cmap); } void MainWindow::setMap(bool isNew) { unsaved = isNew; if(isNew) filename.clear(); setWindowTitle(filename + "* - VCMI Map Editor"); reloadMap(); if(map->twoLevel) reloadMap(1); mapLevel = 0; ui->mapView->setScene(scenes[mapLevel]); } void MainWindow::on_actionOpen_triggered() { auto filenameSelect = QFileDialog::getOpenFileName(this, tr("Open Image"), QString::fromStdString(VCMIDirs::get().userCachePath().native()), tr("Homm3 Files (*.vmap *.h3m)")); if(filenameSelect.isNull()) return; QFileInfo fi(filenameSelect); std::string fname = fi.fileName().toStdString(); std::string fdir = fi.dir().path().toStdString(); ResourceID resId("MAPS/" + fname, EResType::MAP); //ResourceID resId("MAPS/SomeMap.vmap", EResType::MAP); if(!CResourceHandler::get()->existsResource(resId)) { QMessageBox::information(this, "Failed to open map", "Only map folder is supported"); return; } CMapService mapService; try { map = mapService.loadMap(resId); } catch(const std::exception & e) { QMessageBox::critical(this, "Failed to open map", e.what()); } setMap(false); } void MainWindow::saveMap() { if(!map) return; if(!unsaved) return; CMapService mapService; try { mapService.saveMap(map, filename.toStdString()); } catch(const std::exception & e) { QMessageBox::critical(this, "Failed to save map", e.what()); } unsaved = false; setWindowTitle(filename + " - VCMI Map Editor"); } void MainWindow::on_actionSave_as_triggered() { if(!map) return; auto filenameSelect = QFileDialog::getSaveFileName(this, tr("Save map"), "", tr("VCMI maps (*.vmap)")); if(filenameSelect.isNull()) return; if(filenameSelect == filename) return; filename = filenameSelect; saveMap(); } void MainWindow::on_actionNew_triggered() { auto newMapDialog = new WindowNewMap(this); } void MainWindow::on_actionSave_triggered() { if(!map) return; if(filename.isNull()) { auto filenameSelect = QFileDialog::getSaveFileName(this, tr("Save map"), "", tr("VCMI maps (*.vmap)")); if(filenameSelect.isNull()) return; filename = filenameSelect; } saveMap(); } void MainWindow::loadObjectsTree() { for(auto & terrain : Terrain::Manager::terrains()) { ui->listTerrains->addItem(QString::fromStdString(terrain)); } /* createHandler(bth, "Bonus type", pomtime); createHandler(generaltexth, "General text", pomtime); createHandler(heroh, "Hero", pomtime); createHandler(arth, "Artifact", pomtime); createHandler(creh, "Creature", pomtime); createHandler(townh, "Town", pomtime); createHandler(objh, "Object", pomtime); createHandler(objtypeh, "Object types information", pomtime); createHandler(spellh, "Spell", pomtime); createHandler(skillh, "Skill", pomtime); createHandler(terviewh, "Terrain view pattern", pomtime); createHandler(tplh, "Template", pomtime); //templates need already resolved identifiers (refactor?) createHandler(scriptHandler, "Script", pomtime); createHandler(battlefieldsHandler, "Battlefields", pomtime); createHandler(obstacleHandler, "Obstacles", pomtime);*/ std::map> identifiers; for(auto primaryID : VLC->objtypeh->knownObjects()) { //QList objTypes; for(auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID)) { //QList objSubTypes; auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID); /*if(handler->isStaticObject()) { for(auto temp : handler->getTemplates()) { } }*/ identifiers[handler->typeName].push_back(handler->subTypeName); } } objectsModel.setHorizontalHeaderLabels(QStringList() << QStringLiteral("Type")); QList objTypes; for(auto & el1 : identifiers) { auto * objTypei = new QStandardItem(QString::fromStdString(el1.first)); for(auto & el2 : el1.second) { objTypei->appendRow(new QStandardItem(QString::fromStdString(el2))); } objectsModel.appendRow(objTypei); } ui->treeView->setModel(&objectsModel); } void MainWindow::on_actionLevel_triggered() { if(map && map->twoLevel) { mapLevel = mapLevel ? 0 : 1; ui->mapView->setScene(scenes[mapLevel]); } } void MainWindow::on_actionPass_triggered(bool checked) { if(map) { scenes[0]->passabilityView.show(checked); scenes[1]->passabilityView.show(checked); } } void MainWindow::on_actionGrid_triggered(bool checked) { if(map) { scenes[0]->gridView.show(checked); scenes[1]->gridView.show(checked); } }