1 /* 2 * The ManaPlus Client 3 * Copyright (C) 2004-2009 The Mana World Development Team 4 * Copyright (C) 2009-2010 The Mana Developers 5 * Copyright (C) 2011-2019 The ManaPlus Developers 6 * Copyright (C) 2019-2021 Andrei Karas 7 * 8 * This file is part of The ManaPlus Client. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 #ifndef RESOURCES_MAP_MAP_H 25 #define RESOURCES_MAP_MAP_H 26 27 #include "position.h" 28 29 #include "being/actor.h" 30 31 #include "enums/render/rendertype.h" 32 33 #include "enums/resources/map/blocktype.h" 34 #include "enums/resources/map/maplayerposition.h" 35 #include "enums/resources/map/maptype.h" 36 37 #include "listeners/configlistener.h" 38 39 #include "utils/vector.h" 40 41 #include "resources/memorycounter.h" 42 43 #include "resources/map/properties.h" 44 45 class AmbientLayer; 46 #ifdef USE_OPENGL 47 class AtlasResource; 48 #endif // USE_OPENGL 49 50 class MapHeights; 51 class MapItem; 52 class MapLayer; 53 class ObjectsLayer; 54 class SpecialLayer; 55 class Tileset; 56 class TileAnimation; 57 class WalkLayer; 58 59 struct MetaTile; 60 61 typedef STD_VECTOR<Tileset*> Tilesets; 62 typedef STD_VECTOR<MapLayer*> Layers; 63 typedef Layers::const_iterator LayersCIter; 64 65 typedef STD_VECTOR<AmbientLayer*> AmbientLayerVector; 66 typedef AmbientLayerVector::const_iterator AmbientLayerVectorCIter; 67 typedef AmbientLayerVector::iterator AmbientLayerVectorIter; 68 69 /** 70 * A tile map. 71 */ 72 class Map final : public Properties, 73 public ConfigListener, 74 public MemoryCounter 75 { 76 public: 77 /** 78 * Constructor, taking map and tile size as parameters. 79 */ 80 Map(const std::string &name, 81 const int width, 82 const int height, 83 const int tileWidth, 84 const int tileHeight); 85 86 A_DELETE_COPY(Map) 87 88 /** 89 * Destructor. 90 */ 91 ~Map() override final; 92 93 /** 94 * Initialize ambient layers. Has to be called after all the properties 95 * are set. 96 */ 97 void initializeAmbientLayers() restrict2; 98 99 /** 100 * Updates animations. Called as needed. 101 */ 102 void update(const int ticks) restrict2; 103 104 /** 105 * Draws the map to the given graphics output. This method draws all 106 * layers, actors and overlay effects. 107 */ 108 void draw(Graphics *restrict const graphics, 109 int scrollX, 110 int scrollY) restrict2 A_NONNULL(2); 111 112 /** 113 * Visualizes collision layer for debugging 114 */ 115 void drawCollision(Graphics *restrict const graphics, 116 const int scrollX, 117 const int scrollY, 118 const MapTypeT drawFlags) const 119 restrict2 A_NONNULL(2); 120 121 /** 122 * Adds a layer to this map. The map takes ownership of the layer. 123 */ 124 void addLayer(MapLayer *const layer) restrict2 A_NONNULL(2); 125 126 /** 127 * Adds a tileset to this map. The map takes ownership of the tileset. 128 */ 129 void addTileset(Tileset *const tileset) restrict2 A_NONNULL(2); 130 131 /** 132 * Finds the tile set that a tile with the given global id is part of. 133 */ 134 const Tileset *getTilesetWithGid(const int gid) const 135 restrict2 A_WARN_UNUSED; 136 137 /** 138 * Get tile reference. 139 */ 140 const MetaTile *getMetaTile(const int x, 141 const int y) const 142 restrict2 A_WARN_UNUSED; 143 144 void addBlockMask(const int x, const int y, 145 const BlockTypeT type) restrict2; 146 147 void setBlockMask(const int x, const int y, 148 const BlockTypeT type) restrict2; 149 150 /** 151 * Gets walkability for a tile with a blocking bitmask. When called 152 * without walkmask, only blocks against colliding tiles. 153 */ 154 bool getWalk(const int x, const int y, 155 const unsigned char blockWalkMask) const 156 restrict2 A_WARN_UNUSED; 157 158 void setWalk(const int x, const int y) restrict2; 159 160 unsigned char getBlockMask(const int x, 161 const int y) const restrict2; 162 163 /** 164 * Returns the width of this map in tiles. 165 */ getWidth()166 int getWidth() const restrict2 noexcept2 A_WARN_UNUSED 167 { return mWidth; } 168 169 /** 170 * Returns the height of this map in tiles. 171 */ getHeight()172 int getHeight() const restrict2 noexcept2 A_WARN_UNUSED 173 { return mHeight; } 174 175 /** 176 * Returns the tile width of this map. 177 */ getTileWidth()178 int getTileWidth() const restrict2 noexcept2 A_WARN_UNUSED 179 { return mTileWidth; } 180 181 /** 182 * Returns the tile height used by this map. 183 */ getTileHeight()184 int getTileHeight() const restrict2 noexcept2 A_WARN_UNUSED 185 { return mTileHeight; } 186 187 const std::string getMusicFile() const restrict2 A_WARN_UNUSED; 188 189 void setMusicFile(const std::string &restrict file) restrict2; 190 191 const std::string getName() const restrict2 A_WARN_UNUSED; 192 193 /** 194 * Gives the map id based on filepath (ex: 009-1) 195 */ 196 const std::string getFilename() const restrict2 A_WARN_UNUSED; 197 198 const std::string getGatName() const restrict2 A_WARN_UNUSED; 199 200 /** 201 * Find a path from one location to the next. 202 */ 203 Path findPath(const int startX, const int startY, 204 const int destX, const int destY, 205 const unsigned char blockWalkmask, 206 const int maxCost) restrict2 A_WARN_UNUSED; 207 208 /** 209 * Adds a particle effect 210 */ 211 void addParticleEffect(const std::string &restrict effectFile, 212 const int x, 213 const int y, 214 const int w, 215 const int h) restrict2; 216 217 /** 218 * Initializes all added particle effects 219 */ 220 void initializeParticleEffects() const restrict2; 221 222 /** 223 * Adds a tile animation to the map 224 */ 225 void addAnimation(const int gid, 226 TileAnimation *restrict const animation) restrict2 227 A_NONNULL(3); 228 229 void setDrawLayersFlags(const MapTypeT &restrict n) restrict2; 230 getDrawLayersFlags()231 MapTypeT getDrawLayersFlags() const restrict2 A_WARN_UNUSED 232 { return mDrawLayersFlags; } 233 234 void addExtraLayer() restrict2; 235 236 void saveExtraLayer() const restrict2; 237 getTempLayer()238 SpecialLayer *getTempLayer() const restrict2 noexcept2 A_WARN_UNUSED 239 { return mTempLayer; } 240 getSpecialLayer()241 SpecialLayer *getSpecialLayer() const restrict2 noexcept2 A_WARN_UNUSED 242 { return mSpecialLayer; } 243 setHasWarps(const bool n)244 void setHasWarps(const bool n) restrict2 noexcept2 245 { mHasWarps = n; } 246 getHasWarps()247 bool getHasWarps() const restrict2 noexcept2 A_WARN_UNUSED 248 { return mHasWarps; } 249 250 std::string getUserMapDirectory() const restrict2 A_WARN_UNUSED; 251 252 void addPortal(const std::string &restrict name, 253 const int type, 254 const int x, const int y, 255 const int dx, const int dy) restrict2; 256 257 void addRange(const std::string &restrict name, 258 const int type, 259 const int x, const int y, 260 const int dx, const int dy) restrict2; 261 262 void addPortalTile(const std::string &restrict name, 263 const int type, 264 const int x, const int y) restrict2; 265 266 void updatePortalTile(const std::string &restrict name, 267 const int type, 268 const int x, const int y, 269 const bool addNew) restrict2; 270 getPortals()271 const STD_VECTOR<MapItem*> &getPortals() const restrict2 noexcept2 272 A_WARN_UNUSED 273 { return mMapPortals; } 274 275 /** 276 * Gets the tile animation for a specific gid 277 */ 278 const TileAnimation *getAnimationForGid(const int gid) 279 const restrict2 A_WARN_UNUSED; 280 281 void optionChanged(const std::string &restrict value) 282 restrict2 override final; 283 284 MapItem *findPortalXY(const int x, 285 const int y) const restrict2 A_WARN_UNUSED; 286 getActorsCount()287 int getActorsCount() const restrict2 A_WARN_UNUSED 288 { return CAST_S32(mActors.size()); } 289 290 void setPvpMode(const int mode) restrict2; 291 getPvpMode()292 int getPvpMode() const restrict2 noexcept2 A_WARN_UNUSED 293 { return mPvp; } 294 getObjectsLayer()295 const ObjectsLayer* getObjectsLayer() const restrict2 noexcept2 296 A_WARN_UNUSED 297 { return mObjects; } 298 299 std::string getObjectData(const unsigned x, 300 const unsigned y, 301 const int type) const 302 restrict2 A_WARN_UNUSED; 303 304 void indexTilesets() restrict2; 305 306 void clearIndexedTilesets() restrict2; 307 308 void setActorsFix(const int x, const int y) restrict2; 309 getVersion()310 int getVersion() const restrict2 noexcept2 A_WARN_UNUSED 311 { return mVersion; } 312 setVersion(const int n)313 void setVersion(const int n) restrict2 noexcept2 314 { mVersion = n; } 315 316 void reduce() restrict2; 317 redrawMap()318 void redrawMap() restrict2 noexcept2 319 { mRedrawMap = true; } 320 empty()321 bool empty() const restrict2 A_WARN_UNUSED 322 { return mLayers.empty(); } 323 setCustom(const bool b)324 void setCustom(const bool b) restrict2 noexcept2 325 { mCustom = b; } 326 isCustom()327 bool isCustom() const restrict2 noexcept2 A_WARN_UNUSED 328 { return mCustom; } 329 getTileAnimations()330 const std::map<int, TileAnimation*> &getTileAnimations() const 331 restrict2 noexcept2 A_WARN_UNUSED 332 { return mTileAnimations; } 333 334 #ifdef USE_OPENGL 335 int getAtlasCount() const restrict2 A_WARN_UNUSED; 336 setAtlas(AtlasResource * restrict const atlas)337 void setAtlas(AtlasResource *restrict const atlas) restrict2 noexcept2 338 { mAtlas = atlas; } 339 haveAtlas()340 bool haveAtlas() const 341 { return mAtlas != nullptr; } 342 #endif // USE_OPENGL 343 getMetaTiles()344 const MetaTile *getMetaTiles() const restrict2 noexcept2 345 { return mMetaTiles; } 346 getWalkLayer()347 const WalkLayer *getWalkLayer() const restrict2 noexcept2 348 { return mWalkLayer; } 349 setWalkLayer(WalkLayer * restrict const layer)350 void setWalkLayer(WalkLayer *restrict const layer) restrict2 noexcept2 351 { mWalkLayer = layer; } 352 353 void addHeights(const MapHeights *restrict const heights) restrict2 354 A_NONNULL(2); 355 356 uint8_t getHeightOffset(const int x, const int y) const restrict2; 357 358 void setMask(const int mask) restrict2; 359 360 void updateDrawLayersList() restrict2; 361 isHeightsPresent()362 bool isHeightsPresent() const restrict2 noexcept2 363 { return mHeights != nullptr; } 364 365 void updateConditionLayers() restrict2; 366 367 void preCacheLayers() restrict2; 368 369 int calcMemoryLocal() const override final; 370 371 int calcMemoryChilds(const int level) const override final; 372 getCounterName()373 std::string getCounterName() const override final 374 { return mName; } 375 376 void screenResized(); 377 378 protected: 379 friend class Actor; 380 friend class Minimap; 381 382 /** 383 * Adds an actor to the map. 384 */ 385 Actors::iterator addActor(Actor *const actor) restrict2 A_NONNULL(2); 386 387 /** 388 * Removes an actor from the map. 389 */ 390 void removeActor(const Actors::iterator &restrict iterator) restrict2; 391 392 private: 393 /** 394 * Updates scrolling of ambient layers. Has to be called each game tick. 395 */ 396 void updateAmbientLayers(const float scrollX, 397 const float scrollY) restrict2; 398 399 /** 400 * Draws the foreground or background layers to the given graphics output. 401 */ 402 void drawAmbientLayers(Graphics *restrict const graphics, 403 const MapLayerPositionT type, 404 const int detail) const restrict2 A_NONNULL(2); 405 406 /** 407 * Tells whether the given coordinates fall within the map boundaries. 408 */ 409 bool contains(const int x, 410 const int y) const restrict2 A_WARN_UNUSED; 411 412 const int mWidth; 413 const int mHeight; 414 const int mTileWidth; 415 const int mTileHeight; 416 int mMaxTileHeight; 417 MetaTile *const mMetaTiles; 418 WalkLayer *mWalkLayer; 419 Layers mLayers; 420 Layers mDrawUnderLayers; 421 Layers mDrawOverLayers; 422 Tilesets mTilesets; 423 Actors mActors; 424 bool mHasWarps; 425 426 // draw flags 427 MapTypeT mDrawLayersFlags; 428 429 // Pathfinding members 430 unsigned int mOnClosedList; 431 unsigned int mOnOpenList; 432 433 // Overlay data 434 AmbientLayerVector mBackgrounds; 435 AmbientLayerVector mForegrounds; 436 float mLastAScrollX; 437 float mLastAScrollY; 438 439 // Particle effect data 440 struct ParticleEffectData final 441 { ParticleEffectDatafinal442 ParticleEffectData(const std::string &restrict file0, 443 const int x0, 444 const int y0, 445 const int w0, 446 const int h0) noexcept2 : 447 file(file0), 448 x(x0), 449 y(y0), 450 w(w0), 451 h(h0) 452 { 453 } 454 455 A_DEFAULT_COPY(ParticleEffectData) 456 457 const2 std::string file; 458 const2 int x; 459 const2 int y; 460 const2 int w; 461 const2 int h; 462 }; 463 STD_VECTOR<ParticleEffectData> mParticleEffects; 464 465 STD_VECTOR<MapItem*> mMapPortals; 466 467 std::map<int, TileAnimation*> mTileAnimations; 468 469 std::string mName; 470 int mOverlayDetail; 471 float mOpacity; 472 const RenderType mOpenGL; 473 int mPvp; 474 bool mTilesetsIndexed; 475 Tileset** mIndexedTilesets; 476 int mIndexedTilesetsSize; 477 int mActorFixX; 478 int mActorFixY; 479 int mVersion; 480 481 SpecialLayer *mSpecialLayer; 482 SpecialLayer *mTempLayer; 483 ObjectsLayer *mObjects; 484 MapLayer *mFringeLayer; 485 486 int mLastX; 487 int mLastY; 488 int mLastScrollX; 489 int mLastScrollY; 490 491 int mDrawX; 492 int mDrawY; 493 int mDrawScrollX; 494 int mDrawScrollY; 495 int mMask; 496 #ifdef USE_OPENGL 497 AtlasResource *mAtlas; 498 #endif // USE_OPENGL 499 500 const MapHeights *mHeights; 501 bool mRedrawMap; 502 bool mBeingOpacity; 503 bool mCachedDraw; 504 bool mCustom; 505 bool mDrawOnlyFringe; 506 bool mClear; 507 }; 508 509 #endif // RESOURCES_MAP_MAP_H 510