mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Merge pull request #6230 from Opuszek/fix_editor_display_blocking_of_objects
Rework drawing objects and fix drawing locked objects
This commit is contained in:
		| @@ -365,49 +365,39 @@ std::vector<ObjectRect> & MapHandler::getObjects(int x, int y, int z) | ||||
| 	return tileObjects[index(x, y, z)]; | ||||
| } | ||||
|  | ||||
| void MapHandler::drawObjects(QPainter & painter, int x, int y, int z, QPointF offset, const std::set<const CGObjectInstance *> & locked) | ||||
|  | ||||
|  | ||||
| void MapHandler::drawObjects(QPainter & painter, const QRectF & section, int z, std::set<const CGObjectInstance *> & locked) | ||||
| { | ||||
| 	painter.setRenderHint(QPainter::Antialiasing, false); | ||||
| 	painter.setRenderHint(QPainter::SmoothPixmapTransform, false); | ||||
| 	std::map<int3, std::set<const CGObjectInstance *>> objectMap;	//following the natural order of int3 we draw from north-west to south-east, in accordance with H3's perspective | ||||
|  | ||||
| 	for(auto & object : getObjects(x, y, z)) | ||||
|  | ||||
| 	int left = static_cast<int>(std::round(section.left()))/tileSize; | ||||
| 	int right = static_cast<int>(std::round(section.right()))/tileSize; | ||||
| 	int top = static_cast<int>(std::round(section.top()))/tileSize; | ||||
| 	int bottom = static_cast<int>(std::round(section.bottom()))/tileSize; | ||||
|  | ||||
| 	for(int x = left; x < right; ++x) | ||||
| 	{ | ||||
| 		const CGObjectInstance * obj = object.obj; | ||||
| 		if(!obj) | ||||
| 		for(int y = top; y < bottom; ++y) | ||||
| 		{ | ||||
| 			logGlobal->error("Stray map object that isn't fading"); | ||||
| 			return; | ||||
| 			for(auto & object : getObjects(x, y, z)) | ||||
| 				objectMap[object.obj->pos].insert(object.obj); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 		uint8_t animationFrame = 0; | ||||
|  | ||||
| 		auto objData = findObjectBitmap(obj, animationFrame, obj->ID == Obj::HERO ? 2 : 0); | ||||
| 		if(obj->ID == Obj::HERO && obj->tempOwner.isValidPlayer()) | ||||
| 			objData.flagBitmap = findFlagBitmap(dynamic_cast<const CGHeroInstance*>(obj), 0, obj->tempOwner, 4); | ||||
|  | ||||
| 		if(objData.objBitmap) | ||||
| 		{ | ||||
| 			auto pos = obj->anchorPos(); | ||||
|  | ||||
| 			painter.drawImage(QPoint(x * tileSize - offset.x(), y * tileSize - offset.y()), *objData.objBitmap, object.rect, Qt::AutoColor | Qt::NoOpaqueDetection); | ||||
|  | ||||
| 			if(locked.count(obj)) | ||||
| 			{ | ||||
| 				painter.setCompositionMode(QPainter::CompositionMode_DestinationIn); | ||||
| 				painter.fillRect(x * tileSize, y * tileSize, object.rect.width(), object.rect.height(), Qt::Dense4Pattern); | ||||
| 				painter.setCompositionMode(QPainter::CompositionMode_SourceOver); | ||||
| 			} | ||||
|  | ||||
| 			if(objData.flagBitmap) | ||||
| 			{ | ||||
| 				if(x == pos.x && y == pos.y) | ||||
| 					painter.drawImage(QPoint((x - 2) * tileSize - offset.x(), (y - 1) * tileSize - offset.y()), *objData.flagBitmap); | ||||
| 			} | ||||
| 		} | ||||
| 	for (auto const& objectsOnTile : objectMap) | ||||
| 	{ | ||||
| 		auto tile = objectsOnTile.first; | ||||
| 		auto objects = objectsOnTile.second; | ||||
| 		for (const CGObjectInstance * object : objects) | ||||
| 			drawObjectAt(painter, object, tile.x, tile.y, section.topLeft(), locked.count(object)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void MapHandler::drawObjectAt(QPainter & painter, const CGObjectInstance * obj, int x, int y, QPointF offset) | ||||
| void MapHandler::drawObjectAt(QPainter & painter, const CGObjectInstance * obj, int x, int y, QPointF offset, bool locked) | ||||
| { | ||||
| 	if (!obj) | ||||
| 	{ | ||||
| @@ -423,10 +413,19 @@ void MapHandler::drawObjectAt(QPainter & painter, const CGObjectInstance * obj, | ||||
|  | ||||
| 	if (objData.objBitmap) | ||||
| 	{ | ||||
| 		painter.drawImage(QPoint((x + 1) * tileSize - objData.objBitmap->width() - offset.x(), (y + 1) * tileSize - objData.objBitmap->height() - offset.y()), *objData.objBitmap); | ||||
| 		QPoint point((x + 1) * tileSize - (objData.objBitmap->width() + offset.x()), (y + 1) * tileSize - (objData.objBitmap->height() + offset.y())); | ||||
| 		QRect rect(point, QSize(objData.objBitmap->width(), objData.objBitmap->height())); | ||||
| 		painter.drawImage(rect, *objData.objBitmap); | ||||
|  | ||||
| 		if (locked) | ||||
| 		{ | ||||
| 			painter.setCompositionMode(QPainter::CompositionMode_DestinationIn); | ||||
| 			painter.fillRect(rect, Qt::Dense4Pattern); | ||||
| 			painter.setCompositionMode(QPainter::CompositionMode_SourceOver); | ||||
| 		} | ||||
|  | ||||
| 		if (objData.flagBitmap) | ||||
| 			painter.drawImage(QPoint((x + 1) * tileSize - objData.objBitmap->width() - offset.x(), (y + 1) * tileSize - objData.objBitmap->height() - offset.y()), *objData.flagBitmap); | ||||
| 			painter.drawImage(point, *objData.flagBitmap); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -111,8 +111,8 @@ public: | ||||
| 	std::set<int3> addObject(const CGObjectInstance * object); | ||||
| 	 | ||||
| 	/// draws all objects on current tile (higher-level logic, unlike other draw*** methods) | ||||
| 	void drawObjects(QPainter & painter, int x, int y, int z, QPointF offset, const std::set<const CGObjectInstance *> & locked); | ||||
| 	void drawObjectAt(QPainter & painter, const CGObjectInstance * object, int x, int y, QPointF offset); | ||||
| 	void drawObjects(QPainter & painter, const QRectF & section, int z, std::set<const CGObjectInstance *> & locked); | ||||
| 	void drawObjectAt(QPainter & painter, const CGObjectInstance * object, int x, int y, QPointF offset, bool locked = false); | ||||
| 	 | ||||
| 	void drawMinimapTile(QPainter & painter, int x, int y, int z); | ||||
|  | ||||
|   | ||||
| @@ -545,28 +545,13 @@ ObjectsLayer::ObjectsLayer(MapSceneBase * s): AbstractViewportLayer(s) | ||||
|  | ||||
| QGraphicsItem * ObjectsLayer::draw(const QRectF & section) | ||||
| { | ||||
| 	int left = toInt(section.left()); | ||||
| 	int right = toInt(section.right()); | ||||
| 	int top = toInt(section.top()); | ||||
| 	int bottom = toInt(section.bottom()); | ||||
| 	QPixmap pixmap(toInt(section.width()), toInt(section.height())); | ||||
| 	pixmap.fill(Qt::transparent); | ||||
|  | ||||
| 	if (isShown) | ||||
| 	{ | ||||
| 		QPainter painter(&pixmap); | ||||
|  | ||||
| 		QPointF offset = section.topLeft(); | ||||
|  | ||||
| 		int margin = 2;		// margin is necessary to properly display flags on heroes on a border between two sections | ||||
|  | ||||
| 		for(int x = (left - margin)/tileSize; x < (right + margin)/tileSize; ++x) | ||||
| 		{ | ||||
| 			for(int y = (top - margin)/tileSize; y < (bottom + margin)/tileSize; ++y) | ||||
| 			{ | ||||
| 				handler->drawObjects(painter, x, y, scene->level, offset, lockedObjects); | ||||
| 			} | ||||
| 		} | ||||
| 		handler->drawObjects(painter, section, scene->level, lockedObjects); | ||||
| 	} | ||||
|  | ||||
| 	QGraphicsPixmapItem * result = scene->addPixmap(pixmap); | ||||
| @@ -586,11 +571,14 @@ void ObjectsLayer::setLockObject(const CGObjectInstance * object, bool lock) | ||||
| 		lockedObjects.insert(object); | ||||
| 	else | ||||
| 		lockedObjects.erase(object); | ||||
| 	QRectF area = getObjectArea(object); | ||||
| 	redraw({area}); | ||||
| } | ||||
|  | ||||
| void ObjectsLayer::unlockAll() | ||||
| { | ||||
| 	lockedObjects.clear(); | ||||
| 	redraw(); | ||||
| } | ||||
|  | ||||
| SelectionObjectsLayer::SelectionObjectsLayer(MapSceneBase * s): AbstractViewportLayer(s), newObject(nullptr) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user