1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

Remove creations of custom animations in runtime

This commit is contained in:
Ivan Savenko 2024-06-13 10:44:56 +00:00
parent 5409936509
commit fd726523a2
10 changed files with 35 additions and 70 deletions

View File

@ -47,22 +47,16 @@ void BattleObstacleController::loadObstacleImage(const CObstacleInstance & oi)
{
AnimationPath animationName = oi.getAnimation();
if (animationsCache.count(animationName) == 0)
if (oi.obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE)
{
if (oi.obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE)
{
// obstacle uses single bitmap image for animations
auto animation = GH.renderHandler().createAnimation();
animation->setCustom(animationName.getName(), 0, 0);
animationsCache[animationName] = animation;
}
else
{
auto animation = GH.renderHandler().loadAnimation(animationName, EImageBlitMode::COLORKEY);
animationsCache[animationName] = animation;
}
// obstacle uses single bitmap image for animations
obstacleImages[oi.uniqueID] = GH.renderHandler().loadImage(animationName.toType<EResType::IMAGE>(), EImageBlitMode::COLORKEY);
}
else
{
obstacleAnimations[oi.uniqueID] = GH.renderHandler().loadAnimation(animationName, EImageBlitMode::COLORKEY);
obstacleImages[oi.uniqueID] = obstacleAnimations[oi.uniqueID]->getImage(0);
}
obstacleAnimations[oi.uniqueID] = animationsCache[animationName];
}
void BattleObstacleController::obstacleRemoved(const std::vector<ObstacleChanges> & obstacles)
@ -96,6 +90,7 @@ void BattleObstacleController::obstacleRemoved(const std::vector<ObstacleChanges
owner.stacksController->addNewAnim(new EffectAnimation(owner, animationPath, whereTo, obstacle["position"].Integer(), 0, true));
obstacleAnimations.erase(oi.id);
obstacleImages.erase(oi.id);
//so when multiple obstacles are removed, they show up one after another
owner.waitForAnimations();
}
@ -182,26 +177,22 @@ void BattleObstacleController::collectRenderableObjects(BattleRenderer & rendere
void BattleObstacleController::tick(uint32_t msPassed)
{
timePassed += msPassed / 1000.f;
int framesCount = timePassed * AnimationControls::getObstaclesSpeed();
for(auto & animation : obstacleAnimations)
{
int frameIndex = framesCount % animation.second->size(0);
obstacleImages[animation.first] = animation.second->getImage(frameIndex, 0);
}
}
std::shared_ptr<IImage> BattleObstacleController::getObstacleImage(const CObstacleInstance & oi)
{
int framesCount = timePassed * AnimationControls::getObstaclesSpeed();
std::shared_ptr<CAnimation> animation;
// obstacle is not loaded yet, don't show anything
if (obstacleAnimations.count(oi.uniqueID) == 0)
if (obstacleImages.count(oi.uniqueID) == 0)
return nullptr;
animation = obstacleAnimations[oi.uniqueID];
assert(animation);
if(animation)
{
int frameIndex = framesCount % animation->size(0);
return animation->getImage(frameIndex, 0);
}
return nullptr;
return obstacleImages[oi.uniqueID];
}
Point BattleObstacleController::getObstaclePosition(std::shared_ptr<IImage> image, const CObstacleInstance & obstacle)

View File

@ -36,12 +36,12 @@ class BattleObstacleController
/// total time, in seconds, since start of battle. Used for animating obstacles
float timePassed;
/// cached animations of all obstacles in current battle
std::map<AnimationPath, std::shared_ptr<CAnimation>> animationsCache;
/// list of all obstacles that are currently being rendered
std::map<si32, std::shared_ptr<CAnimation>> obstacleAnimations;
/// Current images for all present obstacles
std::map<si32, std::shared_ptr<IImage>> obstacleImages;
void loadObstacleImage(const CObstacleInstance & oi);
std::shared_ptr<IImage> getObstacleImage(const CObstacleInstance & oi);

View File

@ -105,21 +105,28 @@ void MapTileStorage::load(size_t index, const AnimationPath & filename, EImageBl
{
if (!filename.empty())
entry = GH.renderHandler().loadAnimation(filename, blitMode);
else
entry = GH.renderHandler().createAnimation();
}
terrainAnimations[1]->verticalFlip();
terrainAnimations[3]->verticalFlip();
if (terrainAnimations[1])
terrainAnimations[1]->verticalFlip();
terrainAnimations[2]->horizontalFlip();
terrainAnimations[3]->horizontalFlip();
if (terrainAnimations[3])
terrainAnimations[3]->verticalFlip();
if (terrainAnimations[2])
terrainAnimations[2]->horizontalFlip();
if (terrainAnimations[3])
terrainAnimations[3]->horizontalFlip();
}
std::shared_ptr<IImage> MapTileStorage::find(size_t fileIndex, size_t rotationIndex, size_t imageIndex)
{
const auto & animation = animations[fileIndex][rotationIndex];
return animation->getImage(imageIndex);
if (animation)
return animation->getImage(imageIndex);
else
return nullptr;
}
MapRendererTerrain::MapRendererTerrain()

View File

@ -113,7 +113,6 @@ CAnimation::CAnimation(const AnimationPath & Name, std::map<size_t, std::vector
logAnim->error("Animation %s failed to load", Name.getOriginalName());
}
CAnimation::CAnimation() = default;
CAnimation::~CAnimation() = default;
void CAnimation::duplicateImage(const size_t sourceGroup, const size_t sourceFrame, const size_t targetGroup)
@ -142,14 +141,6 @@ void CAnimation::duplicateImage(const size_t sourceGroup, const size_t sourceFra
source[targetGroup].push_back(clone);
}
void CAnimation::setCustom(std::string filename, size_t frame, size_t group)
{
if (source[group].size() <= frame)
source[group].resize(frame+1);
source[group][frame]["file"].String() = filename;
//FIXME: update image if already loaded
}
std::shared_ptr<IImage> CAnimation::getImage(size_t frame, size_t group, bool verbose)
{
if (!loadFrame(frame, group))

View File

@ -48,16 +48,12 @@ private:
std::shared_ptr<IImage> getImageImpl(size_t frame, size_t group=0, bool verbose=true);
public:
CAnimation(const AnimationPath & Name, std::map<size_t, std::vector <JsonNode> > layout, EImageBlitMode mode);
CAnimation();
~CAnimation();
//duplicates frame at [sourceGroup, sourceFrame] as last frame in targetGroup
//and loads it if animation is preloaded
void duplicateImage(const size_t sourceGroup, const size_t sourceFrame, const size_t targetGroup);
//add custom surface to the selected position.
void setCustom(std::string filename, size_t frame, size_t group=0);
std::shared_ptr<IImage> getImage(size_t frame, size_t group=0, bool verbose=true);
void exportBitmaps(const boost::filesystem::path & path) const;

View File

@ -40,7 +40,4 @@ public:
/// Loads animation using given path
virtual std::shared_ptr<CAnimation> loadAnimation(const AnimationPath & path, EImageBlitMode mode) = 0;
/// Creates empty CAnimation. Temporary compatibility method
virtual std::shared_ptr<CAnimation> createAnimation() = 0;
};

View File

@ -251,11 +251,6 @@ std::shared_ptr<CAnimation> RenderHandler::loadAnimation(const AnimationPath & p
return std::make_shared<CAnimation>(path, getAnimationLayout(path), mode);
}
std::shared_ptr<CAnimation> RenderHandler::createAnimation()
{
return std::make_shared<CAnimation>();
}
void RenderHandler::addImageListEntries(const EntityService * service)
{
service->forEachBase([this](const Entity * entity, bool & stop)

View File

@ -65,5 +65,4 @@ public:
std::shared_ptr<CAnimation> loadAnimation(const AnimationPath & path, EImageBlitMode mode) override;
std::shared_ptr<IImage> createImage(SDL_Surface * source) override;
std::shared_ptr<CAnimation> createAnimation() override;
};

View File

@ -711,14 +711,6 @@ void Animation::duplicateImage(const size_t sourceGroup, const size_t sourceFram
load(index, targetGroup);
}
void Animation::setCustom(std::string filename, size_t frame, size_t group)
{
if(source[group].size() <= frame)
source[group].resize(frame+1);
source[group][frame]["file"].String() = filename;
//FIXME: update image if already loaded
}
std::shared_ptr<QImage> Animation::getImage(size_t frame, size_t group, bool verbose) const
{
auto groupIter = images.find(group);

View File

@ -68,9 +68,6 @@ public:
// adjust the color of the animation, used in battle spell effects, e.g. Cloned objects
//add custom surface to the selected position.
void setCustom(std::string filename, size_t frame, size_t group = 0);
std::shared_ptr<QImage> getImage(size_t frame, size_t group = 0, bool verbose = true) const;
//all available frames