diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index d6fb4f6bc..1a4e0d30d 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -46,6 +46,8 @@ set(client_SOURCES ${client_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/mapio.cpp ${CMAKE_CURRENT_LIST_DIR}/mapview.cpp ${CMAKE_CURRENT_LIST_DIR}/mapview.h + ${CMAKE_CURRENT_LIST_DIR}/mapviewcontrol.cpp + ${CMAKE_CURRENT_LIST_DIR}/mapviewcontrol.h ${CMAKE_CURRENT_LIST_DIR}/minimap.cpp ${CMAKE_CURRENT_LIST_DIR}/minimap.h ${CMAKE_CURRENT_LIST_DIR}/lightview.cpp diff --git a/src/client/game.cpp b/src/client/game.cpp index 833ac34fd..d2d9b7fd7 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -653,6 +653,8 @@ bool Game::walk(Otc::Direction direction, bool dash) } m_localPlayer->stopAutoWalk(); + for(const auto& mapView: g_map.getMapViews()) + mapView->requestVisibleTilesCacheUpdate(); if(getClientVersion() <= 740) { const TilePtr& fromTile = g_map.getTile(m_localPlayer->getPosition()); diff --git a/src/client/localplayer.cpp b/src/client/localplayer.cpp index 2d2e53b12..ad9c61b0d 100644 --- a/src/client/localplayer.cpp +++ b/src/client/localplayer.cpp @@ -243,6 +243,9 @@ void LocalPlayer::stopWalk() m_lastPrewalkDone = true; m_lastPrewalkDestination = Position(); + + for(const auto& mapView: g_map.getMapViews()) + mapView->requestVisibleTilesCacheUpdate(); } void LocalPlayer::updateWalkOffset(int totalPixelsWalked) diff --git a/src/client/map.cpp b/src/client/map.cpp index 461cefbf0..7b3b87c08 100644 --- a/src/client/map.cpp +++ b/src/client/map.cpp @@ -29,6 +29,7 @@ #include "statictext.h" #include "mapview.h" #include "minimap.h" +#include "mapviewcontrol.h" #include #include @@ -689,10 +690,10 @@ void Map::setAwareRange(const AwareRange& range) void Map::resetAwareRange() { AwareRange range; - range.left = 8; - range.top = 6; - range.bottom = 7; - range.right = 9; + range.left = MapViewControl::maxMapviewX; + range.top = MapViewControl::maxMapviewY; + range.bottom = range.top + 1; + range.right = range.left + 1; setAwareRange(range); } diff --git a/src/client/map.h b/src/client/map.h index a7ce119b4..966a4991a 100644 --- a/src/client/map.h +++ b/src/client/map.h @@ -144,6 +144,7 @@ class Map void addMapView(const MapViewPtr& mapView); void removeMapView(const MapViewPtr& mapView); + const std::vector& getMapViews() const { return m_mapViews; } void notificateTileUpdate(const Position& pos); bool loadOtcm(const std::string& fileName); diff --git a/src/client/mapview.cpp b/src/client/mapview.cpp index eb12a5870..83425b36e 100644 --- a/src/client/mapview.cpp +++ b/src/client/mapview.cpp @@ -23,6 +23,7 @@ #include "mapview.h" #include "creature.h" +#include "game.h" #include "map.h" #include "tile.h" #include "statictext.h" @@ -66,6 +67,11 @@ MapView::MapView() setVisibleDimension(Size(15, 11)); m_shader = g_shaders.getDefaultMapShader(); + + for(int dir = Otc::North; dir < Otc::InvalidDirection; ++dir) { + MapViewControl mapViewControl = MapViewControl((Otc::Direction) dir); + m_mapViewControl[dir] = mapViewControl; + } } MapView::~MapView() @@ -130,7 +136,6 @@ void MapView::draw(const Rect& rect) auto it = m_cachedVisibleTiles.begin(); auto end = m_cachedVisibleTiles.end(); for(int z=m_cachedLastVisibleFloor;z>=m_cachedFirstVisibleFloor;--z) { - while(it != end) { const TilePtr& tile = *it; Position tilePos = tile->getPosition(); @@ -160,7 +165,6 @@ void MapView::draw(const Rect& rect) m_mustDrawVisibleTilesCache = false; } - float fadeOpacity = 1.0f; if(!m_shaderSwitchDone && m_fadeOutTime > 0) { fadeOpacity = 1.0f - (m_fadeTimer.timeElapsed() / m_fadeOutTime); @@ -311,6 +315,10 @@ void MapView::updateVisibleTilesCache(int start) if(!cameraPosition.isValid()) return; + const LocalPlayerPtr player = g_game.getLocalPlayer(); + const bool isWalking = player->isWalking() || player->isPreWalking() || player->isServerWalking(); + const auto& mapViewControl = isWalking ? m_mapViewControl[player->getDirection()] : m_mapViewControl[Otc::InvalidDirection]; + bool stop = false; // clear current visible tiles cache @@ -352,6 +360,8 @@ void MapView::updateVisibleTilesCache(int start) // skip tiles that are completely behind another tile if(g_map.isCompletelyCovered(tilePos, m_cachedFirstVisibleFloor)) continue; + if(!mapViewControl.isValid(tile, cameraPosition)) + continue; m_cachedVisibleTiles.push_back(tile); } m_updateTilesPos++; @@ -401,7 +411,7 @@ void MapView::updateVisibleTilesCache(int start) Position tilePos = cameraPosition.translated(p.x - m_virtualCenterOffset.x, p.y - m_virtualCenterOffset.y); tilePos.coveredUp(cameraPosition.z - iz); if(const TilePtr& tile = g_map.getTile(tilePos)) { - if(tile->isDrawable()) + if(tile->isDrawable() && mapViewControl.isValid(tile, cameraPosition)) m_cachedVisibleTiles.push_back(tile); } } diff --git a/src/client/mapview.h b/src/client/mapview.h index 4f5721c53..7130a53f1 100644 --- a/src/client/mapview.h +++ b/src/client/mapview.h @@ -29,6 +29,7 @@ #include #include #include "lightview.h" +#include "mapviewcontrol.h" // @bindclass class MapView : public LuaObject @@ -48,7 +49,6 @@ class MapView : public LuaObject private: void updateGeometry(const Size& visibleDimension, const Size& optimizedSize); void updateVisibleTilesCache(int start = 0); - void requestVisibleTilesCacheUpdate() { m_mustUpdateVisibleTilesCache = true; } protected: void onTileUpdate(const Position& pos); @@ -57,6 +57,8 @@ class MapView : public LuaObject friend class Map; public: + void requestVisibleTilesCacheUpdate() { m_mustUpdateVisibleTilesCache = true; } + // floor visibility related void lockFirstVisibleFloor(int firstVisibleFloor); void unlockFirstVisibleFloor(); @@ -162,6 +164,7 @@ class MapView : public LuaObject stdext::boolean m_follow; std::vector m_cachedVisibleTiles; std::vector m_cachedFloorVisibleCreatures; + std::array m_mapViewControl; CreaturePtr m_followingCreature; FrameBufferPtr m_framebuffer; PainterShaderProgramPtr m_shader; diff --git a/src/client/mapviewcontrol.cpp b/src/client/mapviewcontrol.cpp new file mode 100644 index 000000000..b9de0a730 --- /dev/null +++ b/src/client/mapviewcontrol.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2010-2020 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "mapviewcontrol.h" +#include "map.h" + +MapViewControl::MapViewControl(const Otc::Direction directionWalking) +{ + m_top = maxMapviewY; + m_right = maxMapviewX; + m_bottom = m_top; + m_left = m_right; + + switch(directionWalking) { + case Otc::North: + m_top += 1; + m_bottom += 1; + break; + case Otc::East: + m_right += 1; + m_left += 1; + break; + case Otc::South: + m_top += 1; + m_bottom += 1; + break; + case Otc::West: + m_left += 1; + m_right += 1; + break; + case Otc::NorthEast: + m_left += 1; + m_bottom += 1; + + m_top += 1; + m_right += 1; + break; + case Otc::SouthEast: + m_right += 1; + m_bottom += 1; + + m_top += 1; + m_left += 1; + break; + case Otc::SouthWest: + m_top += 1; + m_right += 1; + + m_left += 1; + m_bottom += 1; + break; + case Otc::NorthWest: + m_right += 1; + m_bottom += 1; + + m_top += 1; + m_left += 1; + break; + case Otc::InvalidDirection: + break; + } +} + +bool MapViewControl::isValid(const TilePtr& tile, const Position cameraPosition) const +{ + const Position tilePos = tile->getPosition(); + const int dz = tilePos.z - cameraPosition.z; + Position checkPos = tilePos.translated(dz, dz); + + if(cameraPosition.x - checkPos.x >= m_left || cameraPosition.y - checkPos.y >= m_top) + return false; + else if((checkPos.x - cameraPosition.x >= m_right || checkPos.y - cameraPosition.y >= m_bottom) && tile->isSingleDimension()) + return false; + + return true; +} diff --git a/src/client/mapviewcontrol.h b/src/client/mapviewcontrol.h new file mode 100644 index 000000000..562e62039 --- /dev/null +++ b/src/client/mapviewcontrol.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010-2020 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MAPVIEW_OPTIMIZED_H +#define MAPVIEW_OPTIMIZED_H + +#include "declarations.h" +#include "const.h" + +class MapViewControl { +public: + static const int32_t maxMapviewX = 8; + static const int32_t maxMapviewY = 6; + + MapViewControl(const Otc::Direction directionWalking = Otc::InvalidDirection); + + bool isValid(const TilePtr& tile, const Position cameraPosition) const; + + int top() const { return m_top; } + int right() const { return m_right; } + int bottom() const { return m_bottom; } + int left() const { return m_left; } + +private: + int m_top; + int m_right; + int m_bottom; + int m_left; +}; + +#endif diff --git a/vc14/otclient.vcxproj b/vc14/otclient.vcxproj index 095b26bfe..b7a89c2d0 100644 --- a/vc14/otclient.vcxproj +++ b/vc14/otclient.vcxproj @@ -161,6 +161,7 @@ + @@ -312,6 +313,7 @@ + @@ -474,4 +476,4 @@ - \ No newline at end of file + diff --git a/vc14/otclient.vcxproj.filters b/vc14/otclient.vcxproj.filters index 560887f35..4b0983936 100644 --- a/vc14/otclient.vcxproj.filters +++ b/vc14/otclient.vcxproj.filters @@ -453,6 +453,9 @@ Source Files\client + + Source Files\client + Source Files\client