mirror of
https://github.com/vcmi/vcmi.git
synced 2025-04-15 11:46:56 +02:00
Remove creations of custom animations in runtime
This commit is contained in:
parent
5409936509
commit
fd726523a2
@ -47,23 +47,17 @@ void BattleObstacleController::loadObstacleImage(const CObstacleInstance & oi)
|
|||||||
{
|
{
|
||||||
AnimationPath animationName = oi.getAnimation();
|
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
|
// obstacle uses single bitmap image for animations
|
||||||
auto animation = GH.renderHandler().createAnimation();
|
obstacleImages[oi.uniqueID] = GH.renderHandler().loadImage(animationName.toType<EResType::IMAGE>(), EImageBlitMode::COLORKEY);
|
||||||
animation->setCustom(animationName.getName(), 0, 0);
|
|
||||||
animationsCache[animationName] = animation;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto animation = GH.renderHandler().loadAnimation(animationName, EImageBlitMode::COLORKEY);
|
obstacleAnimations[oi.uniqueID] = GH.renderHandler().loadAnimation(animationName, EImageBlitMode::COLORKEY);
|
||||||
animationsCache[animationName] = animation;
|
obstacleImages[oi.uniqueID] = obstacleAnimations[oi.uniqueID]->getImage(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
obstacleAnimations[oi.uniqueID] = animationsCache[animationName];
|
|
||||||
}
|
|
||||||
|
|
||||||
void BattleObstacleController::obstacleRemoved(const std::vector<ObstacleChanges> & obstacles)
|
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));
|
owner.stacksController->addNewAnim(new EffectAnimation(owner, animationPath, whereTo, obstacle["position"].Integer(), 0, true));
|
||||||
|
|
||||||
obstacleAnimations.erase(oi.id);
|
obstacleAnimations.erase(oi.id);
|
||||||
|
obstacleImages.erase(oi.id);
|
||||||
//so when multiple obstacles are removed, they show up one after another
|
//so when multiple obstacles are removed, they show up one after another
|
||||||
owner.waitForAnimations();
|
owner.waitForAnimations();
|
||||||
}
|
}
|
||||||
@ -182,26 +177,22 @@ void BattleObstacleController::collectRenderableObjects(BattleRenderer & rendere
|
|||||||
void BattleObstacleController::tick(uint32_t msPassed)
|
void BattleObstacleController::tick(uint32_t msPassed)
|
||||||
{
|
{
|
||||||
timePassed += msPassed / 1000.f;
|
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)
|
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
|
// obstacle is not loaded yet, don't show anything
|
||||||
if (obstacleAnimations.count(oi.uniqueID) == 0)
|
if (obstacleImages.count(oi.uniqueID) == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
animation = obstacleAnimations[oi.uniqueID];
|
return obstacleImages[oi.uniqueID];
|
||||||
assert(animation);
|
|
||||||
|
|
||||||
if(animation)
|
|
||||||
{
|
|
||||||
int frameIndex = framesCount % animation->size(0);
|
|
||||||
return animation->getImage(frameIndex, 0);
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Point BattleObstacleController::getObstaclePosition(std::shared_ptr<IImage> image, const CObstacleInstance & obstacle)
|
Point BattleObstacleController::getObstaclePosition(std::shared_ptr<IImage> image, const CObstacleInstance & obstacle)
|
||||||
|
@ -36,12 +36,12 @@ class BattleObstacleController
|
|||||||
/// total time, in seconds, since start of battle. Used for animating obstacles
|
/// total time, in seconds, since start of battle. Used for animating obstacles
|
||||||
float timePassed;
|
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
|
/// list of all obstacles that are currently being rendered
|
||||||
std::map<si32, std::shared_ptr<CAnimation>> obstacleAnimations;
|
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);
|
void loadObstacleImage(const CObstacleInstance & oi);
|
||||||
|
|
||||||
std::shared_ptr<IImage> getObstacleImage(const CObstacleInstance & oi);
|
std::shared_ptr<IImage> getObstacleImage(const CObstacleInstance & oi);
|
||||||
|
@ -105,21 +105,28 @@ void MapTileStorage::load(size_t index, const AnimationPath & filename, EImageBl
|
|||||||
{
|
{
|
||||||
if (!filename.empty())
|
if (!filename.empty())
|
||||||
entry = GH.renderHandler().loadAnimation(filename, blitMode);
|
entry = GH.renderHandler().loadAnimation(filename, blitMode);
|
||||||
else
|
|
||||||
entry = GH.renderHandler().createAnimation();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (terrainAnimations[1])
|
||||||
terrainAnimations[1]->verticalFlip();
|
terrainAnimations[1]->verticalFlip();
|
||||||
|
|
||||||
|
if (terrainAnimations[3])
|
||||||
terrainAnimations[3]->verticalFlip();
|
terrainAnimations[3]->verticalFlip();
|
||||||
|
|
||||||
|
if (terrainAnimations[2])
|
||||||
terrainAnimations[2]->horizontalFlip();
|
terrainAnimations[2]->horizontalFlip();
|
||||||
|
|
||||||
|
if (terrainAnimations[3])
|
||||||
terrainAnimations[3]->horizontalFlip();
|
terrainAnimations[3]->horizontalFlip();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IImage> MapTileStorage::find(size_t fileIndex, size_t rotationIndex, size_t imageIndex)
|
std::shared_ptr<IImage> MapTileStorage::find(size_t fileIndex, size_t rotationIndex, size_t imageIndex)
|
||||||
{
|
{
|
||||||
const auto & animation = animations[fileIndex][rotationIndex];
|
const auto & animation = animations[fileIndex][rotationIndex];
|
||||||
|
if (animation)
|
||||||
return animation->getImage(imageIndex);
|
return animation->getImage(imageIndex);
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRendererTerrain::MapRendererTerrain()
|
MapRendererTerrain::MapRendererTerrain()
|
||||||
|
@ -113,7 +113,6 @@ CAnimation::CAnimation(const AnimationPath & Name, std::map<size_t, std::vector
|
|||||||
logAnim->error("Animation %s failed to load", Name.getOriginalName());
|
logAnim->error("Animation %s failed to load", Name.getOriginalName());
|
||||||
}
|
}
|
||||||
|
|
||||||
CAnimation::CAnimation() = default;
|
|
||||||
CAnimation::~CAnimation() = default;
|
CAnimation::~CAnimation() = default;
|
||||||
|
|
||||||
void CAnimation::duplicateImage(const size_t sourceGroup, const size_t sourceFrame, const size_t targetGroup)
|
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);
|
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)
|
std::shared_ptr<IImage> CAnimation::getImage(size_t frame, size_t group, bool verbose)
|
||||||
{
|
{
|
||||||
if (!loadFrame(frame, group))
|
if (!loadFrame(frame, group))
|
||||||
|
@ -48,16 +48,12 @@ private:
|
|||||||
std::shared_ptr<IImage> getImageImpl(size_t frame, size_t group=0, bool verbose=true);
|
std::shared_ptr<IImage> getImageImpl(size_t frame, size_t group=0, bool verbose=true);
|
||||||
public:
|
public:
|
||||||
CAnimation(const AnimationPath & Name, std::map<size_t, std::vector <JsonNode> > layout, EImageBlitMode mode);
|
CAnimation(const AnimationPath & Name, std::map<size_t, std::vector <JsonNode> > layout, EImageBlitMode mode);
|
||||||
CAnimation();
|
|
||||||
~CAnimation();
|
~CAnimation();
|
||||||
|
|
||||||
//duplicates frame at [sourceGroup, sourceFrame] as last frame in targetGroup
|
//duplicates frame at [sourceGroup, sourceFrame] as last frame in targetGroup
|
||||||
//and loads it if animation is preloaded
|
//and loads it if animation is preloaded
|
||||||
void duplicateImage(const size_t sourceGroup, const size_t sourceFrame, const size_t targetGroup);
|
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);
|
std::shared_ptr<IImage> getImage(size_t frame, size_t group=0, bool verbose=true);
|
||||||
|
|
||||||
void exportBitmaps(const boost::filesystem::path & path) const;
|
void exportBitmaps(const boost::filesystem::path & path) const;
|
||||||
|
@ -40,7 +40,4 @@ public:
|
|||||||
|
|
||||||
/// Loads animation using given path
|
/// Loads animation using given path
|
||||||
virtual std::shared_ptr<CAnimation> loadAnimation(const AnimationPath & path, EImageBlitMode mode) = 0;
|
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;
|
|
||||||
};
|
};
|
||||||
|
@ -251,11 +251,6 @@ std::shared_ptr<CAnimation> RenderHandler::loadAnimation(const AnimationPath & p
|
|||||||
return std::make_shared<CAnimation>(path, getAnimationLayout(path), mode);
|
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)
|
void RenderHandler::addImageListEntries(const EntityService * service)
|
||||||
{
|
{
|
||||||
service->forEachBase([this](const Entity * entity, bool & stop)
|
service->forEachBase([this](const Entity * entity, bool & stop)
|
||||||
|
@ -65,5 +65,4 @@ public:
|
|||||||
std::shared_ptr<CAnimation> loadAnimation(const AnimationPath & path, EImageBlitMode mode) override;
|
std::shared_ptr<CAnimation> loadAnimation(const AnimationPath & path, EImageBlitMode mode) override;
|
||||||
|
|
||||||
std::shared_ptr<IImage> createImage(SDL_Surface * source) override;
|
std::shared_ptr<IImage> createImage(SDL_Surface * source) override;
|
||||||
std::shared_ptr<CAnimation> createAnimation() override;
|
|
||||||
};
|
};
|
||||||
|
@ -711,14 +711,6 @@ void Animation::duplicateImage(const size_t sourceGroup, const size_t sourceFram
|
|||||||
load(index, targetGroup);
|
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
|
std::shared_ptr<QImage> Animation::getImage(size_t frame, size_t group, bool verbose) const
|
||||||
{
|
{
|
||||||
auto groupIter = images.find(group);
|
auto groupIter = images.find(group);
|
||||||
|
@ -68,9 +68,6 @@ public:
|
|||||||
|
|
||||||
// adjust the color of the animation, used in battle spell effects, e.g. Cloned objects
|
// 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;
|
std::shared_ptr<QImage> getImage(size_t frame, size_t group = 0, bool verbose = true) const;
|
||||||
|
|
||||||
//all available frames
|
//all available frames
|
||||||
|
Loading…
x
Reference in New Issue
Block a user