mirror of
https://github.com/vcmi/vcmi.git
synced 2025-10-08 23:22:25 +02:00
Merge pull request #6156 from Laserlicht/butgen
adventure map config button generation
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
#include "../GameInstance.h"
|
#include "../GameInstance.h"
|
||||||
#include "../gui/Shortcut.h"
|
#include "../gui/Shortcut.h"
|
||||||
#include "../mapView/MapView.h"
|
#include "../mapView/MapView.h"
|
||||||
|
#include "../render/AssetGenerator.h"
|
||||||
#include "../render/IImage.h"
|
#include "../render/IImage.h"
|
||||||
#include "../render/IRenderHandler.h"
|
#include "../render/IRenderHandler.h"
|
||||||
#include "../widgets/Buttons.h"
|
#include "../widgets/Buttons.h"
|
||||||
@@ -153,6 +154,15 @@ std::shared_ptr<CIntObject> AdventureMapWidget::buildMapButton(const JsonNode &
|
|||||||
auto help = readHintText(input["help"]);
|
auto help = readHintText(input["help"]);
|
||||||
bool playerColored = input["playerColored"].Bool();
|
bool playerColored = input["playerColored"].Bool();
|
||||||
|
|
||||||
|
if(!input["generateFromBaseImage"].isNull())
|
||||||
|
{
|
||||||
|
bool small = input["generateSmall"].Bool();
|
||||||
|
auto assetGenerator = ENGINE->renderHandler().getAssetGenerator();
|
||||||
|
auto layout = assetGenerator->createAdventureMapButton(ImagePath::fromJson(input["generateFromBaseImage"]), small);
|
||||||
|
assetGenerator->addAnimationFile(AnimationPath::builtin("SPRITES/" + input["image"].String()), layout);
|
||||||
|
ENGINE->renderHandler().updateGeneratedAssets();
|
||||||
|
}
|
||||||
|
|
||||||
auto button = std::make_shared<CButton>(position.topLeft(), image, help, 0, EShortcut::NONE, playerColored);
|
auto button = std::make_shared<CButton>(position.topLeft(), image, help, 0, EShortcut::NONE, playerColored);
|
||||||
|
|
||||||
loadButtonBorderColor(button, input["borderColor"]);
|
loadButtonBorderColor(button, input["borderColor"]);
|
||||||
|
@@ -68,7 +68,7 @@ void AssetGenerator::initialize()
|
|||||||
for(int i = 1; i < 9; i++)
|
for(int i = 1; i < 9; i++)
|
||||||
imageFiles[ImagePath::builtin("CampaignHc" + std::to_string(i) + "Image.png")] = [this, i](){ return createChroniclesCampaignImages(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"));
|
animationFiles[AnimationPath::builtin("SPRITES/adventureLayersButton")] = createAdventureMapButton(ImagePath::builtin("adventureLayers.png"), true);
|
||||||
|
|
||||||
createPaletteShiftedSprites();
|
createPaletteShiftedSprites();
|
||||||
}
|
}
|
||||||
@@ -96,6 +96,16 @@ std::map<AnimationPath, AssetGenerator::AnimationLayoutMap> AssetGenerator::gene
|
|||||||
return animationFiles;
|
return animationFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssetGenerator::addImageFile(const ImagePath & path, ImageGenerationFunctor & img)
|
||||||
|
{
|
||||||
|
imageFiles[path] = img;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetGenerator::addAnimationFile(const AnimationPath & path, AnimationLayoutMap & anim)
|
||||||
|
{
|
||||||
|
animationFiles[path] = anim;
|
||||||
|
}
|
||||||
|
|
||||||
AssetGenerator::CanvasPtr AssetGenerator::createAdventureOptionsCleanBackground() const
|
AssetGenerator::CanvasPtr AssetGenerator::createAdventureOptionsCleanBackground() const
|
||||||
{
|
{
|
||||||
auto locator = ImageLocator(ImagePath::builtin("ADVOPTBK"), EImageBlitMode::OPAQUE);
|
auto locator = ImageLocator(ImagePath::builtin("ADVOPTBK"), EImageBlitMode::OPAQUE);
|
||||||
@@ -467,30 +477,56 @@ void meanImage(AssetGenerator::CanvasPtr dst, std::vector<Canvas> & images)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetGenerator::CanvasPtr AssetGenerator::createAdventureMapButtonClear(const PlayerColor & player) const
|
AssetGenerator::CanvasPtr AssetGenerator::createAdventureMapButtonClear(const PlayerColor & player, bool small) const
|
||||||
{
|
{
|
||||||
auto imageNames = { "iam002", "iam003", "iam004", "iam005", "iam006", "iam007", "iam008", "iam009", "iam010", "iam011" };
|
|
||||||
std::vector<Canvas> images;
|
|
||||||
|
|
||||||
CanvasPtr dst = nullptr;
|
CanvasPtr dst = nullptr;
|
||||||
for(auto & imageName : imageNames)
|
if(small)
|
||||||
{
|
{
|
||||||
auto animation = ENGINE->renderHandler().loadAnimation(AnimationPath::builtin(imageName), EImageBlitMode::COLORKEY);
|
auto imageNames = { "iam002", "iam003", "iam004", "iam005", "iam006", "iam007", "iam008", "iam009", "iam010", "iam011" };
|
||||||
animation->playerColored(player);
|
std::vector<Canvas> images;
|
||||||
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);
|
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);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto animation = ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("iam001"), EImageBlitMode::COLORKEY);
|
||||||
|
animation->playerColored(player);
|
||||||
|
auto image = animation->getImage(2);
|
||||||
|
|
||||||
|
dst = ENGINE->renderHandler().createImage(image->dimensions(), CanvasScalingPolicy::IGNORE);
|
||||||
|
Canvas canvas = dst->getCanvas();
|
||||||
|
canvas.draw(image, Point(0, 0));
|
||||||
|
|
||||||
|
auto tmp = ENGINE->renderHandler().createImage(Point(5, 22), CanvasScalingPolicy::IGNORE);
|
||||||
|
std::vector<Canvas> meanImages;
|
||||||
|
auto tmpLeft = ENGINE->renderHandler().createImage(Point(5, 22), CanvasScalingPolicy::IGNORE);
|
||||||
|
tmpLeft->getCanvas().draw(image, Point(0, 0), Rect(18, 6, 5, 22));
|
||||||
|
meanImages.push_back(tmpLeft->getCanvas());
|
||||||
|
auto tmpRight = ENGINE->renderHandler().createImage(Point(5, 22), CanvasScalingPolicy::IGNORE);
|
||||||
|
tmpRight->getCanvas().draw(image, Point(0, 0), Rect(42, 6, 5, 22));
|
||||||
|
meanImages.push_back(tmpRight->getCanvas());
|
||||||
|
meanImage(tmp, meanImages);
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
canvas.draw(tmp, Point(23 + i * 5, 6));
|
||||||
|
}
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetGenerator::AnimationLayoutMap AssetGenerator::createAdventureMapButton(const ImagePath & overlay)
|
AssetGenerator::AnimationLayoutMap AssetGenerator::createAdventureMapButton(const ImagePath & overlay, bool small)
|
||||||
{
|
{
|
||||||
std::shared_ptr<IImage> overlayImg = ENGINE->renderHandler().loadImage(ImageLocator(overlay, EImageBlitMode::OPAQUE));
|
std::shared_ptr<IImage> overlayImg = ENGINE->renderHandler().loadImage(ImageLocator(overlay, EImageBlitMode::OPAQUE));
|
||||||
auto overlayCanvasImg = ENGINE->renderHandler().createImage(overlayImg->dimensions(), CanvasScalingPolicy::IGNORE);
|
auto overlayCanvasImg = ENGINE->renderHandler().createImage(overlayImg->dimensions(), CanvasScalingPolicy::IGNORE);
|
||||||
@@ -500,34 +536,36 @@ AssetGenerator::AnimationLayoutMap AssetGenerator::createAdventureMapButton(cons
|
|||||||
AnimationLayoutMap layout;
|
AnimationLayoutMap layout;
|
||||||
for (PlayerColor color(0); color < PlayerColor::PLAYER_LIMIT; ++color)
|
for (PlayerColor color(0); color < PlayerColor::PLAYER_LIMIT; ++color)
|
||||||
{
|
{
|
||||||
auto clearButtonImg = createAdventureMapButtonClear(color);
|
int offs = small ? 0 : 16;
|
||||||
|
auto clearButtonImg = createAdventureMapButtonClear(color, small);
|
||||||
for(int i = 0; i < 4; i++)
|
for(int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
ImagePath spriteName = ImagePath::builtin(overlay.getOriginalName() + "Btn" + std::to_string(i) + ".png");
|
std::string baseName = overlay.getOriginalName() + "Btn" + (small ? "Small" : "Big") + std::to_string(i);
|
||||||
ImagePath spriteNameColor = ImagePath::builtin(overlay.getOriginalName() + "Btn" + std::to_string(i) + "-" + color.toString() + ".png");
|
ImagePath spriteName = ImagePath::builtin(baseName + ".png");
|
||||||
|
ImagePath spriteNameColor = ImagePath::builtin(baseName + "-" + color.toString() + ".png");
|
||||||
|
|
||||||
imageFiles[spriteNameColor] = [overlayCanvasImg, clearButtonImg, i](){
|
imageFiles[spriteNameColor] = [overlayCanvasImg, clearButtonImg, i, offs](){
|
||||||
auto newImg = ENGINE->renderHandler().createImage(overlayCanvasImg->dimensions(), CanvasScalingPolicy::IGNORE);
|
auto newImg = ENGINE->renderHandler().createImage(clearButtonImg->dimensions(), CanvasScalingPolicy::IGNORE);
|
||||||
auto canvas = newImg->getCanvas();
|
auto canvas = newImg->getCanvas();
|
||||||
canvas.draw(clearButtonImg, Point(0, 0));
|
canvas.draw(clearButtonImg, Point(0, 0));
|
||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
canvas.draw(overlayCanvasImg, Point(0, 0));
|
canvas.draw(overlayCanvasImg, Point(offs, 0));
|
||||||
return newImg;
|
return newImg;
|
||||||
case 1:
|
case 1:
|
||||||
canvas.draw(clearButtonImg, Point(1, 1));
|
canvas.draw(clearButtonImg, Point(1, 1));
|
||||||
canvas.draw(overlayCanvasImg, Point(1, 1));
|
canvas.draw(overlayCanvasImg, Point(offs + 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(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.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, newImg->width(), 4), ColorRGBA(0, 0, 0, 160));
|
||||||
canvas.drawColorBlended(Rect(0, 0, 4, newImg->height()), ColorRGBA(0, 0, 0, 160));
|
canvas.drawColorBlended(Rect(0, 0, 4, newImg->height()), ColorRGBA(0, 0, 0, 160));
|
||||||
return newImg;
|
return newImg;
|
||||||
case 2:
|
case 2:
|
||||||
canvas.drawTransparent(overlayCanvasImg->getCanvas(), Point(0, 0), 0.25);
|
canvas.drawTransparent(overlayCanvasImg->getCanvas(), Point(offs, 0), 0.25);
|
||||||
return newImg;
|
return newImg;
|
||||||
default:
|
default:
|
||||||
canvas.draw(overlayCanvasImg, Point(0, 0));
|
canvas.draw(overlayCanvasImg, Point(offs, 0));
|
||||||
canvas.drawLine(Point(0, 0), Point(newImg->width() - 1, 0), ColorRGBA(255, 255, 255), ColorRGBA(255, 255, 255));
|
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, 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(newImg->width() - 1, newImg->height() - 1), Point(0, newImg->height() - 1), ColorRGBA(255, 255, 255), ColorRGBA(255, 255, 255));
|
||||||
|
@@ -23,6 +23,7 @@ class AssetGenerator
|
|||||||
public:
|
public:
|
||||||
using AnimationLayoutMap = std::map<size_t, std::vector<ImageLocator>>;
|
using AnimationLayoutMap = std::map<size_t, std::vector<ImageLocator>>;
|
||||||
using CanvasPtr = std::shared_ptr<CanvasImage>;
|
using CanvasPtr = std::shared_ptr<CanvasImage>;
|
||||||
|
using ImageGenerationFunctor = std::function<CanvasPtr()>;
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
@@ -31,9 +32,12 @@ public:
|
|||||||
std::map<ImagePath, std::shared_ptr<ISharedImage>> generateAllImages();
|
std::map<ImagePath, std::shared_ptr<ISharedImage>> generateAllImages();
|
||||||
std::map<AnimationPath, AnimationLayoutMap> generateAllAnimations();
|
std::map<AnimationPath, AnimationLayoutMap> generateAllAnimations();
|
||||||
|
|
||||||
private:
|
void addImageFile(const ImagePath & path, ImageGenerationFunctor & img);
|
||||||
using ImageGenerationFunctor = std::function<CanvasPtr()>;
|
void addAnimationFile(const AnimationPath & path, AnimationLayoutMap & anim);
|
||||||
|
|
||||||
|
AnimationLayoutMap createAdventureMapButton(const ImagePath & overlay, bool small);
|
||||||
|
|
||||||
|
private:
|
||||||
struct PaletteAnimation
|
struct PaletteAnimation
|
||||||
{
|
{
|
||||||
/// index of first color to cycle
|
/// index of first color to cycle
|
||||||
@@ -53,14 +57,12 @@ private:
|
|||||||
CanvasPtr createSpellTabNone() const;
|
CanvasPtr createSpellTabNone() const;
|
||||||
CanvasPtr createChroniclesCampaignImages(int chronicle) const;
|
CanvasPtr createChroniclesCampaignImages(int chronicle) const;
|
||||||
CanvasPtr createPaletteShiftedImage(const AnimationPath & source, const std::vector<PaletteAnimation> & animation, int frameIndex, int paletteShiftCounter) const;
|
CanvasPtr createPaletteShiftedImage(const AnimationPath & source, const std::vector<PaletteAnimation> & animation, int frameIndex, int paletteShiftCounter) const;
|
||||||
CanvasPtr createAdventureMapButtonClear(const PlayerColor & player) const;
|
CanvasPtr createAdventureMapButtonClear(const PlayerColor & player, bool small) const;
|
||||||
CanvasPtr createCreatureInfoPanel(int boxesAmount) const;
|
CanvasPtr createCreatureInfoPanel(int boxesAmount) const;
|
||||||
enum CreatureInfoPanelElement{ BONUS_EFFECTS, SPELL_EFFECTS, BUTTON_PANEL, COMMANDER_BACKGROUND, COMMANDER_ABILITIES };
|
enum CreatureInfoPanelElement{ BONUS_EFFECTS, SPELL_EFFECTS, BUTTON_PANEL, COMMANDER_BACKGROUND, COMMANDER_ABILITIES };
|
||||||
CanvasPtr createCreatureInfoPanelElement(CreatureInfoPanelElement element) const;
|
CanvasPtr createCreatureInfoPanelElement(CreatureInfoPanelElement element) const;
|
||||||
CanvasPtr createQuestWindow() const;
|
CanvasPtr createQuestWindow() const;
|
||||||
AnimationLayoutMap createAdventureMapButton(const ImagePath & overlay);
|
|
||||||
|
|
||||||
void createPaletteShiftedSprites();
|
void createPaletteShiftedSprites();
|
||||||
void generatePaletteShiftedAnimation(const AnimationPath & source, const std::vector<PaletteAnimation> & animation);
|
void generatePaletteShiftedAnimation(const AnimationPath & source, const std::vector<PaletteAnimation> & animation);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -22,6 +22,7 @@ class IImage;
|
|||||||
class CAnimation;
|
class CAnimation;
|
||||||
class CanvasImage;
|
class CanvasImage;
|
||||||
class SDLImageShared;
|
class SDLImageShared;
|
||||||
|
class AssetGenerator;
|
||||||
enum class EImageBlitMode : uint8_t;
|
enum class EImageBlitMode : uint8_t;
|
||||||
enum class CanvasScalingPolicy;
|
enum class CanvasScalingPolicy;
|
||||||
enum EFonts : int8_t;
|
enum EFonts : int8_t;
|
||||||
@@ -52,4 +53,8 @@ public:
|
|||||||
virtual std::shared_ptr<const IFont> loadFont(EFonts font) = 0;
|
virtual std::shared_ptr<const IFont> loadFont(EFonts font) = 0;
|
||||||
|
|
||||||
virtual void exportGeneratedAssets() = 0;
|
virtual void exportGeneratedAssets() = 0;
|
||||||
|
|
||||||
|
virtual std::shared_ptr<AssetGenerator> getAssetGenerator() = 0;
|
||||||
|
|
||||||
|
virtual void updateGeneratedAssets() = 0;
|
||||||
};
|
};
|
||||||
|
@@ -486,7 +486,7 @@ void RenderHandler::onLibraryLoadingFinished(const Services * services)
|
|||||||
{
|
{
|
||||||
assert(animationLayouts.empty());
|
assert(animationLayouts.empty());
|
||||||
assetGenerator->initialize();
|
assetGenerator->initialize();
|
||||||
animationLayouts = assetGenerator->generateAllAnimations();
|
updateGeneratedAssets();
|
||||||
|
|
||||||
addImageListEntries(services->creatures());
|
addImageListEntries(services->creatures());
|
||||||
addImageListEntries(services->heroTypes());
|
addImageListEntries(services->heroTypes());
|
||||||
@@ -540,3 +540,14 @@ void RenderHandler::exportGeneratedAssets()
|
|||||||
for (const auto & entry : assetGenerator->generateAllImages())
|
for (const auto & entry : assetGenerator->generateAllImages())
|
||||||
entry.second->exportBitmap(VCMIDirs::get().userDataPath() / "Generated" / (entry.first.getOriginalName() + ".png"), nullptr);
|
entry.second->exportBitmap(VCMIDirs::get().userDataPath() / "Generated" / (entry.first.getOriginalName() + ".png"), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<AssetGenerator> RenderHandler::getAssetGenerator()
|
||||||
|
{
|
||||||
|
return assetGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderHandler::updateGeneratedAssets()
|
||||||
|
{
|
||||||
|
for (const auto& [key, value] : assetGenerator->generateAllAnimations())
|
||||||
|
animationLayouts[key] = value;
|
||||||
|
}
|
||||||
|
@@ -28,7 +28,7 @@ class RenderHandler final : public IRenderHandler
|
|||||||
std::map<AnimationPath, AnimationLayoutMap> animationLayouts;
|
std::map<AnimationPath, AnimationLayoutMap> animationLayouts;
|
||||||
std::map<SharedImageLocator, std::weak_ptr<ScalableImageShared>> imageFiles;
|
std::map<SharedImageLocator, std::weak_ptr<ScalableImageShared>> imageFiles;
|
||||||
std::map<EFonts, std::shared_ptr<const IFont>> fonts;
|
std::map<EFonts, std::shared_ptr<const IFont>> fonts;
|
||||||
std::unique_ptr<AssetGenerator> assetGenerator;
|
std::shared_ptr<AssetGenerator> assetGenerator;
|
||||||
|
|
||||||
std::shared_ptr<CDefFile> getAnimationFile(const AnimationPath & path);
|
std::shared_ptr<CDefFile> getAnimationFile(const AnimationPath & path);
|
||||||
AnimationLayoutMap & getAnimationLayout(const AnimationPath & path, int scalingFactor, EImageBlitMode mode);
|
AnimationLayoutMap & getAnimationLayout(const AnimationPath & path, int scalingFactor, EImageBlitMode mode);
|
||||||
@@ -67,4 +67,7 @@ public:
|
|||||||
std::shared_ptr<const IFont> loadFont(EFonts font) override;
|
std::shared_ptr<const IFont> loadFont(EFonts font) override;
|
||||||
|
|
||||||
void exportGeneratedAssets() override;
|
void exportGeneratedAssets() override;
|
||||||
|
|
||||||
|
std::shared_ptr<AssetGenerator> getAssetGenerator() override;
|
||||||
|
void updateGeneratedAssets() override;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user