2022-09-05 02:19:21 +02:00
|
|
|
#include "mapcontroller.h"
|
|
|
|
|
|
|
|
#include "../lib/GameConstants.h"
|
|
|
|
#include "../lib/mapping/CMapService.h"
|
|
|
|
#include "../lib/mapping/CMap.h"
|
|
|
|
#include "../lib/mapping/CMapEditManager.h"
|
|
|
|
#include "../lib/Terrain.h"
|
|
|
|
#include "../lib/mapObjects/CObjectClassesHandler.h"
|
|
|
|
#include "../lib/rmg/ObstaclePlacer.h"
|
|
|
|
#include "mapview.h"
|
|
|
|
#include "scenelayer.h"
|
|
|
|
#include "maphandler.h"
|
|
|
|
#include "mainwindow.h"
|
|
|
|
#include "inspector.h"
|
|
|
|
|
|
|
|
|
2022-09-05 04:18:38 +02:00
|
|
|
MapController::MapController(MainWindow * m): main(m)
|
2022-09-05 02:19:21 +02:00
|
|
|
{
|
2022-09-05 03:50:21 +02:00
|
|
|
_scenes[0].reset(new MapScene(0));
|
|
|
|
_scenes[1].reset(new MapScene(1));
|
2022-09-05 12:10:39 +02:00
|
|
|
_miniscenes[0].reset(new MinimapScene(0));
|
|
|
|
_miniscenes[1].reset(new MinimapScene(1));
|
2022-09-06 08:05:34 +02:00
|
|
|
connectScenes();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapController::connectScenes()
|
|
|
|
{
|
|
|
|
for (int level = 0; level <= 1; level++)
|
|
|
|
{
|
|
|
|
//selections for both layers will be handled separately
|
|
|
|
QObject::connect(_scenes[level].get(), &MapScene::selected, [this, level](bool anythingSelected)
|
|
|
|
{
|
|
|
|
main->onSelectionMade(level, anythingSelected);
|
|
|
|
});
|
|
|
|
}
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
MapController::~MapController()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-09-05 18:55:30 +02:00
|
|
|
const std::unique_ptr<CMap> & MapController::getMapUniquePtr() const
|
|
|
|
{
|
|
|
|
return _map;
|
|
|
|
}
|
|
|
|
|
2022-09-05 02:19:21 +02:00
|
|
|
CMap * MapController::map()
|
|
|
|
{
|
|
|
|
return _map.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
MapHandler * MapController::mapHandler()
|
|
|
|
{
|
|
|
|
return _mapHandler.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
MapScene * MapController::scene(int level)
|
|
|
|
{
|
2022-09-05 03:50:21 +02:00
|
|
|
return _scenes[level].get();
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
|
|
|
|
2022-09-05 12:10:39 +02:00
|
|
|
MinimapScene * MapController::miniScene(int level)
|
|
|
|
{
|
|
|
|
return _miniscenes[level].get();
|
|
|
|
}
|
|
|
|
|
2022-09-05 02:19:21 +02:00
|
|
|
void MapController::setMap(std::unique_ptr<CMap> cmap)
|
|
|
|
{
|
|
|
|
_map = std::move(cmap);
|
2022-09-05 04:18:38 +02:00
|
|
|
_scenes[0].reset(new MapScene(0));
|
|
|
|
_scenes[1].reset(new MapScene(1));
|
2022-09-05 12:10:39 +02:00
|
|
|
_miniscenes[0].reset(new MinimapScene(0));
|
|
|
|
_miniscenes[1].reset(new MinimapScene(1));
|
2022-09-05 02:19:21 +02:00
|
|
|
resetMapHandler();
|
|
|
|
sceneForceUpdate();
|
2022-09-05 18:27:09 +02:00
|
|
|
|
2022-09-06 08:05:34 +02:00
|
|
|
connectScenes();
|
|
|
|
|
2022-09-05 18:27:09 +02:00
|
|
|
_map->getEditManager()->getUndoManager().setUndoCallback([this](bool allowUndo, bool allowRedo)
|
|
|
|
{
|
|
|
|
main->enableUndo(allowUndo);
|
|
|
|
main->enableRedo(allowRedo);
|
|
|
|
}
|
|
|
|
);
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapController::sceneForceUpdate()
|
|
|
|
{
|
|
|
|
_scenes[0]->updateViews();
|
2022-09-05 12:10:39 +02:00
|
|
|
_miniscenes[0]->updateViews();
|
2022-09-05 02:19:21 +02:00
|
|
|
if(_map->twoLevel)
|
2022-09-05 12:10:39 +02:00
|
|
|
{
|
2022-09-05 02:19:21 +02:00
|
|
|
_scenes[1]->updateViews();
|
2022-09-05 12:10:39 +02:00
|
|
|
_miniscenes[1]->updateViews();
|
|
|
|
}
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapController::sceneForceUpdate(int level)
|
|
|
|
{
|
|
|
|
_scenes[level]->updateViews();
|
2022-09-05 12:10:39 +02:00
|
|
|
_miniscenes[level]->updateViews();
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapController::resetMapHandler()
|
|
|
|
{
|
2022-09-06 19:15:13 +02:00
|
|
|
if(!_mapHandler)
|
|
|
|
_mapHandler.reset(new MapHandler());
|
|
|
|
_mapHandler->reset(map());
|
2022-09-05 02:19:21 +02:00
|
|
|
_scenes[0]->initialize(*this);
|
|
|
|
_scenes[1]->initialize(*this);
|
2022-09-05 12:10:39 +02:00
|
|
|
_miniscenes[0]->initialize(*this);
|
|
|
|
_miniscenes[1]->initialize(*this);
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapController::commitTerrainChange(int level, const Terrain & terrain)
|
|
|
|
{
|
|
|
|
std::vector<int3> v(_scenes[level]->selectionTerrainView.selection().begin(),
|
|
|
|
_scenes[level]->selectionTerrainView.selection().end());
|
|
|
|
if(v.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
_scenes[level]->selectionTerrainView.clear();
|
|
|
|
_scenes[level]->selectionTerrainView.draw();
|
|
|
|
|
|
|
|
_map->getEditManager()->getTerrainSelection().setSelection(v);
|
|
|
|
_map->getEditManager()->drawTerrain(terrain, &CRandomGenerator::getDefault());
|
|
|
|
|
|
|
|
for(auto & t : v)
|
|
|
|
_scenes[level]->terrainView.setDirty(t);
|
|
|
|
_scenes[level]->terrainView.draw();
|
2022-09-05 04:18:38 +02:00
|
|
|
|
2022-09-05 12:10:39 +02:00
|
|
|
_miniscenes[level]->updateViews();
|
2022-09-05 04:18:38 +02:00
|
|
|
main->mapChanged();
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapController::commitObjectErase(int level)
|
|
|
|
{
|
2022-09-06 17:54:48 +02:00
|
|
|
auto selectedObjects = _scenes[level]->selectionObjectsView.getSelection();
|
|
|
|
if (selectedObjects.size() > 1)
|
2022-09-05 02:19:21 +02:00
|
|
|
{
|
2022-09-06 17:54:48 +02:00
|
|
|
//mass erase => undo in one operation
|
|
|
|
_map->getEditManager()->removeObjects(selectedObjects);
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
2022-09-06 17:54:48 +02:00
|
|
|
else if (selectedObjects.size() == 1)
|
|
|
|
{
|
2022-09-06 21:30:16 +02:00
|
|
|
_map->getEditManager()->removeObject(*selectedObjects.begin());
|
2022-09-06 17:54:48 +02:00
|
|
|
}
|
|
|
|
else //nothing to erase - shouldn't be here
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-09-06 21:30:16 +02:00
|
|
|
for (auto obj : selectedObjects)
|
|
|
|
{
|
|
|
|
//invalidate tiles under objects
|
|
|
|
_mapHandler->invalidate(_mapHandler->geTilesUnderObject(obj));
|
|
|
|
}
|
|
|
|
|
2022-09-05 02:19:21 +02:00
|
|
|
_scenes[level]->selectionObjectsView.clear();
|
2022-09-06 19:15:13 +02:00
|
|
|
_scenes[level]->objectsView.draw();
|
|
|
|
_scenes[level]->selectionObjectsView.draw();
|
2022-09-05 04:18:38 +02:00
|
|
|
|
2022-09-05 12:10:39 +02:00
|
|
|
_miniscenes[level]->updateViews();
|
2022-09-05 04:18:38 +02:00
|
|
|
main->mapChanged();
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool MapController::discardObject(int level) const
|
|
|
|
{
|
|
|
|
_scenes[level]->selectionObjectsView.clear();
|
|
|
|
if(_scenes[level]->selectionObjectsView.newObject)
|
|
|
|
{
|
|
|
|
delete _scenes[level]->selectionObjectsView.newObject;
|
|
|
|
_scenes[level]->selectionObjectsView.newObject = nullptr;
|
|
|
|
_scenes[level]->selectionObjectsView.shift = QPoint(0, 0);
|
|
|
|
_scenes[level]->selectionObjectsView.selectionMode = 0;
|
|
|
|
_scenes[level]->selectionObjectsView.draw();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapController::createObject(int level, CGObjectInstance * obj) const
|
|
|
|
{
|
|
|
|
_scenes[level]->selectionObjectsView.newObject = obj;
|
|
|
|
_scenes[level]->selectionObjectsView.selectionMode = 2;
|
|
|
|
_scenes[level]->selectionObjectsView.draw();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapController::commitObstacleFill(int level)
|
|
|
|
{
|
|
|
|
auto selection = _scenes[level]->selectionTerrainView.selection();
|
|
|
|
if(selection.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
//split by zones
|
|
|
|
std::map<Terrain, ObstacleProxy> terrainSelected;
|
|
|
|
for(auto & t : selection)
|
|
|
|
{
|
|
|
|
auto tl = _map->getTile(t);
|
|
|
|
if(tl.blocked || tl.visitable)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
terrainSelected[tl.terType].blockedArea.add(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(auto & sel : terrainSelected)
|
|
|
|
{
|
|
|
|
sel.second.collectPossibleObstacles(sel.first);
|
|
|
|
sel.second.placeObstacles(_map.get(), CRandomGenerator::getDefault());
|
|
|
|
}
|
|
|
|
|
2022-09-06 19:15:13 +02:00
|
|
|
for(auto & t : selection)
|
|
|
|
{
|
|
|
|
_mapHandler->invalidate(t.x, t.y, t.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
_scenes[level]->selectionTerrainView.clear();
|
|
|
|
_scenes[level]->selectionTerrainView.draw();
|
|
|
|
_scenes[level]->objectsView.draw();
|
2022-09-05 04:18:38 +02:00
|
|
|
|
2022-09-05 12:10:39 +02:00
|
|
|
_miniscenes[level]->updateViews();
|
2022-09-05 04:18:38 +02:00
|
|
|
main->mapChanged();
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapController::commitObjectChange(int level)
|
|
|
|
{
|
2022-09-06 19:15:13 +02:00
|
|
|
//for(auto * o : _scenes[level]->selectionObjectsView.getSelection())
|
|
|
|
//_mapHandler->invalidate(o);
|
2022-09-05 03:50:21 +02:00
|
|
|
_scenes[level]->objectsView.draw();
|
|
|
|
_scenes[level]->selectionObjectsView.draw();
|
2022-09-05 04:18:38 +02:00
|
|
|
|
2022-09-05 12:10:39 +02:00
|
|
|
_miniscenes[level]->updateViews();
|
2022-09-05 04:18:38 +02:00
|
|
|
main->mapChanged();
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MapController::commitChangeWithoutRedraw()
|
|
|
|
{
|
|
|
|
//DO NOT REDRAW
|
2022-09-05 04:18:38 +02:00
|
|
|
main->mapChanged();
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapController::commitObjectShiftOrCreate(int level)
|
|
|
|
{
|
|
|
|
auto shift = _scenes[level]->selectionObjectsView.shift;
|
|
|
|
if(shift.isNull())
|
|
|
|
return;
|
|
|
|
|
|
|
|
for(auto * obj : _scenes[level]->selectionObjectsView.getSelection())
|
|
|
|
{
|
|
|
|
int3 pos = obj->pos;
|
|
|
|
pos.z = level;
|
|
|
|
pos.x += shift.x(); pos.y += shift.y();
|
|
|
|
|
|
|
|
if(obj == _scenes[level]->selectionObjectsView.newObject)
|
|
|
|
{
|
|
|
|
_scenes[level]->selectionObjectsView.newObject->pos = pos;
|
|
|
|
commitObjectCreate(level);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-09-06 19:15:13 +02:00
|
|
|
auto prevPositions = _mapHandler->geTilesUnderObject(obj);
|
2022-09-05 02:19:21 +02:00
|
|
|
_map->getEditManager()->moveObject(obj, pos);
|
2022-09-06 19:15:13 +02:00
|
|
|
_mapHandler->invalidate(prevPositions);
|
|
|
|
_mapHandler->invalidate(obj);
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_scenes[level]->selectionObjectsView.newObject = nullptr;
|
|
|
|
_scenes[level]->selectionObjectsView.shift = QPoint(0, 0);
|
|
|
|
_scenes[level]->selectionObjectsView.selectionMode = 0;
|
2022-09-06 19:15:13 +02:00
|
|
|
_scenes[level]->objectsView.draw();
|
|
|
|
_scenes[level]->selectionObjectsView.draw();
|
2022-09-05 04:18:38 +02:00
|
|
|
|
2022-09-05 12:10:39 +02:00
|
|
|
_miniscenes[level]->updateViews();
|
2022-09-05 04:18:38 +02:00
|
|
|
main->mapChanged();
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapController::commitObjectCreate(int level)
|
|
|
|
{
|
|
|
|
auto * newObj = _scenes[level]->selectionObjectsView.newObject;
|
|
|
|
if(!newObj)
|
|
|
|
return;
|
2022-09-06 19:15:13 +02:00
|
|
|
Initializer init(map(), newObj);
|
2022-09-05 04:18:38 +02:00
|
|
|
|
2022-09-05 20:02:50 +02:00
|
|
|
_map->getEditManager()->insertObject(newObj);
|
2022-09-06 19:15:13 +02:00
|
|
|
_mapHandler->invalidate(newObj);
|
2022-09-05 04:18:38 +02:00
|
|
|
main->mapChanged();
|
2022-09-05 02:19:21 +02:00
|
|
|
}
|
2022-09-05 18:27:09 +02:00
|
|
|
|
|
|
|
void MapController::undo()
|
|
|
|
{
|
|
|
|
_map->getEditManager()->getUndoManager().undo();
|
|
|
|
resetMapHandler();
|
|
|
|
sceneForceUpdate();
|
|
|
|
main->mapChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapController::redo()
|
|
|
|
{
|
|
|
|
_map->getEditManager()->getUndoManager().redo();
|
|
|
|
resetMapHandler();
|
|
|
|
sceneForceUpdate();
|
|
|
|
main->mapChanged();
|
2022-09-05 20:02:50 +02:00
|
|
|
}
|