mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-15 01:24:45 +02:00
Added basic overlay support for World View mode
This commit is contained in:
@ -136,6 +136,15 @@ public:
|
|||||||
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
|
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MapRendererOverlay
|
||||||
|
{
|
||||||
|
std::unique_ptr<CAnimation> iconsStorage;
|
||||||
|
public:
|
||||||
|
MapRendererOverlay();
|
||||||
|
|
||||||
|
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
|
||||||
|
};
|
||||||
|
|
||||||
class MapRenderer
|
class MapRenderer
|
||||||
{
|
{
|
||||||
MapRendererTerrain rendererTerrain;
|
MapRendererTerrain rendererTerrain;
|
||||||
|
@ -67,6 +67,9 @@ public:
|
|||||||
// /// returns size of ouput tile, in pixels. 32x32 for "standard" map, may be smaller for world view mode
|
// /// returns size of ouput tile, in pixels. 32x32 for "standard" map, may be smaller for world view mode
|
||||||
// virtual Point getTileSize() const = 0;
|
// virtual Point getTileSize() const = 0;
|
||||||
|
|
||||||
|
/// if true, world view overlay will be shown
|
||||||
|
virtual bool showOverlay() const = 0;
|
||||||
|
|
||||||
/// if true, map grid should be visible on map
|
/// if true, map grid should be visible on map
|
||||||
virtual bool showGrid() const = 0;
|
virtual bool showGrid() const = 0;
|
||||||
virtual bool showVisitable() const = 0;
|
virtual bool showVisitable() const = 0;
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "../gui/CGuiHandler.h"
|
#include "../gui/CGuiHandler.h"
|
||||||
#include "../render/CAnimation.h"
|
#include "../render/CAnimation.h"
|
||||||
#include "../render/Canvas.h"
|
#include "../render/Canvas.h"
|
||||||
|
#include "../render/IImage.h"
|
||||||
#include "../renderSDL/SDL_Extensions.h"
|
#include "../renderSDL/SDL_Extensions.h"
|
||||||
|
|
||||||
#include "../../CCallback.h"
|
#include "../../CCallback.h"
|
||||||
@ -33,9 +34,14 @@ MapViewCache::~MapViewCache() = default;
|
|||||||
MapViewCache::MapViewCache(const std::shared_ptr<MapViewModel> & model)
|
MapViewCache::MapViewCache(const std::shared_ptr<MapViewModel> & model)
|
||||||
: model(model)
|
: model(model)
|
||||||
, mapRenderer(new MapRenderer())
|
, mapRenderer(new MapRenderer())
|
||||||
|
, iconsStorage(new CAnimation("VwSymbol"))
|
||||||
, intermediate(new Canvas(Point(32,32)))
|
, intermediate(new Canvas(Point(32,32)))
|
||||||
, terrain(new Canvas(model->getCacheDimensionsPixels()))
|
, terrain(new Canvas(model->getCacheDimensionsPixels()))
|
||||||
{
|
{
|
||||||
|
iconsStorage->preload();
|
||||||
|
for (size_t i = 0; i < iconsStorage->size(); ++i)
|
||||||
|
iconsStorage->getImage(i)->setBlitMode(EImageBlitMode::COLORKEY);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Canvas MapViewCache::getTile(const int3 & coordinates)
|
Canvas MapViewCache::getTile(const int3 & coordinates)
|
||||||
@ -43,6 +49,45 @@ Canvas MapViewCache::getTile(const int3 & coordinates)
|
|||||||
return Canvas(*terrain, model->getCacheTileArea(coordinates));
|
return Canvas(*terrain, model->getCacheTileArea(coordinates));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<IImage> MapViewCache::getOverlayImageForTile(const std::shared_ptr<MapRendererContext> & context, const int3 & coordinates)
|
||||||
|
{
|
||||||
|
if (!context->isVisible(coordinates))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
for(const auto & objectID : context->getObjects(coordinates))
|
||||||
|
{
|
||||||
|
const auto * object = context->getObject(objectID);
|
||||||
|
|
||||||
|
if (!object->visitableAt(coordinates.x, coordinates.y))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
size_t ownerIndex = PlayerColor::PLAYER_LIMIT.getNum() * static_cast<size_t>(EWorldViewIcon::ICONS_PER_PLAYER);
|
||||||
|
if (object->tempOwner.isValidPlayer())
|
||||||
|
ownerIndex = object->tempOwner.getNum() * static_cast<size_t>(EWorldViewIcon::ICONS_PER_PLAYER);
|
||||||
|
|
||||||
|
switch (object->ID)
|
||||||
|
{
|
||||||
|
case Obj::MONOLITH_ONE_WAY_ENTRANCE:
|
||||||
|
case Obj::MONOLITH_ONE_WAY_EXIT:
|
||||||
|
case Obj::MONOLITH_TWO_WAY:
|
||||||
|
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::TELEPORT));
|
||||||
|
case Obj::SUBTERRANEAN_GATE:
|
||||||
|
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::GATE));
|
||||||
|
case Obj::ARTIFACT:
|
||||||
|
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::ARTIFACT));
|
||||||
|
case Obj::TOWN:
|
||||||
|
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::TOWN));
|
||||||
|
case Obj::HERO:
|
||||||
|
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::HERO));
|
||||||
|
case Obj::MINE:
|
||||||
|
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::MINE_WOOD) + object->subID);
|
||||||
|
case Obj::RESOURCE:
|
||||||
|
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::RES_WOOD) + object->subID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void MapViewCache::updateTile(const std::shared_ptr<MapRendererContext> & context, const int3 & coordinates)
|
void MapViewCache::updateTile(const std::shared_ptr<MapRendererContext> & context, const int3 & coordinates)
|
||||||
{
|
{
|
||||||
Canvas target = getTile(coordinates);
|
Canvas target = getTile(coordinates);
|
||||||
@ -67,7 +112,7 @@ void MapViewCache::update(const std::shared_ptr<MapRendererContext> & context)
|
|||||||
updateTile(context, {x, y, model->getLevel()});
|
updateTile(context, {x, y, model->getLevel()});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapViewCache::render(Canvas & target)
|
void MapViewCache::render(const std::shared_ptr<MapRendererContext> & context, Canvas & target)
|
||||||
{
|
{
|
||||||
Rect dimensions = model->getTilesTotalRect();
|
Rect dimensions = model->getTilesTotalRect();
|
||||||
|
|
||||||
@ -79,6 +124,17 @@ void MapViewCache::render(Canvas & target)
|
|||||||
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());
|
||||||
|
|
||||||
|
if (context->showOverlay())
|
||||||
|
{
|
||||||
|
auto overlay = getOverlayImageForTile(context, tile);
|
||||||
|
|
||||||
|
if (overlay)
|
||||||
|
{
|
||||||
|
Point position = targetRect.center() - overlay->dimensions() / 2;
|
||||||
|
target.draw(overlay, position);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +171,7 @@ void MapView::show(SDL_Surface * to)
|
|||||||
|
|
||||||
controller->update(GH.mainFPSmng->getElapsedMilliseconds());
|
controller->update(GH.mainFPSmng->getElapsedMilliseconds());
|
||||||
tilesCache->update(context);
|
tilesCache->update(context);
|
||||||
tilesCache->render(targetClipped);
|
tilesCache->render(context, targetClipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapView::showAll(SDL_Surface * to)
|
void MapView::showAll(SDL_Surface * to)
|
||||||
@ -194,6 +250,11 @@ size_t MapRendererContext::terrainImageIndex(size_t groupSize) const
|
|||||||
// return Point(32, 32);
|
// return Point(32, 32);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
bool MapRendererContext::showOverlay() const
|
||||||
|
{
|
||||||
|
return worldViewModeActive;
|
||||||
|
}
|
||||||
|
|
||||||
bool MapRendererContext::showGrid() const
|
bool MapRendererContext::showGrid() const
|
||||||
{
|
{
|
||||||
return settings["gameTweaks"]["showGrid"].Bool();
|
return settings["gameTweaks"]["showGrid"].Bool();
|
||||||
@ -550,7 +611,8 @@ void MapViewController::update(uint32_t timeDelta)
|
|||||||
}
|
}
|
||||||
|
|
||||||
context->animationTime += timeDelta;
|
context->animationTime += timeDelta;
|
||||||
context->tileSize = Point(32,32); //model->getSingleTileSize();
|
//context->tileSize = Point(32,32); //model->getSingleTileSize();
|
||||||
|
context->worldViewModeActive = model->getSingleTileSize() != Point(32,32);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapViewController::onObjectFadeIn(const CGObjectInstance * obj)
|
void MapViewController::onObjectFadeIn(const CGObjectInstance * obj)
|
||||||
|
@ -38,7 +38,7 @@ class MapRendererContext : public IMapRendererContext
|
|||||||
|
|
||||||
boost::multi_array<MapObjectsList, 3> objects;
|
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> movementAnimation;
|
||||||
@ -47,6 +47,8 @@ class MapRendererContext : public IMapRendererContext
|
|||||||
boost::optional<FadingAnimationState> fadeOutAnimation;
|
boost::optional<FadingAnimationState> fadeOutAnimation;
|
||||||
boost::optional<FadingAnimationState> fadeInAnimation;
|
boost::optional<FadingAnimationState> fadeInAnimation;
|
||||||
|
|
||||||
|
bool worldViewModeActive = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MapRendererContext();
|
MapRendererContext();
|
||||||
|
|
||||||
@ -69,6 +71,8 @@ public:
|
|||||||
size_t objectImageIndex(ObjectInstanceID objectID, size_t groupSize) const override;
|
size_t objectImageIndex(ObjectInstanceID objectID, size_t groupSize) const override;
|
||||||
size_t terrainImageIndex(size_t groupSize) const override;
|
size_t terrainImageIndex(size_t groupSize) const override;
|
||||||
// Point getTileSize() const override;
|
// Point getTileSize() const override;
|
||||||
|
|
||||||
|
bool showOverlay() const override;
|
||||||
bool showGrid() const override;
|
bool showGrid() const override;
|
||||||
bool showVisitable() const override;
|
bool showVisitable() const override;
|
||||||
bool showBlockable() const override;
|
bool showBlockable() const override;
|
||||||
@ -130,10 +134,12 @@ class MapViewCache
|
|||||||
std::unique_ptr<Canvas> intermediate;
|
std::unique_ptr<Canvas> intermediate;
|
||||||
std::unique_ptr<MapRenderer> mapRenderer;
|
std::unique_ptr<MapRenderer> mapRenderer;
|
||||||
|
|
||||||
|
std::unique_ptr<CAnimation> iconsStorage;
|
||||||
|
|
||||||
Canvas getTile(const int3 & coordinates);
|
Canvas getTile(const int3 & coordinates);
|
||||||
void updateTile(const std::shared_ptr<MapRendererContext> & context, const int3 & coordinates);
|
void updateTile(const std::shared_ptr<MapRendererContext> & context, const int3 & coordinates);
|
||||||
|
|
||||||
|
std::shared_ptr<IImage> getOverlayImageForTile(const std::shared_ptr<MapRendererContext> & context, const int3 & coordinates);
|
||||||
public:
|
public:
|
||||||
explicit MapViewCache(const std::shared_ptr<MapViewModel> & model);
|
explicit MapViewCache(const std::shared_ptr<MapViewModel> & model);
|
||||||
~MapViewCache();
|
~MapViewCache();
|
||||||
@ -142,7 +148,7 @@ public:
|
|||||||
void update(const std::shared_ptr<MapRendererContext> & context);
|
void update(const std::shared_ptr<MapRendererContext> & context);
|
||||||
|
|
||||||
/// renders updated terrain cache onto provided canvas
|
/// renders updated terrain cache onto provided canvas
|
||||||
void render(Canvas & target);
|
void render(const std::shared_ptr<MapRendererContext> &context, Canvas & target);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Class responsible for updating view state,
|
/// Class responsible for updating view state,
|
||||||
|
@ -22,108 +22,6 @@
|
|||||||
#include "../../lib/CGeneralTextHandler.h"
|
#include "../../lib/CGeneralTextHandler.h"
|
||||||
#include "../../lib/TerrainHandler.h"
|
#include "../../lib/TerrainHandler.h"
|
||||||
|
|
||||||
/*
|
|
||||||
std::shared_ptr<IImage> CMapWorldViewBlitter::objectToIcon(Obj id, si32 subId, PlayerColor owner) const
|
|
||||||
{
|
|
||||||
int ownerIndex = 0;
|
|
||||||
if(owner < PlayerColor::PLAYER_LIMIT)
|
|
||||||
{
|
|
||||||
ownerIndex = owner.getNum() * 19;
|
|
||||||
}
|
|
||||||
else if (owner == PlayerColor::NEUTRAL)
|
|
||||||
{
|
|
||||||
ownerIndex = PlayerColor::PLAYER_LIMIT.getNum() * 19;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(id)
|
|
||||||
{
|
|
||||||
case Obj::MONOLITH_ONE_WAY_ENTRANCE:
|
|
||||||
case Obj::MONOLITH_ONE_WAY_EXIT:
|
|
||||||
case Obj::MONOLITH_TWO_WAY:
|
|
||||||
return info->icons->getImage((int)EWorldViewIcon::TELEPORT);
|
|
||||||
case Obj::SUBTERRANEAN_GATE:
|
|
||||||
return info->icons->getImage((int)EWorldViewIcon::GATE);
|
|
||||||
case Obj::ARTIFACT:
|
|
||||||
return info->icons->getImage((int)EWorldViewIcon::ARTIFACT);
|
|
||||||
case Obj::TOWN:
|
|
||||||
return info->icons->getImage((int)EWorldViewIcon::TOWN + ownerIndex);
|
|
||||||
case Obj::HERO:
|
|
||||||
return info->icons->getImage((int)EWorldViewIcon::HERO + ownerIndex);
|
|
||||||
case Obj::MINE:
|
|
||||||
return info->icons->getImage((int)EWorldViewIcon::MINE_WOOD + subId + ownerIndex);
|
|
||||||
case Obj::RESOURCE:
|
|
||||||
return info->icons->getImage((int)EWorldViewIcon::RES_WOOD + subId + ownerIndex);
|
|
||||||
}
|
|
||||||
return std::shared_ptr<IImage>();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
void CMapWorldViewBlitter::drawTileOverlay(SDL_Surface * targetSurf, const TerrainTile2 & tile) const
|
|
||||||
{
|
|
||||||
auto drawIcon = [this,targetSurf](Obj id, si32 subId, PlayerColor owner)
|
|
||||||
{
|
|
||||||
auto wvIcon = this->objectToIcon(id, subId, owner);
|
|
||||||
|
|
||||||
if(nullptr != wvIcon)
|
|
||||||
{
|
|
||||||
// centering icon on the object
|
|
||||||
Point dest(realPos.x + tileSize / 2 - wvIcon->width() / 2, realPos.y + tileSize / 2 - wvIcon->height() / 2);
|
|
||||||
wvIcon->draw(targetSurf, dest.x, dest.y);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto & objects = tile.objects;
|
|
||||||
for(auto & object : objects)
|
|
||||||
{
|
|
||||||
const CGObjectInstance * obj = object.obj;
|
|
||||||
if(!obj)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const bool sameLevel = obj->pos.z == pos.z;
|
|
||||||
|
|
||||||
//FIXME: Don't read options in a loop :v
|
|
||||||
const bool isVisible = settings["session"]["spectate"].Bool() ? true : (*info->visibilityMap)[pos.z][pos.x][pos.y];
|
|
||||||
const bool isVisitable = obj->visitableAt(pos.x, pos.y);
|
|
||||||
|
|
||||||
if(sameLevel && isVisible && isVisitable)
|
|
||||||
drawIcon(obj->ID, obj->subID, obj->tempOwner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
void CMapWorldViewBlitter::drawOverlayEx(SDL_Surface * targetSurf)
|
|
||||||
{
|
|
||||||
if(nullptr == info->additionalIcons)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const int3 bottomRight = pos + tileCount;
|
|
||||||
|
|
||||||
for(const ObjectPosInfo & iconInfo : *(info->additionalIcons))
|
|
||||||
{
|
|
||||||
if( iconInfo.pos.z != pos.z)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if((iconInfo.pos.x < topTile.x) || (iconInfo.pos.y < topTile.y))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if((iconInfo.pos.x > bottomRight.x) || (iconInfo.pos.y > bottomRight.y))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
realPos.x = initPos.x + (iconInfo.pos.x - topTile.x) * tileSize;
|
|
||||||
realPos.y = initPos.y + (iconInfo.pos.y - topTile.y) * tileSize;
|
|
||||||
|
|
||||||
auto wvIcon = this->objectToIcon(iconInfo.id, iconInfo.subId, iconInfo.owner);
|
|
||||||
|
|
||||||
if(nullptr != wvIcon)
|
|
||||||
{
|
|
||||||
// centering icon on the object
|
|
||||||
Point dest(realPos.x + tileSize / 2 - wvIcon->width() / 2, realPos.y + tileSize / 2 - wvIcon->height() / 2);
|
|
||||||
wvIcon->draw(targetSurf, dest.x, dest.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/*
|
/*
|
||||||
void CMapPuzzleViewBlitter::drawObjects(SDL_Surface * targetSurf, const TerrainTile2 & tile) const
|
void CMapPuzzleViewBlitter::drawObjects(SDL_Surface * targetSurf, const TerrainTile2 & tile) const
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user