1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-22 22:13:35 +02:00

Objects are selectable

This commit is contained in:
nordsoft 2022-09-01 17:08:03 +04:00
parent facc29b6d7
commit 6290274371
4 changed files with 149 additions and 9 deletions

View File

@ -100,9 +100,9 @@ void MapHandler::drawTerrainTile(QPainter & painter, int x, int y, int z)
void MapHandler::initObjectRects()
{
//initializing objects / rects
for(auto & elem : map->objects)
for(const CGObjectInstance * elem : map->objects)
{
const CGObjectInstance *obj = elem;
CGObjectInstance *obj = const_cast<CGObjectInstance *>(elem);
if( !obj
|| (obj->ID==Obj::HERO && static_cast<const CGHeroInstance*>(obj)->inTownGarrison) //garrisoned hero
|| (obj->ID==Obj::BOAT && static_cast<const CGBoat*>(obj)->hero)) //boat with hero (hero graphics is used)
@ -176,7 +176,7 @@ bool MapHandler::compareObjectBlitOrder(const CGObjectInstance * a, const CGObje
return false;
}
TerrainTileObject::TerrainTileObject(const CGObjectInstance * obj_, QRect rect_, bool real_)
TerrainTileObject::TerrainTileObject(CGObjectInstance * obj_, QRect rect_, bool real_)
: obj(obj_),
rect(rect_),
real(real_)
@ -331,7 +331,7 @@ MapHandler::AnimBitmapHolder MapHandler::findObjectBitmap(const CGObjectInstance
return MapHandler::AnimBitmapHolder(bitmap);
}
const std::vector<TerrainTileObject> & MapHandler::getObjects(int x, int y, int z)
std::vector<TerrainTileObject> & MapHandler::getObjects(int x, int y, int z)
{
return ttiles[z * (sizes.x * sizes.y) + y * sizes.x + x].objects;
}

View File

@ -15,11 +15,11 @@ class PlayerColor;
struct TerrainTileObject
{
const CGObjectInstance *obj;
CGObjectInstance *obj;
QRect rect;
bool real;
TerrainTileObject(const CGObjectInstance *obj_, QRect rect_, bool visitablePos = false);
TerrainTileObject(CGObjectInstance *obj_, QRect rect_, bool visitablePos = false);
~TerrainTileObject();
};
@ -94,7 +94,7 @@ public:
/// draws all objects on current tile (higher-level logic, unlike other draw*** methods)
void drawObjects(QPainter & painter, int x, int y, int z);
void drawObject(QPainter & painter, const TerrainTileObject & object);
const std::vector<TerrainTileObject> & getObjects(int x, int y, int z);
std::vector<TerrainTileObject> & getObjects(int x, int y, int z);
//void drawObject(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, bool moving) const;
//void drawHeroFlag(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const;

View File

@ -5,7 +5,7 @@
MapView::MapView(QWidget *parent):
QGraphicsView(parent),
selectionTool(MapView::SelectionTool::Brush)
selectionTool(MapView::SelectionTool::None)
{
}
@ -75,6 +75,8 @@ void MapView::mousePressEvent(QMouseEvent *event)
switch(selectionTool)
{
case MapView::SelectionTool::Brush:
sc->selectionObjectsView.clear();
sc->selectionObjectsView.draw();
if(pressedOnSelected)
sc->selectionTerrainView.erase(tileStart);
else
@ -85,6 +87,16 @@ void MapView::mousePressEvent(QMouseEvent *event)
case MapView::SelectionTool::Area:
sc->selectionTerrainView.clear();
sc->selectionTerrainView.draw();
sc->selectionObjectsView.clear();
sc->selectionObjectsView.draw();
break;
case MapView::SelectionTool::None:
sc->selectionTerrainView.clear();
sc->selectionTerrainView.draw();
sc->selectionObjectsView.clear();
sc->selectionObjectsView.selectObjectAt(tileStart.x, tileStart.y);
sc->selectionObjectsView.draw();
break;
}
@ -103,6 +115,7 @@ MapScene::MapScene(MainWindow *parent, int l):
selectionTerrainView(parent, this),
terrainView(parent, this),
objectsView(parent, this),
selectionObjectsView(parent, this),
main(parent),
level(l)
{
@ -116,10 +129,12 @@ void MapScene::updateViews()
gridView.update();
passabilityView.update();
selectionTerrainView.update();
selectionObjectsView.update();
terrainView.show(true);
objectsView.show(true);
selectionTerrainView.show(true);
selectionObjectsView.show(true);
}
BasicView::BasicView(MainWindow * m, MapScene * s): main(m), scene(s)
@ -444,3 +459,110 @@ void ObjectsView::setDirty(const CGObjectInstance * object)
{
dirty.insert(object);
}
SelectionObjectsView::SelectionObjectsView(MainWindow * m, MapScene * s): BasicView(m, s)
{
}
void SelectionObjectsView::update()
{
auto map = main->getMap();
if(!map)
return;
selectedObjects.clear();
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
//pixmap->fill(QColor(0, 0, 0, 0));
draw();
}
void SelectionObjectsView::draw()
{
if(!pixmap)
return;
pixmap->fill(QColor(0, 0, 0, 0));
QPainter painter(pixmap.get());
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.setPen(QColor(255, 255, 255));
for(auto * obj : selectedObjects)
{
QRect bbox(obj->getPosition().x, obj->getPosition().y, 1, 1);
for(auto & t : obj->getBlockedPos())
{
QPoint topLeft(std::min(t.x, bbox.topLeft().x()), std::min(t.y, bbox.topLeft().y()));
bbox.setTopLeft(topLeft);
QPoint bottomRight(std::max(t.x, bbox.bottomRight().x()), std::max(t.y, bbox.bottomRight().y()));
bbox.setBottomRight(bottomRight);
}
painter.drawRect(bbox.x() * 32, bbox.y() * 32, bbox.width() * 32, bbox.height() * 32);
}
redraw();
}
CGObjectInstance * SelectionObjectsView::selectObjectAt(int x, int y)
{
if(!main->getMap() || !main->getMapHandler())
return nullptr;
auto & objects = main->getMapHandler()->getObjects(x, y, scene->level);
//visitable is most important
for(auto & object : objects)
{
if(!object.obj || selectedObjects.count(object.obj))
continue;
if(object.obj->visitableAt(x, y))
{
selectedObjects.insert(objects.back().obj);
return object.obj;
}
}
//if not visitable tile - try to get blocked
for(auto & object : objects)
{
if(!object.obj || selectedObjects.count(object.obj))
continue;
if(object.obj->blockingAt(x, y))
{
selectedObjects.insert(objects.back().obj);
return object.obj;
}
}
//finally, we can take any object
for(auto & object : objects)
{
if(!object.obj || selectedObjects.count(object.obj))
continue;
if(object.obj->coveringAt(x, y))
{
selectedObjects.insert(objects.back().obj);
return object.obj;
}
}
return nullptr;
}
std::set<CGObjectInstance *> SelectionObjectsView::selectObjects(int x1, int y1, int x2, int y2)
{
std::set<CGObjectInstance *> result;
//TBD
return result;
}
void SelectionObjectsView::clear()
{
selectedObjects.clear();
}

View File

@ -116,7 +116,7 @@ public:
void update() override;
void draw(bool onlyDirty = true);
void draw(bool onlyDirty = true); //TODO: implement dirty
void setDirty(int x, int y);
void setDirty(const CGObjectInstance * object);
@ -125,6 +125,23 @@ private:
std::set<const CGObjectInstance *> dirty;
};
class SelectionObjectsView: public BasicView
{
public:
SelectionObjectsView(MainWindow * m, MapScene * s);
void update() override;
void draw();
CGObjectInstance * selectObjectAt(int x, int y);
std::set<CGObjectInstance *> selectObjects(int x1, int y1, int x2, int y2);
void clear();
private:
std::set<CGObjectInstance *> selectedObjects;
};
class MapScene : public QGraphicsScene
{
public:
@ -137,6 +154,7 @@ public:
SelectionTerrainView selectionTerrainView;
TerrainView terrainView;
ObjectsView objectsView;
SelectionObjectsView selectionObjectsView;
const int level;