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:
parent
facc29b6d7
commit
6290274371
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user