From 9e7d90f2c93e0158e4c6312f8cf77fe9dd1583fd Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Wed, 21 Oct 2015 22:53:37 +0300 Subject: Add support for layers with conditional tiles. For enable this mode for layer need add property: TileCondition and set value to one of BlockMask bits. --- src/net/eathena/maprecv.cpp | 5 +---- src/resources/map/map.cpp | 14 +++++++++++++ src/resources/map/map.h | 2 ++ src/resources/map/maplayer.cpp | 46 ++++++++++++++++++++++++++++++++++++------ src/resources/map/maplayer.h | 7 ++++++- src/resources/map/tileinfo.h | 4 +++- src/resources/mapreader.cpp | 1 + 7 files changed, 67 insertions(+), 12 deletions(-) diff --git a/src/net/eathena/maprecv.cpp b/src/net/eathena/maprecv.cpp index fbad1ce0c..e40077af8 100644 --- a/src/net/eathena/maprecv.cpp +++ b/src/net/eathena/maprecv.cpp @@ -75,17 +75,14 @@ void MapRecv::processSetTilesType(Net::MessageIn &msg) if (layer) return; Map *const map = viewport->getMap(); -// logger->log("map test name: %s, mask %d", map->getGatName().c_str(), (int)mask); if (map && map->getGatName() == name) { for (int y = y1; y <= y2; y ++) { for (int x = x1; x <= x2; x ++) - { - logger->log("set col %d,%d", x, y); map->setBlockMask(x, y, mask); - } } + map->updateConditionLayers(); } } diff --git a/src/resources/map/map.cpp b/src/resources/map/map.cpp index de6090dc2..d05bb2c23 100644 --- a/src/resources/map/map.cpp +++ b/src/resources/map/map.cpp @@ -1645,3 +1645,17 @@ void Map::setActorsFix(const int x, const int y) if (mFringeLayer) mFringeLayer->setActorsFix(y); } + +void Map::updateConditionLayers() +{ + mRedrawMap = true; + + FOR_EACH (LayersCIter, it, mLayers) + { + MapLayer *const layer = *it; + if (!layer || layer->mTileCondition == -1) + continue; + layer->updateConditionTiles(mMetaTiles, + mWidth, mHeight); + } +} diff --git a/src/resources/map/map.h b/src/resources/map/map.h index 65fcb8f00..c3f4c7cac 100644 --- a/src/resources/map/map.h +++ b/src/resources/map/map.h @@ -339,6 +339,8 @@ class Map final : public Properties, public ConfigListener bool isHeightsPresent() const { return mHeights != nullptr; } + void updateConditionLayers(); + protected: friend class Actor; friend class Minimap; diff --git a/src/resources/map/maplayer.cpp b/src/resources/map/maplayer.cpp index 57583aef9..920a0f363 100644 --- a/src/resources/map/maplayer.cpp +++ b/src/resources/map/maplayer.cpp @@ -30,6 +30,7 @@ #include "being/localplayer.h" +#include "enums/resources/map/blockmask.h" #include "enums/resources/map/mapitemtype.h" #include "gui/userpalette.h" @@ -40,6 +41,7 @@ #include "resources/map/mapitem.h" #include "resources/map/maprowvertexes.h" +#include "resources/map/metatile.h" #include "resources/map/speciallayer.h" #include "debug.h" @@ -132,6 +134,8 @@ void MapLayer::draw(Graphics *const graphics, for (int x = startX; x < endX; x++, tilePtr++) { + if (!tilePtr->isEnabled) + continue; const int x32 = x * mapTileSize; int c = 0; @@ -144,7 +148,7 @@ void MapLayer::draw(Graphics *const graphics, { int width = 0; // here need not draw over player position - c = getTileDrawWidth(img, endX - x, width); + c = getTileDrawWidth(tilePtr, endX - x, width); if (!c) { @@ -225,6 +229,8 @@ void MapLayer::updateSDL(const Graphics *const graphics, for (int x = startX; x < endX; x++, tilePtr++) { + if (!tilePtr->isEnabled) + continue; Image *const img = (*tilePtr).image; if (img) { @@ -287,6 +293,8 @@ void MapLayer::updateOGL(Graphics *const graphics, TileInfo *tilePtr = &mTiles[static_cast(startX + yWidth)]; for (int x = startX; x < endX; x++, tilePtr++) { + if (!tilePtr->isEnabled) + continue; Image *const img = (*tilePtr).image; if (img) { @@ -501,7 +509,7 @@ void MapLayer::drawFringe(Graphics *const graphics, const int py = py0 - img->mBounds.h; int width = 0; // here need not draw over player position - c = getTileDrawWidth(img, endX - x, width); + c = getTileDrawWidth(tilePtr, endX - x, width); if (!c) { @@ -583,7 +591,7 @@ void MapLayer::drawFringe(Graphics *const graphics, { int width = 0; // here need not draw over player position - const int c = getTileDrawWidth(img, endX - x, width); + const int c = getTileDrawWidth(tilePtr, endX - x, width); if (!c) { @@ -646,12 +654,12 @@ void MapLayer::drawFringe(Graphics *const graphics, BLOCK_END("MapLayer::drawFringe") } -int MapLayer::getTileDrawWidth(const Image *img, +int MapLayer::getTileDrawWidth(const TileInfo *tilePtr, const int endX, int &width) { BLOCK_START("MapLayer::getTileDrawWidth") - const Image *const img1 = img; + const Image *const img1 = tilePtr->image; int c = 0; if (!img1) { @@ -662,7 +670,8 @@ int MapLayer::getTileDrawWidth(const Image *img, width = img1->mBounds.w; for (int x = 1; x < endX; x++) { - img ++; + tilePtr ++; + const Image *const img = tilePtr->image; if (img != img1) break; c ++; @@ -680,3 +689,28 @@ void MapLayer::setDrawLayerFlags(const MapTypeT &n) && mDrawLayerFlags != MapType::SPECIAL2 && mDrawLayerFlags != MapType::SPECIAL4); } + +void MapLayer::updateConditionTiles(MetaTile *const metaTiles, + const int width, const int height) +{ + const int width1 = width < mWidth ? width : mWidth; + const int height1 = height < mHeight ? height : mHeight; + + for (int y = mY; y < height1; y ++) + { + MetaTile *metaPtr = metaTiles + (y - mY) * width; + TileInfo *tilePtr = mTiles + y * mWidth; + for (int x = mX; x < width1; x ++, metaPtr ++, tilePtr ++) + { + if (metaPtr->blockmask & mTileCondition || + (metaPtr->blockmask == 0 && mTileCondition == BlockMask::GROUND)) + { + tilePtr->isEnabled = true; + } + else + { + tilePtr->isEnabled = false; + } + } + } +} diff --git a/src/resources/map/maplayer.h b/src/resources/map/maplayer.h index 2c1832691..9c0fc12c0 100644 --- a/src/resources/map/maplayer.h +++ b/src/resources/map/maplayer.h @@ -37,6 +37,8 @@ class Image; class MapRowVertexes; class SpecialLayer; +struct MetaTile; + /** * A map layer. Stores a grid of tiles and their offset, and implements layer * rendering. @@ -152,10 +154,13 @@ class MapLayer final: public ConfigListener { mActorsFix = y; } protected: - static int getTileDrawWidth(const Image *img, + static int getTileDrawWidth(const TileInfo *img, const int endX, int &width) A_WARN_UNUSED; + void updateConditionTiles(MetaTile *const metaTiles, + const int width, const int height); + private: const int mX; const int mY; diff --git a/src/resources/map/tileinfo.h b/src/resources/map/tileinfo.h index 4edd6d2b9..dc5120c95 100644 --- a/src/resources/map/tileinfo.h +++ b/src/resources/map/tileinfo.h @@ -28,11 +28,13 @@ class Image; struct TileInfo final { TileInfo() : - image(nullptr) + image(nullptr), + isEnabled(true) { } Image *image; + bool isEnabled; }; #endif // RESOURCES_MAP_TILEINFO_H diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp index 4fbef0d1b..9c0a9648f 100644 --- a/src/resources/mapreader.cpp +++ b/src/resources/mapreader.cpp @@ -272,6 +272,7 @@ Map *MapReader::readMap(const std::string &restrict filename, updateMusic(map); } + map->updateConditionLayers(); BLOCK_END("MapReader::readMap str") return map; } -- cgit v1.2.3-70-g09d2