diff --git a/src/framework/core/resourcemanager.cpp b/src/framework/core/resourcemanager.cpp index a0debf80..8e7db4e9 100644 --- a/src/framework/core/resourcemanager.cpp +++ b/src/framework/core/resourcemanager.cpp @@ -123,7 +123,7 @@ bool ResourceManager::saveFile(const std::string& fileName, const uchar* data, u return true; } -bool ResourceManager::saveFile(const std::string& fileName, std::istream& in) +bool ResourceManager::saveFile(const std::string& fileName, std::iostream& in) { std::streampos oldPos = in.tellg(); in.seekg(0, std::ios::end); diff --git a/src/framework/core/resourcemanager.h b/src/framework/core/resourcemanager.h index 54920e5f..d576b1cb 100644 --- a/src/framework/core/resourcemanager.h +++ b/src/framework/core/resourcemanager.h @@ -44,7 +44,7 @@ public: bool saveFile(const std::string& fileName, const uchar* data, uint size); bool saveFile(const std::string& fileName, const std::string& data); - bool saveFile(const std::string& fileName, std::istream& in); + bool saveFile(const std::string& fileName, std::iostream& in); bool deleteFile(const std::string& fileName); diff --git a/src/otclient/core/game.cpp b/src/otclient/core/game.cpp index 06226ec0..ddc6432e 100644 --- a/src/otclient/core/game.cpp +++ b/src/otclient/core/game.cpp @@ -94,7 +94,7 @@ void Game::processLogout() m_protocolGame = nullptr; } - g_map.clean(); + g_map.save(); } void Game::processDeath() diff --git a/src/otclient/core/map.cpp b/src/otclient/core/map.cpp index f22dc294..8b72b37e 100644 --- a/src/otclient/core/map.cpp +++ b/src/otclient/core/map.cpp @@ -30,6 +30,7 @@ #include #include "mapview.h" +#include Map g_map; @@ -51,6 +52,51 @@ void Map::notificateTileUpdateToMapViews(const Position& pos) mapView->onTileUpdate(pos); } +void Map::load() +{ + if(!g_resources.fileExists("/map.otcmap")) + return; + + std::stringstream in; + g_resources.loadFile("/map.otcmap", in); + + while(!in.eof()) { + Position pos; + in.read((char*)&pos, sizeof(pos)); + + uint16 id; + in.read((char*)&id, sizeof(id)); + while(id != 0xFFFF) { + addThing(Item::create(id), pos); + in.read((char*)&id, sizeof(id)); + } + } +} + +void Map::save() +{ + std::stringstream out; + + for(auto& pair : m_tiles) { + Position pos = pair.first; + TilePtr tile = pair.second; + if(!tile) + continue; + out.write((char*)&pos, sizeof(pos)); + uint16 id; + for(const ThingPtr& thing : tile->getThings()) { + if(ItemPtr item = thing->asItem()) { + id = item->getId(); + out.write((char*)&id, sizeof(id)); + } + } + id = 0xFFFF; + out.write((char*)&id, sizeof(id)); + } + + g_resources.saveFile("/map.otcmap", out); +} + void Map::clean() { m_tiles.clear(); diff --git a/src/otclient/core/map.h b/src/otclient/core/map.h index bae49bda..e203ac34 100644 --- a/src/otclient/core/map.h +++ b/src/otclient/core/map.h @@ -34,6 +34,8 @@ public: void removeMapView(const MapViewPtr& mapView); void notificateTileUpdateToMapViews(const Position& pos); + void load(); + void save(); void clean(); // thing related diff --git a/src/otclient/core/mapview.cpp b/src/otclient/core/mapview.cpp index f5d1035e..6b8e11a1 100644 --- a/src/otclient/core/mapview.cpp +++ b/src/otclient/core/mapview.cpp @@ -53,6 +53,7 @@ void MapView::draw(const Rect& rect) bool updated = updateVisibleTilesCache(); float scaleFactor = m_tileSize/(float)Otc::TILE_PIXELS; + Position cameraPosition = getCameraPosition(); if(updated || m_animated) { m_framebuffer->bind(); @@ -76,6 +77,10 @@ void MapView::draw(const Rect& rect) g_painter.releaseCustomProgram(); + // this could happen if the player position is not known yet + if(!cameraPosition.isValid()) + return; + float horizontalStretchFactor = rect.width() / (float)(m_visibleDimension.width() * m_tileSize); float verticalStretchFactor = rect.height() / (float)(m_visibleDimension.height() * m_tileSize); Size tileStretchedSize = Size(m_tileSize * horizontalStretchFactor, m_tileSize * verticalStretchFactor); @@ -139,6 +144,11 @@ bool MapView::updateVisibleTilesCache() // clear current visible tiles cache m_cachedVisibleTiles.clear(); + m_cachedFloorVisibleCreatures.clear(); + + // there is no tile to render on invalid positions + if(!cameraPosition.isValid()) + return true; // cache visible tiles in draw order // draw from last floor (the lower) to first floor (the higher) @@ -238,8 +248,6 @@ void MapView::setVisibleDimension(const Size& visibleDimension) m_virtualCenterOffset = (m_drawDimension/2 - Size(1,1)).toPoint(); recalculateTileSize(); - dump << m_framebuffer->getSize(); - dump << visibleDimension * m_tileSize; requestVisibleTilesCacheUpdate(); } diff --git a/src/otclient/core/tile.h b/src/otclient/core/tile.h index 0404bb45..92d9e872 100644 --- a/src/otclient/core/tile.h +++ b/src/otclient/core/tile.h @@ -45,10 +45,6 @@ public: int getThingStackpos(const ThingPtr& thing); ThingPtr getTopThing(); - void addWalkingCreature(const CreaturePtr& creature); - void removeWalkingCreature(const CreaturePtr& creature); - - ThingPtr getTopLookThing(); ThingPtr getTopUseThing(); CreaturePtr getTopCreature(); @@ -58,6 +54,7 @@ public: const Position& getPosition() { return m_position; } int getDrawElevation() { return m_drawElevation; } std::vector getCreatures(); + const std::vector& getThings() { return m_things; } ItemPtr getGround(); int getGroundSpeed(); bool isWalkable(); @@ -73,7 +70,6 @@ public: TilePtr asTile() { return std::static_pointer_cast(shared_from_this()); } private: - std::vector m_walkingCreatures; std::vector m_effects; // leave this outside m_things because it has no stackpos. std::vector m_things; Position m_position; diff --git a/src/otclient/otclient.cpp b/src/otclient/otclient.cpp index 087e4dde..bc84d753 100644 --- a/src/otclient/otclient.cpp +++ b/src/otclient/otclient.cpp @@ -24,6 +24,7 @@ #include #include "core/game.h" #include +#include "core/map.h" OTClient::OTClient(const std::string& appName) : Application(appName) { @@ -40,6 +41,8 @@ void OTClient::init(const std::vector& args) g_modules.ensureModuleLoaded("client"); g_modules.autoLoadModules(1000); + g_map.load(); + // load otclientrc.lua if(g_resources.fileExists("/otclientrc.lua")) { try { diff --git a/src/otclient/util/position.h b/src/otclient/util/position.h index 9ff18853..cb5a87b0 100644 --- a/src/otclient/util/position.h +++ b/src/otclient/util/position.h @@ -98,7 +98,7 @@ public: return Otc::InvalidDirection; } - bool isValid() const { return x >= 0 && y >= 0 && z >= 0 && x <= 65535 && y <= 65535 && z <= 255; } + bool isValid() const { return x >= 0 && y >= 0 && z >= 0 && x <= 65535 && y <= 65535 && z <= 15; } Position operator+(const Position& other) const { return Position(x + other.x, y + other.y, z + other.z); } Position& operator+=(const Position& other) { x+=other.x; y+=other.y; z +=other.z; return *this; }