2022-09-01 03:51:29 +02:00
# include "StdInc.h"
2022-08-28 23:28:36 +02:00
# include "mainwindow.h"
# include "ui_mainwindow.h"
# include <QFileDialog>
2022-08-29 20:19:05 +02:00
# include <QFile>
# include <QMessageBox>
# include <QFileInfo>
2022-08-28 23:28:36 +02:00
# 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"
2022-08-29 20:19:05 +02:00
# include "../lib/mapping/CMapService.h"
# include "../lib/mapping/CMap.h"
2022-09-01 03:51:29 +02:00
# include "../lib/mapping/CMapEditManager.h"
2022-08-31 20:05:57 +02:00
# include "../lib/Terrain.h"
# include "../lib/mapObjects/CObjectClassesHandler.h"
2022-08-28 23:28:36 +02:00
# include "CGameInfo.h"
2022-08-30 00:44:02 +02:00
# include "maphandler.h"
2022-08-30 04:38:24 +02:00
# include "graphics.h"
2022-08-30 15:08:33 +02:00
# include "windownewmap.h"
2022-09-03 06:12:07 +02:00
# include "objectbrowser.h"
2022-09-04 02:12:33 +02:00
# include "inspector.h"
2022-09-04 18:16:36 +02:00
# include "mapsettings.h"
2022-09-04 20:01:49 +02:00
# include "playersettings.h"
2022-09-06 21:16:30 +02:00
# include "validator.h"
2022-08-28 23:28:36 +02:00
static CBasicLogConfigurator * logConfig ;
2022-09-03 12:49:57 +02:00
QJsonValue jsonFromPixmap ( const QPixmap & p )
{
QBuffer buffer ;
buffer . open ( QIODevice : : WriteOnly ) ;
p . save ( & buffer , " PNG " ) ;
auto const encoded = buffer . data ( ) . toBase64 ( ) ;
return { QLatin1String ( encoded ) } ;
}
QPixmap pixmapFromJson ( const QJsonValue & val )
{
auto const encoded = val . toString ( ) . toLatin1 ( ) ;
QPixmap p ;
p . loadFromData ( QByteArray : : fromBase64 ( encoded ) , " PNG " ) ;
return p ;
}
2022-08-28 23:28:36 +02:00
void init ( )
{
loadDLLClasses ( ) ;
const_cast < CGameInfo * > ( CGI ) - > setFromLib ( ) ;
logGlobal - > info ( " Initializing VCMI_Lib " ) ;
}
MainWindow : : MainWindow ( QWidget * parent ) :
2022-09-05 02:19:21 +02:00
QMainWindow ( parent ) ,
2022-09-05 04:18:38 +02:00
ui ( new Ui : : MainWindow ) ,
controller ( this )
2022-08-28 23:28:36 +02:00
{
2022-09-05 02:19:21 +02:00
ui - > setupUi ( this ) ;
2022-09-06 03:46:22 +02:00
setTitle ( ) ;
2022-09-04 02:12:33 +02:00
// Set current working dir to executable folder.
// This is important on Mac for relative paths to work inside DMG.
QDir : : setCurrent ( QApplication : : applicationDirPath ( ) ) ;
2022-08-31 20:05:57 +02:00
2022-08-28 23:28:36 +02:00
//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 ( ) ;
2022-08-30 04:38:24 +02:00
graphics = new Graphics ( ) ; // should be before curh->init()
graphics - > load ( ) ; //must be after Content loading but should be in main thread
2022-08-28 23:28:36 +02:00
if ( ! testFile ( " DATA/new-menu/Background.png " , " Cannot find file " ) )
{
QApplication : : quit ( ) ;
}
//now let's try to draw
2022-09-03 06:12:07 +02:00
//auto resPath = *CResourceHandler::get()->getResourceName(ResourceID("DATA/new-menu/Background.png"));
2022-08-28 23:28:36 +02:00
2022-09-05 02:19:21 +02:00
ui - > mapView - > setScene ( controller . scene ( 0 ) ) ;
ui - > mapView - > setController ( & controller ) ;
2022-09-08 00:59:02 +02:00
ui - > mapView - > setOptimizationFlags ( QGraphicsView : : DontSavePainterState | QGraphicsView : : DontAdjustForAntialiasing ) ;
2022-09-05 02:19:21 +02:00
connect ( ui - > mapView , & MapView : : openObjectProperties , this , & MainWindow : : loadInspector ) ;
2022-08-28 23:28:36 +02:00
2022-09-05 12:10:39 +02:00
ui - > minimapView - > setScene ( controller . miniScene ( 0 ) ) ;
ui - > minimapView - > setController ( & controller ) ;
2022-09-05 14:28:47 +02:00
connect ( ui - > minimapView , & MinimapView : : cameraPositionChanged , ui - > mapView , & MapView : : cameraChanged ) ;
2022-08-30 15:08:33 +02:00
2022-09-02 23:04:28 +02:00
scenePreview = new QGraphicsScene ( this ) ;
ui - > objectPreview - > setScene ( scenePreview ) ;
2022-09-03 06:12:07 +02:00
//scenes[0]->addPixmap(QPixmap(QString::fromStdString(resPath.native())));
2022-08-31 20:05:57 +02:00
//loading objects
loadObjectsTree ( ) ;
2022-08-30 15:08:33 +02:00
show ( ) ;
2022-08-28 23:28:36 +02:00
}
MainWindow : : ~ MainWindow ( )
{
delete ui ;
}
2022-08-31 20:05:57 +02:00
void MainWindow : : setStatusMessage ( const QString & status )
{
statusBar ( ) - > showMessage ( status ) ;
}
2022-09-06 03:46:22 +02:00
void MainWindow : : setTitle ( )
{
QString title = QString ( " %1%2 - %3 (v%4) " ) . arg ( filename , unsaved ? " * " : " " , VCMI_EDITOR_NAME , VCMI_EDITOR_VERSION ) ;
setWindowTitle ( title ) ;
}
2022-09-05 04:18:38 +02:00
void MainWindow : : mapChanged ( )
{
unsaved = true ;
2022-09-06 03:46:22 +02:00
setTitle ( ) ;
2022-09-05 04:18:38 +02:00
}
2022-09-05 02:19:21 +02:00
void MainWindow : : initializeMap ( bool isNew )
2022-08-30 23:24:12 +02:00
{
2022-08-31 20:05:57 +02:00
unsaved = isNew ;
if ( isNew )
filename . clear ( ) ;
2022-09-06 03:46:22 +02:00
setTitle ( ) ;
2022-08-31 20:05:57 +02:00
mapLevel = 0 ;
2022-09-05 02:19:21 +02:00
ui - > mapView - > setScene ( controller . scene ( mapLevel ) ) ;
2022-09-05 12:10:39 +02:00
ui - > minimapView - > setScene ( controller . miniScene ( mapLevel ) ) ;
ui - > minimapView - > dimensions ( ) ;
2022-09-05 03:50:21 +02:00
setStatusMessage ( QString ( " Scene objects: %1 " ) . arg ( ui - > mapView - > scene ( ) - > items ( ) . size ( ) ) ) ;
2022-09-04 18:16:36 +02:00
//enable settings
ui - > actionMapSettings - > setEnabled ( true ) ;
2022-09-05 04:18:38 +02:00
ui - > actionPlayers_settings - > setEnabled ( true ) ;
2022-08-30 15:08:33 +02:00
}
2022-08-28 23:28:36 +02:00
void MainWindow : : on_actionOpen_triggered ( )
{
2022-09-05 09:45:15 +02:00
auto filenameSelect = QFileDialog : : getOpenFileName ( this , tr ( " Open Image " ) , QString : : fromStdString ( VCMIDirs : : get ( ) . userCachePath ( ) . make_preferred ( ) . string ( ) ) , tr ( " Homm3 Files (*.vmap *.h3m) " ) ) ;
2022-08-29 20:19:05 +02:00
2022-08-30 15:08:33 +02:00
if ( filenameSelect . isNull ( ) )
2022-08-29 20:19:05 +02:00
return ;
2022-08-30 15:08:33 +02:00
QFileInfo fi ( filenameSelect ) ;
2022-08-29 20:19:05 +02:00
std : : string fname = fi . fileName ( ) . toStdString ( ) ;
std : : string fdir = fi . dir ( ) . path ( ) . toStdString ( ) ;
2022-08-30 02:48:44 +02:00
ResourceID resId ( " MAPS/ " + fname , EResType : : MAP ) ;
//ResourceID resId("MAPS/SomeMap.vmap", EResType::MAP);
2022-08-29 20:19:05 +02:00
if ( ! CResourceHandler : : get ( ) - > existsResource ( resId ) )
{
QMessageBox : : information ( this , " Failed to open map " , " Only map folder is supported " ) ;
return ;
}
CMapService mapService ;
try
{
2022-09-05 02:19:21 +02:00
controller . setMap ( mapService . loadMap ( resId ) ) ;
2022-08-29 20:19:05 +02:00
}
catch ( const std : : exception & e )
{
QMessageBox : : critical ( this , " Failed to open map " , e . what ( ) ) ;
2022-09-08 00:59:02 +02:00
return ;
2022-08-29 20:19:05 +02:00
}
2022-08-30 00:44:02 +02:00
2022-09-07 00:26:53 +02:00
2022-09-05 20:50:09 +02:00
filename = filenameSelect ;
2022-09-07 00:26:53 +02:00
initializeMap ( controller . map ( ) - > version ! = EMapFormat : : VCMI ) ;
2022-08-30 15:08:33 +02:00
}
2022-08-30 23:24:12 +02:00
void MainWindow : : saveMap ( )
2022-08-30 15:08:33 +02:00
{
2022-09-05 02:19:21 +02:00
if ( ! controller . map ( ) )
2022-08-30 15:08:33 +02:00
return ;
2022-08-30 23:24:12 +02:00
if ( ! unsaved )
2022-08-30 15:08:33 +02:00
return ;
2022-09-06 21:16:30 +02:00
//validate map
auto issues = Validator : : validate ( controller . map ( ) ) ;
bool critical = false ;
for ( auto & issue : issues )
critical | = issue . critical ;
if ( ! issues . empty ( ) )
{
if ( critical )
QMessageBox : : warning ( this , " Map validation " , " Map has critical problems and most probably will not be playable. Open Validator from the Map menu to see issues found " ) ;
else
QMessageBox : : information ( this , " Map validation " , " Map has some errors. Open Validator from the Map menu to see issues found " ) ;
}
2022-08-30 15:08:33 +02:00
CMapService mapService ;
try
2022-08-30 00:44:02 +02:00
{
2022-09-05 18:55:30 +02:00
mapService . saveMap ( controller . getMapUniquePtr ( ) , filename . toStdString ( ) ) ;
2022-08-30 00:44:02 +02:00
}
2022-08-30 15:08:33 +02:00
catch ( const std : : exception & e )
{
QMessageBox : : critical ( this , " Failed to save map " , e . what ( ) ) ;
}
unsaved = false ;
2022-09-06 03:46:22 +02:00
setTitle ( ) ;
2022-08-30 15:08:33 +02:00
}
2022-08-30 23:24:12 +02:00
void MainWindow : : on_actionSave_as_triggered ( )
{
2022-09-05 02:19:21 +02:00
if ( ! controller . map ( ) )
2022-08-30 23:24:12 +02:00
return ;
auto filenameSelect = QFileDialog : : getSaveFileName ( this , tr ( " Save map " ) , " " , tr ( " VCMI maps (*.vmap) " ) ) ;
if ( filenameSelect . isNull ( ) )
return ;
if ( filenameSelect = = filename )
return ;
filename = filenameSelect ;
saveMap ( ) ;
}
2022-08-30 15:08:33 +02:00
void MainWindow : : on_actionNew_triggered ( )
{
2022-09-05 02:19:21 +02:00
new WindowNewMap ( this ) ;
2022-08-28 23:28:36 +02:00
}
2022-08-30 23:24:12 +02:00
void MainWindow : : on_actionSave_triggered ( )
{
2022-09-05 02:19:21 +02:00
if ( ! controller . map ( ) )
2022-08-30 23:24:12 +02:00
return ;
if ( filename . isNull ( ) )
{
auto filenameSelect = QFileDialog : : getSaveFileName ( this , tr ( " Save map " ) , " " , tr ( " VCMI maps (*.vmap) " ) ) ;
if ( filenameSelect . isNull ( ) )
return ;
filename = filenameSelect ;
}
saveMap ( ) ;
}
2022-09-01 03:51:29 +02:00
void MainWindow : : terrainButtonClicked ( Terrain terrain )
{
2022-09-05 02:19:21 +02:00
controller . commitTerrainChange ( mapLevel , terrain ) ;
2022-09-01 03:51:29 +02:00
}
2022-09-03 06:12:07 +02:00
void MainWindow : : addGroupIntoCatalog ( const std : : string & groupName , bool staticOnly )
2022-08-31 20:05:57 +02:00
{
2022-09-03 06:12:07 +02:00
auto knownObjects = VLC - > objtypeh - > knownObjects ( ) ;
for ( auto ID : knownObjects )
2022-08-31 20:05:57 +02:00
{
2022-09-03 06:12:07 +02:00
if ( catalog . count ( ID ) )
continue ;
2022-09-02 23:04:28 +02:00
2022-09-03 06:12:07 +02:00
addGroupIntoCatalog ( groupName , staticOnly , ID ) ;
}
}
2022-09-02 23:04:28 +02:00
2022-09-03 06:12:07 +02:00
void MainWindow : : addGroupIntoCatalog ( const std : : string & groupName , bool staticOnly , int ID )
{
QStandardItem * itemGroup = nullptr ;
auto itms = objectsModel . findItems ( QString : : fromStdString ( groupName ) ) ;
if ( itms . empty ( ) )
{
itemGroup = new QStandardItem ( QString : : fromStdString ( groupName ) ) ;
objectsModel . appendRow ( itemGroup ) ;
}
else
{
itemGroup = itms . front ( ) ;
}
2022-09-02 23:04:28 +02:00
2022-09-03 06:12:07 +02:00
auto knownSubObjects = VLC - > objtypeh - > knownSubObjects ( ID ) ;
bool singleSubObject = knownSubObjects . size ( ) = = 1 ;
for ( auto secondaryID : knownSubObjects )
2022-09-02 23:04:28 +02:00
{
2022-09-03 06:12:07 +02:00
auto factory = VLC - > objtypeh - > getHandlerFor ( ID , secondaryID ) ;
auto templates = factory - > getTemplates ( ) ;
bool singleTemplate = templates . size ( ) = = 1 ;
if ( staticOnly & & ! factory - > isStaticObject ( ) )
continue ;
2022-09-02 23:04:28 +02:00
auto * itemType = new QStandardItem ( QString : : fromStdString ( factory - > subTypeName ) ) ;
2022-09-03 06:12:07 +02:00
for ( int templateId = 0 ; templateId < templates . size ( ) ; + + templateId )
2022-09-02 23:04:28 +02:00
{
2022-09-03 06:12:07 +02:00
auto templ = templates [ templateId ] ;
2022-09-03 12:49:57 +02:00
//selecting file
const std : : string & afile = templ . editorAnimationFile . empty ( ) ? templ . animationFile : templ . editorAnimationFile ;
//creating picture
QPixmap preview ( 128 , 128 ) ;
preview . fill ( QColor ( 255 , 255 , 255 ) ) ;
QPainter painter ( & preview ) ;
Animation animation ( afile ) ;
animation . preload ( ) ;
auto picture = animation . getImage ( 0 ) ;
if ( picture & & picture - > width ( ) & & picture - > height ( ) )
{
qreal xscale = qreal ( 128 ) / qreal ( picture - > width ( ) ) , yscale = qreal ( 128 ) / qreal ( picture - > height ( ) ) ;
qreal scale = std : : min ( xscale , yscale ) ;
painter . scale ( scale , scale ) ;
painter . drawImage ( QPoint ( 0 , 0 ) , * picture ) ;
}
//add parameters
2022-09-03 06:12:07 +02:00
QJsonObject data { { " id " , QJsonValue ( ID ) } ,
2022-09-02 23:04:28 +02:00
{ " subid " , QJsonValue ( secondaryID ) } ,
2022-09-03 06:12:07 +02:00
{ " template " , QJsonValue ( templateId ) } ,
2022-09-02 23:04:28 +02:00
{ " animationEditor " , QString : : fromStdString ( templ . editorAnimationFile ) } ,
2022-09-03 12:49:57 +02:00
{ " animation " , QString : : fromStdString ( templ . animationFile ) } ,
{ " preview " , jsonFromPixmap ( preview ) } } ;
2022-09-03 06:12:07 +02:00
2022-09-03 12:49:57 +02:00
//do not have extra level
2022-09-03 06:12:07 +02:00
if ( singleTemplate )
{
2022-09-03 12:49:57 +02:00
itemType - > setIcon ( QIcon ( preview ) ) ;
2022-09-03 06:12:07 +02:00
itemType - > setData ( data ) ;
}
else
{
2022-09-03 12:49:57 +02:00
auto * item = new QStandardItem ( QIcon ( preview ) , QString : : fromStdString ( templ . stringID ) ) ;
2022-09-03 06:12:07 +02:00
item - > setData ( data ) ;
itemType - > appendRow ( item ) ;
}
2022-09-02 23:04:28 +02:00
}
itemGroup - > appendRow ( itemType ) ;
2022-09-03 06:12:07 +02:00
catalog . insert ( ID ) ;
2022-09-02 23:04:28 +02:00
}
2022-09-03 06:12:07 +02:00
}
2022-09-02 23:04:28 +02:00
2022-09-03 06:12:07 +02:00
void MainWindow : : loadObjectsTree ( )
{
ui - > terrainFilterCombo - > addItem ( " " ) ;
//adding terrains
for ( auto & terrain : Terrain : : Manager : : terrains ( ) )
2022-08-31 20:05:57 +02:00
{
2022-09-03 06:12:07 +02:00
QPushButton * b = new QPushButton ( QString : : fromStdString ( terrain ) ) ;
ui - > terrainLayout - > addWidget ( b ) ;
connect ( b , & QPushButton : : clicked , this , [ this , terrain ] { terrainButtonClicked ( terrain ) ; } ) ;
2022-08-31 20:05:57 +02:00
2022-09-03 06:12:07 +02:00
//filter
ui - > terrainFilterCombo - > addItem ( QString : : fromStdString ( terrain ) ) ;
}
2022-08-31 20:05:57 +02:00
2022-09-03 06:12:07 +02:00
//add spacer to keep terrain button on the top
ui - > terrainLayout - > addItem ( new QSpacerItem ( 20 , 20 , QSizePolicy : : Minimum , QSizePolicy : : Expanding ) ) ;
2022-08-31 20:05:57 +02:00
2022-09-03 06:12:07 +02:00
if ( objectBrowser )
throw std : : runtime_error ( " object browser exists " ) ;
2022-08-31 20:05:57 +02:00
2022-09-03 06:12:07 +02:00
//model
objectsModel . setHorizontalHeaderLabels ( QStringList ( ) < < QStringLiteral ( " Type " ) ) ;
objectBrowser = new ObjectBrowser ( this ) ;
objectBrowser - > setSourceModel ( & objectsModel ) ;
objectBrowser - > setDynamicSortFilter ( false ) ;
objectBrowser - > setRecursiveFilteringEnabled ( true ) ;
ui - > treeView - > setModel ( objectBrowser ) ;
2022-09-02 23:04:28 +02:00
ui - > treeView - > setSelectionBehavior ( QAbstractItemView : : SelectItems ) ;
ui - > treeView - > setSelectionMode ( QAbstractItemView : : SingleSelection ) ;
connect ( ui - > treeView - > selectionModel ( ) , SIGNAL ( currentChanged ( const QModelIndex & , const QModelIndex & ) ) , this , SLOT ( treeViewSelected ( const QModelIndex & , const QModelIndex & ) ) ) ;
2022-09-03 06:12:07 +02:00
//adding objects
addGroupIntoCatalog ( " TOWNS " , false , Obj : : TOWN ) ;
addGroupIntoCatalog ( " TOWNS " , false , Obj : : RANDOM_TOWN ) ;
addGroupIntoCatalog ( " TOWNS " , false , Obj : : SHIPYARD ) ;
addGroupIntoCatalog ( " TOWNS " , false , Obj : : GARRISON ) ;
addGroupIntoCatalog ( " TOWNS " , false , Obj : : GARRISON2 ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : ALTAR_OF_SACRIFICE ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : ARENA ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : BLACK_MARKET ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : BORDERGUARD ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : KEYMASTER ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : BUOY ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : CAMPFIRE ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : CARTOGRAPHER ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : SWAN_POND ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : COVER_OF_DARKNESS ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : CORPSE ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : MARLETTO_TOWER ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : DERELICT_SHIP ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : FAERIE_RING ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : FLOTSAM ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : FOUNTAIN_OF_FORTUNE ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : FOUNTAIN_OF_YOUTH ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : GARDEN_OF_REVELATION ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : HILL_FORT ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : IDOL_OF_FORTUNE ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : LIBRARY_OF_ENLIGHTENMENT ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : LIGHTHOUSE ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : SCHOOL_OF_MAGIC ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : MAGIC_SPRING ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : MAGIC_WELL ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : MERCENARY_CAMP ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : MERMAID ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : MYSTICAL_GARDEN ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : OASIS ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : OBELISK ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : REDWOOD_OBSERVATORY ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : OCEAN_BOTTLE ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : PILLAR_OF_FIRE ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : STAR_AXIS ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : RALLY_FLAG ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : LEAN_TO ) ;
addGroupIntoCatalog ( " MISC " , false , Obj : : WATERING_HOLE ) ;
addGroupIntoCatalog ( " PRISON " , false , Obj : : PRISON ) ;
addGroupIntoCatalog ( " ARTIFACTS " , false , Obj : : ARTIFACT ) ;
addGroupIntoCatalog ( " ARTIFACTS " , false , Obj : : RANDOM_ART ) ;
addGroupIntoCatalog ( " ARTIFACTS " , false , Obj : : RANDOM_TREASURE_ART ) ;
addGroupIntoCatalog ( " ARTIFACTS " , false , Obj : : RANDOM_MINOR_ART ) ;
addGroupIntoCatalog ( " ARTIFACTS " , false , Obj : : RANDOM_MAJOR_ART ) ;
addGroupIntoCatalog ( " ARTIFACTS " , false , Obj : : RANDOM_RELIC_ART ) ;
addGroupIntoCatalog ( " RESOURCES " , false , Obj : : PANDORAS_BOX ) ;
addGroupIntoCatalog ( " RESOURCES " , false , Obj : : RANDOM_RESOURCE ) ;
addGroupIntoCatalog ( " RESOURCES " , false , Obj : : RESOURCE ) ;
addGroupIntoCatalog ( " RESOURCES " , false , Obj : : SEA_CHEST ) ;
addGroupIntoCatalog ( " RESOURCES " , false , Obj : : TREASURE_CHEST ) ;
addGroupIntoCatalog ( " RESOURCES " , false , Obj : : SPELL_SCROLL ) ;
addGroupIntoCatalog ( " BANKS " , false , Obj : : CREATURE_BANK ) ;
2022-09-03 12:49:57 +02:00
addGroupIntoCatalog ( " BANKS " , false , Obj : : DRAGON_UTOPIA ) ;
2022-09-03 06:12:07 +02:00
addGroupIntoCatalog ( " DWELLINGS " , false , Obj : : CREATURE_GENERATOR1 ) ;
addGroupIntoCatalog ( " DWELLINGS " , false , Obj : : CREATURE_GENERATOR2 ) ;
addGroupIntoCatalog ( " DWELLINGS " , false , Obj : : CREATURE_GENERATOR3 ) ;
addGroupIntoCatalog ( " DWELLINGS " , false , Obj : : CREATURE_GENERATOR4 ) ;
addGroupIntoCatalog ( " DWELLINGS " , false , Obj : : RANDOM_DWELLING ) ;
addGroupIntoCatalog ( " DWELLINGS " , false , Obj : : RANDOM_DWELLING_LVL ) ;
addGroupIntoCatalog ( " DWELLINGS " , false , Obj : : RANDOM_DWELLING_FACTION ) ;
addGroupIntoCatalog ( " GROUNDS " , false , Obj : : CURSED_GROUND1 ) ;
addGroupIntoCatalog ( " GROUNDS " , false , Obj : : MAGIC_PLAINS1 ) ;
addGroupIntoCatalog ( " GROUNDS " , false , Obj : : CLOVER_FIELD ) ;
addGroupIntoCatalog ( " GROUNDS " , false , Obj : : CURSED_GROUND2 ) ;
addGroupIntoCatalog ( " GROUNDS " , false , Obj : : EVIL_FOG ) ;
addGroupIntoCatalog ( " GROUNDS " , false , Obj : : FAVORABLE_WINDS ) ;
addGroupIntoCatalog ( " GROUNDS " , false , Obj : : FIERY_FIELDS ) ;
addGroupIntoCatalog ( " GROUNDS " , false , Obj : : HOLY_GROUNDS ) ;
addGroupIntoCatalog ( " GROUNDS " , false , Obj : : LUCID_POOLS ) ;
addGroupIntoCatalog ( " GROUNDS " , false , Obj : : MAGIC_CLOUDS ) ;
addGroupIntoCatalog ( " GROUNDS " , false , Obj : : MAGIC_PLAINS2 ) ;
addGroupIntoCatalog ( " GROUNDS " , false , Obj : : ROCKLANDS ) ;
addGroupIntoCatalog ( " TELEPORTS " , false , Obj : : MONOLITH_ONE_WAY_ENTRANCE ) ;
addGroupIntoCatalog ( " TELEPORTS " , false , Obj : : MONOLITH_ONE_WAY_EXIT ) ;
addGroupIntoCatalog ( " TELEPORTS " , false , Obj : : MONOLITH_TWO_WAY ) ;
addGroupIntoCatalog ( " TELEPORTS " , false , Obj : : SUBTERRANEAN_GATE ) ;
addGroupIntoCatalog ( " TELEPORTS " , false , Obj : : WHIRLPOOL ) ;
addGroupIntoCatalog ( " MINES " , false , Obj : : MINE ) ;
addGroupIntoCatalog ( " MINES " , false , Obj : : ABANDONED_MINE ) ;
addGroupIntoCatalog ( " MINES " , false , Obj : : WINDMILL ) ;
addGroupIntoCatalog ( " MINES " , false , Obj : : WATER_WHEEL ) ;
addGroupIntoCatalog ( " TRIGGERS " , false , Obj : : EVENT ) ;
addGroupIntoCatalog ( " TRIGGERS " , false , Obj : : GRAIL ) ;
addGroupIntoCatalog ( " TRIGGERS " , false , Obj : : SIGN ) ;
addGroupIntoCatalog ( " MONSTERS " , false , Obj : : MONSTER ) ;
addGroupIntoCatalog ( " MONSTERS " , false , Obj : : RANDOM_MONSTER ) ;
addGroupIntoCatalog ( " MONSTERS " , false , Obj : : RANDOM_MONSTER_L1 ) ;
addGroupIntoCatalog ( " MONSTERS " , false , Obj : : RANDOM_MONSTER_L2 ) ;
addGroupIntoCatalog ( " MONSTERS " , false , Obj : : RANDOM_MONSTER_L3 ) ;
addGroupIntoCatalog ( " MONSTERS " , false , Obj : : RANDOM_MONSTER_L4 ) ;
addGroupIntoCatalog ( " MONSTERS " , false , Obj : : RANDOM_MONSTER_L5 ) ;
addGroupIntoCatalog ( " MONSTERS " , false , Obj : : RANDOM_MONSTER_L6 ) ;
addGroupIntoCatalog ( " MONSTERS " , false , Obj : : RANDOM_MONSTER_L7 ) ;
addGroupIntoCatalog ( " QUESTS " , false , Obj : : SEER_HUT ) ;
addGroupIntoCatalog ( " QUESTS " , false , Obj : : BORDER_GATE ) ;
addGroupIntoCatalog ( " QUESTS " , false , Obj : : QUEST_GUARD ) ;
addGroupIntoCatalog ( " QUESTS " , false , Obj : : HUT_OF_MAGI ) ;
addGroupIntoCatalog ( " QUESTS " , false , Obj : : EYE_OF_MAGI ) ;
addGroupIntoCatalog ( " OBSTACLES " , true ) ;
addGroupIntoCatalog ( " OTHER " , false ) ;
/*
HERO = 34 ,
LEAN_TO = 39 ,
PYRAMID = 63 , //subtype 0
WOG_OBJECT = 63 , //subtype > 0
RANDOM_HERO = 70 ,
REFUGEE_CAMP = 78 ,
SANCTUARY = 80 ,
SCHOLAR = 81 ,
CRYPT = 84 ,
SHIPWRECK = 85 ,
SHIPWRECK_SURVIVOR = 86 ,
SHRINE_OF_MAGIC_INCANTATION = 88 ,
SHRINE_OF_MAGIC_GESTURE = 89 ,
SHRINE_OF_MAGIC_THOUGHT = 90 ,
SIRENS = 92 ,
STABLES = 94 ,
TAVERN = 95 ,
TEMPLE = 96 ,
DEN_OF_THIEVES = 97 ,
TRADING_POST = 99 ,
LEARNING_STONE = 100 ,
TREE_OF_KNOWLEDGE = 102 ,
UNIVERSITY = 104 ,
WAGON = 105 ,
WAR_MACHINE_FACTORY = 106 ,
SCHOOL_OF_WAR = 107 ,
WARRIORS_TOMB = 108 ,
WITCH_HUT = 113 ,
HOLE = 124 ,
FREELANCERS_GUILD = 213 ,
HERO_PLACEHOLDER = 214 ,
TRADING_POST_SNOW = 221 ,
*/
2022-08-31 20:05:57 +02:00
}
void MainWindow : : on_actionLevel_triggered ( )
{
2022-09-05 02:19:21 +02:00
if ( controller . map ( ) & & controller . map ( ) - > twoLevel )
2022-08-31 20:05:57 +02:00
{
mapLevel = mapLevel ? 0 : 1 ;
2022-09-05 02:19:21 +02:00
ui - > mapView - > setScene ( controller . scene ( mapLevel ) ) ;
2022-09-05 12:10:39 +02:00
ui - > minimapView - > setScene ( controller . miniScene ( mapLevel ) ) ;
2022-08-31 20:05:57 +02:00
}
}
2022-09-05 18:27:09 +02:00
void MainWindow : : on_actionUndo_triggered ( )
{
QString str ( " Undo clicked " ) ;
statusBar ( ) - > showMessage ( str , 1000 ) ;
if ( controller . map ( ) )
{
controller . undo ( ) ;
}
}
void MainWindow : : on_actionRedo_triggered ( )
{
QString str ( " Redo clicked " ) ;
statusBar ( ) - > showMessage ( str , 1000 ) ;
if ( controller . map ( ) )
{
controller . redo ( ) ;
}
}
2022-08-31 20:05:57 +02:00
void MainWindow : : on_actionPass_triggered ( bool checked )
{
2022-09-05 02:19:21 +02:00
if ( controller . map ( ) )
2022-08-31 20:05:57 +02:00
{
2022-09-05 02:19:21 +02:00
controller . scene ( 0 ) - > passabilityView . show ( checked ) ;
controller . scene ( 1 ) - > passabilityView . show ( checked ) ;
2022-08-31 20:05:57 +02:00
}
}
void MainWindow : : on_actionGrid_triggered ( bool checked )
{
2022-09-05 02:19:21 +02:00
if ( controller . map ( ) )
2022-08-31 20:05:57 +02:00
{
2022-09-05 02:19:21 +02:00
controller . scene ( 0 ) - > gridView . show ( checked ) ;
controller . scene ( 0 ) - > gridView . show ( checked ) ;
2022-08-31 20:05:57 +02:00
}
}
2022-09-03 15:43:20 +02:00
void MainWindow : : changeBrushState ( int idx )
{
}
2022-09-01 03:51:29 +02:00
void MainWindow : : on_toolBrush_clicked ( bool checked )
{
//ui->toolBrush->setChecked(false);
ui - > toolBrush2 - > setChecked ( false ) ;
ui - > toolBrush4 - > setChecked ( false ) ;
ui - > toolArea - > setChecked ( false ) ;
ui - > toolLasso - > setChecked ( false ) ;
if ( checked )
ui - > mapView - > selectionTool = MapView : : SelectionTool : : Brush ;
else
ui - > mapView - > selectionTool = MapView : : SelectionTool : : None ;
}
2022-09-03 15:43:20 +02:00
void MainWindow : : on_toolBrush2_clicked ( bool checked )
{
ui - > toolBrush - > setChecked ( false ) ;
//ui->toolBrush2->setChecked(false);
ui - > toolBrush4 - > setChecked ( false ) ;
ui - > toolArea - > setChecked ( false ) ;
ui - > toolLasso - > setChecked ( false ) ;
if ( checked )
ui - > mapView - > selectionTool = MapView : : SelectionTool : : Brush2 ;
else
ui - > mapView - > selectionTool = MapView : : SelectionTool : : None ;
}
void MainWindow : : on_toolBrush4_clicked ( bool checked )
{
ui - > toolBrush - > setChecked ( false ) ;
ui - > toolBrush2 - > setChecked ( false ) ;
//ui->toolBrush4->setChecked(false);
ui - > toolArea - > setChecked ( false ) ;
ui - > toolLasso - > setChecked ( false ) ;
if ( checked )
ui - > mapView - > selectionTool = MapView : : SelectionTool : : Brush4 ;
else
ui - > mapView - > selectionTool = MapView : : SelectionTool : : None ;
}
2022-09-01 03:51:29 +02:00
void MainWindow : : on_toolArea_clicked ( bool checked )
{
ui - > toolBrush - > setChecked ( false ) ;
ui - > toolBrush2 - > setChecked ( false ) ;
ui - > toolBrush4 - > setChecked ( false ) ;
//ui->toolArea->setChecked(false);
ui - > toolLasso - > setChecked ( false ) ;
if ( checked )
ui - > mapView - > selectionTool = MapView : : SelectionTool : : Area ;
else
ui - > mapView - > selectionTool = MapView : : SelectionTool : : None ;
}
2022-09-06 08:05:34 +02:00
void MainWindow : : on_actionErase_triggered ( )
{
on_toolErase_clicked ( ) ;
}
2022-09-02 23:04:28 +02:00
void MainWindow : : on_toolErase_clicked ( )
{
2022-09-05 02:19:21 +02:00
if ( controller . map ( ) )
2022-09-02 23:04:28 +02:00
{
2022-09-05 02:19:21 +02:00
controller . commitObjectErase ( mapLevel ) ;
2022-09-02 23:04:28 +02:00
}
}
2022-09-03 06:12:07 +02:00
void MainWindow : : preparePreview ( const QModelIndex & index , bool createNew )
2022-09-02 23:04:28 +02:00
{
2022-09-03 12:49:57 +02:00
scenePreview - > clear ( ) ;
2022-09-03 06:12:07 +02:00
auto data = objectsModel . itemFromIndex ( objectBrowser - > mapToSource ( index ) ) - > data ( ) . toJsonObject ( ) ;
2022-09-02 23:04:28 +02:00
2022-09-03 06:12:07 +02:00
if ( ! data . empty ( ) )
{
2022-09-03 12:49:57 +02:00
auto preview = data [ " preview " ] ;
if ( preview ! = QJsonValue : : Undefined )
2022-09-02 23:04:28 +02:00
{
2022-09-03 12:49:57 +02:00
QPixmap objPreview = pixmapFromJson ( preview ) ;
scenePreview - > addPixmap ( objPreview ) ;
2022-09-03 06:12:07 +02:00
auto objId = data [ " id " ] . toInt ( ) ;
auto objSubId = data [ " subid " ] . toInt ( ) ;
auto templateId = data [ " template " ] . toInt ( ) ;
2022-09-05 02:19:21 +02:00
if ( controller . discardObject ( mapLevel ) | | createNew )
2022-09-02 23:04:28 +02:00
{
2022-09-03 06:12:07 +02:00
auto factory = VLC - > objtypeh - > getHandlerFor ( objId , objSubId ) ;
auto templ = factory - > getTemplates ( ) [ templateId ] ;
2022-09-05 02:19:21 +02:00
controller . createObject ( mapLevel , factory - > create ( templ ) ) ;
2022-09-02 23:04:28 +02:00
}
}
}
}
2022-09-03 06:12:07 +02:00
void MainWindow : : treeViewSelected ( const QModelIndex & index , const QModelIndex & deselected )
{
preparePreview ( index , false ) ;
}
void MainWindow : : on_treeView_activated ( const QModelIndex & index )
{
ui - > toolBrush - > setChecked ( false ) ;
ui - > toolBrush2 - > setChecked ( false ) ;
ui - > toolBrush4 - > setChecked ( false ) ;
ui - > toolArea - > setChecked ( false ) ;
ui - > toolLasso - > setChecked ( false ) ;
ui - > mapView - > selectionTool = MapView : : SelectionTool : : None ;
preparePreview ( index , true ) ;
}
void MainWindow : : on_terrainFilterCombo_currentTextChanged ( const QString & arg1 )
{
if ( ! objectBrowser )
return ;
objectBrowser - > terrain = arg1 . isEmpty ( ) ? Terrain : : ANY : Terrain ( arg1 . toStdString ( ) ) ;
objectBrowser - > invalidate ( ) ;
objectBrowser - > sort ( 0 ) ;
}
void MainWindow : : on_filter_textChanged ( const QString & arg1 )
{
if ( ! objectBrowser )
return ;
objectBrowser - > filter = arg1 ;
objectBrowser - > invalidate ( ) ;
objectBrowser - > sort ( 0 ) ;
}
2022-09-03 14:27:06 +02:00
void MainWindow : : on_actionFill_triggered ( )
{
2022-09-05 02:19:21 +02:00
if ( ! controller . map ( ) )
2022-09-03 14:27:06 +02:00
return ;
2022-09-05 02:19:21 +02:00
controller . commitObstacleFill ( mapLevel ) ;
2022-09-03 14:27:06 +02:00
}
2022-09-04 02:12:33 +02:00
void MainWindow : : loadInspector ( CGObjectInstance * obj )
{
2022-09-08 00:59:02 +02:00
Inspector inspector ( controller . map ( ) , obj , ui - > inspectorWidget ) ;
2022-09-04 02:12:33 +02:00
inspector . updateProperties ( ) ;
}
void MainWindow : : on_inspectorWidget_itemChanged ( QTableWidgetItem * item )
{
if ( ! item - > isSelected ( ) )
return ;
int r = item - > row ( ) ;
int c = item - > column ( ) ;
if ( c < 1 )
return ;
auto * tableWidget = item - > tableWidget ( ) ;
//get identifier
auto identifier = tableWidget - > item ( 0 , 1 ) - > text ( ) ;
static_assert ( sizeof ( CGObjectInstance * ) = = sizeof ( decltype ( identifier . toLongLong ( ) ) ) ,
" Compilied for 64 bit arcitecture. Use .toInt() method " ) ;
CGObjectInstance * obj = reinterpret_cast < CGObjectInstance * > ( identifier . toLongLong ( ) ) ;
//get parameter name
auto param = tableWidget - > item ( r , c - 1 ) - > text ( ) ;
//set parameter
2022-09-08 00:59:02 +02:00
Inspector inspector ( controller . map ( ) , obj , tableWidget ) ;
2022-09-04 02:12:33 +02:00
inspector . setProperty ( param , item - > text ( ) ) ;
2022-09-05 02:19:21 +02:00
controller . commitObjectChange ( mapLevel ) ;
2022-09-04 02:12:33 +02:00
}
2022-09-04 18:16:36 +02:00
void MainWindow : : on_actionMapSettings_triggered ( )
{
2022-09-05 18:55:30 +02:00
auto settingsDialog = new MapSettings ( controller , this ) ;
settingsDialog - > setWindowModality ( Qt : : WindowModal ) ;
settingsDialog - > setModal ( true ) ;
2022-09-04 18:16:36 +02:00
}
2022-09-04 20:01:49 +02:00
void MainWindow : : on_actionPlayers_settings_triggered ( )
{
2022-09-06 03:46:22 +02:00
auto settingsDialog = new PlayerSettings ( controller , this ) ;
2022-09-05 18:55:30 +02:00
settingsDialog - > setWindowModality ( Qt : : WindowModal ) ;
settingsDialog - > setModal ( true ) ;
2022-09-04 20:01:49 +02:00
}
2022-09-05 18:27:09 +02:00
void MainWindow : : enableUndo ( bool enable )
{
ui - > actionUndo - > setEnabled ( enable ) ;
}
void MainWindow : : enableRedo ( bool enable )
{
ui - > actionRedo - > setEnabled ( enable ) ;
2022-09-06 08:05:34 +02:00
}
void MainWindow : : onSelectionMade ( int level , bool anythingSelected )
{
if ( level = = mapLevel )
{
auto info = QString : : asprintf ( " Selection on layer %s: %s " , level , anythingSelected ? " true " : " false " ) ;
setStatusMessage ( info ) ;
ui - > actionErase - > setEnabled ( anythingSelected ) ;
ui - > toolErase - > setEnabled ( anythingSelected ) ;
}
2022-09-06 08:59:28 +02:00
}
2022-09-06 23:46:33 +02:00
2022-09-06 21:16:30 +02:00
void MainWindow : : on_actionValidate_triggered ( )
{
new Validator ( controller . map ( ) , this ) ;
}