mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Added basic overlay support for World View mode
This commit is contained in:
parent
def1e35836
commit
1c144637c1
@ -136,6 +136,15 @@ public:
|
||||
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
|
||||
{
|
||||
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
|
||||
// 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
|
||||
virtual bool showGrid() const = 0;
|
||||
virtual bool showVisitable() const = 0;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../render/CAnimation.h"
|
||||
#include "../render/Canvas.h"
|
||||
#include "../render/IImage.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
@ -33,9 +34,14 @@ MapViewCache::~MapViewCache() = default;
|
||||
MapViewCache::MapViewCache(const std::shared_ptr<MapViewModel> & model)
|
||||
: model(model)
|
||||
, mapRenderer(new MapRenderer())
|
||||
, iconsStorage(new CAnimation("VwSymbol"))
|
||||
, intermediate(new Canvas(Point(32,32)))
|
||||
, 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)
|
||||
@ -43,6 +49,45 @@ Canvas MapViewCache::getTile(const int3 & 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)
|
||||
{
|
||||
Canvas target = getTile(coordinates);
|
||||
@ -67,7 +112,7 @@ void MapViewCache::update(const std::shared_ptr<MapRendererContext> & context)
|
||||
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();
|
||||
|
||||
@ -79,6 +124,17 @@ void MapViewCache::render(Canvas & target)
|
||||
Canvas source = getTile(tile);
|
||||
Rect targetRect = model->getTargetTileArea(tile);
|
||||
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());
|
||||
tilesCache->update(context);
|
||||
tilesCache->render(targetClipped);
|
||||
tilesCache->render(context, targetClipped);
|
||||
}
|
||||
|
||||
void MapView::showAll(SDL_Surface * to)
|
||||
@ -194,6 +250,11 @@ size_t MapRendererContext::terrainImageIndex(size_t groupSize) const
|
||||
// return Point(32, 32);
|
||||
//}
|
||||
|
||||
bool MapRendererContext::showOverlay() const
|
||||
{
|
||||
return worldViewModeActive;
|
||||
}
|
||||
|
||||
bool MapRendererContext::showGrid() const
|
||||
{
|
||||
return settings["gameTweaks"]["showGrid"].Bool();
|
||||
@ -550,7 +611,8 @@ void MapViewController::update(uint32_t 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)
|
||||
|
@ -38,7 +38,7 @@ class MapRendererContext : public IMapRendererContext
|
||||
|
||||
boost::multi_array<MapObjectsList, 3> objects;
|
||||
|
||||
Point tileSize = Point(32, 32);
|
||||
//Point tileSize = Point(32, 32);
|
||||
uint32_t animationTime = 0;
|
||||
|
||||
boost::optional<HeroAnimationState> movementAnimation;
|
||||
@ -47,6 +47,8 @@ class MapRendererContext : public IMapRendererContext
|
||||
boost::optional<FadingAnimationState> fadeOutAnimation;
|
||||
boost::optional<FadingAnimationState> fadeInAnimation;
|
||||
|
||||
bool worldViewModeActive = false;
|
||||
|
||||
public:
|
||||
MapRendererContext();
|
||||
|
||||
@ -69,6 +71,8 @@ public:
|
||||
size_t objectImageIndex(ObjectInstanceID objectID, size_t groupSize) const override;
|
||||
size_t terrainImageIndex(size_t groupSize) const override;
|
||||
// Point getTileSize() const override;
|
||||
|
||||
bool showOverlay() const override;
|
||||
bool showGrid() const override;
|
||||
bool showVisitable() const override;
|
||||
bool showBlockable() const override;
|
||||
@ -130,10 +134,12 @@ class MapViewCache
|
||||
std::unique_ptr<Canvas> intermediate;
|
||||
std::unique_ptr<MapRenderer> mapRenderer;
|
||||
|
||||
std::unique_ptr<CAnimation> iconsStorage;
|
||||
|
||||
Canvas getTile(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:
|
||||
explicit MapViewCache(const std::shared_ptr<MapViewModel> & model);
|
||||
~MapViewCache();
|
||||
@ -142,7 +148,7 @@ public:
|
||||
void update(const std::shared_ptr<MapRendererContext> & context);
|
||||
|
||||
/// 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,
|
||||
|
@ -22,108 +22,6 @@
|
||||
#include "../../lib/CGeneralTextHandler.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
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user