mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Moved path rendering to new map renderer
This commit is contained in:
parent
600054e001
commit
21a48e4f0d
@ -26,6 +26,7 @@
|
||||
#include "../../lib/TerrainHandler.h"
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
#include "../../lib/mapping/CMap.h"
|
||||
#include "../../lib/CPathfinder.h"
|
||||
|
||||
struct NeighborTilesInfo
|
||||
{
|
||||
@ -534,10 +535,98 @@ void MapRendererDebugGrid::renderTile(const IMapRendererContext & context, Canva
|
||||
}
|
||||
}
|
||||
|
||||
MapRendererPath::MapRendererPath()
|
||||
: pathNodes(new CAnimation("ADAG"))
|
||||
{
|
||||
pathNodes->preload();
|
||||
}
|
||||
|
||||
void MapRendererPath::renderImage(Canvas & target, bool reachableToday, size_t imageIndex)
|
||||
{
|
||||
const static size_t unreachableTodayOffset = 25;
|
||||
|
||||
if(reachableToday)
|
||||
target.draw(pathNodes->getImage(imageIndex), Point(0, 0));
|
||||
else
|
||||
target.draw(pathNodes->getImage(imageIndex + unreachableTodayOffset), Point(0, 0));
|
||||
}
|
||||
|
||||
void MapRendererPath::renderImageCross(Canvas & target, bool reachableToday, const int3 & curr)
|
||||
{
|
||||
renderImage(target, reachableToday, 0);
|
||||
}
|
||||
|
||||
void MapRendererPath::renderImageArrow(Canvas & target, bool reachableToday, const int3 & curr, const int3 & prev, const int3 & next)
|
||||
{
|
||||
// Vector directions
|
||||
// 0 1 2
|
||||
// |
|
||||
// 3 - 4 - 5
|
||||
// |
|
||||
// 6 7 8
|
||||
//For example:
|
||||
// |
|
||||
// +->
|
||||
// is (directionToArrowIndex[7][5])
|
||||
//
|
||||
const static size_t directionToArrowIndex[9][9] = {
|
||||
{16, 17, 18, 7, 0, 19, 6, 5, 0 },
|
||||
{8, 9, 18, 7, 0, 19, 6, 0, 20},
|
||||
{8, 1, 10, 7, 0, 19, 0, 21, 20},
|
||||
{24, 17, 18, 15, 0, 0, 6, 5, 4 },
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{8, 1, 2, 0, 0, 11, 22, 21, 20},
|
||||
{24, 17, 0, 23, 0, 3, 14, 5, 4 },
|
||||
{24, 0, 2, 23, 0, 3, 22, 13, 4 },
|
||||
{0, 1, 2, 23, 0, 3, 22, 21, 12}
|
||||
};
|
||||
|
||||
size_t enterDirection = (curr.x - next.x + 1) + 3 * (curr.y - next.y + 1);
|
||||
size_t leaveDirection = (prev.x - curr.x + 1) + 3 * (prev.y - curr.y + 1);
|
||||
size_t imageIndex = directionToArrowIndex[enterDirection][leaveDirection];
|
||||
|
||||
renderImage(target, reachableToday, imageIndex);
|
||||
}
|
||||
|
||||
void MapRendererPath::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)
|
||||
{
|
||||
const auto & functor = [&](const CGPathNode & node)
|
||||
{
|
||||
return node.coord == coordinates;
|
||||
};
|
||||
|
||||
const auto * path = context.currentPath();
|
||||
if(!path)
|
||||
return;
|
||||
|
||||
const auto & iter = boost::range::find_if(path->nodes, functor);
|
||||
|
||||
if(iter == path->nodes.end())
|
||||
return;
|
||||
|
||||
bool reachableToday = iter->turns == 0;
|
||||
if(iter == path->nodes.begin())
|
||||
renderImageCross(target, reachableToday, iter->coord);
|
||||
|
||||
auto next = iter + 1;
|
||||
auto prev = iter - 1;
|
||||
|
||||
// start of path - currentl hero location
|
||||
if(next == path->nodes.end())
|
||||
return;
|
||||
|
||||
bool pathContinuous = iter->coord.areNeighbours(next->coord) && iter->coord.areNeighbours(prev->coord);
|
||||
bool embarking = iter->action == CGPathNode::EMBARK || iter->action == CGPathNode::DISEMBARK;
|
||||
|
||||
if(pathContinuous && !embarking)
|
||||
renderImageArrow(target, reachableToday, iter->coord, prev->coord, next->coord);
|
||||
else
|
||||
renderImageCross(target, reachableToday, iter->coord);
|
||||
}
|
||||
|
||||
MapRenderer::MapRenderer(const IMapRendererContext & context)
|
||||
: rendererObjects(context)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MapRenderer::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)
|
||||
@ -560,6 +649,7 @@ void MapRenderer::renderTile(const IMapRendererContext & context, Canvas & targe
|
||||
rendererRiver.renderTile(context, target, coordinates);
|
||||
rendererRoad.renderTile(context, target, coordinates);
|
||||
rendererObjects.renderTile(context, target, coordinates);
|
||||
rendererPath.renderTile(context, target, coordinates);
|
||||
|
||||
if (!context.isVisible(coordinates))
|
||||
rendererFow.renderTile(context, target, coordinates);
|
||||
|
@ -113,6 +113,19 @@ public:
|
||||
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
|
||||
};
|
||||
|
||||
class MapRendererPath
|
||||
{
|
||||
std::unique_ptr<CAnimation> pathNodes;
|
||||
|
||||
void renderImage(Canvas & target, bool reachableToday, size_t imageIndex);
|
||||
void renderImageCross(Canvas & target, bool reachableToday, const int3 & curr);
|
||||
void renderImageArrow(Canvas & target, bool reachableToday, const int3 & curr, const int3 & prev, const int3 & next);
|
||||
public:
|
||||
MapRendererPath();
|
||||
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
|
||||
};
|
||||
|
||||
|
||||
class MapRendererDebugGrid
|
||||
{
|
||||
public:
|
||||
@ -127,6 +140,7 @@ class MapRenderer
|
||||
MapRendererBorder rendererBorder;
|
||||
MapRendererFow rendererFow;
|
||||
MapRendererObjects rendererObjects;
|
||||
MapRendererPath rendererPath;
|
||||
MapRendererDebugGrid rendererDebugGrid;
|
||||
|
||||
public:
|
||||
|
@ -18,6 +18,7 @@ class Point;
|
||||
class ObjectInstanceID;
|
||||
class CGObjectInstance;
|
||||
struct TerrainTile;
|
||||
struct CGPath;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
@ -26,22 +27,38 @@ class IMapRendererContext
|
||||
public:
|
||||
virtual ~IMapRendererContext() = default;
|
||||
|
||||
using VisibilityMap = std::shared_ptr<const boost::multi_array<ui8, 3>>;
|
||||
using ObjectsVector = std::vector< ConstTransitivePtr<CGObjectInstance> >;
|
||||
|
||||
/// returns dimensions of current map
|
||||
virtual int3 getMapSize() const = 0;
|
||||
|
||||
/// returns true if chosen coordinates exist on map
|
||||
virtual bool isInMap(const int3 & coordinates) const = 0;
|
||||
|
||||
/// returns tile by selected coordinates. Coordinates MUST be valid
|
||||
virtual const TerrainTile & getMapTile(const int3 & coordinates) const = 0;
|
||||
|
||||
/// returns vector of all objects present on current map
|
||||
virtual ObjectsVector getAllObjects() const = 0;
|
||||
|
||||
/// returns specific object by ID, or nullptr if not found
|
||||
virtual const CGObjectInstance * getObject( ObjectInstanceID objectID ) const = 0;
|
||||
|
||||
virtual bool isVisible(const int3 & coordinates) const = 0;
|
||||
virtual VisibilityMap getVisibilityMap() const = 0;
|
||||
/// returns path of currently active hero, or nullptr if none
|
||||
virtual const CGPath * currentPath() const = 0;
|
||||
|
||||
/// returns true if specified tile is visible in current context
|
||||
virtual bool isVisible(const int3 & coordinates) const = 0;
|
||||
|
||||
/// returns how long should each frame of animation be visible, in milliseconds
|
||||
virtual uint32_t getAnimationPeriod() const = 0;
|
||||
|
||||
/// returns total animation time since creation of this context
|
||||
virtual uint32_t getAnimationTime() const = 0;
|
||||
|
||||
/// returns size of ouput tile, in pixels. 32x32 for "standard" map, may be smaller for world view mode
|
||||
virtual Point tileSize() const = 0;
|
||||
|
||||
/// if true, map grid should be visible on map
|
||||
virtual bool showGrid() const = 0;
|
||||
};
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "MapRenderer.h"
|
||||
#include "mapHandler.h"
|
||||
#include "CAdvMapInt.h"
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CMusicHandler.h"
|
||||
@ -266,9 +267,17 @@ bool MapRendererContext::isVisible(const int3 & coordinates) const
|
||||
return LOCPLINT->cb->isVisible(coordinates) || settings["session"]["spectate"].Bool();
|
||||
}
|
||||
|
||||
MapRendererContext::VisibilityMap MapRendererContext::getVisibilityMap() const
|
||||
const CGPath * MapRendererContext::currentPath() const
|
||||
{
|
||||
return LOCPLINT->cb->getVisibilityMap();
|
||||
const auto * hero = adventureInt->curHero();
|
||||
|
||||
if(!hero)
|
||||
return nullptr;
|
||||
|
||||
if(!LOCPLINT->paths.hasPath(hero))
|
||||
return nullptr;
|
||||
|
||||
return &LOCPLINT->paths.getPath(hero);
|
||||
}
|
||||
|
||||
uint32_t MapRendererContext::getAnimationPeriod() const
|
||||
|
@ -30,8 +30,9 @@ public:
|
||||
ObjectsVector getAllObjects() const override;
|
||||
const CGObjectInstance * getObject(ObjectInstanceID objectID) const override;
|
||||
|
||||
const CGPath * currentPath() const override;
|
||||
|
||||
bool isVisible(const int3 & coordinates) const override;
|
||||
VisibilityMap getVisibilityMap() const override;
|
||||
|
||||
uint32_t getAnimationPeriod() const override;
|
||||
uint32_t getAnimationTime() const override;
|
||||
|
Loading…
Reference in New Issue
Block a user