mirror of
https://github.com/vcmi/vcmi.git
synced 2025-09-16 09:26:28 +02:00
Merge pull request #6027 from Laserlicht/button
Adventure map button for layer > 2
This commit is contained in:
BIN
Mods/vcmi/Content/Sprites/adventureLayers.png
Normal file
BIN
Mods/vcmi/Content/Sprites/adventureLayers.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
@@ -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()
|
||||
|
@@ -84,7 +84,7 @@ public:
|
||||
|
||||
bool optionCanViewQuests();
|
||||
bool optionCanToggleLevel();
|
||||
bool optionMapLevelSurface();
|
||||
int optionMapLevel();
|
||||
bool optionHeroSleeping();
|
||||
bool optionHeroAwake();
|
||||
bool optionHeroSelected();
|
||||
|
@@ -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());
|
||||
|
@@ -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] = [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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -128,6 +128,10 @@ public:
|
||||
/// Returns true if this image is still loading and can't be used
|
||||
virtual bool isLoading() const = 0;
|
||||
|
||||
/// When disabled upscaling needs to be done in sync (e.g. because there is no 1x base image)
|
||||
virtual void setAsyncUpscale(bool on) = 0;
|
||||
virtual bool getAsyncUpscale() const = 0;
|
||||
|
||||
virtual ~ISharedImage() = default;
|
||||
|
||||
virtual const SDL_Palette * getPalette() const = 0;
|
||||
|
@@ -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)
|
||||
{
|
||||
@@ -331,6 +333,9 @@ std::shared_ptr<SDLImageShared> RenderHandler::loadScaledImage(const ImageLocato
|
||||
img = img->drawShadow((*locator.generateShadow) == SharedImageLocator::ShadowMode::SHADOW_SHEAR);
|
||||
if(isOverlay && generateOverlay && (*locator.generateOverlay) == SharedImageLocator::OverlayMode::OVERLAY_OUTLINE)
|
||||
img = img->drawOutline(Colors::WHITE, 1);
|
||||
|
||||
if(locator.scalingFactor == 1)
|
||||
img->setAsyncUpscale(false); // no base image, needs to be done in sync
|
||||
}
|
||||
|
||||
return img;
|
||||
|
@@ -271,7 +271,7 @@ std::shared_ptr<SDLImageShared> SDLImageShared::createScaled(const SDLImageShare
|
||||
self->upscalingInProgress = false;
|
||||
};
|
||||
|
||||
if(settings["video"]["asyncUpscaling"].Bool())
|
||||
if(settings["video"]["asyncUpscaling"].Bool() && from->getAsyncUpscale())
|
||||
ENGINE->async().run(scalingTask);
|
||||
else
|
||||
scalingTask();
|
||||
@@ -284,6 +284,16 @@ bool SDLImageShared::isLoading() const
|
||||
return upscalingInProgress;
|
||||
}
|
||||
|
||||
void SDLImageShared::setAsyncUpscale(bool on)
|
||||
{
|
||||
asyncUpscale = on;
|
||||
}
|
||||
|
||||
bool SDLImageShared::getAsyncUpscale() const
|
||||
{
|
||||
return asyncUpscale;
|
||||
}
|
||||
|
||||
std::shared_ptr<const ISharedImage> SDLImageShared::scaleTo(const Point & size, SDL_Palette * palette) const
|
||||
{
|
||||
if(upscalingInProgress)
|
||||
|
@@ -36,6 +36,7 @@ class SDLImageShared final : public ISharedImage, public std::enable_shared_from
|
||||
Point fullSize;
|
||||
|
||||
std::atomic_bool upscalingInProgress = false;
|
||||
bool asyncUpscale = true;
|
||||
|
||||
// Keep the original palette, in order to do color switching operation
|
||||
void savePalette();
|
||||
@@ -63,6 +64,8 @@ public:
|
||||
Rect contentRect() const override;
|
||||
|
||||
bool isLoading() const override;
|
||||
void setAsyncUpscale(bool on) override;
|
||||
bool getAsyncUpscale() const override;
|
||||
|
||||
const SDL_Palette * getPalette() const override;
|
||||
|
||||
|
@@ -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",
|
||||
@@ -513,8 +529,8 @@
|
||||
"items" : [
|
||||
{
|
||||
"type": "adventureMapButton",
|
||||
"name": "worldViewSurface",
|
||||
"image" : "IAM003.DEF",
|
||||
"name": "worldViewUnderground",
|
||||
"image" : "IAM010.DEF",
|
||||
"hotkey": "adventureToggleMapLevel",
|
||||
"playerColored" : true,
|
||||
"area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 }
|
||||
@@ -536,8 +552,23 @@
|
||||
"items" : [
|
||||
{
|
||||
"type": "adventureMapButton",
|
||||
"name": "worldViewUnderground",
|
||||
"image" : "IAM010.DEF",
|
||||
"name": "worldViewSurface",
|
||||
"image" : "IAM003.DEF",
|
||||
"playerColored" : true,
|
||||
"hotkey": "adventureToggleMapLevel",
|
||||
"area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"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 }
|
||||
|
Reference in New Issue
Block a user