mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
Implemented basic hero movement animation & object fade-out
This commit is contained in:
parent
4501036a04
commit
7cf00ba87d
@ -53,7 +53,6 @@ set(client_SRCS
|
|||||||
render/CAnimation.cpp
|
render/CAnimation.cpp
|
||||||
render/CBitmapHandler.cpp
|
render/CBitmapHandler.cpp
|
||||||
render/CDefFile.cpp
|
render/CDefFile.cpp
|
||||||
render/CFadeAnimation.cpp
|
|
||||||
render/Canvas.cpp
|
render/Canvas.cpp
|
||||||
render/ColorFilter.cpp
|
render/ColorFilter.cpp
|
||||||
render/Colors.cpp
|
render/Colors.cpp
|
||||||
@ -169,7 +168,6 @@ set(client_HEADERS
|
|||||||
render/CAnimation.h
|
render/CAnimation.h
|
||||||
render/CBitmapHandler.h
|
render/CBitmapHandler.h
|
||||||
render/CDefFile.h
|
render/CDefFile.h
|
||||||
render/CFadeAnimation.h
|
|
||||||
render/Canvas.h
|
render/Canvas.h
|
||||||
render/ColorFilter.h
|
render/ColorFilter.h
|
||||||
render/Colors.h
|
render/Colors.h
|
||||||
|
@ -457,22 +457,10 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
adventureInt->centerOn(hero); //actualizing screen pos
|
|
||||||
adventureInt->minimap->redraw();
|
adventureInt->minimap->redraw();
|
||||||
adventureInt->heroList->redraw();
|
adventureInt->heroList->redraw();
|
||||||
|
|
||||||
auto waitFrame = [&]()
|
CGI->mh->waitForOngoingAnimations();
|
||||||
{
|
|
||||||
int frameNumber = GH.mainFPSmng->getFrameNumber();
|
|
||||||
|
|
||||||
auto unlockPim = vstd::makeUnlockGuard(*pim);
|
|
||||||
while(frameNumber == GH.mainFPSmng->getFrameNumber())
|
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
|
|
||||||
};
|
|
||||||
|
|
||||||
//main moving
|
|
||||||
while (CGI->mh->hasActiveAnimations())
|
|
||||||
waitFrame(); //for animation purposes
|
|
||||||
|
|
||||||
//finishing move
|
//finishing move
|
||||||
hero->isStanding = true;
|
hero->isStanding = true;
|
||||||
|
@ -344,6 +344,8 @@ void ApplyFirstClientNetPackVisitor::visitChangeObjPos(ChangeObjPos & pack)
|
|||||||
CGObjectInstance *obj = gs.getObjInstance(pack.objid);
|
CGObjectInstance *obj = gs.getObjInstance(pack.objid);
|
||||||
if(CGI->mh)
|
if(CGI->mh)
|
||||||
CGI->mh->onObjectFadeOut(obj);
|
CGI->mh->onObjectFadeOut(obj);
|
||||||
|
|
||||||
|
CGI->mh->waitForOngoingAnimations();
|
||||||
}
|
}
|
||||||
void ApplyClientNetPackVisitor::visitChangeObjPos(ChangeObjPos & pack)
|
void ApplyClientNetPackVisitor::visitChangeObjPos(ChangeObjPos & pack)
|
||||||
{
|
{
|
||||||
@ -351,6 +353,7 @@ void ApplyClientNetPackVisitor::visitChangeObjPos(ChangeObjPos & pack)
|
|||||||
if(CGI->mh)
|
if(CGI->mh)
|
||||||
CGI->mh->onObjectFadeIn(obj);
|
CGI->mh->onObjectFadeIn(obj);
|
||||||
|
|
||||||
|
CGI->mh->waitForOngoingAnimations();
|
||||||
cl.invalidatePaths();
|
cl.invalidatePaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,6 +429,8 @@ void ApplyFirstClientNetPackVisitor::visitRemoveObject(RemoveObject & pack)
|
|||||||
if(gs.isVisible(o, i->first) || (!cl.getPlayerState(i->first)->human && o->ID == Obj::HERO && o->tempOwner != i->first))
|
if(gs.isVisible(o, i->first) || (!cl.getPlayerState(i->first)->human && o->ID == Obj::HERO && o->tempOwner != i->first))
|
||||||
i->second->objectRemoved(o);
|
i->second->objectRemoved(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CGI->mh->waitForOngoingAnimations();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitRemoveObject(RemoveObject & pack)
|
void ApplyClientNetPackVisitor::visitRemoveObject(RemoveObject & pack)
|
||||||
@ -938,7 +943,6 @@ void ApplyClientNetPackVisitor::visitOpenWindow(OpenWindow & pack)
|
|||||||
callInterfaceIfPresent(cl, obj1->tempOwner, &IGameEventsReceiver::showTavernWindow, obj2);
|
callInterfaceIfPresent(cl, obj1->tempOwner, &IGameEventsReceiver::showTavernWindow, obj2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitCenterView(CenterView & pack)
|
void ApplyClientNetPackVisitor::visitCenterView(CenterView & pack)
|
||||||
@ -959,6 +963,7 @@ void ApplyClientNetPackVisitor::visitNewObject(NewObject & pack)
|
|||||||
if(gs.isVisible(obj, i->first))
|
if(gs.isVisible(obj, i->first))
|
||||||
i->second->newObject(obj);
|
i->second->newObject(obj);
|
||||||
}
|
}
|
||||||
|
CGI->mh->waitForOngoingAnimations();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyClientNetPackVisitor::visitSetAvailableArtifacts(SetAvailableArtifacts & pack)
|
void ApplyClientNetPackVisitor::visitSetAvailableArtifacts(SetAvailableArtifacts & pack)
|
||||||
|
@ -319,7 +319,7 @@ void CAdvMapInt::fsleepWake()
|
|||||||
void CAdvMapInt::fmoveHero()
|
void CAdvMapInt::fmoveHero()
|
||||||
{
|
{
|
||||||
const CGHeroInstance *h = curHero();
|
const CGHeroInstance *h = curHero();
|
||||||
if (!h || !LOCPLINT->paths.hasPath(h) || CGI->mh->hasActiveAnimations())
|
if (!h || !LOCPLINT->paths.hasPath(h) || CGI->mh->hasOngoingAnimations())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LOCPLINT->moveHero(h, LOCPLINT->paths.getPath(h));
|
LOCPLINT->moveHero(h, LOCPLINT->paths.getPath(h));
|
||||||
@ -833,7 +833,7 @@ void CAdvMapInt::keyPressed(const SDL_Keycode & key)
|
|||||||
if(!h || !isActive())
|
if(!h || !isActive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (CGI->mh->hasActiveAnimations())
|
if (CGI->mh->hasOngoingAnimations())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(*direction == Point(0,0))
|
if(*direction == Point(0,0))
|
||||||
@ -1138,7 +1138,7 @@ void CAdvMapInt::tileLClicked(const int3 &mapPos)
|
|||||||
if(LOCPLINT->paths.hasPath(currentHero) &&
|
if(LOCPLINT->paths.hasPath(currentHero) &&
|
||||||
LOCPLINT->paths.getPath(currentHero).endPos() == mapPos)//we'll be moving
|
LOCPLINT->paths.getPath(currentHero).endPos() == mapPos)//we'll be moving
|
||||||
{
|
{
|
||||||
if(!CGI->mh->hasActiveAnimations())
|
if(!CGI->mh->hasOngoingAnimations())
|
||||||
LOCPLINT->moveHero(currentHero, LOCPLINT->paths.getPath(currentHero));
|
LOCPLINT->moveHero(currentHero, LOCPLINT->paths.getPath(currentHero));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include "../gui/CursorHandler.h"
|
#include "../gui/CursorHandler.h"
|
||||||
#include "../gui/CGuiHandler.h"
|
#include "../gui/CGuiHandler.h"
|
||||||
#include "../render/CAnimation.h"
|
#include "../render/CAnimation.h"
|
||||||
#include "../render/CFadeAnimation.h"
|
|
||||||
#include "../render/IImage.h"
|
#include "../render/IImage.h"
|
||||||
#include "../renderSDL/SDL_Extensions.h"
|
#include "../renderSDL/SDL_Extensions.h"
|
||||||
#include "../widgets/TextControls.h"
|
#include "../widgets/TextControls.h"
|
||||||
@ -35,9 +34,7 @@
|
|||||||
#define ADVOPT (conf.go()->ac)
|
#define ADVOPT (conf.go()->ac)
|
||||||
|
|
||||||
CTerrainRect::CTerrainRect()
|
CTerrainRect::CTerrainRect()
|
||||||
: fadeSurface(nullptr)
|
: curHoveredTile(-1, -1, -1)
|
||||||
, fadeAnim(std::make_shared<CFadeAnimation>())
|
|
||||||
, curHoveredTile(-1, -1, -1)
|
|
||||||
, isSwiping(false)
|
, isSwiping(false)
|
||||||
{
|
{
|
||||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||||
@ -51,20 +48,14 @@ CTerrainRect::CTerrainRect()
|
|||||||
renderer = std::make_shared<MapView>( Point(0,0), pos.dimensions() );
|
renderer = std::make_shared<MapView>( Point(0,0), pos.dimensions() );
|
||||||
}
|
}
|
||||||
|
|
||||||
CTerrainRect::~CTerrainRect()
|
|
||||||
{
|
|
||||||
if(fadeSurface)
|
|
||||||
SDL_FreeSurface(fadeSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CTerrainRect::setViewCenter(const int3 &coordinates)
|
void CTerrainRect::setViewCenter(const int3 &coordinates)
|
||||||
{
|
{
|
||||||
renderer->setViewCenter(coordinates);
|
renderer->getController()->setViewCenter(coordinates);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTerrainRect::setViewCenter(const Point & position, int level)
|
void CTerrainRect::setViewCenter(const Point & position, int level)
|
||||||
{
|
{
|
||||||
renderer->setViewCenter(position, level);
|
renderer->getController()->setViewCenter(position, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTerrainRect::deactivate()
|
void CTerrainRect::deactivate()
|
||||||
@ -220,30 +211,17 @@ Rect CTerrainRect::visibleTilesArea()
|
|||||||
|
|
||||||
void CTerrainRect::fadeFromCurrentView()
|
void CTerrainRect::fadeFromCurrentView()
|
||||||
{
|
{
|
||||||
if (!ADVOPT.screenFading)
|
assert(0);//TODO
|
||||||
return;
|
|
||||||
if (adventureInt->mode == EAdvMapMode::WORLD_VIEW)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!fadeSurface)
|
|
||||||
fadeSurface = CSDL_Ext::newSurface(pos.w, pos.h);
|
|
||||||
CSDL_Ext::blitSurface(screen, fadeSurface, Point(0,0));
|
|
||||||
fadeAnim->init(CFadeAnimation::EMode::OUT, fadeSurface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTerrainRect::setLevel(int level)
|
void CTerrainRect::setLevel(int level)
|
||||||
{
|
{
|
||||||
renderer->setViewCenter(renderer->getModel()->getMapViewCenter(), level);
|
renderer->getController()->setViewCenter(renderer->getModel()->getMapViewCenter(), level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTerrainRect::moveViewBy(const Point & delta)
|
void CTerrainRect::moveViewBy(const Point & delta)
|
||||||
{
|
{
|
||||||
renderer->setViewCenter(renderer->getModel()->getMapViewCenter() + delta, getLevel());
|
renderer->getController()->setViewCenter(renderer->getModel()->getMapViewCenter() + delta, getLevel());
|
||||||
}
|
|
||||||
|
|
||||||
int3 CTerrainRect::getTileCenter()
|
|
||||||
{
|
|
||||||
return renderer->getModel()->getTileCenter();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Point CTerrainRect::getViewCenter()
|
Point CTerrainRect::getViewCenter()
|
||||||
@ -258,5 +236,5 @@ int CTerrainRect::getLevel()
|
|||||||
|
|
||||||
void CTerrainRect::setTileSize(int sizePixels)
|
void CTerrainRect::setTileSize(int sizePixels)
|
||||||
{
|
{
|
||||||
renderer->setTileSize(Point(sizePixels, sizePixels));
|
renderer->getController()->setTileSize(Point(sizePixels, sizePixels));
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ VCMI_LIB_NAMESPACE_BEGIN
|
|||||||
struct CGPath;
|
struct CGPath;
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|
||||||
class CFadeAnimation;
|
|
||||||
class MapView;
|
class MapView;
|
||||||
|
|
||||||
/// Holds information about which tiles of the terrain are shown/not shown at the screen
|
/// Holds information about which tiles of the terrain are shown/not shown at the screen
|
||||||
@ -24,9 +23,6 @@ class CTerrainRect : public CIntObject
|
|||||||
{
|
{
|
||||||
std::shared_ptr<MapView> renderer;
|
std::shared_ptr<MapView> renderer;
|
||||||
|
|
||||||
SDL_Surface * fadeSurface;
|
|
||||||
std::shared_ptr<CFadeAnimation> fadeAnim;
|
|
||||||
|
|
||||||
Point swipeInitialViewPos;
|
Point swipeInitialViewPos;
|
||||||
Point swipeInitialRealPos;
|
Point swipeInitialRealPos;
|
||||||
bool isSwiping;
|
bool isSwiping;
|
||||||
@ -48,7 +44,6 @@ class CTerrainRect : public CIntObject
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
CTerrainRect();
|
CTerrainRect();
|
||||||
~CTerrainRect();
|
|
||||||
|
|
||||||
void moveViewBy(const Point & delta);
|
void moveViewBy(const Point & delta);
|
||||||
void setViewCenter(const int3 & coordinates);
|
void setViewCenter(const int3 & coordinates);
|
||||||
@ -56,7 +51,6 @@ public:
|
|||||||
void setLevel(int level);
|
void setLevel(int level);
|
||||||
void setTileSize(int sizePixels);
|
void setTileSize(int sizePixels);
|
||||||
|
|
||||||
int3 getTileCenter();
|
|
||||||
Point getViewCenter();
|
Point getViewCenter();
|
||||||
int getLevel();
|
int getLevel();
|
||||||
|
|
||||||
|
@ -182,8 +182,8 @@ void MapRendererRiver::renderTile(const IMapRendererContext & context, Canvas &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRendererRoad::MapRendererRoad():
|
MapRendererRoad::MapRendererRoad()
|
||||||
storage(VLC->roadTypeHandler->objects.size())
|
: storage(VLC->roadTypeHandler->objects.size())
|
||||||
{
|
{
|
||||||
for(const auto & road : VLC->roadTypeHandler->objects)
|
for(const auto & road : VLC->roadTypeHandler->objects)
|
||||||
storage.load(road->getIndex(), road->tilesFilename);
|
storage.load(road->getIndex(), road->tilesFilename);
|
||||||
@ -191,19 +191,19 @@ MapRendererRoad::MapRendererRoad():
|
|||||||
|
|
||||||
void MapRendererRoad::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)
|
void MapRendererRoad::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)
|
||||||
{
|
{
|
||||||
const int3 coordinatesAbove = coordinates - int3(0,1,0);
|
const int3 coordinatesAbove = coordinates - int3(0, 1, 0);
|
||||||
|
|
||||||
if (context.isInMap(coordinatesAbove))
|
if(context.isInMap(coordinatesAbove))
|
||||||
{
|
{
|
||||||
const TerrainTile & mapTileAbove = context.getMapTile(coordinatesAbove);
|
const TerrainTile & mapTileAbove = context.getMapTile(coordinatesAbove);
|
||||||
if (mapTileAbove.roadType->getId() != Road::NO_ROAD)
|
if(mapTileAbove.roadType->getId() != Road::NO_ROAD)
|
||||||
{
|
{
|
||||||
int32_t terrainIndex = mapTileAbove.roadType->getIndex();
|
int32_t terrainIndex = mapTileAbove.roadType->getIndex();
|
||||||
int32_t imageIndex = mapTileAbove.roadDir;
|
int32_t imageIndex = mapTileAbove.roadDir;
|
||||||
int32_t rotationIndex = (mapTileAbove.extTileFlags >> 4) % 4;
|
int32_t rotationIndex = (mapTileAbove.extTileFlags >> 4) % 4;
|
||||||
|
|
||||||
const auto & image = storage.find(terrainIndex, rotationIndex, imageIndex);
|
const auto & image = storage.find(terrainIndex, rotationIndex, imageIndex);
|
||||||
target.draw(image, Point(0,0), Rect(0, 16, 32, 16));
|
target.draw(image, Point(0, 0), Rect(0, 16, 32, 16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ void MapRendererRoad::renderTile(const IMapRendererContext & context, Canvas & t
|
|||||||
int32_t rotationIndex = (mapTile.extTileFlags >> 4) % 4;
|
int32_t rotationIndex = (mapTile.extTileFlags >> 4) % 4;
|
||||||
|
|
||||||
const auto & image = storage.find(terrainIndex, rotationIndex, imageIndex);
|
const auto & image = storage.find(terrainIndex, rotationIndex, imageIndex);
|
||||||
target.draw(image, Point(0,16), Rect(0, 0, 32, 16));
|
target.draw(image, Point(0, 16), Rect(0, 0, 32, 16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,31 +231,31 @@ size_t MapRendererBorder::getIndexForTile(const IMapRendererContext & context, c
|
|||||||
|
|
||||||
int3 size = context.getMapSize();
|
int3 size = context.getMapSize();
|
||||||
|
|
||||||
if (tile.x < -1 || tile.x > size.x || tile.y < -1 || tile.y > size.y)
|
if(tile.x < -1 || tile.x > size.x || tile.y < -1 || tile.y > size.y)
|
||||||
return std::abs(tile.x) % 4 + 4*(std::abs(tile.y) % 4);
|
return std::abs(tile.x) % 4 + 4 * (std::abs(tile.y) % 4);
|
||||||
|
|
||||||
if (tile.x == -1 && tile.y == -1)
|
if(tile.x == -1 && tile.y == -1)
|
||||||
return 16;
|
return 16;
|
||||||
|
|
||||||
if (tile.x == size.x && tile.y == -1)
|
if(tile.x == size.x && tile.y == -1)
|
||||||
return 17;
|
return 17;
|
||||||
|
|
||||||
if (tile.x == size.x && tile.y == size.y)
|
if(tile.x == size.x && tile.y == size.y)
|
||||||
return 18;
|
return 18;
|
||||||
|
|
||||||
if (tile.x == -1 && tile.y == size.y)
|
if(tile.x == -1 && tile.y == size.y)
|
||||||
return 19;
|
return 19;
|
||||||
|
|
||||||
if (tile.y == -1)
|
if(tile.y == -1)
|
||||||
return 20 + (tile.x % 4);
|
return 20 + (tile.x % 4);
|
||||||
|
|
||||||
if (tile.x == size.x)
|
if(tile.x == size.x)
|
||||||
return 24 + (tile.y % 4);
|
return 24 + (tile.y % 4);
|
||||||
|
|
||||||
if (tile.y == size.y)
|
if(tile.y == size.y)
|
||||||
return 28 + (tile.x % 4);
|
return 28 + (tile.x % 4);
|
||||||
|
|
||||||
if (tile.x == -1)
|
if(tile.x == -1)
|
||||||
return 32 + (tile.y % 4);
|
return 32 + (tile.y % 4);
|
||||||
|
|
||||||
//else - visible area, no renderable border
|
//else - visible area, no renderable border
|
||||||
@ -266,7 +266,7 @@ size_t MapRendererBorder::getIndexForTile(const IMapRendererContext & context, c
|
|||||||
void MapRendererBorder::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)
|
void MapRendererBorder::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)
|
||||||
{
|
{
|
||||||
const auto & image = animation->getImage(getIndexForTile(context, coordinates));
|
const auto & image = animation->getImage(getIndexForTile(context, coordinates));
|
||||||
target.draw(image, Point(0,0));
|
target.draw(image, Point(0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRendererFow::MapRendererFow()
|
MapRendererFow::MapRendererFow()
|
||||||
@ -278,7 +278,7 @@ MapRendererFow::MapRendererFow()
|
|||||||
|
|
||||||
static const std::vector<int> rotations = {22, 15, 2, 13, 12, 16, 28, 17, 20, 19, 7, 24, 26, 25, 30, 32, 27};
|
static const std::vector<int> rotations = {22, 15, 2, 13, 12, 16, 28, 17, 20, 19, 7, 24, 26, 25, 30, 32, 27};
|
||||||
|
|
||||||
size_t size = fogOfWarPartialHide->size(0);//group size after next rotation
|
size_t size = fogOfWarPartialHide->size(0); //group size after next rotation
|
||||||
|
|
||||||
for(const int rotation : rotations)
|
for(const int rotation : rotations)
|
||||||
{
|
{
|
||||||
@ -295,8 +295,8 @@ void MapRendererFow::renderTile(const IMapRendererContext & context, Canvas & ta
|
|||||||
|
|
||||||
const NeighborTilesInfo neighborInfo(context, coordinates);
|
const NeighborTilesInfo neighborInfo(context, coordinates);
|
||||||
|
|
||||||
int retBitmapID = neighborInfo.getBitmapID();// >=0 -> partial hide, <0 - full hide
|
int retBitmapID = neighborInfo.getBitmapID(); // >=0 -> partial hide, <0 - full hide
|
||||||
if (retBitmapID < 0)
|
if(retBitmapID < 0)
|
||||||
{
|
{
|
||||||
// generate a number that is predefined for each tile,
|
// generate a number that is predefined for each tile,
|
||||||
// but appears random to break visible pattern in large areas of fow
|
// but appears random to break visible pattern in large areas of fow
|
||||||
@ -304,15 +304,15 @@ void MapRendererFow::renderTile(const IMapRendererContext & context, Canvas & ta
|
|||||||
size_t pseudorandomNumber = ((coordinates.x * 997) ^ (coordinates.y * 1009)) / 101;
|
size_t pseudorandomNumber = ((coordinates.x * 997) ^ (coordinates.y * 1009)) / 101;
|
||||||
size_t imageIndex = pseudorandomNumber % fogOfWarFullHide->size();
|
size_t imageIndex = pseudorandomNumber % fogOfWarFullHide->size();
|
||||||
|
|
||||||
target.draw(fogOfWarFullHide->getImage(imageIndex), Point(0,0));
|
target.draw(fogOfWarFullHide->getImage(imageIndex), Point(0, 0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
target.draw(fogOfWarPartialHide->getImage(retBitmapID), Point(0,0));
|
target.draw(fogOfWarPartialHide->getImage(retBitmapID), Point(0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<CAnimation> MapRendererObjects::getAnimation(const CGObjectInstance* obj)
|
std::shared_ptr<CAnimation> MapRendererObjects::getAnimation(const CGObjectInstance * obj)
|
||||||
{
|
{
|
||||||
const auto & info = obj->appearance;
|
const auto & info = obj->appearance;
|
||||||
|
|
||||||
@ -333,36 +333,26 @@ std::shared_ptr<CAnimation> MapRendererObjects::getAnimation(const CGObjectInsta
|
|||||||
|
|
||||||
std::shared_ptr<CAnimation> MapRendererObjects::getAnimation(const std::string & filename, bool generateMovementGroups)
|
std::shared_ptr<CAnimation> MapRendererObjects::getAnimation(const std::string & filename, bool generateMovementGroups)
|
||||||
{
|
{
|
||||||
if (animations.count(filename))
|
if(animations.count(filename))
|
||||||
return animations[filename];
|
return animations[filename];
|
||||||
|
|
||||||
auto ret = std::make_shared<CAnimation>(filename);
|
auto ret = std::make_shared<CAnimation>(filename);
|
||||||
animations[filename] = ret;
|
animations[filename] = ret;
|
||||||
ret->preload();
|
ret->preload();
|
||||||
|
|
||||||
if (generateMovementGroups)
|
if(generateMovementGroups)
|
||||||
{
|
{
|
||||||
ret->createFlippedGroup(1,13);
|
ret->createFlippedGroup(1, 13);
|
||||||
ret->createFlippedGroup(2,14);
|
ret->createFlippedGroup(2, 14);
|
||||||
ret->createFlippedGroup(3,15);
|
ret->createFlippedGroup(3, 15);
|
||||||
|
|
||||||
ret->createFlippedGroup(6,10);
|
ret->createFlippedGroup(6, 10);
|
||||||
ret->createFlippedGroup(7,11);
|
ret->createFlippedGroup(7, 11);
|
||||||
ret->createFlippedGroup(8,12);
|
ret->createFlippedGroup(8, 12);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRendererObjects::MapRendererObjects(const IMapRendererContext & context)
|
|
||||||
{
|
|
||||||
auto mapSize = context.getMapSize();
|
|
||||||
|
|
||||||
objects.resize(boost::extents[mapSize.z][mapSize.x][mapSize.y]);
|
|
||||||
|
|
||||||
for(const auto & obj : context.getAllObjects())
|
|
||||||
onObjectInstantAdd(context, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<CAnimation> MapRendererObjects::getFlagAnimation(const CGObjectInstance* obj)
|
std::shared_ptr<CAnimation> MapRendererObjects::getFlagAnimation(const CGObjectInstance* obj)
|
||||||
{
|
{
|
||||||
//TODO: relocate to config file?
|
//TODO: relocate to config file?
|
||||||
@ -401,7 +391,7 @@ std::shared_ptr<IImage> MapRendererObjects::getImage(const IMapRendererContext &
|
|||||||
if(!animation)
|
if(!animation)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
size_t groupIndex = getAnimationGroup(context, obj);
|
size_t groupIndex = context.objectGroupIndex(obj->id);
|
||||||
|
|
||||||
if(animation->size(groupIndex) == 0)
|
if(animation->size(groupIndex) == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -412,52 +402,37 @@ std::shared_ptr<IImage> MapRendererObjects::getImage(const IMapRendererContext &
|
|||||||
return animation->getImage(frameIndex, groupIndex);
|
return animation->getImage(frameIndex, groupIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t MapRendererObjects::getAnimationGroup(const IMapRendererContext & context, const CGObjectInstance * obj) const
|
void MapRendererObjects::renderImage(const IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * object, const std::shared_ptr<IImage>& image)
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
//static const std::vector<size_t> moveGroups = {99, 10, 5, 6, 7, 8, 9, 12, 11};
|
|
||||||
static const std::vector<size_t> idleGroups = {99, 13, 0, 1, 2, 3, 4, 15, 14};
|
|
||||||
|
|
||||||
if(obj->ID == Obj::HERO)
|
|
||||||
{
|
|
||||||
const auto * hero = dynamic_cast<const CGHeroInstance *>(obj);
|
|
||||||
return idleGroups[hero->moveDir];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(obj->ID == Obj::BOAT)
|
|
||||||
{
|
|
||||||
const auto * boat = dynamic_cast<const CGBoat *>(obj);
|
|
||||||
return idleGroups[boat->direction];
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapRendererObjects::renderImage(Canvas & target, const int3 & coordinates, const CGObjectInstance * object, const std::shared_ptr<IImage>& image)
|
|
||||||
{
|
{
|
||||||
if(!image)
|
if(!image)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
uint8_t transparency = static_cast<uint8_t>(std::round(255 * context.objectTransparency(object->id)));
|
||||||
|
|
||||||
|
if (transparency == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
image->setAlpha(transparency);
|
||||||
image->setFlagColor(object->tempOwner);
|
image->setFlagColor(object->tempOwner);
|
||||||
|
|
||||||
int3 offsetTiles(object->getPosition() - coordinates);
|
Point offsetPixels = context.objectImageOffset(object->id, coordinates);
|
||||||
|
|
||||||
Point offsetPixels(offsetTiles.x * 32, offsetTiles.y * 32);
|
if ( offsetPixels.x < image->dimensions().x && offsetPixels.y < image->dimensions().y)
|
||||||
Point imagePos = image->dimensions() - offsetPixels - Point(32, 32);
|
{
|
||||||
Point tileDimensions(32, 32);
|
Point imagePos = image->dimensions() - offsetPixels - Point(32, 32);
|
||||||
|
target.draw(image, Point(0, 0), Rect(imagePos, Point(32,32)));
|
||||||
target.draw(image, Point(0, 0), Rect(imagePos, tileDimensions));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapRendererObjects::renderObject(const IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance* instance)
|
void MapRendererObjects::renderObject(const IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance* instance)
|
||||||
{
|
{
|
||||||
renderImage(target, coordinates, instance, getImage(context, instance, getAnimation(instance)));
|
renderImage(context, target, coordinates, instance, getImage(context, instance, getAnimation(instance)));
|
||||||
renderImage(target, coordinates, instance, getImage(context, instance, getFlagAnimation(instance)));
|
renderImage(context, target, coordinates, instance, getImage(context, instance, getFlagAnimation(instance)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapRendererObjects::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)
|
void MapRendererObjects::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)
|
||||||
{
|
{
|
||||||
for(const auto & objectID : objects[coordinates.z][coordinates.x][coordinates.y])
|
for(const auto & objectID : context.getObjects(coordinates))
|
||||||
{
|
{
|
||||||
const auto * objectInstance = context.getObject(objectID);
|
const auto * objectInstance = context.getObject(objectID);
|
||||||
|
|
||||||
@ -472,61 +447,6 @@ void MapRendererObjects::renderTile(const IMapRendererContext & context, Canvas
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapRendererObjects::onObjectInstantAdd(const IMapRendererContext & context, const CGObjectInstance * obj)
|
|
||||||
{
|
|
||||||
if(!obj)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(obj->ID == Obj::HERO && dynamic_cast<const CGHeroInstance *>(obj)->inTownGarrison)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(obj->ID == Obj::BOAT && dynamic_cast<const CGBoat *>(obj)->hero)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::shared_ptr<CAnimation> animation = getAnimation(obj);
|
|
||||||
|
|
||||||
//no animation at all, e.g. Event
|
|
||||||
if(!animation)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//empty animation. Illegal?
|
|
||||||
assert(animation->size(0) > 0);
|
|
||||||
if(animation->size(0) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto image = animation->getImage(0, 0);
|
|
||||||
|
|
||||||
int imageWidthTiles = (image->width() + 31) / 32;
|
|
||||||
int imageHeightTiles = (image->height() + 31) / 32;
|
|
||||||
|
|
||||||
int objectWidth = std::min(obj->getWidth(), imageWidthTiles);
|
|
||||||
int objectHeight = std::min(obj->getHeight(), imageHeightTiles);
|
|
||||||
|
|
||||||
for(int fx = 0; fx < objectWidth; ++fx)
|
|
||||||
{
|
|
||||||
for(int fy = 0; fy < objectHeight; ++fy)
|
|
||||||
{
|
|
||||||
int3 currTile(obj->pos.x - fx, obj->pos.y - fy, obj->pos.z);
|
|
||||||
|
|
||||||
if(context.isInMap(currTile) && obj->coveringAt(currTile.x, currTile.y))
|
|
||||||
{
|
|
||||||
auto & container = objects[currTile.z][currTile.x][currTile.y];
|
|
||||||
|
|
||||||
container.push_back(obj->id);
|
|
||||||
boost::range::sort(container, MapObjectsSorter(context));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapRendererObjects::onObjectInstantRemove(const IMapRendererContext & context, const CGObjectInstance * object)
|
|
||||||
{
|
|
||||||
for(int z = 0; z < context.getMapSize().z; z++)
|
|
||||||
for(int x = 0; x < context.getMapSize().x; x++)
|
|
||||||
for(int y = 0; y < context.getMapSize().y; y++)
|
|
||||||
vstd::erase(objects[z][x][y], object->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapRendererDebugGrid::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)
|
void MapRendererDebugGrid::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)
|
||||||
{
|
{
|
||||||
if(context.showGrid())
|
if(context.showGrid())
|
||||||
@ -625,14 +545,9 @@ void MapRendererPath::renderTile(const IMapRendererContext & context, Canvas & t
|
|||||||
renderImageCross(target, reachableToday, iter->coord);
|
renderImageCross(target, reachableToday, iter->coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRenderer::MapRenderer(const IMapRendererContext & context)
|
|
||||||
: rendererObjects(context)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapRenderer::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)
|
void MapRenderer::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)
|
||||||
{
|
{
|
||||||
if (!context.isInMap(coordinates))
|
if(!context.isInMap(coordinates))
|
||||||
{
|
{
|
||||||
rendererBorder.renderTile(context, target, coordinates);
|
rendererBorder.renderTile(context, target, coordinates);
|
||||||
return;
|
return;
|
||||||
@ -640,7 +555,7 @@ void MapRenderer::renderTile(const IMapRendererContext & context, Canvas & targe
|
|||||||
|
|
||||||
const NeighborTilesInfo neighborInfo(context, coordinates);
|
const NeighborTilesInfo neighborInfo(context, coordinates);
|
||||||
|
|
||||||
if (neighborInfo.areAllHidden())
|
if(neighborInfo.areAllHidden())
|
||||||
{
|
{
|
||||||
rendererFow.renderTile(context, target, coordinates);
|
rendererFow.renderTile(context, target, coordinates);
|
||||||
}
|
}
|
||||||
@ -652,8 +567,8 @@ void MapRenderer::renderTile(const IMapRendererContext & context, Canvas & targe
|
|||||||
rendererObjects.renderTile(context, target, coordinates);
|
rendererObjects.renderTile(context, target, coordinates);
|
||||||
rendererPath.renderTile(context, target, coordinates);
|
rendererPath.renderTile(context, target, coordinates);
|
||||||
|
|
||||||
if (!context.isVisible(coordinates))
|
if(!context.isVisible(coordinates))
|
||||||
rendererFow.renderTile(context, target, coordinates);
|
rendererFow.renderTile(context, target, coordinates);
|
||||||
}
|
}
|
||||||
rendererDebugGrid.renderTile(context, target,coordinates);
|
rendererDebugGrid.renderTile(context, target, coordinates);
|
||||||
}
|
}
|
||||||
|
@ -72,12 +72,8 @@ public:
|
|||||||
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
|
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
|
||||||
};
|
};
|
||||||
|
|
||||||
class MapRendererObjects : public IMapObjectObserver
|
class MapRendererObjects
|
||||||
{
|
{
|
||||||
using MapObject = ObjectInstanceID;
|
|
||||||
using MapTile = std::vector<MapObject>;
|
|
||||||
|
|
||||||
boost::multi_array<MapTile, 3> objects;
|
|
||||||
std::map<std::string, std::shared_ptr<CAnimation>> animations;
|
std::map<std::string, std::shared_ptr<CAnimation>> animations;
|
||||||
|
|
||||||
std::shared_ptr<CAnimation> getFlagAnimation(const CGObjectInstance * obj);
|
std::shared_ptr<CAnimation> getFlagAnimation(const CGObjectInstance * obj);
|
||||||
@ -85,17 +81,12 @@ class MapRendererObjects : public IMapObjectObserver
|
|||||||
std::shared_ptr<CAnimation> getAnimation(const std::string & filename, bool generateMovementGroups);
|
std::shared_ptr<CAnimation> getAnimation(const std::string & filename, bool generateMovementGroups);
|
||||||
|
|
||||||
std::shared_ptr<IImage> getImage(const IMapRendererContext & context, const CGObjectInstance * obj, const std::shared_ptr<CAnimation> & animation) const;
|
std::shared_ptr<IImage> getImage(const IMapRendererContext & context, const CGObjectInstance * obj, const std::shared_ptr<CAnimation> & animation) const;
|
||||||
size_t getAnimationGroup(const IMapRendererContext & context, const CGObjectInstance * obj) const;
|
|
||||||
|
|
||||||
void renderImage(Canvas & target, const int3 & coordinates, const CGObjectInstance * object, const std::shared_ptr<IImage> & image);
|
void renderImage(const IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * object, const std::shared_ptr<IImage> & image);
|
||||||
void renderObject(const IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * obj);
|
void renderObject(const IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * obj);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MapRendererObjects(const IMapRendererContext & context);
|
|
||||||
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
|
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
|
||||||
|
|
||||||
void onObjectInstantAdd(const IMapRendererContext & context, const CGObjectInstance * object) final override;
|
|
||||||
void onObjectInstantRemove(const IMapRendererContext & context, const CGObjectInstance * object) final override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MapRendererBorder
|
class MapRendererBorder
|
||||||
@ -150,7 +141,5 @@ class MapRenderer
|
|||||||
MapRendererDebugGrid rendererDebugGrid;
|
MapRendererDebugGrid rendererDebugGrid;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MapRenderer(const IMapRendererContext & context);
|
|
||||||
|
|
||||||
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
|
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
|
||||||
};
|
};
|
||||||
|
@ -15,9 +15,9 @@ VCMI_LIB_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
class int3;
|
class int3;
|
||||||
class Point;
|
class Point;
|
||||||
class ObjectInstanceID;
|
|
||||||
class CGObjectInstance;
|
class CGObjectInstance;
|
||||||
class CGHeroInstance;
|
class CGHeroInstance;
|
||||||
|
class ObjectInstanceID;
|
||||||
struct TerrainTile;
|
struct TerrainTile;
|
||||||
struct CGPath;
|
struct CGPath;
|
||||||
|
|
||||||
@ -26,9 +26,10 @@ VCMI_LIB_NAMESPACE_END
|
|||||||
class IMapRendererContext
|
class IMapRendererContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~IMapRendererContext() = default;
|
using MapObject = ObjectInstanceID;
|
||||||
|
using MapObjectsList = std::vector<MapObject>;
|
||||||
|
|
||||||
using ObjectsVector = std::vector<ConstTransitivePtr<CGObjectInstance>>;
|
virtual ~IMapRendererContext() = default;
|
||||||
|
|
||||||
/// returns dimensions of current map
|
/// returns dimensions of current map
|
||||||
virtual int3 getMapSize() const = 0;
|
virtual int3 getMapSize() const = 0;
|
||||||
@ -39,8 +40,8 @@ public:
|
|||||||
/// returns tile by selected coordinates. Coordinates MUST be valid
|
/// returns tile by selected coordinates. Coordinates MUST be valid
|
||||||
virtual const TerrainTile & getMapTile(const int3 & coordinates) const = 0;
|
virtual const TerrainTile & getMapTile(const int3 & coordinates) const = 0;
|
||||||
|
|
||||||
/// returns vector of all objects present on current map
|
/// returns all objects visible on specified tile
|
||||||
virtual ObjectsVector getAllObjects() const = 0;
|
virtual const MapObjectsList & getObjects(const int3 & coordinates) const = 0;
|
||||||
|
|
||||||
/// returns specific object by ID, or nullptr if not found
|
/// returns specific object by ID, or nullptr if not found
|
||||||
virtual const CGObjectInstance * getObject(ObjectInstanceID objectID) const = 0;
|
virtual const CGObjectInstance * getObject(ObjectInstanceID objectID) const = 0;
|
||||||
@ -51,6 +52,12 @@ public:
|
|||||||
/// returns true if specified tile is visible in current context
|
/// returns true if specified tile is visible in current context
|
||||||
virtual bool isVisible(const int3 & coordinates) const = 0;
|
virtual bool isVisible(const int3 & coordinates) const = 0;
|
||||||
|
|
||||||
|
virtual size_t objectGroupIndex(ObjectInstanceID objectID) const = 0;
|
||||||
|
virtual Point objectImageOffset(ObjectInstanceID objectID, const int3 & coordinates) const = 0;
|
||||||
|
|
||||||
|
/// returns object animation transparency. IF set to 0, object will not be visible
|
||||||
|
virtual double objectTransparency(ObjectInstanceID objectID) const = 0;
|
||||||
|
|
||||||
/// returns how long should each frame of animation be visible, in milliseconds
|
/// returns how long should each frame of animation be visible, in milliseconds
|
||||||
virtual uint32_t getAnimationPeriod() const = 0;
|
virtual uint32_t getAnimationPeriod() const = 0;
|
||||||
|
|
||||||
@ -70,24 +77,26 @@ public:
|
|||||||
IMapObjectObserver();
|
IMapObjectObserver();
|
||||||
virtual ~IMapObjectObserver();
|
virtual ~IMapObjectObserver();
|
||||||
|
|
||||||
|
virtual bool hasOngoingAnimations() = 0;
|
||||||
|
|
||||||
/// Plays fade-in animation and adds object to map
|
/// Plays fade-in animation and adds object to map
|
||||||
virtual void onObjectFadeIn(const IMapRendererContext & context, const CGObjectInstance * obj) {}
|
virtual void onObjectFadeIn(const CGObjectInstance * obj) {}
|
||||||
|
|
||||||
/// Plays fade-out animation and removed object from map
|
/// Plays fade-out animation and removed object from map
|
||||||
virtual void onObjectFadeOut(const IMapRendererContext & context, const CGObjectInstance * obj) {}
|
virtual void onObjectFadeOut(const CGObjectInstance * obj) {}
|
||||||
|
|
||||||
/// Adds object to map instantly, with no animation
|
/// Adds object to map instantly, with no animation
|
||||||
virtual void onObjectInstantAdd(const IMapRendererContext & context, const CGObjectInstance * obj) {}
|
virtual void onObjectInstantAdd(const CGObjectInstance * obj) {}
|
||||||
|
|
||||||
/// Removes object from map instantly, with no animation
|
/// Removes object from map instantly, with no animation
|
||||||
virtual void onObjectInstantRemove(const IMapRendererContext & context, const CGObjectInstance * obj) {}
|
virtual void onObjectInstantRemove(const CGObjectInstance * obj) {}
|
||||||
|
|
||||||
/// Perform hero teleportation animation with terrain fade animation
|
/// Perform hero teleportation animation with terrain fade animation
|
||||||
virtual void onHeroTeleported(const IMapRendererContext & context, const CGHeroInstance * obj, const int3 & from, const int3 & dest) {}
|
virtual void onHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest) {}
|
||||||
|
|
||||||
/// Perform hero movement animation, moving hero across terrain
|
/// Perform hero movement animation, moving hero across terrain
|
||||||
virtual void onHeroMoved(const IMapRendererContext & context, const CGHeroInstance * obj, const int3 & from, const int3 & dest) {}
|
virtual void onHeroMoved(const CGHeroInstance * obj, const int3 & from, const int3 & dest) {}
|
||||||
|
|
||||||
/// Instantly rotates hero to face destination tile
|
/// Instantly rotates hero to face destination tile
|
||||||
virtual void onHeroRotated(const IMapRendererContext & context, const CGHeroInstance * obj, const int3 & from, const int3 & dest) {}
|
virtual void onHeroRotated(const CGHeroInstance * obj, const int3 & from, const int3 & dest) {}
|
||||||
};
|
};
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
#include "MapView.h"
|
#include "MapView.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "MapRenderer.h"
|
#include "MapRenderer.h"
|
||||||
#include "mapHandler.h"
|
#include "mapHandler.h"
|
||||||
#include "CAdvMapInt.h"
|
#include "CAdvMapInt.h"
|
||||||
@ -20,7 +22,6 @@
|
|||||||
#include "../CPlayerInterface.h"
|
#include "../CPlayerInterface.h"
|
||||||
#include "../gui/CGuiHandler.h"
|
#include "../gui/CGuiHandler.h"
|
||||||
#include "../render/CAnimation.h"
|
#include "../render/CAnimation.h"
|
||||||
#include "../render/CFadeAnimation.h"
|
|
||||||
#include "../render/Canvas.h"
|
#include "../render/Canvas.h"
|
||||||
#include "../render/Colors.h"
|
#include "../render/Colors.h"
|
||||||
#include "../render/Graphics.h"
|
#include "../render/Graphics.h"
|
||||||
@ -41,51 +42,45 @@
|
|||||||
#include "../../lib/mapObjects/CObjectClassesHandler.h"
|
#include "../../lib/mapObjects/CObjectClassesHandler.h"
|
||||||
#include "../../lib/mapping/CMap.h"
|
#include "../../lib/mapping/CMap.h"
|
||||||
|
|
||||||
MapCache::~MapCache() = default;
|
MapViewCache::~MapViewCache() = default;
|
||||||
|
|
||||||
MapCache::MapCache(const std::shared_ptr<MapViewModel> & model)
|
MapViewCache::MapViewCache(const std::shared_ptr<MapViewModel> & model)
|
||||||
: model(model)
|
: model(model)
|
||||||
, context(new MapRendererContext())
|
, mapRenderer(new MapRenderer())
|
||||||
, mapRenderer(new MapRenderer(*context))
|
, terrain(new Canvas(model->getCacheDimensionsPixels()))
|
||||||
{
|
{
|
||||||
terrain = std::make_unique<Canvas>(model->getCacheDimensionsPixels());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Canvas MapCache::getTile(const int3 & coordinates)
|
Canvas MapViewCache::getTile(const int3 & coordinates)
|
||||||
{
|
{
|
||||||
return Canvas(*terrain, model->getCacheTileArea(coordinates));
|
return Canvas(*terrain, model->getCacheTileArea(coordinates));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapCache::updateTile(const int3 & coordinates)
|
void MapViewCache::updateTile(const std::shared_ptr<MapRendererContext> & context, const int3 & coordinates)
|
||||||
{
|
{
|
||||||
Canvas target = getTile(coordinates);
|
Canvas target = getTile(coordinates);
|
||||||
|
|
||||||
mapRenderer->renderTile(*context, target, coordinates);
|
mapRenderer->renderTile(*context, target, coordinates);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapCache::update(uint32_t timeDelta)
|
void MapViewCache::update(const std::shared_ptr<MapRendererContext> & context)
|
||||||
{
|
{
|
||||||
context->advanceAnimations(timeDelta);
|
|
||||||
context->setTileSize(model->getSingleTileSize());
|
|
||||||
|
|
||||||
Rect dimensions = model->getTilesTotalRect();
|
Rect dimensions = model->getTilesTotalRect();
|
||||||
|
|
||||||
for(int y = dimensions.top(); y < dimensions.bottom(); ++y)
|
for(int y = dimensions.top(); y < dimensions.bottom(); ++y)
|
||||||
for(int x = dimensions.left(); x < dimensions.right(); ++x)
|
for(int x = dimensions.left(); x < dimensions.right(); ++x)
|
||||||
updateTile({x, y, model->getLevel()});
|
updateTile(context, {x, y, model->getLevel()});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapCache::render(Canvas & target)
|
void MapViewCache::render(Canvas & target)
|
||||||
{
|
{
|
||||||
update(GH.mainFPSmng->getElapsedMilliseconds());
|
|
||||||
|
|
||||||
Rect dimensions = model->getTilesTotalRect();
|
Rect dimensions = model->getTilesTotalRect();
|
||||||
|
|
||||||
for(int y = dimensions.top(); y < dimensions.bottom(); ++y)
|
for(int y = dimensions.top(); y < dimensions.bottom(); ++y)
|
||||||
{
|
{
|
||||||
for(int x = dimensions.left(); x < dimensions.right(); ++x)
|
for(int x = dimensions.left(); x < dimensions.right(); ++x)
|
||||||
{
|
{
|
||||||
int3 tile( x,y,model->getLevel());
|
int3 tile(x, y, model->getLevel());
|
||||||
Canvas source = getTile(tile);
|
Canvas source = getTile(tile);
|
||||||
Rect targetRect = model->getTargetTileArea(tile);
|
Rect targetRect = model->getTargetTileArea(tile);
|
||||||
target.draw(source, targetRect.topLeft());
|
target.draw(source, targetRect.topLeft());
|
||||||
@ -98,8 +93,8 @@ std::shared_ptr<MapViewModel> MapView::createModel(const Point & dimensions) con
|
|||||||
auto result = std::make_shared<MapViewModel>();
|
auto result = std::make_shared<MapViewModel>();
|
||||||
|
|
||||||
result->setLevel(0);
|
result->setLevel(0);
|
||||||
result->setTileSize(Point(32,32));
|
result->setTileSize(Point(32, 32));
|
||||||
result->setViewCenter(Point(0,0));
|
result->setViewCenter(Point(0, 0));
|
||||||
result->setViewDimensions(dimensions);
|
result->setViewDimensions(dimensions);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -107,12 +102,13 @@ std::shared_ptr<MapViewModel> MapView::createModel(const Point & dimensions) con
|
|||||||
|
|
||||||
MapView::MapView(const Point & offset, const Point & dimensions)
|
MapView::MapView(const Point & offset, const Point & dimensions)
|
||||||
: model(createModel(dimensions))
|
: model(createModel(dimensions))
|
||||||
, tilesCache(new MapCache(model))
|
, context(new MapRendererContext())
|
||||||
|
, controller(new MapViewController(context, model))
|
||||||
|
, tilesCache(new MapViewCache(model))
|
||||||
{
|
{
|
||||||
pos += offset;
|
pos += offset;
|
||||||
pos.w = dimensions.x;
|
pos.w = dimensions.x;
|
||||||
pos.h = dimensions.y;
|
pos.h = dimensions.y;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapView::show(SDL_Surface * to)
|
void MapView::show(SDL_Surface * to)
|
||||||
@ -122,6 +118,8 @@ void MapView::show(SDL_Surface * to)
|
|||||||
|
|
||||||
CSDL_Ext::CClipRectGuard guard(to, pos);
|
CSDL_Ext::CClipRectGuard guard(to, pos);
|
||||||
|
|
||||||
|
controller->update(GH.mainFPSmng->getElapsedMilliseconds());
|
||||||
|
tilesCache->update(context);
|
||||||
tilesCache->render(targetClipped);
|
tilesCache->render(targetClipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,11 +128,6 @@ void MapView::showAll(SDL_Surface * to)
|
|||||||
show(to);
|
show(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapRendererContext::advanceAnimations(uint32_t ms)
|
|
||||||
{
|
|
||||||
animationTime += ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
int3 MapRendererContext::getMapSize() const
|
int3 MapRendererContext::getMapSize() const
|
||||||
{
|
{
|
||||||
return LOCPLINT->cb->getMapSize();
|
return LOCPLINT->cb->getMapSize();
|
||||||
@ -150,11 +143,6 @@ const TerrainTile & MapRendererContext::getMapTile(const int3 & coordinates) con
|
|||||||
return CGI->mh->getMap()->getTile(coordinates);
|
return CGI->mh->getMap()->getTile(coordinates);
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRendererContext::ObjectsVector MapRendererContext::getAllObjects() const
|
|
||||||
{
|
|
||||||
return CGI->mh->getMap()->objects;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CGObjectInstance * MapRendererContext::getObject(ObjectInstanceID objectID) const
|
const CGObjectInstance * MapRendererContext::getObject(ObjectInstanceID objectID) const
|
||||||
{
|
{
|
||||||
return CGI->mh->getMap()->objects.at(objectID.getNum());
|
return CGI->mh->getMap()->objects.at(objectID.getNum());
|
||||||
@ -165,11 +153,6 @@ bool MapRendererContext::isVisible(const int3 & coordinates) const
|
|||||||
return LOCPLINT->cb->isVisible(coordinates) || settings["session"]["spectate"].Bool();
|
return LOCPLINT->cb->isVisible(coordinates) || settings["session"]["spectate"].Bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapRendererContext::setTileSize(const Point & dimensions)
|
|
||||||
{
|
|
||||||
tileSize = dimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CGPath * MapRendererContext::currentPath() const
|
const CGPath * MapRendererContext::currentPath() const
|
||||||
{
|
{
|
||||||
const auto * hero = adventureInt->curHero();
|
const auto * hero = adventureInt->curHero();
|
||||||
@ -208,19 +191,19 @@ bool MapRendererContext::showGrid() const
|
|||||||
return true; // settings["session"]["showGrid"].Bool();
|
return true; // settings["session"]["showGrid"].Bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapView::setViewCenter(const int3 & position)
|
void MapViewController::setViewCenter(const int3 & position)
|
||||||
{
|
{
|
||||||
model->setViewCenter(Point(position.x, position.y) * model->getSingleTileSize());
|
model->setViewCenter(Point(position.x, position.y) * model->getSingleTileSize());
|
||||||
model->setLevel(position.z);
|
model->setLevel(position.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapView::setViewCenter(const Point & position, int level)
|
void MapViewController::setViewCenter(const Point & position, int level)
|
||||||
{
|
{
|
||||||
model->setViewCenter(position);
|
model->setViewCenter(position);
|
||||||
model->setLevel(level);
|
model->setLevel(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapView::setTileSize(const Point & tileSize)
|
void MapViewController::setTileSize(const Point & tileSize)
|
||||||
{
|
{
|
||||||
model->setTileSize(tileSize);
|
model->setTileSize(tileSize);
|
||||||
}
|
}
|
||||||
@ -290,11 +273,6 @@ Rect MapViewModel::getTilesTotalRect() const
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
int3 MapViewModel::getTileCenter() const
|
|
||||||
{
|
|
||||||
return getTileAtPoint(getMapViewCenter());
|
|
||||||
}
|
|
||||||
|
|
||||||
int3 MapViewModel::getTileAtPoint(const Point & position) const
|
int3 MapViewModel::getTileAtPoint(const Point & position) const
|
||||||
{
|
{
|
||||||
Point topLeftOffset = getMapViewCenter() - getPixelsVisibleDimensions() / 2;
|
Point topLeftOffset = getMapViewCenter() - getPixelsVisibleDimensions() / 2;
|
||||||
@ -335,8 +313,259 @@ Rect MapViewModel::getTargetTileArea(const int3 & coordinates) const
|
|||||||
Point tilePosAbsolute = Point(coordinates) * tileSize;
|
Point tilePosAbsolute = Point(coordinates) * tileSize;
|
||||||
Point tilePosRelative = tilePosAbsolute - topLeftOffset;
|
Point tilePosRelative = tilePosAbsolute - topLeftOffset;
|
||||||
|
|
||||||
return {
|
return Rect(tilePosRelative, tileSize);
|
||||||
tilePosRelative,
|
}
|
||||||
tileSize
|
|
||||||
};
|
MapRendererContext::MapRendererContext()
|
||||||
|
{
|
||||||
|
auto mapSize = getMapSize();
|
||||||
|
|
||||||
|
objects.resize(boost::extents[mapSize.z][mapSize.x][mapSize.y]);
|
||||||
|
|
||||||
|
for(const auto & obj : CGI->mh->getMap()->objects)
|
||||||
|
addObject(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapRendererContext::addObject(const CGObjectInstance * obj)
|
||||||
|
{
|
||||||
|
if(!obj)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(int fx = 0; fx < obj->getWidth(); ++fx)
|
||||||
|
{
|
||||||
|
for(int fy = 0; fy < obj->getHeight(); ++fy)
|
||||||
|
{
|
||||||
|
int3 currTile(obj->pos.x - fx, obj->pos.y - fy, obj->pos.z);
|
||||||
|
|
||||||
|
if(isInMap(currTile) && obj->coveringAt(currTile.x, currTile.y))
|
||||||
|
{
|
||||||
|
auto & container = objects[currTile.z][currTile.x][currTile.y];
|
||||||
|
|
||||||
|
container.push_back(obj->id);
|
||||||
|
boost::range::sort(container, MapObjectsSorter(*this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapRendererContext::addMovingObject(const CGObjectInstance * object, const int3 & tileFrom, const int3 & tileDest)
|
||||||
|
{
|
||||||
|
int xFrom = std::min(tileFrom.x, tileDest.x) - object->getWidth();
|
||||||
|
int xDest = std::max(tileFrom.x, tileDest.x);
|
||||||
|
int yFrom = std::min(tileFrom.y, tileDest.y) - object->getHeight();
|
||||||
|
int yDest = std::max(tileFrom.y, tileDest.y);
|
||||||
|
|
||||||
|
for(int x = xFrom; x <= xDest; ++x)
|
||||||
|
{
|
||||||
|
for(int y = yFrom; y <= yDest; ++y)
|
||||||
|
{
|
||||||
|
int3 currTile(x, y, object->pos.z);
|
||||||
|
|
||||||
|
if(isInMap(currTile))
|
||||||
|
{
|
||||||
|
auto & container = objects[currTile.z][currTile.x][currTile.y];
|
||||||
|
|
||||||
|
container.push_back(object->id);
|
||||||
|
boost::range::sort(container, MapObjectsSorter(*this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapRendererContext::removeObject(const CGObjectInstance * object)
|
||||||
|
{
|
||||||
|
for(int z = 0; z < getMapSize().z; z++)
|
||||||
|
for(int x = 0; x < getMapSize().x; x++)
|
||||||
|
for(int y = 0; y < getMapSize().y; y++)
|
||||||
|
vstd::erase(objects[z][x][y], object->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const MapRendererContext::MapObjectsList & MapRendererContext::getObjects(const int3 & coordinates) const
|
||||||
|
{
|
||||||
|
assert(isInMap(coordinates));
|
||||||
|
return objects[coordinates.z][coordinates.x][coordinates.y];
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MapRendererContext::objectGroupIndex(ObjectInstanceID objectID) const
|
||||||
|
{
|
||||||
|
const CGObjectInstance * obj = getObject(objectID);
|
||||||
|
// TODO
|
||||||
|
static const std::vector<size_t> moveGroups = {99, 10, 5, 6, 7, 8, 9, 12, 11};
|
||||||
|
static const std::vector<size_t> idleGroups = {99, 13, 0, 1, 2, 3, 4, 15, 14};
|
||||||
|
|
||||||
|
if(obj->ID == Obj::HERO)
|
||||||
|
{
|
||||||
|
const auto * hero = dynamic_cast<const CGHeroInstance *>(obj);
|
||||||
|
if (movementAnimation && movementAnimation->target == objectID)
|
||||||
|
return moveGroups[hero->moveDir];
|
||||||
|
return idleGroups[hero->moveDir];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(obj->ID == Obj::BOAT)
|
||||||
|
{
|
||||||
|
const auto * boat = dynamic_cast<const CGBoat *>(obj);
|
||||||
|
if (movementAnimation && movementAnimation->target == objectID)
|
||||||
|
return moveGroups[boat->direction];
|
||||||
|
return idleGroups[boat->direction];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point MapRendererContext::objectImageOffset(ObjectInstanceID objectID, const int3 & coordinates) const
|
||||||
|
{
|
||||||
|
if (movementAnimation && movementAnimation->target == objectID)
|
||||||
|
{
|
||||||
|
int3 offsetTilesFrom = movementAnimation->tileFrom - coordinates;
|
||||||
|
int3 offsetTilesDest = movementAnimation->tileDest - coordinates;
|
||||||
|
|
||||||
|
Point offsetPixelsFrom = Point(offsetTilesFrom) * Point(32,32);
|
||||||
|
Point offsetPixelsDest = Point(offsetTilesDest) * Point(32,32);
|
||||||
|
|
||||||
|
Point result = vstd::lerp(offsetPixelsFrom, offsetPixelsDest, movementAnimation->progress);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CGObjectInstance * object = getObject(objectID);
|
||||||
|
int3 offsetTiles(object->getPosition() - coordinates);
|
||||||
|
return Point(offsetTiles) * Point(32, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
double MapRendererContext::objectTransparency(ObjectInstanceID objectID) const
|
||||||
|
{
|
||||||
|
if (fadeOutAnimation && objectID == fadeOutAnimation->target)
|
||||||
|
return 1.0 - fadeOutAnimation->progress;
|
||||||
|
|
||||||
|
if (fadeInAnimation && objectID == fadeInAnimation->target)
|
||||||
|
return fadeInAnimation->progress;
|
||||||
|
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapViewController::MapViewController(std::shared_ptr<MapRendererContext> context, std::shared_ptr<MapViewModel> model)
|
||||||
|
: context(std::move(context))
|
||||||
|
, model(std::move(model))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapViewController::update(uint32_t timeDelta)
|
||||||
|
{
|
||||||
|
static const double fadeOutDuration = 1.0;
|
||||||
|
static const double fadeInDuration = 1.0;
|
||||||
|
static const double heroMoveDuration = 1.0;
|
||||||
|
static const double heroTeleportDuration = 1.0;
|
||||||
|
|
||||||
|
//FIXME: remove code duplication?
|
||||||
|
|
||||||
|
if (context->movementAnimation)
|
||||||
|
{
|
||||||
|
context->movementAnimation->progress += heroMoveDuration * timeDelta / 1000;
|
||||||
|
|
||||||
|
Point positionFrom = Point(context->movementAnimation->tileFrom) * model->getSingleTileSize();
|
||||||
|
Point positionDest = Point(context->movementAnimation->tileDest) * model->getSingleTileSize();
|
||||||
|
|
||||||
|
Point positionCurr = vstd::lerp(positionFrom, positionDest, context->movementAnimation->progress);
|
||||||
|
|
||||||
|
setViewCenter(positionCurr, context->movementAnimation->tileDest.z);
|
||||||
|
|
||||||
|
if (context->movementAnimation->progress >= 1.0)
|
||||||
|
{
|
||||||
|
setViewCenter(context->movementAnimation->tileDest);
|
||||||
|
|
||||||
|
context->removeObject(context->getObject(context->movementAnimation->target));
|
||||||
|
context->addObject(context->getObject(context->movementAnimation->target));
|
||||||
|
context->movementAnimation.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->teleportAnimation)
|
||||||
|
{
|
||||||
|
context->teleportAnimation->progress += heroTeleportDuration * timeDelta / 1000;
|
||||||
|
if (context->teleportAnimation->progress >= 1.0)
|
||||||
|
context->teleportAnimation.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->fadeOutAnimation)
|
||||||
|
{
|
||||||
|
context->fadeOutAnimation->progress += fadeOutDuration * timeDelta / 1000;
|
||||||
|
if (context->fadeOutAnimation->progress >= 1.0)
|
||||||
|
{
|
||||||
|
context->removeObject(context->getObject(context->fadeOutAnimation->target));
|
||||||
|
context->fadeOutAnimation.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->fadeInAnimation)
|
||||||
|
{
|
||||||
|
context->fadeInAnimation->progress += fadeInDuration * timeDelta / 1000;
|
||||||
|
if (context->fadeInAnimation->progress >= 1.0)
|
||||||
|
context->fadeInAnimation.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
context->animationTime += timeDelta;
|
||||||
|
context->tileSize =model->getSingleTileSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapViewController::onObjectFadeIn(const CGObjectInstance * obj)
|
||||||
|
{
|
||||||
|
assert(!context->fadeInAnimation);
|
||||||
|
context->fadeInAnimation = FadingAnimationState{obj->id, 0.0};
|
||||||
|
context->addObject(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapViewController::onObjectFadeOut(const CGObjectInstance * obj)
|
||||||
|
{
|
||||||
|
assert(!context->fadeOutAnimation);
|
||||||
|
context->fadeOutAnimation = FadingAnimationState{obj->id, 0.0};
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapViewController::onObjectInstantAdd(const CGObjectInstance * obj)
|
||||||
|
{
|
||||||
|
context->addObject(obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
void MapViewController::onObjectInstantRemove(const CGObjectInstance * obj)
|
||||||
|
{
|
||||||
|
context->removeObject(obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
void MapViewController::onHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
||||||
|
{
|
||||||
|
assert(!context->teleportAnimation);
|
||||||
|
context->teleportAnimation = HeroAnimationState{ obj->id, from, dest, 0.0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapViewController::onHeroMoved(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
||||||
|
{
|
||||||
|
assert(!context->movementAnimation);
|
||||||
|
context->removeObject(obj);
|
||||||
|
context->addMovingObject(obj, from, dest);
|
||||||
|
context->movementAnimation = HeroAnimationState{ obj->id, from, dest, 0.0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapViewController::onHeroRotated(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MapViewController> MapView::getController()
|
||||||
|
{
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MapViewController::hasOngoingAnimations()
|
||||||
|
{
|
||||||
|
if(context->movementAnimation)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(context->teleportAnimation)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(context->fadeOutAnimation)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(context->fadeInAnimation)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -9,37 +9,65 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../gui/CIntObject.h"
|
|
||||||
|
|
||||||
#include "MapRendererContext.h"
|
#include "MapRendererContext.h"
|
||||||
|
#include "../gui/CIntObject.h"
|
||||||
|
#include "../lib/int3.h"
|
||||||
|
|
||||||
class Canvas;
|
class Canvas;
|
||||||
class MapRenderer;
|
class MapRenderer;
|
||||||
|
class MapViewController;
|
||||||
|
|
||||||
|
struct HeroAnimationState
|
||||||
|
{
|
||||||
|
ObjectInstanceID target;
|
||||||
|
int3 tileFrom;
|
||||||
|
int3 tileDest;
|
||||||
|
double progress;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FadingAnimationState
|
||||||
|
{
|
||||||
|
ObjectInstanceID target;
|
||||||
|
double progress;
|
||||||
|
};
|
||||||
|
|
||||||
class MapRendererContext : public IMapRendererContext
|
class MapRendererContext : public IMapRendererContext
|
||||||
{
|
{
|
||||||
|
friend class MapViewController;
|
||||||
|
|
||||||
|
boost::multi_array<MapObjectsList, 3> objects;
|
||||||
|
|
||||||
Point tileSize = Point(32, 32);
|
Point tileSize = Point(32, 32);
|
||||||
uint32_t animationTime = 0;
|
uint32_t animationTime = 0;
|
||||||
|
|
||||||
|
boost::optional<HeroAnimationState> movementAnimation;
|
||||||
|
boost::optional<HeroAnimationState> teleportAnimation;
|
||||||
|
|
||||||
|
boost::optional<FadingAnimationState> fadeOutAnimation;
|
||||||
|
boost::optional<FadingAnimationState> fadeInAnimation;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void advanceAnimations(uint32_t ms);
|
MapRendererContext();
|
||||||
void setTileSize(const Point & dimensions);
|
|
||||||
|
|
||||||
int3 getMapSize() const override;
|
void addObject(const CGObjectInstance * object);
|
||||||
bool isInMap(const int3 & coordinates) const override;
|
void addMovingObject(const CGObjectInstance * object, const int3 & tileFrom, const int3 & tileDest);
|
||||||
const TerrainTile & getMapTile(const int3 & coordinates) const override;
|
void removeObject(const CGObjectInstance * object);
|
||||||
|
|
||||||
ObjectsVector getAllObjects() const override;
|
|
||||||
const CGObjectInstance * getObject(ObjectInstanceID objectID) const override;
|
|
||||||
|
|
||||||
const CGPath * currentPath() const override;
|
|
||||||
|
|
||||||
|
int3 getMapSize() const final;
|
||||||
|
bool isInMap(const int3 & coordinates) const final;
|
||||||
bool isVisible(const int3 & coordinates) const override;
|
bool isVisible(const int3 & coordinates) const override;
|
||||||
|
|
||||||
|
const TerrainTile & getMapTile(const int3 & coordinates) const override;
|
||||||
|
const MapObjectsList & getObjects(const int3 & coordinates) const override;
|
||||||
|
const CGObjectInstance * getObject(ObjectInstanceID objectID) const override;
|
||||||
|
const CGPath * currentPath() const override;
|
||||||
|
|
||||||
|
size_t objectGroupIndex(ObjectInstanceID objectID) const override;
|
||||||
|
Point objectImageOffset(ObjectInstanceID objectID, const int3 & coordinates) const override;
|
||||||
|
double objectTransparency(ObjectInstanceID objectID) const override;
|
||||||
uint32_t getAnimationPeriod() const override;
|
uint32_t getAnimationPeriod() const override;
|
||||||
uint32_t getAnimationTime() const override;
|
uint32_t getAnimationTime() const override;
|
||||||
Point getTileSize() const override;
|
Point getTileSize() const override;
|
||||||
|
|
||||||
bool showGrid() const override;
|
bool showGrid() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,50 +109,79 @@ public:
|
|||||||
/// returns area covered by specified tile in target view
|
/// returns area covered by specified tile in target view
|
||||||
Rect getTargetTileArea(const int3 & coordinates) const;
|
Rect getTargetTileArea(const int3 & coordinates) const;
|
||||||
|
|
||||||
int getLevel() const;
|
|
||||||
int3 getTileCenter() const;
|
|
||||||
|
|
||||||
/// returns tile under specified position in target view
|
/// returns tile under specified position in target view
|
||||||
int3 getTileAtPoint(const Point & position) const;
|
int3 getTileAtPoint(const Point & position) const;
|
||||||
|
|
||||||
|
/// returns currently visible map level
|
||||||
|
int getLevel() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MapCache
|
/// Class responsible for rendering of entire map view
|
||||||
|
/// uses rendering parameters provided by owner class
|
||||||
|
class MapViewCache
|
||||||
{
|
{
|
||||||
std::unique_ptr<Canvas> terrain;
|
|
||||||
std::shared_ptr<MapViewModel> model;
|
std::shared_ptr<MapViewModel> model;
|
||||||
|
|
||||||
std::unique_ptr<MapRendererContext> context;
|
std::unique_ptr<Canvas> terrain;
|
||||||
std::unique_ptr<MapRenderer> mapRenderer;
|
std::unique_ptr<MapRenderer> mapRenderer;
|
||||||
|
|
||||||
Canvas getTile(const int3 & coordinates);
|
Canvas getTile(const int3 & coordinates);
|
||||||
void updateTile(const int3 & coordinates);
|
void updateTile(const std::shared_ptr<MapRendererContext> & context, const int3 & coordinates);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MapCache(const std::shared_ptr<MapViewModel> & model);
|
explicit MapViewCache(const std::shared_ptr<MapViewModel> & model);
|
||||||
~MapCache();
|
~MapViewCache();
|
||||||
|
|
||||||
void update(uint32_t timeDelta);
|
/// updates internal terrain cache according to provided time delta
|
||||||
|
void update(const std::shared_ptr<MapRendererContext> & context);
|
||||||
|
|
||||||
|
/// renders updated terrain cache onto provided canvas
|
||||||
void render(Canvas & target);
|
void render(Canvas & target);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Class responsible for updating view state,
|
||||||
|
/// such as its position and any animations
|
||||||
|
class MapViewController : public IMapObjectObserver
|
||||||
|
{
|
||||||
|
std::shared_ptr<MapRendererContext> context;
|
||||||
|
std::shared_ptr<MapViewModel> model;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// IMapObjectObserver impl
|
||||||
|
bool hasOngoingAnimations() override;
|
||||||
|
void onObjectFadeIn(const CGObjectInstance * obj) override;
|
||||||
|
void onObjectFadeOut(const CGObjectInstance * obj) override;
|
||||||
|
void onObjectInstantAdd(const CGObjectInstance * obj) override;
|
||||||
|
void onObjectInstantRemove(const CGObjectInstance * obj) override;
|
||||||
|
void onHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest) override;
|
||||||
|
void onHeroMoved(const CGHeroInstance * obj, const int3 & from, const int3 & dest) override;
|
||||||
|
void onHeroRotated(const CGHeroInstance * obj, const int3 & from, const int3 & dest) override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MapViewController(std::shared_ptr<MapRendererContext> context, std::shared_ptr<MapViewModel> model);
|
||||||
|
|
||||||
|
void setViewCenter(const int3 & position);
|
||||||
|
void setViewCenter(const Point & position, int level);
|
||||||
|
void setTileSize(const Point & tileSize);
|
||||||
|
void update(uint32_t timeDelta);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Main map rendering class that mostly acts as container for component classes
|
||||||
class MapView : public CIntObject
|
class MapView : public CIntObject
|
||||||
{
|
{
|
||||||
std::shared_ptr<MapViewModel> model;
|
std::shared_ptr<MapViewModel> model;
|
||||||
std::unique_ptr<MapCache> tilesCache;
|
std::shared_ptr<MapRendererContext> context;
|
||||||
|
std::unique_ptr<MapViewCache> tilesCache;
|
||||||
|
std::shared_ptr<MapViewController> controller;
|
||||||
|
|
||||||
std::shared_ptr<MapViewModel> createModel(const Point & dimensions) const;
|
std::shared_ptr<MapViewModel> createModel(const Point & dimensions) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::shared_ptr<const MapViewModel> getModel() const;
|
std::shared_ptr<const MapViewModel> getModel() const;
|
||||||
|
std::shared_ptr<MapViewController> getController();
|
||||||
|
|
||||||
MapView(const Point & offset, const Point & dimensions);
|
MapView(const Point & offset, const Point & dimensions);
|
||||||
|
|
||||||
void setViewCenter(const int3 & position);
|
|
||||||
void setViewCenter(const Point & position, int level);
|
|
||||||
void setTileSize(const Point & tileSize);
|
|
||||||
|
|
||||||
void moveHero();
|
|
||||||
|
|
||||||
void show(SDL_Surface * to) override;
|
void show(SDL_Surface * to) override;
|
||||||
void showAll(SDL_Surface * to) override;
|
void showAll(SDL_Surface * to) override;
|
||||||
};
|
};
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include "MapView.h"
|
#include "MapView.h"
|
||||||
|
|
||||||
#include "../render/CAnimation.h"
|
#include "../render/CAnimation.h"
|
||||||
#include "../render/CFadeAnimation.h"
|
|
||||||
#include "../render/Colors.h"
|
#include "../render/Colors.h"
|
||||||
#include "../gui/CGuiHandler.h"
|
#include "../gui/CGuiHandler.h"
|
||||||
#include "../renderSDL/SDL_Extensions.h"
|
#include "../renderSDL/SDL_Extensions.h"
|
||||||
@ -27,6 +26,7 @@
|
|||||||
|
|
||||||
#include "../../CCallback.h"
|
#include "../../CCallback.h"
|
||||||
|
|
||||||
|
#include "../../lib/UnlockGuard.h"
|
||||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||||
#include "../../lib/mapObjects/CObjectClassesHandler.h"
|
#include "../../lib/mapObjects/CObjectClassesHandler.h"
|
||||||
#include "../../lib/mapping/CMap.h"
|
#include "../../lib/mapping/CMap.h"
|
||||||
@ -476,10 +476,24 @@ bool CMapHandler::hideObject(const CGObjectInstance * obj, bool fadeout)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool CMapHandler::hasActiveAnimations()
|
bool CMapHandler::hasOngoingAnimations()
|
||||||
{
|
{
|
||||||
return false; // !fadeAnims.empty(); // don't allow movement during fade animation
|
for (auto * observer : observers)
|
||||||
|
if (observer->hasOngoingAnimations())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMapHandler::waitForOngoingAnimations()
|
||||||
|
{
|
||||||
|
while (CGI->mh->hasOngoingAnimations())
|
||||||
|
{
|
||||||
|
auto unlockPim = vstd::makeUnlockGuard(*CPlayerInterface::pim);
|
||||||
|
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void CMapHandler::updateWater() //shift colors in palettes of water tiles
|
void CMapHandler::updateWater() //shift colors in palettes of water tiles
|
||||||
{
|
{
|
||||||
@ -600,26 +614,6 @@ bool CMapHandler::compareObjectBlitOrder(const CGObjectInstance * a, const CGObj
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TerrainTileObject::TerrainTileObject(const CGObjectInstance * obj_, Rect rect_, bool visitablePos)
|
|
||||||
: obj(obj_),
|
|
||||||
rect(rect_),
|
|
||||||
fadeAnimKey(-1)
|
|
||||||
{
|
|
||||||
// We store information about ambient sound is here because object might disappear while sound is updating
|
|
||||||
if(obj->getAmbientSound())
|
|
||||||
{
|
|
||||||
// All tiles of static objects are sound sources. E.g Volcanos and special terrains
|
|
||||||
// For visitable object only their visitable tile is sound source
|
|
||||||
if(!CCS->soundh->ambientCheckVisitable() || !obj->isVisitable() || visitablePos)
|
|
||||||
ambientSound = obj->getAmbientSound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TerrainTileObject::~TerrainTileObject()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
CMapHandler::CMapHandler(const CMap * map)
|
CMapHandler::CMapHandler(const CMap * map)
|
||||||
: map(map)
|
: map(map)
|
||||||
{
|
{
|
||||||
@ -652,45 +646,47 @@ std::vector<std::string> CMapHandler::getAmbientSounds(const int3 & tile)
|
|||||||
|
|
||||||
void CMapHandler::onObjectFadeIn(const CGObjectInstance * obj)
|
void CMapHandler::onObjectFadeIn(const CGObjectInstance * obj)
|
||||||
{
|
{
|
||||||
onObjectInstantAdd(obj);
|
for (auto * observer : observers)
|
||||||
|
observer->onObjectFadeIn(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHandler::onObjectFadeOut(const CGObjectInstance * obj)
|
void CMapHandler::onObjectFadeOut(const CGObjectInstance * obj)
|
||||||
{
|
{
|
||||||
onObjectInstantRemove(obj);
|
for (auto * observer : observers)
|
||||||
|
observer->onObjectFadeOut(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHandler::onObjectInstantAdd(const CGObjectInstance * obj)
|
void CMapHandler::onObjectInstantAdd(const CGObjectInstance * obj)
|
||||||
{
|
{
|
||||||
MapRendererContext context;
|
|
||||||
for (auto * observer : observers)
|
for (auto * observer : observers)
|
||||||
observer->onObjectInstantAdd(context, obj);
|
observer->onObjectInstantAdd(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHandler::onObjectInstantRemove(const CGObjectInstance * obj)
|
void CMapHandler::onObjectInstantRemove(const CGObjectInstance * obj)
|
||||||
{
|
{
|
||||||
MapRendererContext context;
|
|
||||||
for (auto * observer : observers)
|
for (auto * observer : observers)
|
||||||
observer->onObjectInstantRemove(context, obj);
|
observer->onObjectInstantRemove(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHandler::onHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
void CMapHandler::onHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
||||||
{
|
{
|
||||||
assert(obj->pos == dest);
|
assert(obj->pos == dest);
|
||||||
onObjectInstantRemove(obj);
|
for (auto * observer : observers)
|
||||||
onObjectInstantAdd(obj);
|
observer->onHeroTeleported(obj, from, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHandler::onHeroMoved(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
void CMapHandler::onHeroMoved(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
||||||
{
|
{
|
||||||
assert(obj->pos == dest);
|
assert(obj->pos == dest);
|
||||||
onObjectInstantRemove(obj);
|
for (auto * observer : observers)
|
||||||
onObjectInstantAdd(obj);
|
observer->onHeroMoved(obj, from, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHandler::onHeroRotated(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
void CMapHandler::onHeroRotated(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
||||||
{
|
{
|
||||||
//TODO
|
assert(obj->pos == from);
|
||||||
|
for (auto * observer : observers)
|
||||||
|
observer->onHeroRotated(obj, from, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHandler::addMapObserver(IMapObjectObserver * object)
|
void CMapHandler::addMapObserver(IMapObjectObserver * object)
|
||||||
|
@ -38,7 +38,6 @@ VCMI_LIB_NAMESPACE_END
|
|||||||
struct SDL_Surface;
|
struct SDL_Surface;
|
||||||
class CAnimation;
|
class CAnimation;
|
||||||
class IImage;
|
class IImage;
|
||||||
class CFadeAnimation;
|
|
||||||
class CMapHandler;
|
class CMapHandler;
|
||||||
class IMapObjectObserver;
|
class IMapObjectObserver;
|
||||||
|
|
||||||
@ -63,30 +62,6 @@ enum class EWorldViewIcon
|
|||||||
RES_CRYSTAL,
|
RES_CRYSTAL,
|
||||||
RES_GEM,
|
RES_GEM,
|
||||||
RES_GOLD,
|
RES_GOLD,
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class EMapObjectFadingType
|
|
||||||
{
|
|
||||||
NONE,
|
|
||||||
IN,
|
|
||||||
OUT
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TerrainTileObject
|
|
||||||
{
|
|
||||||
const CGObjectInstance *obj;
|
|
||||||
Rect rect;
|
|
||||||
int fadeAnimKey;
|
|
||||||
boost::optional<std::string> ambientSound;
|
|
||||||
|
|
||||||
TerrainTileObject(const CGObjectInstance *obj_, Rect rect_, bool visitablePos = false);
|
|
||||||
~TerrainTileObject();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TerrainTile2
|
|
||||||
{
|
|
||||||
std::vector<TerrainTileObject> objects; //pointers to objects being on this tile with rects to be easier to blit this tile on screen
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CMapHandler
|
class CMapHandler
|
||||||
@ -125,7 +100,10 @@ public:
|
|||||||
bool hasObjectHole(const int3 & pos) const;
|
bool hasObjectHole(const int3 & pos) const;
|
||||||
|
|
||||||
/// determines if the map is ready to handle new hero movement (not available during fading animations)
|
/// determines if the map is ready to handle new hero movement (not available during fading animations)
|
||||||
bool hasActiveAnimations();
|
bool hasOngoingAnimations();
|
||||||
|
|
||||||
|
/// blocking wait until all ongoing animatins are over
|
||||||
|
void waitForOngoingAnimations();
|
||||||
|
|
||||||
static bool compareObjectBlitOrder(const CGObjectInstance * a, const CGObjectInstance * b);
|
static bool compareObjectBlitOrder(const CGObjectInstance * a, const CGObjectInstance * b);
|
||||||
};
|
};
|
||||||
|
@ -1,101 +0,0 @@
|
|||||||
/*
|
|
||||||
* CFadeAnimation.cpp, part of VCMI engine
|
|
||||||
*
|
|
||||||
* Authors: listed in file AUTHORS in main folder
|
|
||||||
*
|
|
||||||
* License: GNU General Public License v2.0 or later
|
|
||||||
* Full text of license available in license.txt file, in main folder
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "StdInc.h"
|
|
||||||
#include "CFadeAnimation.h"
|
|
||||||
|
|
||||||
#include "../renderSDL/SDL_Extensions.h"
|
|
||||||
|
|
||||||
#include <SDL_surface.h>
|
|
||||||
|
|
||||||
float CFadeAnimation::initialCounter() const
|
|
||||||
{
|
|
||||||
if (fadingMode == EMode::OUT)
|
|
||||||
return 1.0f;
|
|
||||||
return 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CFadeAnimation::update()
|
|
||||||
{
|
|
||||||
if (!fading)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (fadingMode == EMode::OUT)
|
|
||||||
fadingCounter -= delta;
|
|
||||||
else
|
|
||||||
fadingCounter += delta;
|
|
||||||
|
|
||||||
if (isFinished())
|
|
||||||
{
|
|
||||||
fading = false;
|
|
||||||
if (shouldFreeSurface)
|
|
||||||
{
|
|
||||||
SDL_FreeSurface(fadingSurface);
|
|
||||||
fadingSurface = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CFadeAnimation::isFinished() const
|
|
||||||
{
|
|
||||||
if (fadingMode == EMode::OUT)
|
|
||||||
return fadingCounter <= 0.0f;
|
|
||||||
return fadingCounter >= 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFadeAnimation::CFadeAnimation()
|
|
||||||
: delta(0), fadingSurface(nullptr), fading(false), fadingCounter(0), shouldFreeSurface(false),
|
|
||||||
fadingMode(EMode::NONE)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CFadeAnimation::~CFadeAnimation()
|
|
||||||
{
|
|
||||||
if (fadingSurface && shouldFreeSurface)
|
|
||||||
SDL_FreeSurface(fadingSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CFadeAnimation::init(EMode mode, SDL_Surface * sourceSurface, bool freeSurfaceAtEnd, float animDelta)
|
|
||||||
{
|
|
||||||
if (fading)
|
|
||||||
{
|
|
||||||
// in that case, immediately finish the previous fade
|
|
||||||
// (alternatively, we could just return here to ignore the new fade request until this one finished (but we'd need to free the passed bitmap to avoid leaks))
|
|
||||||
logGlobal->warn("Tried to init fading animation that is already running.");
|
|
||||||
if (fadingSurface && shouldFreeSurface)
|
|
||||||
SDL_FreeSurface(fadingSurface);
|
|
||||||
}
|
|
||||||
if (animDelta <= 0.0f)
|
|
||||||
{
|
|
||||||
logGlobal->warn("Fade anim: delta should be positive; %f given.", animDelta);
|
|
||||||
animDelta = DEFAULT_DELTA;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sourceSurface)
|
|
||||||
fadingSurface = sourceSurface;
|
|
||||||
|
|
||||||
delta = animDelta;
|
|
||||||
fadingMode = mode;
|
|
||||||
fadingCounter = initialCounter();
|
|
||||||
fading = true;
|
|
||||||
shouldFreeSurface = freeSurfaceAtEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CFadeAnimation::draw(SDL_Surface * targetSurface, const Point &targetPoint)
|
|
||||||
{
|
|
||||||
if (!fading || !fadingSurface || fadingMode == EMode::NONE)
|
|
||||||
{
|
|
||||||
fading = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CSDL_Ext::setAlpha(fadingSurface, (int)(fadingCounter * 255));
|
|
||||||
CSDL_Ext::blitSurface(fadingSurface, targetSurface, targetPoint); //FIXME
|
|
||||||
CSDL_Ext::setAlpha(fadingSurface, 255);
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* CFadeAnimation.h, part of VCMI engine
|
|
||||||
*
|
|
||||||
* Authors: listed in file AUTHORS in main folder
|
|
||||||
*
|
|
||||||
* License: GNU General Public License v2.0 or later
|
|
||||||
* Full text of license available in license.txt file, in main folder
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef IN
|
|
||||||
#undef IN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef OUT
|
|
||||||
#undef OUT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
|
||||||
class Point;
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
|
||||||
|
|
||||||
struct SDL_Surface;
|
|
||||||
|
|
||||||
const float DEFAULT_DELTA = 0.05f;
|
|
||||||
|
|
||||||
class CFadeAnimation
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum class EMode
|
|
||||||
{
|
|
||||||
NONE, IN, OUT
|
|
||||||
};
|
|
||||||
private:
|
|
||||||
float delta;
|
|
||||||
SDL_Surface * fadingSurface;
|
|
||||||
bool fading;
|
|
||||||
float fadingCounter;
|
|
||||||
bool shouldFreeSurface;
|
|
||||||
|
|
||||||
float initialCounter() const;
|
|
||||||
bool isFinished() const;
|
|
||||||
public:
|
|
||||||
EMode fadingMode;
|
|
||||||
|
|
||||||
CFadeAnimation();
|
|
||||||
~CFadeAnimation();
|
|
||||||
void init(EMode mode, SDL_Surface * sourceSurface, bool freeSurfaceAtEnd = false, float animDelta = DEFAULT_DELTA);
|
|
||||||
void update();
|
|
||||||
void draw(SDL_Surface * targetSurface, const Point & targetPoint);
|
|
||||||
bool isFading() const { return fading; }
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user