Browse Source

button for more than 2 layers

Laserlicht 3 months ago
parent
commit
182100dfd1

BIN
Mods/vcmi/Content/Sprites/adventureLayers.png


+ 2 - 2
client/adventureMap/AdventureMapShortcuts.cpp

@@ -572,9 +572,9 @@ bool AdventureMapShortcuts::optionCanToggleLevel()
 	return optionSidePanelActive() && GAME->interface()->cb->getMapSize().z > 1;
 }
 
-bool AdventureMapShortcuts::optionMapLevelSurface()
+int AdventureMapShortcuts::optionMapLevel()
 {
-	return mapLevel == 0;
+	return mapLevel;
 }
 
 bool AdventureMapShortcuts::optionHeroSleeping()

+ 1 - 1
client/adventureMap/AdventureMapShortcuts.h

@@ -84,7 +84,7 @@ public:
 
 	bool optionCanViewQuests();
 	bool optionCanToggleLevel();
-	bool optionMapLevelSurface();
+	int optionMapLevel();
 	bool optionHeroSleeping();
 	bool optionHeroAwake();
 	bool optionHeroSelected();

+ 10 - 3
client/adventureMap/AdventureMapWidget.cpp

@@ -30,7 +30,9 @@
 #include "../CPlayerInterface.h"
 #include "../PlayerLocalState.h"
 
+#include "../../lib/callback/CCallback.h"
 #include "../../lib/constants/StringConstants.h"
+#include "../../lib/mapping/CMapHeader.h"
 #include "../../lib/filesystem/ResourcePath.h"
 
 AdventureMapWidget::AdventureMapWidget( std::shared_ptr<AdventureMapShortcuts> shortcuts )
@@ -402,6 +404,8 @@ void AdventureMapWidget::updateActiveStateChildden(CIntObject * widget)
 	{
 		auto container = dynamic_cast<CAdventureMapContainerWidget *>(entry);
 
+		int mapLevels = GAME->interface()->cb->getMapHeader()->mapLevels;
+
 		if (container)
 		{
 			if (container->disableCondition == "heroAwake")
@@ -410,11 +414,14 @@ void AdventureMapWidget::updateActiveStateChildden(CIntObject * widget)
 			if (container->disableCondition == "heroSleeping")
 				container->setEnabled(shortcuts->optionHeroSleeping());
 
-			if (container->disableCondition == "mapLayerSurface") // TODO: multilevel support
-				container->setEnabled(shortcuts->optionMapLevelSurface());
+			if (container->disableCondition == "mapLayerSurface")
+				container->setEnabled(shortcuts->optionMapLevel() == 0);
 
 			if (container->disableCondition == "mapLayerUnderground")
-				container->setEnabled(!shortcuts->optionMapLevelSurface());
+				container->setEnabled(shortcuts->optionMapLevel() == mapLevels - 1);
+
+			if (container->disableCondition == "mapLayerOther")
+				container->setEnabled(shortcuts->optionMapLevel() > 0 && shortcuts->optionMapLevel() < mapLevels - 1);
 
 			if (container->disableCondition == "mapViewMode")
 				container->setEnabled(shortcuts->optionInWorldView());

+ 105 - 0
client/render/AssetGenerator.cpp

@@ -56,6 +56,8 @@ void AssetGenerator::initialize()
 
 	for(int i = 1; i < 9; i++)
 		imageFiles[ImagePath::builtin("CampaignHc" + std::to_string(i) + "Image.png")] = [this, i](){ return createChroniclesCampaignImages(i);};
+	
+	animationFiles[AnimationPath::builtin("SPRITES/adventureLayersButton")] = createAdventureMapButton(ImagePath::builtin("adventureLayers.png"));
 
 	createPaletteShiftedSprites();
 }
@@ -428,5 +430,108 @@ AssetGenerator::CanvasPtr AssetGenerator::createPaletteShiftedImage(const Animat
 	canvas.draw(img, Point((32 - img->dimensions().x) / 2, (32 - img->dimensions().y) / 2));
 
 	return image;
+}
+
+void meanImage(AssetGenerator::CanvasPtr dst, std::vector<Canvas> & images)
+{
+	auto image = dst->getCanvas();
+
+	for(int x = 0; x < dst->width(); x++)
+		for(int y = 0; y < dst->height(); y++)
+		{
+			int sumR = 0;
+			int sumG = 0;
+			int sumB = 0;
+			int sumA = 0;
+			for(auto & img : images)
+			{
+				auto color = img.getPixel(Point(x, y));
+				sumR += color.r;
+				sumG += color.g;
+				sumB += color.b;
+				sumA += color.a;
+			}
+			int ct = images.size();
+			image.drawPoint(Point(x, y), ColorRGBA(sumR / ct, sumG / ct, sumB / ct, sumA / ct));
+		}
+}
+
+AssetGenerator::CanvasPtr AssetGenerator::createAdventureMapButtonClear(const PlayerColor & player) const
+{
+	auto imageNames = { "iam002", "iam003", "iam004", "iam005", "iam006", "iam007", "iam008", "iam009", "iam010", "iam011" };
+	std::vector<Canvas> images;
+
+	CanvasPtr dst = nullptr;
+	for(auto & imageName : imageNames)
+	{
+		auto animation = ENGINE->renderHandler().loadAnimation(AnimationPath::builtin(imageName), EImageBlitMode::COLORKEY);
+		animation->playerColored(player);
+		auto image = ENGINE->renderHandler().createImage(animation->getImage(2)->dimensions(), CanvasScalingPolicy::IGNORE);
+		if(!dst)
+			dst = ENGINE->renderHandler().createImage(animation->getImage(2)->dimensions(), CanvasScalingPolicy::IGNORE);
+		Canvas canvas = image->getCanvas();	
+		canvas.draw(animation->getImage(2), Point(0, 0));
+		images.push_back(image->getCanvas());
+	}
+
+	meanImage(dst, images);
+
+	return dst;
+}
+
+AssetGenerator::AnimationLayoutMap AssetGenerator::createAdventureMapButton(const ImagePath & overlay)
+{
+	std::shared_ptr<IImage> overlayImg = ENGINE->renderHandler().loadImage(ImageLocator(overlay, EImageBlitMode::OPAQUE));
+	auto overlayCanvasImg = ENGINE->renderHandler().createImage(overlayImg->dimensions(), CanvasScalingPolicy::IGNORE);
+	Canvas overlayCanvas = overlayCanvasImg->getCanvas();
+	overlayCanvas.draw(overlayImg, Point(0, 0));
+
+	AnimationLayoutMap layout;
+	for (PlayerColor color(0); color < PlayerColor::PLAYER_LIMIT; ++color)
+	{
+		auto clearButtonImg = createAdventureMapButtonClear(color);
+		for(int i = 0; i < 4; i++)
+		{
+			ImagePath spriteName = ImagePath::builtin(overlay.getOriginalName() + "Btn" + std::to_string(i) + ".png");
+			ImagePath spriteNameColor = ImagePath::builtin(overlay.getOriginalName() + "Btn" + std::to_string(i) + "-" + color.toString() + ".png");
+
+			imageFiles[spriteNameColor] = [this, overlayCanvasImg, clearButtonImg, i](){
+				auto newImg = ENGINE->renderHandler().createImage(overlayCanvasImg->dimensions(), CanvasScalingPolicy::IGNORE);
+				auto canvas = newImg->getCanvas();
+				canvas.draw(clearButtonImg, Point(0, 0));
+				switch (i)
+				{
+				case 0:
+					canvas.draw(overlayCanvasImg, Point(0, 0));
+					return newImg;
+				case 1:
+					canvas.draw(clearButtonImg, Point(1, 1));
+					canvas.draw(overlayCanvasImg, Point(1, 1));
+					canvas.drawLine(Point(0, 0), Point(newImg->width() - 1, 0), ColorRGBA(0, 0, 0), ColorRGBA(0, 0, 0));
+					canvas.drawLine(Point(0, 0), Point(0, newImg->height() - 1), ColorRGBA(0, 0, 0), ColorRGBA(0, 0, 0));
+					canvas.drawColorBlended(Rect(0, 0, newImg->width(), 4), ColorRGBA(0, 0, 0, 160));
+					canvas.drawColorBlended(Rect(0, 0, 4, newImg->height()), ColorRGBA(0, 0, 0, 160));
+					return newImg;
+				case 2:
+					canvas.drawTransparent(overlayCanvasImg->getCanvas(), Point(0, 0), 0.25);
+					return newImg;
+				default:
+					canvas.draw(overlayCanvasImg, Point(0, 0));
+					canvas.drawLine(Point(0, 0), Point(newImg->width() - 1, 0), ColorRGBA(255, 255, 255), ColorRGBA(255, 255, 255));
+					canvas.drawLine(Point(newImg->width() - 1, 0), Point(newImg->width() - 1, newImg->height() - 1), ColorRGBA(255, 255, 255), ColorRGBA(255, 255, 255));
+					canvas.drawLine(Point(newImg->width() - 1, newImg->height() - 1), Point(0, newImg->height() - 1), ColorRGBA(255, 255, 255), ColorRGBA(255, 255, 255));
+					canvas.drawLine(Point(0, newImg->height() - 1), Point(0, 0), ColorRGBA(255, 255, 255), ColorRGBA(255, 255, 255));
+					return newImg;
+				}
+			};
+
+			if(color == PlayerColor(0))
+			{
+				layout[0].push_back(ImageLocator(spriteName, EImageBlitMode::SIMPLE));
+				imageFiles[spriteName] = imageFiles[spriteNameColor];
+			}
+		}
+	}
 
+	return layout;
 }

+ 2 - 0
client/render/AssetGenerator.h

@@ -53,6 +53,8 @@ private:
 	CanvasPtr createSpellTabNone() const;
 	CanvasPtr createChroniclesCampaignImages(int chronicle) const;
 	CanvasPtr createPaletteShiftedImage(const AnimationPath & source, const std::vector<PaletteAnimation> & animation, int frameIndex, int paletteShiftCounter) const;
+	CanvasPtr createAdventureMapButtonClear(const PlayerColor & player) const;
+	AnimationLayoutMap createAdventureMapButton(const ImagePath & overlay);
 
 	void createPaletteShiftedSprites();
 	void generatePaletteShiftedAnimation(const AnimationPath & source, const std::vector<PaletteAnimation> & animation);

+ 7 - 0
client/render/Canvas.cpp

@@ -238,6 +238,13 @@ Rect Canvas::getRenderArea() const
 	return renderArea;
 }
 
+ColorRGBA Canvas::getPixel(const Point & position) const
+{
+	SDL_Color color;
+	SDL_GetRGBA(CSDL_Ext::getPixel(surface, position.x, position.y), surface->format, &color.r, &color.g, &color.b, &color.a);
+	return ColorRGBA(color.r, color.g, color.b, color.a);
+}
+
 CanvasClipRectGuard::CanvasClipRectGuard(Canvas & canvas, const Rect & rect): surf(canvas.surface)
 {
 	CSDL_Ext::getClipRect(surf, oldRect);

+ 3 - 0
client/render/Canvas.h

@@ -122,6 +122,9 @@ public:
 
 	/// get the render area
 	Rect getRenderArea() const;
+
+	/// get pixel color
+	ColorRGBA getPixel(const Point & position) const;
 };
 
 class CanvasClipRectGuard : boost::noncopyable

+ 2 - 0
client/renderSDL/RenderHandler.cpp

@@ -322,6 +322,8 @@ std::shared_ptr<SDLImageShared> RenderHandler::loadScaledImage(const ImageLocato
 		img = std::make_shared<SDLImageShared>(imagePathData, optimizeImage);
 	else if(CResourceHandler::get()->existsResource(imagePath))
 		img = std::make_shared<SDLImageShared>(imagePath, optimizeImage);
+	else if(locator.scalingFactor == 1)
+		img = std::dynamic_pointer_cast<SDLImageShared>(assetGenerator->generateImage(imagePath));
 
 	if(img)
 	{

+ 31 - 0
config/widgets/adventureMap.json

@@ -144,6 +144,22 @@
 						}
 					]
 				},
+				{
+					"type": "adventureMapContainer",
+					"hideWhen" : "mapLayerOther",
+					"area": { "top" : 0, "left": 32, "width" : 32, "height" : 32 },
+					"items" : [
+						{
+							"type": "adventureMapButton",
+							"name": "worldViewOther",
+							"image" : "adventureLayersButton",
+							"help" : "core.help.294",
+							"hotkey": "adventureToggleMapLevel",
+							"playerColored" : true,
+							"area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 }
+						}
+					]
+				},
 				{
 					"type": "adventureMapButton",
 					"name": "buttonQuestLog",
@@ -544,6 +560,21 @@
 						}
 					]
 				},
+				{
+					"type": "adventureMapContainer",
+					"hideWhen" : "mapLayerOther",
+					"area": { "top" : 343, "left": 79, "width" : 32, "height" : 32 },
+					"items" : [
+						{
+							"type": "adventureMapButton",
+							"name": "worldViewOther",
+							"image" : "adventureLayersButton",
+							"playerColored" : true,
+							"hotkey": "adventureToggleMapLevel",
+							"area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 }
+						}
+					]
+				},
 				{
 					"type": "adventureMapButton",
 					"name": "worldViewExit",