1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-15 11:46:56 +02:00

Completely removed old TerrainRect class

This commit is contained in:
Ivan Savenko 2023-02-23 19:46:41 +02:00
parent fbb8c18c23
commit 45e2875342
25 changed files with 555 additions and 516 deletions

View File

@ -10,7 +10,6 @@ set(client_SRCS
adventureMap/CList.cpp adventureMap/CList.cpp
adventureMap/CMinimap.cpp adventureMap/CMinimap.cpp
adventureMap/CResDataBar.cpp adventureMap/CResDataBar.cpp
adventureMap/CTerrainRect.cpp
battle/BattleActionsController.cpp battle/BattleActionsController.cpp
battle/BattleAnimationClasses.cpp battle/BattleAnimationClasses.cpp
@ -50,6 +49,7 @@ set(client_SRCS
mapRenderer/MapRenderer.cpp mapRenderer/MapRenderer.cpp
mapRenderer/MapRendererContext.cpp mapRenderer/MapRendererContext.cpp
mapRenderer/MapView.cpp mapRenderer/MapView.cpp
mapRenderer/MapViewActions.cpp
mapRenderer/MapViewCache.cpp mapRenderer/MapViewCache.cpp
mapRenderer/MapViewController.cpp mapRenderer/MapViewController.cpp
mapRenderer/MapViewModel.cpp mapRenderer/MapViewModel.cpp
@ -127,7 +127,6 @@ set(client_HEADERS
adventureMap/CList.h adventureMap/CList.h
adventureMap/CMinimap.h adventureMap/CMinimap.h
adventureMap/CResDataBar.h adventureMap/CResDataBar.h
adventureMap/CTerrainRect.h
battle/BattleActionsController.h battle/BattleActionsController.h
battle/BattleAnimationClasses.h battle/BattleAnimationClasses.h
@ -172,7 +171,7 @@ set(client_HEADERS
mapRenderer/MapRenderer.h mapRenderer/MapRenderer.h
mapRenderer/MapRendererContext.h mapRenderer/MapRendererContext.h
mapRenderer/MapView.h mapRenderer/MapView.h
mapRenderer/MapViewCache.cpp mapRenderer/MapViewActions.h
mapRenderer/MapViewCache.h mapRenderer/MapViewCache.h
mapRenderer/MapViewController.h mapRenderer/MapViewController.h
mapRenderer/MapViewModel.h mapRenderer/MapViewModel.h

View File

@ -14,7 +14,6 @@
#include "adventureMap/CAdvMapInt.h" #include "adventureMap/CAdvMapInt.h"
#include "mapRenderer/mapHandler.h" #include "mapRenderer/mapHandler.h"
#include "adventureMap/CList.h" #include "adventureMap/CList.h"
#include "adventureMap/CTerrainRect.h"
#include "adventureMap/CInfoBar.h" #include "adventureMap/CInfoBar.h"
#include "adventureMap/CMinimap.h" #include "adventureMap/CMinimap.h"
#include "battle/BattleInterface.h" #include "battle/BattleInterface.h"
@ -382,13 +381,11 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
return; return;
} }
adventureInt->minimap->redraw();
adventureInt->heroList->redraw(); adventureInt->heroList->redraw();
CGI->mh->waitForOngoingAnimations(); CGI->mh->waitForOngoingAnimations();
//move finished //move finished
adventureInt->minimap->redraw();
adventureInt->heroList->update(hero); adventureInt->heroList->update(hero);
//check if user cancelled movement //check if user cancelled movement
@ -1480,7 +1477,7 @@ void CPlayerInterface::centerView (int3 pos, int focusTime)
EVENT_HANDLER_CALLED_BY_CLIENT; EVENT_HANDLER_CALLED_BY_CLIENT;
waitWhileDialog(); waitWhileDialog();
CCS->curh->hide(); CCS->curh->hide();
adventureInt->centerOn (pos); adventureInt->centerOnTile(pos);
if (focusTime) if (focusTime)
{ {
GH.totalRedraw(); GH.totalRedraw();

View File

@ -15,11 +15,13 @@
#include "CInGameConsole.h" #include "CInGameConsole.h"
#include "CMinimap.h" #include "CMinimap.h"
#include "CResDataBar.h" #include "CResDataBar.h"
#include "CTerrainRect.h"
#include "CList.h" #include "CList.h"
#include "CInfoBar.h" #include "CInfoBar.h"
#include "../mapRenderer/mapHandler.h" #include "../mapRenderer/mapHandler.h"
#include "../mapRenderer/MapView.h"
#include "../mapRenderer/MapViewModel.h"
#include "../mapRenderer/MapViewController.h"
#include "../windows/CKingdomInterface.h" #include "../windows/CKingdomInterface.h"
#include "../windows/CSpellWindow.h" #include "../windows/CSpellWindow.h"
#include "../windows/CTradeWindow.h" #include "../windows/CTradeWindow.h"
@ -87,7 +89,7 @@ CAdvMapInt::CAdvMapInt():
townList(new CTownList(ADVOPT.tlistSize, Point(ADVOPT.tlistX, ADVOPT.tlistY), ADVOPT.tlistAU, ADVOPT.tlistAD)), townList(new CTownList(ADVOPT.tlistSize, Point(ADVOPT.tlistX, ADVOPT.tlistY), ADVOPT.tlistAU, ADVOPT.tlistAD)),
infoBar(new CInfoBar(Rect(ADVOPT.infoboxX, ADVOPT.infoboxY, 192, 192))), infoBar(new CInfoBar(Rect(ADVOPT.infoboxX, ADVOPT.infoboxY, 192, 192))),
resdatabar(new CResDataBar), resdatabar(new CResDataBar),
terrain(new CTerrainRect), terrain(new MapView(Point(ADVOPT.advmapX, ADVOPT.advmapY), Point(ADVOPT.advmapW, ADVOPT.advmapH))),
state(NA), state(NA),
spellBeingCasted(nullptr), spellBeingCasted(nullptr),
selection(nullptr), selection(nullptr),
@ -258,7 +260,7 @@ void CAdvMapInt::fworldViewBack()
auto hero = curHero(); auto hero = curHero();
if (hero) if (hero)
centerOn(hero); centerOnObject(hero);
} }
void CAdvMapInt::fworldViewScale1x() void CAdvMapInt::fworldViewScale1x()
@ -284,15 +286,18 @@ void CAdvMapInt::fswitchLevel()
if (maxLevels < 2) if (maxLevels < 2)
return; return;
terrain->setLevel((terrain->getLevel() + 1) % maxLevels); terrain->onMapLevelSwitched();
}
underground->setIndex(terrain->getLevel(), true); void CAdvMapInt::onMapViewMoved(const Rect & visibleArea, int mapLevel)
{
underground->setIndex(mapLevel, true);
underground->redraw(); underground->redraw();
worldViewUnderground->setIndex(terrain->getLevel(), true); worldViewUnderground->setIndex(mapLevel, true);
worldViewUnderground->redraw(); worldViewUnderground->redraw();
minimap->setLevel(terrain->getLevel()); minimap->onMapViewMoved(visibleArea, mapLevel);
} }
void CAdvMapInt::fshowQuestlog() void CAdvMapInt::fshowQuestlog()
@ -332,7 +337,7 @@ void CAdvMapInt::fshowSpellbok()
if (!curHero()) //checking necessary values if (!curHero()) //checking necessary values
return; return;
centerOn(selection); centerOnObject(selection);
GH.pushIntT<CSpellWindow>(curHero(), LOCPLINT, false); GH.pushIntT<CSpellWindow>(curHero(), LOCPLINT, false);
} }
@ -570,6 +575,7 @@ void CAdvMapInt::show(SDL_Surface * to)
gems[i]->setFrame(LOCPLINT->playerID.getNum()); gems[i]->setFrame(LOCPLINT->playerID.getNum());
} }
minimap->show(to);
terrain->show(to); terrain->show(to);
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
@ -589,16 +595,16 @@ void CAdvMapInt::handleMapScrollingUpdate()
//if advmap needs updating AND (no dialog is shown OR ctrl is pressed) //if advmap needs updating AND (no dialog is shown OR ctrl is pressed)
if(scrollingDir & LEFT) if(scrollingDir & LEFT)
terrain->moveViewBy(Point(-scrollDistance, 0)); terrain->onMapScrolled(Point(-scrollDistance, 0));
if(scrollingDir & RIGHT) if(scrollingDir & RIGHT)
terrain->moveViewBy(Point(+scrollDistance, 0)); terrain->onMapScrolled(Point(+scrollDistance, 0));
if(scrollingDir & UP) if(scrollingDir & UP)
terrain->moveViewBy(Point(0, -scrollDistance)); terrain->onMapScrolled(Point(0, -scrollDistance));
if(scrollingDir & DOWN) if(scrollingDir & DOWN)
terrain->moveViewBy(Point(0, +scrollDistance)); terrain->onMapScrolled(Point(0, +scrollDistance));
if(scrollingDir) if(scrollingDir)
{ {
@ -619,21 +625,14 @@ void CAdvMapInt::selectionChanged()
select(to); select(to);
} }
void CAdvMapInt::centerOn(int3 on) void CAdvMapInt::centerOnTile(int3 on)
{ {
terrain->setViewCenter(on); terrain->onCenteredTile(on);
underground->setIndex(on.z,true); //change underground switch button image
underground->redraw();
worldViewUnderground->setIndex(on.z, true);
worldViewUnderground->redraw();
minimap->setLevel(terrain->getLevel());
minimap->redraw();
} }
void CAdvMapInt::centerOn(const CGObjectInstance * obj) void CAdvMapInt::centerOnObject(const CGObjectInstance * obj)
{ {
centerOn(obj->getSightCenter()); terrain->onCenteredObject(obj);
} }
void CAdvMapInt::keyReleased(const SDL_Keycode &key) void CAdvMapInt::keyReleased(const SDL_Keycode &key)
@ -812,7 +811,7 @@ void CAdvMapInt::keyPressed(const SDL_Keycode & key)
if(*direction == Point(0,0)) if(*direction == Point(0,0))
{ {
centerOn(h); centerOnObject(h);
return; return;
} }
@ -871,7 +870,7 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView)
CCS->musich->playMusicFromSet("terrain", tile->terType->getJsonKey(), true, false); CCS->musich->playMusicFromSet("terrain", tile->terType->getJsonKey(), true, false);
} }
if(centerView) if(centerView)
centerOn(sel); centerOnObject(sel);
if(sel->ID==Obj::TOWN) if(sel->ID==Obj::TOWN)
{ {
@ -1046,7 +1045,7 @@ const CGObjectInstance* CAdvMapInt::getActiveObject(const int3 &mapPos)
return bobjs.front();*/ return bobjs.front();*/
} }
void CAdvMapInt::tileLClicked(const int3 &mapPos) void CAdvMapInt::onTileLeftClicked(const int3 &mapPos)
{ {
if(mode != EAdvMapMode::NORMAL) if(mode != EAdvMapMode::NORMAL)
return; return;
@ -1130,7 +1129,7 @@ void CAdvMapInt::tileLClicked(const int3 &mapPos)
} }
} }
void CAdvMapInt::tileHovered(const int3 &mapPos) void CAdvMapInt::onTileHovered(const int3 &mapPos)
{ {
if(mode != EAdvMapMode::NORMAL //disable in world view if(mode != EAdvMapMode::NORMAL //disable in world view
|| !selection) //may occur just at the start of game (fake move before full intiialization) || !selection) //may occur just at the start of game (fake move before full intiialization)
@ -1290,7 +1289,7 @@ void CAdvMapInt::showMoveDetailsInStatusbar(const CGHeroInstance & hero, const C
statusbar->write(result); statusbar->write(result);
} }
void CAdvMapInt::tileRClicked(const int3 &mapPos) void CAdvMapInt::onTileRightClicked(const int3 &mapPos)
{ {
if(mode != EAdvMapMode::NORMAL) if(mode != EAdvMapMode::NORMAL)
return; return;
@ -1375,11 +1374,6 @@ Rect CAdvMapInt::terrainAreaPixels() const
return terrain->pos; return terrain->pos;
} }
Rect CAdvMapInt::terrainAreaTiles() const
{
return terrain->visibleTilesArea();
}
const IShipyard * CAdvMapInt::ourInaccessibleShipyard(const CGObjectInstance *obj) const const IShipyard * CAdvMapInt::ourInaccessibleShipyard(const CGObjectInstance *obj) const
{ {
const IShipyard *ret = IShipyard::castFrom(obj); const IShipyard *ret = IShipyard::castFrom(obj);
@ -1440,9 +1434,7 @@ void CAdvMapInt::exitWorldView()
infoBar->activate(); infoBar->activate();
redraw(); redraw();
terrain->setTileSize(32); terrain->onViewMapActivated();
terrain->setTerrainVisibility(false);
terrain->setOverlayVisibility({});
} }
void CAdvMapInt::openWorldView(int tileSize) void CAdvMapInt::openWorldView(int tileSize)
@ -1459,7 +1451,7 @@ void CAdvMapInt::openWorldView(int tileSize)
infoBar->deactivate(); infoBar->deactivate();
redraw(); redraw();
terrain->setTileSize(tileSize); terrain->onViewWorldActivated(tileSize);
} }
void CAdvMapInt::openWorldView() void CAdvMapInt::openWorldView()
@ -1470,6 +1462,5 @@ void CAdvMapInt::openWorldView()
void CAdvMapInt::openWorldView(const std::vector<ObjectPosInfo>& objectPositions, bool showTerrain) void CAdvMapInt::openWorldView(const std::vector<ObjectPosInfo>& objectPositions, bool showTerrain)
{ {
openWorldView(11); openWorldView(11);
terrain->setTerrainVisibility(showTerrain); terrain->onViewSpellActivated(11, objectPositions, showTerrain);
terrain->setOverlayVisibility(objectPositions);
} }

View File

@ -33,7 +33,7 @@ class CGStatusBar;
class CAdvMapPanel; class CAdvMapPanel;
class CAdvMapWorldViewPanel; class CAdvMapWorldViewPanel;
class CAnimation; class CAnimation;
class CTerrainRect; class MapView;
class CResDataBar; class CResDataBar;
class CHeroList; class CHeroList;
class CTownList; class CTownList;
@ -55,7 +55,6 @@ class CAdvMapInt : public CIntObject
{ {
//TODO: remove //TODO: remove
friend class CPlayerInterface; friend class CPlayerInterface;
friend class CTerrainRect;
private: private:
enum EDirections {LEFT=1, RIGHT=2, UP=4, DOWN=8}; enum EDirections {LEFT=1, RIGHT=2, UP=4, DOWN=8};
@ -94,7 +93,7 @@ private:
std::shared_ptr<CButton> endTurn; std::shared_ptr<CButton> endTurn;
std::shared_ptr<CButton> worldViewUnderground; std::shared_ptr<CButton> worldViewUnderground;
std::shared_ptr<CTerrainRect> terrain; std::shared_ptr<MapView> terrain;
std::shared_ptr<CMinimap> minimap; std::shared_ptr<CMinimap> minimap;
std::shared_ptr<CHeroList> heroList; std::shared_ptr<CHeroList> heroList;
std::shared_ptr<CTownList> townList; std::shared_ptr<CTownList> townList;
@ -160,9 +159,13 @@ public:
// public interface // public interface
/// called by MapView whenever currently visible area changes
/// visibleArea describen now visible map section measured in tiles
void onMapViewMoved(const Rect & visibleArea, int mapLevel);
void select(const CArmedInstance *sel, bool centerView = true); void select(const CArmedInstance *sel, bool centerView = true);
void centerOn(int3 on); void centerOnTile(int3 on);
void centerOn(const CGObjectInstance *obj); void centerOnObject(const CGObjectInstance *obj);
bool isHeroSleeping(const CGHeroInstance *hero); bool isHeroSleeping(const CGHeroInstance *hero);
void setHeroSleeping(const CGHeroInstance *hero, bool sleep); void setHeroSleeping(const CGHeroInstance *hero, bool sleep);
@ -178,9 +181,9 @@ public:
void quickCombatLock(); //should be called when quick battle started void quickCombatLock(); //should be called when quick battle started
void quickCombatUnlock(); void quickCombatUnlock();
void tileLClicked(const int3 &mapPos); void onTileLeftClicked(const int3 & mapPos);
void tileHovered(const int3 &mapPos); void onTileHovered(const int3 & mapPos);
void tileRClicked(const int3 &mapPos); void onTileRightClicked(const int3 & mapPos);
void enterCastingMode(const CSpell * sp); void enterCastingMode(const CSpell * sp);
void leaveCastingMode(bool cast = false, int3 dest = int3(-1, -1, -1)); void leaveCastingMode(bool cast = false, int3 dest = int3(-1, -1, -1));
@ -194,9 +197,6 @@ public:
/// returns area of screen covered by terrain (main game area) /// returns area of screen covered by terrain (main game area)
Rect terrainAreaPixels() const; Rect terrainAreaPixels() const;
/// returs visible section of game map, in tiles
Rect terrainAreaTiles() const;
/// exits currently opened world view mode and returns to normal map /// exits currently opened world view mode and returns to normal map
void exitWorldView(); void exitWorldView();

View File

@ -12,7 +12,6 @@
#include "CMinimap.h" #include "CMinimap.h"
#include "CAdvMapInt.h" #include "CAdvMapInt.h"
#include "CTerrainRect.h"
#include "../widgets/Images.h" #include "../widgets/Images.h"
#include "../CGameInfo.h" #include "../CGameInfo.h"
@ -126,7 +125,7 @@ Point CMinimap::tileToPixels(const int3 &tile) const
void CMinimap::moveAdvMapSelection() void CMinimap::moveAdvMapSelection()
{ {
int3 newLocation = pixelToTile(GH.getCursorPosition() - pos.topLeft()); int3 newLocation = pixelToTile(GH.getCursorPosition() - pos.topLeft());
adventureInt->centerOn(newLocation); adventureInt->centerOnTile(newLocation);
if (!(adventureInt->active & GENERAL)) if (!(adventureInt->active & GENERAL))
GH.totalRedraw(); //redraw this as well as inactive adventure map GH.totalRedraw(); //redraw this as well as inactive adventure map
@ -162,13 +161,14 @@ void CMinimap::mouseMoved(const Point & cursorPosition)
void CMinimap::showAll(SDL_Surface * to) void CMinimap::showAll(SDL_Surface * to)
{ {
CSDL_Ext::CClipRectGuard guard(to, pos);
CIntObject::showAll(to); CIntObject::showAll(to);
if(minimap) if(minimap)
{ {
Canvas target(to); Canvas target(to);
int3 mapSizes = LOCPLINT->cb->getMapSize(); int3 mapSizes = LOCPLINT->cb->getMapSize();
Rect screenArea = adventureInt->terrainAreaTiles();
//draw radar //draw radar
Rect radar = Rect radar =
@ -180,7 +180,6 @@ void CMinimap::showAll(SDL_Surface * to)
}; };
Canvas clippedTarget(target, pos); Canvas clippedTarget(target, pos);
CSDL_Ext::CClipRectGuard guard(to, pos);
clippedTarget.drawBorderDashed(radar, CSDL_Ext::fromSDL(Colors::PURPLE)); clippedTarget.drawBorderDashed(radar, CSDL_Ext::fromSDL(Colors::PURPLE));
} }
} }
@ -195,14 +194,21 @@ void CMinimap::update()
redraw(); redraw();
} }
void CMinimap::setLevel(int newLevel) void CMinimap::onMapViewMoved(const Rect & visibleArea, int mapLevel)
{ {
if (level == newLevel) if (screenArea == visibleArea && level == mapLevel)
return; return;
level = newLevel; screenArea = visibleArea;
if(level != mapLevel)
{
level = mapLevel;
update(); update();
} }
else
redraw();
}
void CMinimap::setAIRadar(bool on) void CMinimap::setAIRadar(bool on)
{ {

View File

@ -41,6 +41,7 @@ class CMinimap : public CIntObject
{ {
std::shared_ptr<CPicture> aiShield; //the graphic displayed during AI turn std::shared_ptr<CPicture> aiShield; //the graphic displayed during AI turn
std::shared_ptr<CMinimapInstance> minimap; std::shared_ptr<CMinimapInstance> minimap;
Rect screenArea;
int level; int level;
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
@ -59,11 +60,10 @@ protected:
Point tileToPixels(const int3 & position) const; Point tileToPixels(const int3 & position) const;
public: public:
explicit CMinimap(const Rect & position); explicit CMinimap(const Rect & position);
void onMapViewMoved(const Rect & visibleArea, int mapLevel);
void update(); void update();
void setLevel(int level);
void setAIRadar(bool on); void setAIRadar(bool on);
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;

View File

@ -1,263 +0,0 @@
/*
* CTerrainRect.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 "CTerrainRect.h"
#include "CAdvMapInt.h"
#include "../CGameInfo.h"
#include "../CMT.h"
#include "../CPlayerInterface.h"
#include "../gui/CGuiHandler.h"
#include "../gui/CursorHandler.h"
#include "../mapRenderer/mapHandler.h"
#include "../render/CAnimation.h"
#include "../render/IImage.h"
#include "../renderSDL/SDL_Extensions.h"
#include "../widgets/TextControls.h"
#include "../mapRenderer/MapView.h"
#include "../mapRenderer/MapViewController.h"
#include "../mapRenderer/MapViewModel.h"
#include "../../CCallback.h"
#include "../../lib/CConfigHandler.h"
#include "../../lib/mapping/CMap.h"
#include "../../lib/CPathfinder.h"
#define ADVOPT (conf.go()->ac)
CTerrainRect::CTerrainRect()
: curHoveredTile(-1, -1, -1)
, isSwiping(false)
#if defined(VCMI_ANDROID) || defined(VCMI_IOS)
, swipeEnabled(settings["general"]["swipe"].Bool())
#else
, swipeEnabled(settings["general"]["swipeDesktop"].Bool())
#endif
, swipeMovementRequested(false)
, swipeTargetPosition(Point(0, 0))
{
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
pos.x=ADVOPT.advmapX;
pos.y=ADVOPT.advmapY;
pos.w=ADVOPT.advmapW;
pos.h=ADVOPT.advmapH;
addUsedEvents(LCLICK | RCLICK | MCLICK | HOVER | MOVE);
renderer = std::make_shared<MapView>( Point(0,0), pos.dimensions() );
}
void CTerrainRect::setViewCenter(const int3 &coordinates)
{
renderer->getController()->setViewCenter(coordinates);
}
void CTerrainRect::setViewCenter(const Point & position, int level)
{
renderer->getController()->setViewCenter(position, level);
}
void CTerrainRect::deactivate()
{
CIntObject::deactivate();
curHoveredTile = int3(-1,-1,-1); //we lost info about hovered tile when disabling
}
void CTerrainRect::clickLeft(tribool down, bool previousState)
{
if(adventureInt->mode == EAdvMapMode::WORLD_VIEW)
return;
if(indeterminate(down))
return;
if(swipeEnabled)
{
if(handleSwipeStateChange((bool)down == true))
{
return; // if swipe is enabled, we don't process "down" events and wait for "up" (to make sure this wasn't a swiping gesture)
}
}
else
{
if(down == false)
return;
}
int3 mp = whichTileIsIt();
if(mp.x < 0 || mp.y < 0 || mp.x >= LOCPLINT->cb->getMapSize().x || mp.y >= LOCPLINT->cb->getMapSize().y)
return;
adventureInt->tileLClicked(mp);
}
void CTerrainRect::clickRight(tribool down, bool previousState)
{
if(isSwiping)
return;
if(adventureInt->mode == EAdvMapMode::WORLD_VIEW)
return;
int3 mp = whichTileIsIt();
if(CGI->mh->isInMap(mp) && down)
adventureInt->tileRClicked(mp);
}
void CTerrainRect::clickMiddle(tribool down, bool previousState)
{
handleSwipeStateChange((bool)down == true);
}
void CTerrainRect::mouseMoved(const Point & cursorPosition)
{
handleHover(cursorPosition);
handleSwipeMove(cursorPosition);
}
void CTerrainRect::handleSwipeMove(const Point & cursorPosition)
{
// unless swipe is enabled, swipe move only works with middle mouse button
if(!swipeEnabled && !GH.isMouseButtonPressed(MouseButton::MIDDLE))
return;
// on mobile platforms with enabled swipe any button is enough
if(swipeEnabled && (!GH.isMouseButtonPressed() || GH.multifinger))
return;
if(!isSwiping)
{
static constexpr int touchSwipeSlop = 16;
// try to distinguish if this touch was meant to be a swipe or just fat-fingering press
if(std::abs(cursorPosition.x - swipeInitialRealPos.x) > touchSwipeSlop ||
std::abs(cursorPosition.y - swipeInitialRealPos.y) > touchSwipeSlop)
{
isSwiping = true;
}
}
if(isSwiping)
{
swipeTargetPosition.x = swipeInitialViewPos.x + swipeInitialRealPos.x - cursorPosition.x;
swipeTargetPosition.y = swipeInitialViewPos.y + swipeInitialRealPos.y - cursorPosition.y;
swipeMovementRequested = true;
}
}
bool CTerrainRect::handleSwipeStateChange(bool btnPressed)
{
if(btnPressed)
{
swipeInitialRealPos = Point(GH.getCursorPosition().x, GH.getCursorPosition().y);
swipeInitialViewPos = getViewCenter();
return true;
}
if(isSwiping) // only accept this touch if it wasn't a swipe
{
isSwiping = false;
return true;
}
return false;
}
void CTerrainRect::handleHover(const Point & cursorPosition)
{
int3 tHovered = whichTileIsIt(cursorPosition);
if(!CGI->mh->isInMap(tHovered))
{
CCS->curh->set(Cursor::Map::POINTER);
return;
}
if (tHovered != curHoveredTile)
{
curHoveredTile = tHovered;
adventureInt->tileHovered(tHovered);
}
}
void CTerrainRect::hover(bool on)
{
if (!on)
{
GH.statusbar->clear();
CCS->curh->set(Cursor::Map::POINTER);
}
//Hoverable::hover(on);
}
int3 CTerrainRect::whichTileIsIt(const Point &position)
{
return renderer->getModel()->getTileAtPoint(position - pos);
}
int3 CTerrainRect::whichTileIsIt()
{
return whichTileIsIt(GH.getCursorPosition());
}
Rect CTerrainRect::visibleTilesArea()
{
return renderer->getModel()->getTilesTotalRect();
}
void CTerrainRect::setLevel(int level)
{
renderer->getController()->setViewCenter(renderer->getModel()->getMapViewCenter(), level);
}
void CTerrainRect::moveViewBy(const Point & delta)
{
// ignore scrolling attempts while we are swiping
if (isSwiping || swipeMovementRequested)
return;
renderer->getController()->setViewCenter(renderer->getModel()->getMapViewCenter() + delta, getLevel());
}
Point CTerrainRect::getViewCenter()
{
return renderer->getModel()->getMapViewCenter();
}
int CTerrainRect::getLevel()
{
return renderer->getModel()->getLevel();
}
void CTerrainRect::setTileSize(int sizePixels)
{
renderer->getController()->setTileSize(Point(sizePixels, sizePixels));
}
void CTerrainRect::setTerrainVisibility(bool showAllTerrain)
{
renderer->getController()->setTerrainVisibility(showAllTerrain);
}
void CTerrainRect::setOverlayVisibility(const std::vector<ObjectPosInfo> & objectPositions)
{
renderer->getController()->setOverlayVisibility(objectPositions);
}
void CTerrainRect::show(SDL_Surface * to)
{
if(swipeMovementRequested)
{
setViewCenter(swipeTargetPosition, getLevel());
CCS->curh->set(Cursor::Map::POINTER);
swipeMovementRequested = false;
}
CIntObject::show(to);
}

View File

@ -1,79 +0,0 @@
/*
* CTerrainRect.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
#include "../gui/CIntObject.h"
#include "../../lib/int3.h"
VCMI_LIB_NAMESPACE_BEGIN
struct CGPath;
struct ObjectPosInfo;
VCMI_LIB_NAMESPACE_END
class MapView;
/// Holds information about which tiles of the terrain are shown/not shown at the screen
class CTerrainRect : public CIntObject
{
std::shared_ptr<MapView> renderer;
bool swipeEnabled;
bool swipeMovementRequested;
Point swipeTargetPosition;
Point swipeInitialViewPos;
Point swipeInitialRealPos;
bool isSwiping;
void handleHover(const Point & cursorPosition);
void handleSwipeMove(const Point & cursorPosition);
/// handles start/finish of swipe (press/release of corresponding button); returns true if state change was handled
bool handleSwipeStateChange(bool btnPressed);
int3 curHoveredTile;
int3 whichTileIsIt(const Point & position); //x,y are cursor position
int3 whichTileIsIt(); //uses current cursor pos
Point getViewCenter();
public:
CTerrainRect();
/// Handle swipe & selection of object
void setViewCenter(const int3 & coordinates);
void setViewCenter(const Point & position, int level);
/// Edge scrolling
void moveViewBy(const Point & delta);
/// Toggle undeground view button
void setLevel(int level);
int getLevel();
/// World view & View Earth/Air spells
void setTerrainVisibility(bool showAllTerrain);
void setOverlayVisibility(const std::vector<ObjectPosInfo> & objectPositions);
void setTileSize(int sizePixels);
/// Minimap access
/// @returns number of visible tiles on screen respecting current map scaling
Rect visibleTilesArea();
// CIntObject interface implementation
void deactivate() override;
void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override;
void clickMiddle(tribool down, bool previousState) override;
void hover(bool on) override;
void mouseMoved (const Point & cursorPosition) override;
void show(SDL_Surface * to) override;
//void showAll(SDL_Surface * to) override;
//void showAnim(SDL_Surface * to);
};

View File

@ -70,6 +70,10 @@ public:
/// if true, rendered images will be converted to grayscale /// if true, rendered images will be converted to grayscale
virtual bool filterGrayscale() const = 0; virtual bool filterGrayscale() const = 0;
virtual bool showRoads() const = 0;
virtual bool showRivers() const = 0;
virtual bool showBorder() const = 0;
/// if true, world view overlay will be shown /// if true, world view overlay will be shown
virtual bool showOverlay() const = 0; virtual bool showOverlay() const = 0;

View File

@ -35,7 +35,7 @@ struct NeighborTilesInfo
//012 //012
std::bitset<8> d; std::bitset<8> d;
NeighborTilesInfo(const IMapRendererContext & context, const int3 & pos) NeighborTilesInfo(IMapRendererContext & context, const int3 & pos)
{ {
auto checkTile = [&](int dx, int dy) auto checkTile = [&](int dx, int dy)
{ {
@ -128,7 +128,7 @@ MapRendererTerrain::MapRendererTerrain()
storage.load(terrain->getIndex(), terrain->tilesFilename, EImageBlitMode::OPAQUE); storage.load(terrain->getIndex(), terrain->tilesFilename, EImageBlitMode::OPAQUE);
} }
void MapRendererTerrain::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates) void MapRendererTerrain::renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates)
{ {
const TerrainTile & mapTile = context.getMapTile(coordinates); const TerrainTile & mapTile = context.getMapTile(coordinates);
@ -152,7 +152,7 @@ void MapRendererTerrain::renderTile(const IMapRendererContext & context, Canvas
target.draw(image, Point(0, 0)); target.draw(image, Point(0, 0));
} }
uint8_t MapRendererTerrain::checksum(const IMapRendererContext & context, const int3 & coordinates) uint8_t MapRendererTerrain::checksum(IMapRendererContext & context, const int3 & coordinates)
{ {
const TerrainTile & mapTile = context.getMapTile(coordinates); const TerrainTile & mapTile = context.getMapTile(coordinates);
@ -168,7 +168,7 @@ MapRendererRiver::MapRendererRiver()
storage.load(river->getIndex(), river->tilesFilename, EImageBlitMode::COLORKEY); storage.load(river->getIndex(), river->tilesFilename, EImageBlitMode::COLORKEY);
} }
void MapRendererRiver::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates) void MapRendererRiver::renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates)
{ {
const TerrainTile & mapTile = context.getMapTile(coordinates); const TerrainTile & mapTile = context.getMapTile(coordinates);
@ -202,7 +202,7 @@ void MapRendererRiver::renderTile(const IMapRendererContext & context, Canvas &
target.draw(image, Point(0, 0)); target.draw(image, Point(0, 0));
} }
uint8_t MapRendererRiver::checksum(const IMapRendererContext & context, const int3 & coordinates) uint8_t MapRendererRiver::checksum(IMapRendererContext & context, const int3 & coordinates)
{ {
const TerrainTile & mapTile = context.getMapTile(coordinates); const TerrainTile & mapTile = context.getMapTile(coordinates);
@ -220,7 +220,7 @@ MapRendererRoad::MapRendererRoad()
storage.load(road->getIndex(), road->tilesFilename, EImageBlitMode::COLORKEY); storage.load(road->getIndex(), road->tilesFilename, EImageBlitMode::COLORKEY);
} }
void MapRendererRoad::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates) void MapRendererRoad::renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates)
{ {
const int3 coordinatesAbove = coordinates - int3(0, 1, 0); const int3 coordinatesAbove = coordinates - int3(0, 1, 0);
@ -250,18 +250,19 @@ void MapRendererRoad::renderTile(const IMapRendererContext & context, Canvas & t
} }
} }
uint8_t MapRendererRoad::checksum(const IMapRendererContext & context, const int3 & coordinates) uint8_t MapRendererRoad::checksum(IMapRendererContext & context, const int3 & coordinates)
{ {
return 0; return 0;
} }
MapRendererBorder::MapRendererBorder() MapRendererBorder::MapRendererBorder()
{ {
emptyFill = std::make_unique<Canvas>(Point(32,32));
animation = std::make_unique<CAnimation>("EDG"); animation = std::make_unique<CAnimation>("EDG");
animation->preload(); animation->preload();
} }
size_t MapRendererBorder::getIndexForTile(const IMapRendererContext & context, const int3 & tile) size_t MapRendererBorder::getIndexForTile(IMapRendererContext & context, const int3 & tile)
{ {
assert(!context.isInMap(tile)); assert(!context.isInMap(tile));
@ -299,13 +300,20 @@ size_t MapRendererBorder::getIndexForTile(const IMapRendererContext & context, c
return 0; return 0;
} }
void MapRendererBorder::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates) void MapRendererBorder::renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates)
{
if (context.showBorder())
{ {
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));
} }
else
{
target.draw(*emptyFill, Point(0,0));
}
}
uint8_t MapRendererBorder::checksum(const IMapRendererContext & context, const int3 & coordinates) uint8_t MapRendererBorder::checksum(IMapRendererContext & context, const int3 & coordinates)
{ {
return 0; return 0;
} }
@ -333,7 +341,7 @@ MapRendererFow::MapRendererFow()
} }
} }
void MapRendererFow::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates) void MapRendererFow::renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates)
{ {
assert(!context.isVisible(coordinates)); assert(!context.isVisible(coordinates));
@ -356,7 +364,7 @@ void MapRendererFow::renderTile(const IMapRendererContext & context, Canvas & ta
} }
} }
uint8_t MapRendererFow::checksum(const IMapRendererContext & context, const int3 & coordinates) uint8_t MapRendererFow::checksum(IMapRendererContext & context, const int3 & coordinates)
{ {
const NeighborTilesInfo neighborInfo(context, coordinates); const NeighborTilesInfo neighborInfo(context, coordinates);
int retBitmapID = neighborInfo.getBitmapID(); int retBitmapID = neighborInfo.getBitmapID();
@ -470,7 +478,7 @@ std::shared_ptr<CAnimation> MapRendererObjects::getOverlayAnimation(const CGObje
return nullptr; return nullptr;
} }
std::shared_ptr<IImage> MapRendererObjects::getImage(const IMapRendererContext & context, const CGObjectInstance * obj, const std::shared_ptr<CAnimation>& animation) const std::shared_ptr<IImage> MapRendererObjects::getImage(IMapRendererContext & context, const CGObjectInstance * obj, const std::shared_ptr<CAnimation>& animation) const
{ {
if(!animation) if(!animation)
return nullptr; return nullptr;
@ -485,7 +493,7 @@ std::shared_ptr<IImage> MapRendererObjects::getImage(const IMapRendererContext &
return animation->getImage(frameIndex, groupIndex); return animation->getImage(frameIndex, groupIndex);
} }
void MapRendererObjects::renderImage(const IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * object, const std::shared_ptr<IImage>& image) void MapRendererObjects::renderImage(IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * object, const std::shared_ptr<IImage>& image)
{ {
if(!image) if(!image)
return; return;
@ -517,14 +525,14 @@ void MapRendererObjects::renderImage(const IMapRendererContext & context, Canvas
} }
} }
void MapRendererObjects::renderObject(const IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * instance) void MapRendererObjects::renderObject(IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * instance)
{ {
renderImage(context, target, coordinates, instance, getImage(context, instance, getBaseAnimation(instance))); renderImage(context, target, coordinates, instance, getImage(context, instance, getBaseAnimation(instance)));
renderImage(context, target, coordinates, instance, getImage(context, instance, getFlagAnimation(instance))); renderImage(context, target, coordinates, instance, getImage(context, instance, getFlagAnimation(instance)));
renderImage(context, target, coordinates, instance, getImage(context, instance, getOverlayAnimation(instance))); renderImage(context, target, coordinates, instance, getImage(context, instance, getOverlayAnimation(instance)));
} }
void MapRendererObjects::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates) void MapRendererObjects::renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates)
{ {
for(const auto & objectID : context.getObjects(coordinates)) for(const auto & objectID : context.getObjects(coordinates))
{ {
@ -541,7 +549,7 @@ void MapRendererObjects::renderTile(const IMapRendererContext & context, Canvas
} }
} }
uint8_t MapRendererObjects::checksum(const IMapRendererContext & context, const int3 & coordinates) uint8_t MapRendererObjects::checksum(IMapRendererContext & context, const int3 & coordinates)
{ {
for(const auto & objectID : context.getObjects(coordinates)) for(const auto & objectID : context.getObjects(coordinates))
{ {
@ -579,7 +587,7 @@ MapRendererDebug::MapRendererDebug()
} }
void MapRendererDebug::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates) void MapRendererDebug::renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates)
{ {
if(context.showGrid()) if(context.showGrid())
target.draw(imageGrid, Point(0,0)); target.draw(imageGrid, Point(0,0));
@ -607,7 +615,7 @@ void MapRendererDebug::renderTile(const IMapRendererContext & context, Canvas &
} }
} }
uint8_t MapRendererDebug::checksum(const IMapRendererContext & context, const int3 & coordinates) uint8_t MapRendererDebug::checksum(IMapRendererContext & context, const int3 & coordinates)
{ {
return 0; return 0;
} }
@ -665,7 +673,7 @@ size_t MapRendererPath::selectImageArrow(bool reachableToday, const int3 & curr,
return selectImageReachability(reachableToday, imageIndex); return selectImageReachability(reachableToday, imageIndex);
} }
void MapRendererPath::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates) void MapRendererPath::renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates)
{ {
size_t imageID = selectImage(context, coordinates); size_t imageID = selectImage(context, coordinates);
@ -673,7 +681,7 @@ void MapRendererPath::renderTile(const IMapRendererContext & context, Canvas & t
target.draw(pathNodes->getImage(imageID), Point(0,0)); target.draw(pathNodes->getImage(imageID), Point(0,0));
} }
size_t MapRendererPath::selectImage(const IMapRendererContext & context, const int3 & coordinates) size_t MapRendererPath::selectImage(IMapRendererContext & context, const int3 & coordinates)
{ {
const auto & functor = [&](const CGPathNode & node) const auto & functor = [&](const CGPathNode & node)
{ {
@ -709,12 +717,12 @@ size_t MapRendererPath::selectImage(const IMapRendererContext & context, const i
return selectImageCross(reachableToday, iter->coord); return selectImageCross(reachableToday, iter->coord);
} }
uint8_t MapRendererPath::checksum(const IMapRendererContext & context, const int3 & coordinates) uint8_t MapRendererPath::checksum(IMapRendererContext & context, const int3 & coordinates)
{ {
return selectImage(context, coordinates) & 0xff; return selectImage(context, coordinates) & 0xff;
} }
MapRenderer::TileChecksum MapRenderer::getTileChecksum(const IMapRendererContext & context, const int3 & coordinates) MapRenderer::TileChecksum MapRenderer::getTileChecksum(IMapRendererContext & context, const int3 & coordinates)
{ {
// computes basic checksum to determine whether tile needs an update // computes basic checksum to determine whether tile needs an update
// if any component gives different value, tile will be updated // if any component gives different value, tile will be updated
@ -736,7 +744,9 @@ MapRenderer::TileChecksum MapRenderer::getTileChecksum(const IMapRendererContext
else else
{ {
result[1] = rendererTerrain.checksum(context, coordinates); result[1] = rendererTerrain.checksum(context, coordinates);
if (context.showRivers())
result[2] = rendererRiver.checksum(context, coordinates); result[2] = rendererRiver.checksum(context, coordinates);
if (context.showRoads())
result[3] = rendererRoad.checksum(context, coordinates); result[3] = rendererRoad.checksum(context, coordinates);
result[4] = rendererObjects.checksum(context, coordinates); result[4] = rendererObjects.checksum(context, coordinates);
result[5] = rendererPath.checksum(context, coordinates); result[5] = rendererPath.checksum(context, coordinates);
@ -748,7 +758,7 @@ MapRenderer::TileChecksum MapRenderer::getTileChecksum(const IMapRendererContext
return result; return result;
} }
void MapRenderer::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates) void MapRenderer::renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates)
{ {
if(!context.isInMap(coordinates)) if(!context.isInMap(coordinates))
{ {
@ -765,8 +775,13 @@ void MapRenderer::renderTile(const IMapRendererContext & context, Canvas & targe
else else
{ {
rendererTerrain.renderTile(context, target, coordinates); rendererTerrain.renderTile(context, target, coordinates);
if (context.showRivers())
rendererRiver.renderTile(context, target, coordinates); rendererRiver.renderTile(context, target, coordinates);
if (context.showRoads())
rendererRoad.renderTile(context, target, coordinates); rendererRoad.renderTile(context, target, coordinates);
rendererObjects.renderTile(context, target, coordinates); rendererObjects.renderTile(context, target, coordinates);
rendererPath.renderTile(context, target, coordinates); rendererPath.renderTile(context, target, coordinates);
rendererDebug.renderTile(context, target, coordinates); rendererDebug.renderTile(context, target, coordinates);

View File

@ -41,8 +41,8 @@ class MapRendererTerrain
public: public:
MapRendererTerrain(); MapRendererTerrain();
uint8_t checksum(const IMapRendererContext & context, const int3 & coordinates); uint8_t checksum(IMapRendererContext & context, const int3 & coordinates);
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates); void renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates);
}; };
class MapRendererRiver class MapRendererRiver
@ -52,8 +52,8 @@ class MapRendererRiver
public: public:
MapRendererRiver(); MapRendererRiver();
uint8_t checksum(const IMapRendererContext & context, const int3 & coordinates); uint8_t checksum(IMapRendererContext & context, const int3 & coordinates);
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates); void renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates);
}; };
class MapRendererRoad class MapRendererRoad
@ -63,8 +63,8 @@ class MapRendererRoad
public: public:
MapRendererRoad(); MapRendererRoad();
uint8_t checksum(const IMapRendererContext & context, const int3 & coordinates); uint8_t checksum(IMapRendererContext & context, const int3 & coordinates);
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates); void renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates);
}; };
class MapRendererObjects class MapRendererObjects
@ -77,27 +77,28 @@ class MapRendererObjects
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(IMapRendererContext & context, const CGObjectInstance * obj, const std::shared_ptr<CAnimation> & animation) const;
void renderImage(const IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * object, const std::shared_ptr<IImage> & image); void renderImage(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(IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * obj);
public: public:
uint8_t checksum(const IMapRendererContext & context, const int3 & coordinates); uint8_t checksum(IMapRendererContext & context, const int3 & coordinates);
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates); void renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates);
}; };
class MapRendererBorder class MapRendererBorder
{ {
std::unique_ptr<CAnimation> animation; std::unique_ptr<CAnimation> animation;
std::unique_ptr<Canvas> emptyFill;
size_t getIndexForTile(const IMapRendererContext & context, const int3 & coordinates); size_t getIndexForTile(IMapRendererContext & context, const int3 & coordinates);
public: public:
MapRendererBorder(); MapRendererBorder();
uint8_t checksum(const IMapRendererContext & context, const int3 & coordinates); uint8_t checksum(IMapRendererContext & context, const int3 & coordinates);
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates); void renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates);
}; };
class MapRendererFow class MapRendererFow
@ -108,8 +109,8 @@ class MapRendererFow
public: public:
MapRendererFow(); MapRendererFow();
uint8_t checksum(const IMapRendererContext & context, const int3 & coordinates); uint8_t checksum(IMapRendererContext & context, const int3 & coordinates);
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates); void renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates);
}; };
class MapRendererPath class MapRendererPath
@ -119,13 +120,13 @@ class MapRendererPath
size_t selectImageReachability(bool reachableToday, size_t imageIndex); size_t selectImageReachability(bool reachableToday, size_t imageIndex);
size_t selectImageCross(bool reachableToday, const int3 & curr); size_t selectImageCross(bool reachableToday, const int3 & curr);
size_t selectImageArrow(bool reachableToday, const int3 & curr, const int3 & prev, const int3 & next); size_t selectImageArrow(bool reachableToday, const int3 & curr, const int3 & prev, const int3 & next);
size_t selectImage(const IMapRendererContext & context, const int3 & coordinates); size_t selectImage(IMapRendererContext & context, const int3 & coordinates);
public: public:
MapRendererPath(); MapRendererPath();
uint8_t checksum(const IMapRendererContext & context, const int3 & coordinates); uint8_t checksum(IMapRendererContext & context, const int3 & coordinates);
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates); void renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates);
}; };
class MapRendererDebug class MapRendererDebug
@ -136,8 +137,8 @@ class MapRendererDebug
public: public:
MapRendererDebug(); MapRendererDebug();
uint8_t checksum(const IMapRendererContext & context, const int3 & coordinates); uint8_t checksum(IMapRendererContext & context, const int3 & coordinates);
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates); void renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates);
}; };
class MapRendererOverlay class MapRendererOverlay
@ -146,8 +147,8 @@ class MapRendererOverlay
public: public:
MapRendererOverlay(); MapRendererOverlay();
uint8_t checksum(const IMapRendererContext & context, const int3 & coordinates); uint8_t checksum(IMapRendererContext & context, const int3 & coordinates);
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates); void renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates);
}; };
class MapRenderer class MapRenderer
@ -164,7 +165,7 @@ class MapRenderer
public: public:
using TileChecksum = std::array<uint8_t, 8>; using TileChecksum = std::array<uint8_t, 8>;
TileChecksum getTileChecksum(const IMapRendererContext & context, const int3 & coordinates); TileChecksum getTileChecksum(IMapRendererContext & context, const int3 & coordinates);
void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates); void renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates);
}; };

View File

@ -21,7 +21,7 @@
#include "../../lib/mapObjects/CGHeroInstance.h" #include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/mapping/CMap.h" #include "../../lib/mapping/CMap.h"
MapObjectsSorter::MapObjectsSorter(const IMapRendererContext & context) MapObjectsSorter::MapObjectsSorter(IMapRendererContext & context)
: context(context) : context(context)
{ {
} }
@ -66,6 +66,9 @@ bool MapRendererContext::isVisible(const int3 & coordinates) const
const CGPath * MapRendererContext::currentPath() const const CGPath * MapRendererContext::currentPath() const
{ {
if (worldViewModeActive)
return nullptr;
const auto * hero = adventureInt->curHero(); const auto * hero = adventureInt->curHero();
if(!hero) if(!hero)
@ -86,6 +89,9 @@ size_t MapRendererContext::objectImageIndex(ObjectInstanceID objectID, size_t gr
if (!settingsAdventureObjectAnimation) if (!settingsAdventureObjectAnimation)
return 0; return 0;
if (worldViewModeActive)
return 0;
// H3 timing for adventure map objects animation is 180 ms // H3 timing for adventure map objects animation is 180 ms
// Terrain animations also use identical interval, however those are only present in HotA and/or HD Mod // Terrain animations also use identical interval, however those are only present in HotA and/or HD Mod
size_t baseFrameTime = 180; size_t baseFrameTime = 180;
@ -105,6 +111,9 @@ size_t MapRendererContext::terrainImageIndex(size_t groupSize) const
if (!settingsAdventureTerrainAnimation) if (!settingsAdventureTerrainAnimation)
return 0; return 0;
if (worldViewModeActive)
return 0;
size_t baseFrameTime = 180; size_t baseFrameTime = 180;
size_t frameCounter = animationTime / baseFrameTime; size_t frameCounter = animationTime / baseFrameTime;
size_t frameIndex = frameCounter % groupSize; size_t frameIndex = frameCounter % groupSize;
@ -144,7 +153,22 @@ bool MapRendererContext::tileAnimated(const int3 & coordinates) const
bool MapRendererContext::filterGrayscale() const bool MapRendererContext::filterGrayscale() const
{ {
return false;//true; return false;
}
bool MapRendererContext::showRoads() const
{
return true;
}
bool MapRendererContext::showRivers() const
{
return true;
}
bool MapRendererContext::showBorder() const
{
return !worldViewModeActive;
} }
bool MapRendererContext::showOverlay() const bool MapRendererContext::showOverlay() const

View File

@ -20,10 +20,10 @@ VCMI_LIB_NAMESPACE_END
class MapObjectsSorter class MapObjectsSorter
{ {
const IMapRendererContext & context; IMapRendererContext & context;
public: public:
explicit MapObjectsSorter(const IMapRendererContext & context); explicit MapObjectsSorter(IMapRendererContext & context);
bool operator()(const ObjectInstanceID & left, const ObjectInstanceID & right) const; bool operator()(const ObjectInstanceID & left, const ObjectInstanceID & right) const;
bool operator()(const CGObjectInstance * left, const CGObjectInstance * right) const; bool operator()(const CGObjectInstance * left, const CGObjectInstance * right) const;
@ -122,6 +122,9 @@ public:
size_t overlayImageIndex(const int3 & coordinates) const override; size_t overlayImageIndex(const int3 & coordinates) const override;
bool filterGrayscale() const override; bool filterGrayscale() const override;
bool showRoads() const override;
bool showRivers() const override;
bool showBorder() const override;
bool showOverlay() const override; bool showOverlay() const override;
bool showGrid() const override; bool showGrid() const override;
bool showVisitable() const override; bool showVisitable() const override;

View File

@ -11,14 +11,15 @@
#include "StdInc.h" #include "StdInc.h"
#include "MapView.h" #include "MapView.h"
#include "MapViewModel.h" #include "MapViewActions.h"
#include "MapViewCache.h" #include "MapViewCache.h"
#include "MapViewController.h" #include "MapViewController.h"
#include "MapViewModel.h"
#include "mapHandler.h" #include "mapHandler.h"
#include "../adventureMap/CAdvMapInt.h"
#include "../CGameInfo.h" #include "../CGameInfo.h"
#include "../CPlayerInterface.h" #include "../CPlayerInterface.h"
#include "../adventureMap/CAdvMapInt.h"
#include "../gui/CGuiHandler.h" #include "../gui/CGuiHandler.h"
#include "../render/CAnimation.h" #include "../render/CAnimation.h"
#include "../render/Canvas.h" #include "../render/Canvas.h"
@ -49,17 +50,21 @@ MapView::MapView(const Point & offset, const Point & dimensions)
: model(createModel(dimensions)) : model(createModel(dimensions))
, controller(new MapViewController(model)) , controller(new MapViewController(model))
, tilesCache(new MapViewCache(model)) , tilesCache(new MapViewCache(model))
, isSwiping(false)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
pos += offset; pos += offset;
pos.w = dimensions.x; pos.w = dimensions.x;
pos.h = dimensions.y; pos.h = dimensions.y;
actions = std::make_shared<MapViewActions>(*this, model);
actions->setContext(controller->getContext());
} }
void MapView::render(Canvas & target, bool fullUpdate) void MapView::render(Canvas & target, bool fullUpdate)
{ {
Canvas targetClipped(target, pos); Canvas targetClipped(target, pos);
controller->update(GH.mainFPSmng->getElapsedMilliseconds()); controller->update(GH.mainFPSmng->getElapsedMilliseconds());
tilesCache->update(controller->getContext()); tilesCache->update(controller->getContext());
tilesCache->render(controller->getContext(), targetClipped, fullUpdate); tilesCache->render(controller->getContext(), targetClipped, fullUpdate);
@ -79,12 +84,59 @@ void MapView::showAll(SDL_Surface * to)
render(target, true); render(target, true);
} }
std::shared_ptr<const MapViewModel> MapView::getModel() const void MapView::onMapLevelSwitched()
{ {
return model; if(LOCPLINT->cb->getMapSize().z > 1)
{
if(model->getLevel() == 0)
controller->setViewCenter(model->getMapViewCenter(), 1);
else
controller->setViewCenter(model->getMapViewCenter(), 0);
}
} }
std::shared_ptr<MapViewController> MapView::getController() void MapView::onMapScrolled(const Point & distance)
{ {
return controller; if(!isSwiping)
controller->setViewCenter(model->getMapViewCenter() + distance, model->getLevel());
}
void MapView::onMapSwiped(const Point & viewPosition)
{
isSwiping = true;
controller->setViewCenter(viewPosition, model->getLevel());
}
void MapView::onMapSwipeEnded()
{
isSwiping = true;
}
void MapView::onCenteredTile(const int3 & tile)
{
controller->setViewCenter(tile);
}
void MapView::onCenteredObject(const CGObjectInstance * target)
{
controller->setViewCenter(target->getSightCenter());
}
void MapView::onViewSpellActivated(uint32_t tileSize, const std::vector<ObjectPosInfo> & objectPositions, bool showTerrain)
{
controller->setTileSize(Point(tileSize, tileSize));
controller->setOverlayVisibility(objectPositions);
controller->setTerrainVisibility(showTerrain);
}
void MapView::onViewWorldActivated(uint32_t tileSize)
{
controller->setTileSize(Point(tileSize, tileSize));
}
void MapView::onViewMapActivated()
{
controller->setTileSize(Point(32, 32));
controller->setOverlayVisibility({});
controller->setTerrainVisibility(false);
} }

View File

@ -11,28 +11,64 @@
#include "../gui/CIntObject.h" #include "../gui/CIntObject.h"
VCMI_LIB_NAMESPACE_BEGIN
struct ObjectPosInfo;
VCMI_LIB_NAMESPACE_END
class Canvas; class Canvas;
class MapViewActions;
class MapViewController; class MapViewController;
class MapViewModel; class MapViewModel;
class MapViewCache; class MapViewCache;
/// Main map rendering class that mostly acts as container for component classes /// Main class that represents visible section of adventure map
/// Contains all public interface of view and translates calls to internal model
class MapView : public CIntObject class MapView : public CIntObject
{ {
std::shared_ptr<MapViewModel> model; std::shared_ptr<MapViewModel> model;
std::unique_ptr<MapViewCache> tilesCache; std::shared_ptr<MapViewCache> tilesCache;
std::shared_ptr<MapViewController> controller; std::shared_ptr<MapViewController> controller;
std::shared_ptr<MapViewActions> actions;
bool isSwiping;
std::shared_ptr<MapViewModel> createModel(const Point & dimensions) const; std::shared_ptr<MapViewModel> createModel(const Point & dimensions) const;
void render(Canvas & target, bool fullUpdate); void render(Canvas & target, bool fullUpdate);
public:
std::shared_ptr<const MapViewModel> getModel() const;
std::shared_ptr<MapViewController> getController();
public:
MapView(const Point & offset, const Point & dimensions); MapView(const Point & offset, const Point & dimensions);
~MapView() override; ~MapView() override;
/// Moves current view to another level, preserving position
void onMapLevelSwitched();
/// Moves current view by specified distance in pixels
void onMapScrolled(const Point & distance);
/// Moves current view to specified position, in pixels
void onMapSwiped(const Point & viewPosition);
/// Ends swiping mode and allows normal map scrolling once again
void onMapSwipeEnded();
/// Moves current view to specified tile
void onCenteredTile(const int3 & tile);
/// Centers view on object and starts "tracking" it
/// Whenever object changes position, so will the object
/// Tracking will be disabled on any call that moves view
void onCenteredObject(const CGObjectInstance * target);
/// Switches view to "View Earth" / "View Air" mode, displaying downscaled map with overlay
void onViewSpellActivated( uint32_t tileSize, const std::vector<ObjectPosInfo>& objectPositions, bool showTerrain);
/// Switches view to downscaled View World
void onViewWorldActivated( uint32_t tileSize);
/// Switches view from View World mode back to standard view
void onViewMapActivated();
void show(SDL_Surface * to) override; void show(SDL_Surface * to) override;
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
}; };

View File

@ -0,0 +1,172 @@
/*
* MapViewActions.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 "MapViewActions.h"
#include "IMapRendererContext.h"
#include "MapViewModel.h"
#include "MapView.h"
#include "../CGameInfo.h"
#include "../adventureMap/CAdvMapInt.h"
#include "../gui/CGuiHandler.h"
#include "../gui/CursorHandler.h"
#include "../../lib/CConfigHandler.h"
MapViewActions::MapViewActions(MapView & owner, const std::shared_ptr<MapViewModel>& model)
: model(model)
, owner(owner)
, curHoveredTile(-1, -1, -1)
, isSwiping(false)
#if defined(VCMI_ANDROID) || defined(VCMI_IOS)
, swipeEnabled(settings["general"]["swipe"].Bool())
#else
, swipeEnabled(settings["general"]["swipeDesktop"].Bool())
#endif
{
pos.w = model->getPixelsVisibleDimensions().x;
pos.h = model->getPixelsVisibleDimensions().y;
addUsedEvents(LCLICK | RCLICK | MCLICK | HOVER | MOVE);
}
void MapViewActions::setContext(const std::shared_ptr<IMapRendererContext> & context)
{
this->context = context;
}
void MapViewActions::activate()
{
CIntObject::activate();
}
void MapViewActions::deactivate()
{
CIntObject::deactivate();
curHoveredTile = int3(-1,-1,-1); //we lost info about hovered tile when disabling
}
void MapViewActions::clickLeft(tribool down, bool previousState)
{
if(indeterminate(down))
return;
if(swipeEnabled)
{
if(handleSwipeStateChange(static_cast<bool>(down)))
{
return; // if swipe is enabled, we don't process "down" events and wait for "up" (to make sure this wasn't a swiping gesture)
}
}
else
{
if(down == false)
return;
}
int3 tile = model->getTileAtPoint(GH.getCursorPosition() - pos.topLeft());
if (context->isInMap(tile))
adventureInt->onTileLeftClicked(tile);
}
void MapViewActions::clickRight(tribool down, bool previousState)
{
if(isSwiping)
return;
int3 tile = model->getTileAtPoint(GH.getCursorPosition() - pos.topLeft());
if (down && context->isInMap(tile))
adventureInt->onTileRightClicked(tile);
}
void MapViewActions::clickMiddle(tribool down, bool previousState)
{
handleSwipeStateChange(static_cast<bool>(down));
}
void MapViewActions::mouseMoved(const Point & cursorPosition)
{
handleHover(cursorPosition);
handleSwipeMove(cursorPosition);
}
void MapViewActions::handleSwipeMove(const Point & cursorPosition)
{
// unless swipe is enabled, swipe move only works with middle mouse button
if(!swipeEnabled && !GH.isMouseButtonPressed(MouseButton::MIDDLE))
return;
// on mobile platforms with enabled swipe any button is enough
if(swipeEnabled && (!GH.isMouseButtonPressed() || GH.multifinger))
return;
if(!isSwiping)
{
static constexpr int touchSwipeSlop = 16;
Point distance = (cursorPosition - swipeInitialRealPos);
// try to distinguish if this touch was meant to be a swipe or just fat-fingering press
if( std::abs(distance.x) + std::abs(distance.y) > touchSwipeSlop)
isSwiping = true;
}
if(isSwiping)
{
Point swipeTargetPosition = swipeInitialViewPos + swipeInitialRealPos - cursorPosition;
owner.onMapSwiped(swipeTargetPosition);
}
}
bool MapViewActions::handleSwipeStateChange(bool btnPressed)
{
if(btnPressed)
{
swipeInitialRealPos = GH.getCursorPosition();
swipeInitialViewPos = model->getMapViewCenter();
return true;
}
if(isSwiping) // only accept this touch if it wasn't a swipe
{
owner.onMapSwipeEnded();
isSwiping = false;
return true;
}
return false;
}
void MapViewActions::handleHover(const Point & cursorPosition)
{
int3 tile = model->getTileAtPoint(cursorPosition - pos.topLeft());
if(!context->isInMap(tile))
{
CCS->curh->set(Cursor::Map::POINTER);
return;
}
if (tile != curHoveredTile)
{
curHoveredTile = tile;
adventureInt->onTileHovered(tile);
}
}
void MapViewActions::hover(bool on)
{
if (!on)
{
GH.statusbar->clear();
CCS->curh->set(Cursor::Map::POINTER);
}
}

View File

@ -0,0 +1,49 @@
/*
* MapViewActions.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
#include "../gui/CIntObject.h"
#include "../../lib/int3.h"
class IMapRendererContext;
class MapViewModel;
class MapView;
class MapViewActions : public CIntObject
{
bool swipeEnabled;
bool isSwiping;
Point swipeInitialViewPos;
Point swipeInitialRealPos;
int3 curHoveredTile;
MapView & owner;
std::shared_ptr<MapViewModel> model;
std::shared_ptr<IMapRendererContext> context;
void handleHover(const Point & cursorPosition);
void handleSwipeMove(const Point & cursorPosition);
bool handleSwipeStateChange(bool btnPressed);
public:
MapViewActions(MapView & owner, const std::shared_ptr<MapViewModel>& model);
void setContext(const std::shared_ptr<IMapRendererContext> & context);
void activate() override;
void deactivate() override;
void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override;
void clickMiddle(tribool down, bool previousState) override;
void hover(bool on) override;
void mouseMoved (const Point & cursorPosition) override;
};

View File

@ -45,7 +45,7 @@ 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<const IMapRendererContext> & context, const int3 & coordinates) std::shared_ptr<IImage> MapViewCache::getOverlayImageForTile(const std::shared_ptr<IMapRendererContext> & context, const int3 & coordinates)
{ {
size_t imageIndex = context->overlayImageIndex(coordinates); size_t imageIndex = context->overlayImageIndex(coordinates);
@ -54,7 +54,7 @@ std::shared_ptr<IImage> MapViewCache::getOverlayImageForTile(const std::shared_p
return nullptr; return nullptr;
} }
void MapViewCache::updateTile(const std::shared_ptr<const IMapRendererContext> & context, const int3 & coordinates) void MapViewCache::updateTile(const std::shared_ptr<IMapRendererContext> & context, const int3 & coordinates)
{ {
int cacheX = (terrainChecksum.shape()[0] + coordinates.x) % terrainChecksum.shape()[0]; int cacheX = (terrainChecksum.shape()[0] + coordinates.x) % terrainChecksum.shape()[0];
int cacheY = (terrainChecksum.shape()[1] + coordinates.y) % terrainChecksum.shape()[1]; int cacheY = (terrainChecksum.shape()[1] + coordinates.y) % terrainChecksum.shape()[1];
@ -67,14 +67,7 @@ void MapViewCache::updateTile(const std::shared_ptr<const IMapRendererContext> &
newCacheEntry.checksum = mapRenderer->getTileChecksum(*context, coordinates); newCacheEntry.checksum = mapRenderer->getTileChecksum(*context, coordinates);
if(cachedLevel == coordinates.z && oldCacheEntry == newCacheEntry && !context->tileAnimated(coordinates)) if(cachedLevel == coordinates.z && oldCacheEntry == newCacheEntry && !context->tileAnimated(coordinates))
{
// debug code to check caching - cached tiles will slowly fade to black
//static const auto overlay = IImage::createFromFile("debug/cached");
//Canvas target = getTile(coordinates);
//target.draw(overlay, Point(0,0));
return; return;
}
Canvas target = getTile(coordinates); Canvas target = getTile(coordinates);
@ -95,7 +88,7 @@ void MapViewCache::updateTile(const std::shared_ptr<const IMapRendererContext> &
tilesUpToDate[cacheX][cacheY] = false; tilesUpToDate[cacheX][cacheY] = false;
} }
void MapViewCache::update(const std::shared_ptr<const IMapRendererContext> & context) void MapViewCache::update(const std::shared_ptr<IMapRendererContext> & context)
{ {
Rect dimensions = model->getTilesTotalRect(); Rect dimensions = model->getTilesTotalRect();
@ -103,7 +96,16 @@ void MapViewCache::update(const std::shared_ptr<const IMapRendererContext> & con
{ {
boost::multi_array<TileChecksum, 2> newCache; boost::multi_array<TileChecksum, 2> newCache;
newCache.resize(boost::extents[dimensions.w][dimensions.h]); newCache.resize(boost::extents[dimensions.w][dimensions.h]);
std::swap(newCache, terrainChecksum); terrainChecksum.resize(boost::extents[dimensions.w][dimensions.h]);
terrainChecksum = newCache;
}
if(dimensions.w != tilesUpToDate.shape()[0] || dimensions.h != tilesUpToDate.shape()[1])
{
boost::multi_array<bool, 2> newCache;
newCache.resize(boost::extents[dimensions.w][dimensions.h]);
tilesUpToDate.resize(boost::extents[dimensions.w][dimensions.h]);
tilesUpToDate = newCache;
} }
for(int y = dimensions.top(); y < dimensions.bottom(); ++y) for(int y = dimensions.top(); y < dimensions.bottom(); ++y)
@ -113,20 +115,13 @@ void MapViewCache::update(const std::shared_ptr<const IMapRendererContext> & con
cachedLevel = model->getLevel(); cachedLevel = model->getLevel();
} }
void MapViewCache::render(const std::shared_ptr<const IMapRendererContext> & context, Canvas & target, bool fullRedraw) void MapViewCache::render(const std::shared_ptr<IMapRendererContext> & context, Canvas & target, bool fullRedraw)
{ {
bool mapMoved = (cachedPosition != model->getMapViewCenter()); bool mapMoved = (cachedPosition != model->getMapViewCenter());
bool lazyUpdate = !mapMoved && !fullRedraw; bool lazyUpdate = !mapMoved && !fullRedraw;
Rect dimensions = model->getTilesTotalRect(); Rect dimensions = model->getTilesTotalRect();
if(dimensions.w != tilesUpToDate.shape()[0] || dimensions.h != tilesUpToDate.shape()[1])
{
boost::multi_array<bool, 2> newCache;
newCache.resize(boost::extents[dimensions.w][dimensions.h]);
std::swap(newCache, tilesUpToDate);
}
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)

View File

@ -50,16 +50,16 @@ class MapViewCache
std::unique_ptr<CAnimation> iconsStorage; std::unique_ptr<CAnimation> iconsStorage;
Canvas getTile(const int3 & coordinates); Canvas getTile(const int3 & coordinates);
void updateTile(const std::shared_ptr<const IMapRendererContext> & context, const int3 & coordinates); void updateTile(const std::shared_ptr<IMapRendererContext> & context, const int3 & coordinates);
std::shared_ptr<IImage> getOverlayImageForTile(const std::shared_ptr<const IMapRendererContext> & context, const int3 & coordinates); std::shared_ptr<IImage> getOverlayImageForTile(const std::shared_ptr<IMapRendererContext> & context, const int3 & coordinates);
public: public:
explicit MapViewCache(const std::shared_ptr<MapViewModel> & model); explicit MapViewCache(const std::shared_ptr<MapViewModel> & model);
~MapViewCache(); ~MapViewCache();
/// updates internal terrain cache according to provided time delta /// updates internal terrain cache according to provided time delta
void update(const std::shared_ptr<const IMapRendererContext> & context); void update(const std::shared_ptr<IMapRendererContext> & context);
/// renders updated terrain cache onto provided canvas /// renders updated terrain cache onto provided canvas
void render(const std::shared_ptr<const IMapRendererContext> &context, Canvas & target, bool fullRedraw); void render(const std::shared_ptr<IMapRendererContext> &context, Canvas & target, bool fullRedraw);
}; };

View File

@ -24,23 +24,54 @@
void MapViewController::setViewCenter(const int3 & position) void MapViewController::setViewCenter(const int3 & position)
{ {
assert(context->isInMap(position)); assert(context->isInMap(position));
setViewCenter(Point(position) * model->getSingleTileSize(), position.z); setViewCenter(Point(position) * model->getSingleTileSize() + model->getSingleTileSize() / 2, position.z);
} }
void MapViewController::setViewCenter(const Point & position, int level) void MapViewController::setViewCenter(const Point & position, int level)
{ {
Point upperLimit = Point(context->getMapSize()) * model->getSingleTileSize() + model->getSingleTileSize();
Point lowerLimit = Point(0,0);
if (context->worldViewModeActive)
{
Point area = model->getPixelsVisibleDimensions();
Point mapCenter = upperLimit / 2;
Point desiredLowerLimit = lowerLimit + area / 2;
Point desiredUpperLimit = upperLimit - area / 2;
Point actualLowerLimit {
std::min(desiredLowerLimit.x, mapCenter.x),
std::min(desiredLowerLimit.y, mapCenter.y)
};
Point actualUpperLimit {
std::max(desiredUpperLimit.x, mapCenter.x),
std::max(desiredUpperLimit.y, mapCenter.y)
};
upperLimit = actualUpperLimit;
lowerLimit = actualLowerLimit;
}
Point betterPosition = { Point betterPosition = {
vstd::clamp(position.x, 0, context->getMapSize().x * model->getSingleTileSize().x), vstd::clamp(position.x, lowerLimit.x, upperLimit.x),
vstd::clamp(position.y, 0, context->getMapSize().y * model->getSingleTileSize().y) vstd::clamp(position.y, lowerLimit.y, upperLimit.y)
}; };
model->setViewCenter(betterPosition); model->setViewCenter(betterPosition);
model->setLevel(vstd::clamp(level, 0, context->getMapSize().z)); model->setLevel(vstd::clamp(level, 0, context->getMapSize().z));
if (adventureInt) // may be called before adventureInt is initialized
adventureInt->onMapViewMoved(model->getTilesTotalRect(), model->getLevel());
} }
void MapViewController::setTileSize(const Point & tileSize) void MapViewController::setTileSize(const Point & tileSize)
{ {
model->setTileSize(tileSize); model->setTileSize(tileSize);
// force update of view center since changing tile size may invalidated it
setViewCenter(model->getMapViewCenter(), model->getLevel());
} }
MapViewController::MapViewController(std::shared_ptr<MapViewModel> model) MapViewController::MapViewController(std::shared_ptr<MapViewModel> model)
@ -49,7 +80,7 @@ MapViewController::MapViewController(std::shared_ptr<MapViewModel> model)
{ {
} }
std::shared_ptr<const IMapRendererContext> MapViewController::getContext() const std::shared_ptr<IMapRendererContext> MapViewController::getContext() const
{ {
return context; return context;
} }
@ -92,13 +123,11 @@ void MapViewController::update(uint32_t timeDelta)
context->movementAnimation->progress += timeDelta / heroMoveTime; context->movementAnimation->progress += timeDelta / heroMoveTime;
Point positionFrom = Point(hero->convertToVisitablePos(context->movementAnimation->tileFrom)) * model->getSingleTileSize(); Point positionFrom = Point(hero->convertToVisitablePos(context->movementAnimation->tileFrom)) * model->getSingleTileSize() + model->getSingleTileSize() / 2;
Point positionDest = Point(hero->convertToVisitablePos(context->movementAnimation->tileDest)) * model->getSingleTileSize(); Point positionDest = Point(hero->convertToVisitablePos(context->movementAnimation->tileDest)) * model->getSingleTileSize() + model->getSingleTileSize() / 2;
Point positionCurr = vstd::lerp(positionFrom, positionDest, context->movementAnimation->progress); Point positionCurr = vstd::lerp(positionFrom, positionDest, context->movementAnimation->progress);
setViewCenter(positionCurr, context->movementAnimation->tileDest.z);
if(context->movementAnimation->progress >= 1.0) if(context->movementAnimation->progress >= 1.0)
{ {
setViewCenter(hero->getSightCenter()); setViewCenter(hero->getSightCenter());
@ -107,6 +136,10 @@ void MapViewController::update(uint32_t timeDelta)
context->addObject(context->getObject(context->movementAnimation->target)); context->addObject(context->getObject(context->movementAnimation->target));
context->movementAnimation.reset(); context->movementAnimation.reset();
} }
else
{
setViewCenter(positionCurr, context->movementAnimation->tileDest.z);
}
} }
if(context->teleportAnimation) if(context->teleportAnimation)

View File

@ -42,7 +42,7 @@ private:
public: public:
explicit MapViewController(std::shared_ptr<MapViewModel> model); explicit MapViewController(std::shared_ptr<MapViewModel> model);
std::shared_ptr<const IMapRendererContext> getContext() const; std::shared_ptr<IMapRendererContext> getContext() const;
void setViewCenter(const int3 & position); void setViewCenter(const int3 & position);
void setViewCenter(const Point & position, int level); void setViewCenter(const Point & position, int level);

View File

@ -118,7 +118,7 @@ typedef void (*TColorPutterAlpha)(uint8_t *&ptr, const uint8_t & R, const uint8_
void setDefaultColorKeyPresize(SDL_Surface * surface); void setDefaultColorKeyPresize(SDL_Surface * surface);
/// helper that will safely set and un-set ClipRect for SDL_Surface /// helper that will safely set and un-set ClipRect for SDL_Surface
class CClipRectGuard class CClipRectGuard : boost::noncopyable
{ {
SDL_Surface * surf; SDL_Surface * surf;
Rect oldRect; Rect oldRect;

View File

@ -84,7 +84,7 @@ void CQuestMinimap::addQuestMarks (const QuestInfo * q)
Point offset = tileToPixels(tile); Point offset = tileToPixels(tile);
setLevel(tile.z); onMapViewMoved(Rect(), tile.z);
auto pic = std::make_shared<CQuestIcon>("VwSymbol.def", 3, offset.x, offset.y); auto pic = std::make_shared<CQuestIcon>("VwSymbol.def", 3, offset.x, offset.y);
@ -104,7 +104,7 @@ void CQuestMinimap::update()
void CQuestMinimap::iconClicked() void CQuestMinimap::iconClicked()
{ {
if(currentQuest->obj) if(currentQuest->obj)
adventureInt->centerOn (currentQuest->obj->pos); adventureInt->centerOnTile(currentQuest->obj->pos);
//moveAdvMapSelection(); //moveAdvMapSelection();
} }

View File

@ -22,7 +22,6 @@
#include "../battle/BattleInterface.h" #include "../battle/BattleInterface.h"
#include "../battle/BattleInterfaceClasses.h" #include "../battle/BattleInterfaceClasses.h"
#include "../adventureMap/CAdvMapInt.h" #include "../adventureMap/CAdvMapInt.h"
#include "../adventureMap/CTerrainRect.h"
#include "../windows/CMessage.h" #include "../windows/CMessage.h"
#include "../renderSDL/SDL_Extensions.h" #include "../renderSDL/SDL_Extensions.h"
#include "../gui/CursorHandler.h" #include "../gui/CursorHandler.h"

View File

@ -132,6 +132,11 @@ public:
return *this; return *this;
} }
bool operator == (const Rect & other)
{
return x == other.x && y == other.y && w == other.w && h == other.h;
}
/// returns true if this rect intersects with another rect /// returns true if this rect intersects with another rect
DLL_LINKAGE bool intersectionTest(const Rect & other) const; DLL_LINKAGE bool intersectionTest(const Rect & other) const;