From 9a1dc51f15c875191d5dfdb6baed483b3b5de2b3 Mon Sep 17 00:00:00 2001 From: Ihar Hubchyk Date: Tue, 22 Oct 2024 23:05:18 +0800 Subject: [PATCH 1/2] Rename Addon into Object Part --- src/fheroes2/castle/castle.cpp | 2 +- src/fheroes2/gui/interface_gamearea.cpp | 18 +- src/fheroes2/heroes/heroes_action.cpp | 4 +- src/fheroes2/maps/map_format_helper.cpp | 10 +- src/fheroes2/maps/map_object_info.h | 4 +- src/fheroes2/maps/maps.cpp | 14 +- src/fheroes2/maps/maps.h | 4 +- src/fheroes2/maps/maps_tiles.cpp | 482 ++++++++++++------------ src/fheroes2/maps/maps_tiles.h | 80 ++-- src/fheroes2/maps/maps_tiles_helper.cpp | 88 ++--- src/fheroes2/maps/maps_tiles_helper.h | 4 +- src/fheroes2/maps/maps_tiles_render.cpp | 68 ++-- src/fheroes2/maps/maps_tiles_render.h | 4 +- src/fheroes2/world/world.cpp | 16 +- src/fheroes2/world/world_loadmap.cpp | 6 +- 15 files changed, 402 insertions(+), 402 deletions(-) diff --git a/src/fheroes2/castle/castle.cpp b/src/fheroes2/castle/castle.cpp index 04f27120c2..465a4b059c 100644 --- a/src/fheroes2/castle/castle.cpp +++ b/src/fheroes2/castle/castle.cpp @@ -1959,7 +1959,7 @@ int32_t Castle::getTileIndexToPlaceBoat() const return false; } - // Mark the tile as worthy to a place a boat if the main addon does not exist on this tile. + // Mark the tile as worthy to a place a boat if the main object part does not exist on this tile. // This means that all objects on this tile are not primary objects (like shadows or some parts of objects). return ( tile.getMainObjectPart()._objectIcnType == MP2::OBJ_ICN_TYPE_UNKNOWN || tile.isPassabilityTransparent() ); }; diff --git a/src/fheroes2/gui/interface_gamearea.cpp b/src/fheroes2/gui/interface_gamearea.cpp index 3e8c5fe0f2..1eb4d7739b 100644 --- a/src/fheroes2/gui/interface_gamearea.cpp +++ b/src/fheroes2/gui/interface_gamearea.cpp @@ -298,8 +298,8 @@ namespace // There is a tile below the current. const Maps::Tiles & tileBelow = world.GetTiles( x, y + 1 ); - for ( const auto & lowerAddon : tileBelow.getTopLayerAddons() ) { - if ( lowerAddon._uid == uid ) { + for ( const auto & lowerPart : tileBelow.getTopObjectParts() ) { + if ( lowerPart._uid == uid ) { // This is a tall object. return true; } @@ -646,7 +646,7 @@ void Interface::GameArea::Redraw( fheroes2::Image & dst, int flag, bool isPuzzle // High priority images are drawn after any other object on this tile. renderImagesOnTiles( dst, tileUnfit.highPriorityBottomImages, *this ); - std::vector topLayerTallObjects; + std::vector topLayerTallObjects; // Expand ROI to properly render very tall objects (1 tile - left and right; 2 tiles - bottom): Abandoned mine Ghosts, Flag on the Alchemist lab, and others. const int32_t roiExtraObjectsMaxX = std::min( maxX + 1, world.w() ); @@ -672,19 +672,19 @@ void Interface::GameArea::Redraw( fheroes2::Image & dst, int flag, bool isPuzzle // any other level 2 objects with the same UID. topLayerTallObjects.clear(); - for ( const auto & addon : tile.getTopLayerAddons() ) { - if ( isTallTopLayerObject( x, y, addon._uid ) ) { - topLayerTallObjects.emplace_back( &addon ); + for ( const auto & part : tile.getTopObjectParts() ) { + if ( isTallTopLayerObject( x, y, part._uid ) ) { + topLayerTallObjects.emplace_back( &part ); } else { - redrawTopLayerObject( tile, dst, isPuzzleDraw, *this, addon ); + redrawTopLayerObject( tile, dst, isPuzzleDraw, *this, part ); } } redrawTopLayerExtraObjects( tile, dst, isPuzzleDraw, *this ); - for ( const auto * addon : topLayerTallObjects ) { - redrawTopLayerObject( tile, dst, isPuzzleDraw, *this, *addon ); + for ( const auto * part : topLayerTallObjects ) { + redrawTopLayerObject( tile, dst, isPuzzleDraw, *this, *part ); } } } diff --git a/src/fheroes2/heroes/heroes_action.cpp b/src/fheroes2/heroes/heroes_action.cpp index effb1709f5..5a2d118429 100644 --- a/src/fheroes2/heroes/heroes_action.cpp +++ b/src/fheroes2/heroes/heroes_action.cpp @@ -229,8 +229,8 @@ namespace objectUID = tile.getMainObjectPart()._uid; } else { - // In maps made by the original map editor the action object can be in the bottom layer addons. - for ( auto iter = tile.getBottomLayerAddons().rbegin(); iter != tile.getBottomLayerAddons().rend(); ++iter ) { + // In maps made by the original map editor the action object can be in the ground layer. + for ( auto iter = tile.getGroundObjectParts().rbegin(); iter != tile.getGroundObjectParts().rend(); ++iter ) { if ( Maps::getObjectTypeByIcn( iter->_objectIcnType, iter->_imageIndex ) == objectType ) { objectUID = iter->_uid; break; diff --git a/src/fheroes2/maps/map_format_helper.cpp b/src/fheroes2/maps/map_format_helper.cpp index 8dcf5135ab..ac32548f7c 100644 --- a/src/fheroes2/maps/map_format_helper.cpp +++ b/src/fheroes2/maps/map_format_helper.cpp @@ -232,12 +232,12 @@ namespace Maps streamParts.emplace( tile.getMainObjectPart()._uid, tile.getMainObjectPart()._imageIndex ); } - for ( const auto & addon : tile.getBottomLayerAddons() ) { - if ( addon._objectIcnType == MP2::OBJ_ICN_TYPE_ROAD ) { - roadParts.emplace( addon._uid, addon._imageIndex ); + for ( const auto & part : tile.getGroundObjectParts() ) { + if ( part._objectIcnType == MP2::OBJ_ICN_TYPE_ROAD ) { + roadParts.emplace( part._uid, part._imageIndex ); } - else if ( addon._objectIcnType == MP2::OBJ_ICN_TYPE_STREAM ) { - streamParts.emplace( addon._uid, addon._imageIndex ); + else if ( part._objectIcnType == MP2::OBJ_ICN_TYPE_STREAM ) { + streamParts.emplace( part._uid, part._imageIndex ); } } diff --git a/src/fheroes2/maps/map_object_info.h b/src/fheroes2/maps/map_object_info.h index 13b769c3d4..c96d169a9f 100644 --- a/src/fheroes2/maps/map_object_info.h +++ b/src/fheroes2/maps/map_object_info.h @@ -31,7 +31,7 @@ namespace Maps { // An object usually contains of multiple parts / tiles. Each part has its own features like object layer type or image index. - // An object always contains a main object part (addon). + // An object always contains a main object part. // All object's parts shares images from the same ICN source (MP2::ObjectIcnType). struct ObjectPartInfo { @@ -71,7 +71,7 @@ namespace Maps // Do nothing. } - // A layer where this object part / addon sits on. + // A layer where this object part sits on. // The layer is used for passability calculations as well as an order of rendering objects. ObjectLayerType layerType{ OBJECT_LAYER }; }; diff --git a/src/fheroes2/maps/maps.cpp b/src/fheroes2/maps/maps.cpp index 8c3fb4592c..7322c07d78 100644 --- a/src/fheroes2/maps/maps.cpp +++ b/src/fheroes2/maps/maps.cpp @@ -484,12 +484,12 @@ Maps::Indexes Maps::GetObjectPositions( const MP2::MapObjectType objectType ) return MapsIndexesObject( objectType, true ); } -std::vector> Maps::getObjectParts( const MP2::MapObjectType objectType ) +std::vector> Maps::getObjectParts( const MP2::MapObjectType objectType ) { - std::vector> result; + std::vector> result; const int32_t size = static_cast( world.getSize() ); for ( int32_t idx = 0; idx < size; ++idx ) { - const Maps::TilesAddon * objectPart = getObjectPartByActionType( world.GetTiles( idx ), objectType ); + const Maps::ObjectPart * objectPart = getObjectPartByActionType( world.GetTiles( idx ), objectType ); if ( objectPart != nullptr ) { result.emplace_back( idx, objectPart ); } @@ -725,10 +725,10 @@ void Maps::UpdateCastleSprite( const fheroes2::Point & center, int race, bool is tile.updateObjectImageIndex( castleID, MP2::OBJ_ICN_TYPE_OBJNTOWN, -16 ); if ( index == 0 ) { - TilesAddon * addon = tile.getTopLayerAddon( castleID ); - if ( addon && addon->_objectIcnType == MP2::OBJ_ICN_TYPE_OBJNTWRD ) { - addon->_objectIcnType = MP2::OBJ_ICN_TYPE_OBJNTOWN; - addon->_imageIndex = fullTownIndex - 16; + ObjectPart * part = tile.getTopObjectPart( castleID ); + if ( part && part->_objectIcnType == MP2::OBJ_ICN_TYPE_OBJNTWRD ) { + part->_objectIcnType = MP2::OBJ_ICN_TYPE_OBJNTOWN; + part->_imageIndex = fullTownIndex - 16; } } } diff --git a/src/fheroes2/maps/maps.h b/src/fheroes2/maps/maps.h index d5e184a6bb..093e541763 100644 --- a/src/fheroes2/maps/maps.h +++ b/src/fheroes2/maps/maps.h @@ -41,7 +41,7 @@ using MapsIndexes = std::vector; namespace Maps { - struct TilesAddon; + struct ObjectPart; enum mapsize_t : int { @@ -95,7 +95,7 @@ namespace Maps Indexes GetObjectPositions( const MP2::MapObjectType objectType ); // This is a very slow function by performance. Use it only while loading a map. - std::vector> getObjectParts( const MP2::MapObjectType objectType ); + std::vector> getObjectParts( const MP2::MapObjectType objectType ); Indexes GetObjectPositions( int32_t center, const MP2::MapObjectType objectType, bool ignoreHeroes ); diff --git a/src/fheroes2/maps/maps_tiles.cpp b/src/fheroes2/maps/maps_tiles.cpp index a514a2d5f9..c1fc9ea9ce 100644 --- a/src/fheroes2/maps/maps_tiles.cpp +++ b/src/fheroes2/maps/maps_tiles.cpp @@ -226,7 +226,7 @@ namespace bool isShortObject( const MP2::MapObjectType objectType ) { // Some objects allow middle moves even being attached to the bottom. - // These object actually don't have any sprites on tiles above them within addon 2 level objects. + // These object actually don't have any sprites on tiles above them within top layer object parts. // TODO: find a better way to do not hardcode values here. switch ( objectType ) { @@ -414,26 +414,26 @@ namespace return false; } - bool isAddonShadow( const Maps::TilesAddon & ta ) + bool isObjectPartShadow( const Maps::ObjectPart & ta ) { return isValidShadowSprite( MP2::getIcnIdFromObjectIcnType( ta._objectIcnType ), ta._imageIndex ); } - void getAddonInfo( const Maps::TilesAddon & addon, std::ostringstream & os ) + void getObjectPartInfo( const Maps::ObjectPart & part, std::ostringstream & os ) { - os << "UID : " << addon._uid << std::endl - << "ICN object type : " << static_cast( addon._objectIcnType ) << " (" << ICN::getIcnFileName( MP2::getIcnIdFromObjectIcnType( addon._objectIcnType ) ) + os << "UID : " << part._uid << std::endl + << "ICN object type : " << static_cast( part._objectIcnType ) << " (" << ICN::getIcnFileName( MP2::getIcnIdFromObjectIcnType( part._objectIcnType ) ) << ")" << std::endl - << "image index : " << static_cast( addon._imageIndex ) << std::endl - << "layer type : " << static_cast( addon._layerType ) << " - " << getObjectLayerName( addon._layerType ) << std::endl - << "is shadow : " << ( isAddonShadow( addon ) ? "yes" : "no" ) << std::endl; + << "image index : " << static_cast( part._imageIndex ) << std::endl + << "layer type : " << static_cast( part._layerType ) << " - " << getObjectLayerName( part._layerType ) << std::endl + << "is shadow : " << ( isObjectPartShadow( part ) ? "yes" : "no" ) << std::endl; } - std::string getAddonInfo( const Maps::TilesAddon & addon, const int lvl ) + std::string getObjectPartInfo( const Maps::ObjectPart & part, const int lvl ) { std::ostringstream os; os << "--------- Level " << lvl << " --------" << std::endl; - getAddonInfo( addon, os ); + getObjectPartInfo( part, os ); return os.str(); } } @@ -458,8 +458,8 @@ void Maps::Tiles::Init( int32_t index, const MP2::MP2TileInfo & mp2 ) "Metadata present for non action object " << MP2::StringObject( _mainObjectType ) << " at tile " << _index << ". Metadata value " << _metadata[0] ) } - _addonBottomLayer.clear(); - _addonTopLayer.clear(); + _groundObjectPart.clear(); + _topObjectPart.clear(); const MP2::ObjectIcnType bottomObjectIcnType = static_cast( mp2.objectName1 >> 2 ); @@ -474,21 +474,21 @@ void Maps::Tiles::Init( int32_t index, const MP2::MP2TileInfo & mp2 ) if ( mp2.mapObjectType == MP2::OBJ_NONE && ( layerType == ObjectLayerType::SHADOW_LAYER || layerType == ObjectLayerType::TERRAIN_LAYER ) ) { // If an object sits on shadow or terrain layer then we should put it as a bottom layer add-on. if ( bottomObjectIcnType != MP2::ObjectIcnType::OBJ_ICN_TYPE_UNKNOWN ) { - _addonBottomLayer.emplace_back( layerType, mp2.level1ObjectUID, bottomObjectIcnType, mp2.bottomIcnImageIndex ); + _groundObjectPart.emplace_back( layerType, mp2.level1ObjectUID, bottomObjectIcnType, mp2.bottomIcnImageIndex ); } } else { - _mainAddon._layerType = layerType; - _mainAddon._uid = mp2.level1ObjectUID; - _mainAddon._objectIcnType = bottomObjectIcnType; - _mainAddon._imageIndex = mp2.bottomIcnImageIndex; + _mainObjectPart._layerType = layerType; + _mainObjectPart._uid = mp2.level1ObjectUID; + _mainObjectPart._objectIcnType = bottomObjectIcnType; + _mainObjectPart._imageIndex = mp2.bottomIcnImageIndex; } const MP2::ObjectIcnType topObjectIcnType = static_cast( mp2.objectName2 >> 2 ); if ( topObjectIcnType != MP2::ObjectIcnType::OBJ_ICN_TYPE_UNKNOWN ) { // Top layer objects do not have any internal structure (layers) so all of them should have the same internal layer. // TODO: remove layer type for top layer objects. - _addonTopLayer.emplace_back( OBJECT_LAYER, mp2.level2ObjectUID, topObjectIcnType, mp2.topIcnImageIndex ); + _topObjectPart.emplace_back( OBJECT_LAYER, mp2.level2ObjectUID, topObjectIcnType, mp2.topIcnImageIndex ); } } @@ -567,45 +567,45 @@ void Maps::Tiles::SetObject( const MP2::MapObjectType objectType ) void Maps::Tiles::setBoat( const int direction, const int color ) { - if ( _mainAddon._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) { + if ( _mainObjectPart._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) { // It is important to preserve the order of objects for rendering purposes. Therefore, the main object should go to the front of objects. - _addonBottomLayer.emplace_front( _mainAddon ); + _groundObjectPart.emplace_front( _mainObjectPart ); } // If this assertion blows up then you are trying to put a boat on land! assert( isWater() ); SetObject( MP2::OBJ_BOAT ); - _mainAddon._objectIcnType = MP2::OBJ_ICN_TYPE_BOAT32; + _mainObjectPart._objectIcnType = MP2::OBJ_ICN_TYPE_BOAT32; switch ( direction ) { case Direction::TOP: - _mainAddon._imageIndex = 0; + _mainObjectPart._imageIndex = 0; break; case Direction::TOP_RIGHT: - _mainAddon._imageIndex = 9; + _mainObjectPart._imageIndex = 9; break; case Direction::RIGHT: - _mainAddon._imageIndex = 18; + _mainObjectPart._imageIndex = 18; break; case Direction::BOTTOM_RIGHT: - _mainAddon._imageIndex = 27; + _mainObjectPart._imageIndex = 27; break; case Direction::BOTTOM: - _mainAddon._imageIndex = 36; + _mainObjectPart._imageIndex = 36; break; // Left-side sprites have to be flipped, add 128 to index. case Direction::BOTTOM_LEFT: - _mainAddon._imageIndex = 27 + 128; + _mainObjectPart._imageIndex = 27 + 128; break; case Direction::LEFT: - _mainAddon._imageIndex = 18 + 128; + _mainObjectPart._imageIndex = 18 + 128; break; case Direction::TOP_LEFT: - _mainAddon._imageIndex = 9 + 128; + _mainObjectPart._imageIndex = 9 + 128; break; default: - _mainAddon._imageIndex = 18; + _mainObjectPart._imageIndex = 18; break; } @@ -616,9 +616,9 @@ void Maps::Tiles::setBoat( const int direction, const int color ) for ( uint32_t tileIndex = 0; tileIndex < world.getSize(); ++tileIndex ) { assert( !world.GetTiles( tileIndex ).doesObjectExist( newUid ) ); } - _mainAddon._uid = newUid; + _mainObjectPart._uid = newUid; #else - _mainAddon._uid = getNewObjectUID(); + _mainObjectPart._uid = getNewObjectUID(); #endif // WITH_DEBUG using BoatOwnerColorType = decltype( _boatOwnerColor ); @@ -632,11 +632,11 @@ void Maps::Tiles::setBoat( const int direction, const int color ) int Maps::Tiles::getBoatDirection() const { // Check if it really is a boat - if ( _mainAddon._objectIcnType != MP2::OBJ_ICN_TYPE_BOAT32 ) + if ( _mainObjectPart._objectIcnType != MP2::OBJ_ICN_TYPE_BOAT32 ) return Direction::UNKNOWN; // Left-side sprites have to flipped, add 128 to index - switch ( _mainAddon._imageIndex ) { + switch ( _mainObjectPart._imageIndex ) { case 0: return Direction::TOP; case 9: @@ -668,17 +668,17 @@ int Maps::Tiles::getOriginalPassability() const return MP2::getActionObjectDirection( objectType ); } - if ( _mainAddon._objectIcnType == MP2::OBJ_ICN_TYPE_UNKNOWN || _mainAddon.isPassabilityTransparent() || isShadow() ) { + if ( _mainObjectPart._objectIcnType == MP2::OBJ_ICN_TYPE_UNKNOWN || _mainObjectPart.isPassabilityTransparent() || isShadow() ) { // No object exists. Make it fully passable. return DIRECTION_ALL; } - if ( isValidReefsSprite( _mainAddon._objectIcnType, _mainAddon._imageIndex ) ) { + if ( isValidReefsSprite( _mainObjectPart._objectIcnType, _mainObjectPart._imageIndex ) ) { return 0; } - for ( const auto & addon : _addonBottomLayer ) { - if ( isValidReefsSprite( addon._objectIcnType, addon._imageIndex ) ) { + for ( const auto & part : _groundObjectPart ) { + if ( isValidReefsSprite( part._objectIcnType, part._imageIndex ) ) { return 0; } } @@ -703,7 +703,7 @@ void Maps::Tiles::updatePassability() // Get object type but ignore heroes as they are "temporary" objects. const MP2::MapObjectType objectType = GetObject( false ); - if ( !MP2::isOffGameActionObject( objectType ) && ( _mainAddon._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) && !_mainAddon.isPassabilityTransparent() + if ( !MP2::isOffGameActionObject( objectType ) && ( _mainObjectPart._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) && !_mainObjectPart.isPassabilityTransparent() && !isShadow() ) { // This is a non-action object. @@ -725,14 +725,14 @@ void Maps::Tiles::updatePassability() std::vector tileUIDs; // If this assertion blows up then the object is not set properly. An object must have a valid UID! - assert( _mainAddon._uid != 0 ); - tileUIDs.emplace_back( _mainAddon._uid ); + assert( _mainObjectPart._uid != 0 ); + tileUIDs.emplace_back( _mainObjectPart._uid ); - for ( const auto & addon : _addonBottomLayer ) { - if ( !addon.isPassabilityTransparent() ) { + for ( const auto & part : _groundObjectPart ) { + if ( !part.isPassabilityTransparent() ) { // If this assertion blows up then the object is not set properly. An object must have a valid UID! - assert( addon._uid != 0 ); - tileUIDs.emplace_back( addon._uid ); + assert( part._uid != 0 ); + tileUIDs.emplace_back( part._uid ); } } @@ -744,19 +744,19 @@ void Maps::Tiles::updatePassability() } // Count how many objects are there excluding shadows, roads and river streams. - const std::ptrdiff_t validBottomLayerObjects = std::count_if( _addonBottomLayer.begin(), _addonBottomLayer.end(), []( const auto & addon ) { - if ( isAddonShadow( addon ) ) { + const std::ptrdiff_t validBottomLayerObjects = std::count_if( _groundObjectPart.begin(), _groundObjectPart.end(), []( const auto & part ) { + if ( isObjectPartShadow( part ) ) { return false; } - return addon._objectIcnType != MP2::OBJ_ICN_TYPE_ROAD && addon._objectIcnType != MP2::OBJ_ICN_TYPE_STREAM; + return part._objectIcnType != MP2::OBJ_ICN_TYPE_ROAD && part._objectIcnType != MP2::OBJ_ICN_TYPE_STREAM; } ); - const bool singleObjectTile = ( validBottomLayerObjects == 0 ) && _addonTopLayer.empty() && ( bottomTile._mainAddon._objectIcnType != _mainAddon._objectIcnType ); + const bool singleObjectTile = ( validBottomLayerObjects == 0 ) && _topObjectPart.empty() && ( bottomTile._mainObjectPart._objectIcnType != _mainObjectPart._objectIcnType ); // TODO: we might need to simplify the logic below as singleObjectTile might cover most of it. - if ( !singleObjectTile && !isDetachedObject() && !bottomTile._mainAddon.isPassabilityTransparent() - && ( bottomTile._mainAddon._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) ) { + if ( !singleObjectTile && !isDetachedObject() && !bottomTile._mainObjectPart.isPassabilityTransparent() + && ( bottomTile._mainObjectPart._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) ) { const MP2::MapObjectType bottomTileObjectType = bottomTile.GetObject( false ); const MP2::MapObjectType correctedObjectType = MP2::getBaseActionObjectType( bottomTileObjectType ); @@ -808,12 +808,12 @@ void Maps::Tiles::updatePassability() bool Maps::Tiles::doesObjectExist( const uint32_t uid ) const { - if ( _mainAddon._uid == uid && !_mainAddon.isPassabilityTransparent() ) { + if ( _mainObjectPart._uid == uid && !_mainObjectPart.isPassabilityTransparent() ) { return true; } - return std::any_of( _addonBottomLayer.cbegin(), _addonBottomLayer.cend(), - [uid]( const auto & addon ) { return addon._uid == uid && !addon.isPassabilityTransparent(); } ); + return std::any_of( _groundObjectPart.cbegin(), _groundObjectPart.cend(), + [uid]( const auto & part ) { return part._uid == uid && !part.isPassabilityTransparent(); } ); } void Maps::Tiles::UpdateRegion( uint32_t newRegionID ) @@ -826,7 +826,7 @@ void Maps::Tiles::UpdateRegion( uint32_t newRegionID ) } } -void Maps::Tiles::pushBottomLayerAddon( const MP2::MP2AddonInfo & ma ) +void Maps::Tiles::pushGroundObjectPart( const MP2::MP2AddonInfo & ma ) { const MP2::ObjectIcnType objectIcnType = static_cast( ma.objectNameN1 >> 2 ); if ( objectIcnType == MP2::ObjectIcnType::OBJ_ICN_TYPE_UNKNOWN ) { @@ -840,10 +840,10 @@ void Maps::Tiles::pushBottomLayerAddon( const MP2::MP2AddonInfo & ma ) _isTileMarkedAsRoad = true; } - _addonBottomLayer.emplace_back( static_cast( ma.quantityN & 0x03 ), ma.level1ObjectUID, objectIcnType, ma.bottomIcnImageIndex ); + _groundObjectPart.emplace_back( static_cast( ma.quantityN & 0x03 ), ma.level1ObjectUID, objectIcnType, ma.bottomIcnImageIndex ); } -void Maps::Tiles::pushTopLayerAddon( const MP2::MP2AddonInfo & ma ) +void Maps::Tiles::pushTopObjectPart( const MP2::MP2AddonInfo & ma ) { const MP2::ObjectIcnType objectIcnType = static_cast( ma.objectNameN2 >> 2 ); if ( objectIcnType == MP2::ObjectIcnType::OBJ_ICN_TYPE_UNKNOWN ) { @@ -853,58 +853,58 @@ void Maps::Tiles::pushTopLayerAddon( const MP2::MP2AddonInfo & ma ) // Top layer objects do not have any internal structure (layers) so all of them should have the same internal layer. // TODO: remove layer type for top layer objects. - _addonTopLayer.emplace_back( OBJECT_LAYER, ma.level2ObjectUID, objectIcnType, ma.topIcnImageIndex ); + _topObjectPart.emplace_back( OBJECT_LAYER, ma.level2ObjectUID, objectIcnType, ma.topIcnImageIndex ); } -void Maps::Tiles::pushBottomLayerAddon( TilesAddon ta ) +void Maps::Tiles::pushGroundObjectPart( ObjectPart ta ) { if ( isSpriteRoad( ta._objectIcnType, ta._imageIndex ) ) { _isTileMarkedAsRoad = true; } - _addonBottomLayer.emplace_back( ta ); + _groundObjectPart.emplace_back( ta ); } -void Maps::Tiles::AddonsSort() +void Maps::Tiles::sortObjectParts() { - if ( _addonBottomLayer.empty() ) { + if ( _groundObjectPart.empty() ) { // Nothing to sort. return; } // Push everything to the container and sort it by level. - if ( _mainAddon._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) { - _addonBottomLayer.emplace_front( _mainAddon ); + if ( _mainObjectPart._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) { + _groundObjectPart.emplace_front( _mainObjectPart ); } // Sort by internal layers. - _addonBottomLayer.sort( []( const auto & left, const auto & right ) { return ( left._layerType > right._layerType ); } ); + _groundObjectPart.sort( []( const auto & left, const auto & right ) { return ( left._layerType > right._layerType ); } ); - if ( !_addonBottomLayer.empty() ) { - TilesAddon & highestPriorityAddon = _addonBottomLayer.back(); - std::swap( highestPriorityAddon, _mainAddon ); + if ( !_groundObjectPart.empty() ) { + ObjectPart & highestPriorityPart = _groundObjectPart.back(); + std::swap( highestPriorityPart, _mainObjectPart ); // If this assertion blows up then you are not storing correct values for layer type! - assert( _mainAddon._layerType <= TERRAIN_LAYER ); + assert( _mainObjectPart._layerType <= TERRAIN_LAYER ); - _addonBottomLayer.pop_back(); + _groundObjectPart.pop_back(); } // Top layer objects don't have any rendering priorities so they should be rendered first in queue first to render. } -Maps::TilesAddon * Maps::Tiles::getBottomLayerAddon( const uint32_t uid ) +Maps::ObjectPart * Maps::Tiles::getGroundObjectPart( const uint32_t uid ) { - auto it = std::find_if( _addonBottomLayer.begin(), _addonBottomLayer.end(), [uid]( const auto & v ) { return v._uid == uid; } ); + auto it = std::find_if( _groundObjectPart.begin(), _groundObjectPart.end(), [uid]( const auto & v ) { return v._uid == uid; } ); - return it != _addonBottomLayer.end() ? &( *it ) : nullptr; + return it != _groundObjectPart.end() ? &( *it ) : nullptr; } -Maps::TilesAddon * Maps::Tiles::getTopLayerAddon( const uint32_t uid ) +Maps::ObjectPart * Maps::Tiles::getTopObjectPart( const uint32_t uid ) { - auto it = std::find_if( _addonTopLayer.begin(), _addonTopLayer.end(), [uid]( const auto & v ) { return v._uid == uid; } ); + auto it = std::find_if( _topObjectPart.begin(), _topObjectPart.end(), [uid]( const auto & v ) { return v._uid == uid; } ); - return it != _addonTopLayer.end() ? &( *it ) : nullptr; + return it != _topObjectPart.end() ? &( *it ) : nullptr; } std::string Maps::Tiles::String() const @@ -918,7 +918,7 @@ std::string Maps::Tiles::String() const << "point: (" << GetCenter().x << ", " << GetCenter().y << ")" << std::endl << "MP2 object type : " << static_cast( objectType ) << " (" << MP2::StringObject( objectType ) << ")" << std::endl; - getAddonInfo( _mainAddon, os ); + getObjectPartInfo( _mainObjectPart, os ); os << "region : " << _region << std::endl << "ground : " << Ground::String( GetGround() ) << " (isRoad: " << _isTileMarkedAsRoad << ")" << std::endl @@ -931,12 +931,12 @@ std::string Maps::Tiles::String() const if ( objectType == MP2::OBJ_BOAT ) os << "boat owner color: " << Color::String( _boatOwnerColor ) << std::endl; - for ( const auto & addon : _addonBottomLayer ) { - os << getAddonInfo( addon, 1 ); + for ( const auto & part : _groundObjectPart ) { + os << getObjectPartInfo( part, 1 ); } - for ( const auto & addon : _addonTopLayer ) { - os << getAddonInfo( addon, 2 ); + for ( const auto & part : _topObjectPart ) { + os << getObjectPartInfo( part, 2 ); } os << "--- Extra information ---" << std::endl; @@ -1007,15 +1007,15 @@ bool Maps::Tiles::GoodForUltimateArtifact() const return false; } - if ( _mainAddon._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN && !isAddonShadow( _mainAddon ) ) { + if ( _mainObjectPart._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN && !isObjectPartShadow( _mainObjectPart ) ) { return false; } - if ( static_cast( std::count_if( _addonBottomLayer.begin(), _addonBottomLayer.end(), isAddonShadow ) ) != _addonBottomLayer.size() ) { + if ( static_cast( std::count_if( _groundObjectPart.begin(), _groundObjectPart.end(), isObjectPartShadow ) ) != _groundObjectPart.size() ) { return false; } - if ( static_cast( std::count_if( _addonTopLayer.begin(), _addonTopLayer.end(), isAddonShadow ) ) != _addonTopLayer.size() ) { + if ( static_cast( std::count_if( _topObjectPart.begin(), _topObjectPart.end(), isObjectPartShadow ) ) != _topObjectPart.size() ) { return false; } @@ -1024,13 +1024,13 @@ bool Maps::Tiles::GoodForUltimateArtifact() const bool Maps::Tiles::isPassabilityTransparent() const { - for ( const auto & addon : _addonBottomLayer ) { - if ( !addon.isPassabilityTransparent() ) { + for ( const auto & part : _groundObjectPart ) { + if ( !part.isPassabilityTransparent() ) { return false; } } - return _mainAddon.isPassabilityTransparent(); + return _mainObjectPart.isPassabilityTransparent(); } bool Maps::Tiles::isPassableFrom( const int direction, const bool fromWater, const bool ignoreFog, const int heroColor ) const @@ -1088,36 +1088,36 @@ void Maps::Tiles::SetObjectPassable( bool pass ) bool Maps::Tiles::isStream() const { - for ( const auto & addon : _addonBottomLayer ) { - if ( addon._objectIcnType == MP2::OBJ_ICN_TYPE_STREAM - || ( addon._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNMUL2 - && ( addon._imageIndex < 14 || ( addon._imageIndex > 217 && addon._imageIndex < ( 218 + 14 ) ) ) ) ) { + for ( const auto & part : _groundObjectPart ) { + if ( part._objectIcnType == MP2::OBJ_ICN_TYPE_STREAM + || ( part._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNMUL2 + && ( part._imageIndex < 14 || ( part._imageIndex > 217 && part._imageIndex < ( 218 + 14 ) ) ) ) ) { return true; } } - return _mainAddon._objectIcnType == MP2::OBJ_ICN_TYPE_STREAM - || ( _mainAddon._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNMUL2 - && ( _mainAddon._imageIndex < 14 || ( _mainAddon._imageIndex > 217 && _mainAddon._imageIndex < ( 218 + 14 ) ) ) ); + return _mainObjectPart._objectIcnType == MP2::OBJ_ICN_TYPE_STREAM + || ( _mainObjectPart._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNMUL2 + && ( _mainObjectPart._imageIndex < 14 || ( _mainObjectPart._imageIndex > 217 && _mainObjectPart._imageIndex < ( 218 + 14 ) ) ) ); } bool Maps::Tiles::isShadow() const { - return isAddonShadow( _mainAddon ) - && _addonBottomLayer.size() == static_cast( std::count_if( _addonBottomLayer.begin(), _addonBottomLayer.end(), isAddonShadow ) ); + return isObjectPartShadow( _mainObjectPart ) + && _groundObjectPart.size() == static_cast( std::count_if( _groundObjectPart.begin(), _groundObjectPart.end(), isObjectPartShadow ) ); } -Maps::TilesAddon * Maps::Tiles::getAddonWithFlag( const uint32_t uid ) +Maps::ObjectPart * Maps::Tiles::getObjectPartWithFlag( const uint32_t uid ) { - const auto isFlag = [uid]( const auto & addon ) { return addon._uid == uid && addon._objectIcnType == MP2::OBJ_ICN_TYPE_FLAG32; }; + const auto isFlag = [uid]( const auto & part ) { return part._uid == uid && part._objectIcnType == MP2::OBJ_ICN_TYPE_FLAG32; }; - auto iter = std::find_if( _addonBottomLayer.begin(), _addonBottomLayer.end(), isFlag ); - if ( iter != _addonBottomLayer.end() ) { + auto iter = std::find_if( _groundObjectPart.begin(), _groundObjectPart.end(), isFlag ); + if ( iter != _groundObjectPart.end() ) { return &( *iter ); } - iter = std::find_if( _addonTopLayer.begin(), _addonTopLayer.end(), isFlag ); - if ( iter != _addonTopLayer.end() ) { + iter = std::find_if( _topObjectPart.begin(), _topObjectPart.end(), isFlag ); + if ( iter != _topObjectPart.end() ) { return &( *iter ); } @@ -1165,11 +1165,11 @@ void Maps::Tiles::setOwnershipFlag( const MP2::MapObjectType objectType, int col switch ( objectType ) { case MP2::OBJ_MAGIC_GARDEN: objectSpriteIndex += 128 + 14; - updateFlag( color, objectSpriteIndex, _mainAddon._uid, false ); + updateFlag( color, objectSpriteIndex, _mainObjectPart._uid, false ); objectSpriteIndex += 7; if ( isValidDirection( _index, Direction::RIGHT ) ) { Tiles & tile = world.GetTiles( GetDirectionIndex( _index, Direction::RIGHT ) ); - tile.updateFlag( color, objectSpriteIndex, _mainAddon._uid, false ); + tile.updateFlag( color, objectSpriteIndex, _mainObjectPart._uid, false ); } break; @@ -1178,13 +1178,13 @@ void Maps::Tiles::setOwnershipFlag( const MP2::MapObjectType objectType, int col objectSpriteIndex += 128 + 14; if ( isValidDirection( _index, Direction::TOP ) ) { Tiles & tile = world.GetTiles( GetDirectionIndex( _index, Direction::TOP ) ); - tile.updateFlag( color, objectSpriteIndex, _mainAddon._uid, true ); + tile.updateFlag( color, objectSpriteIndex, _mainObjectPart._uid, true ); } objectSpriteIndex += 7; if ( isValidDirection( _index, Direction::TOP_RIGHT ) ) { Tiles & tile = world.GetTiles( GetDirectionIndex( _index, Direction::TOP_RIGHT ) ); - tile.updateFlag( color, objectSpriteIndex, _mainAddon._uid, true ); + tile.updateFlag( color, objectSpriteIndex, _mainObjectPart._uid, true ); } break; @@ -1193,18 +1193,18 @@ void Maps::Tiles::setOwnershipFlag( const MP2::MapObjectType objectType, int col objectSpriteIndex += 128 + 42; if ( isValidDirection( _index, Direction::LEFT ) ) { Tiles & tile = world.GetTiles( GetDirectionIndex( _index, Direction::LEFT ) ); - tile.updateFlag( color, objectSpriteIndex, _mainAddon._uid, false ); + tile.updateFlag( color, objectSpriteIndex, _mainObjectPart._uid, false ); } objectSpriteIndex += 7; - updateFlag( color, objectSpriteIndex, _mainAddon._uid, false ); + updateFlag( color, objectSpriteIndex, _mainObjectPart._uid, false ); break; case MP2::OBJ_ALCHEMIST_LAB: objectSpriteIndex += 21; if ( isValidDirection( _index, Direction::TOP ) ) { Tiles & tile = world.GetTiles( GetDirectionIndex( _index, Direction::TOP ) ); - tile.updateFlag( color, objectSpriteIndex, _mainAddon._uid, true ); + tile.updateFlag( color, objectSpriteIndex, _mainObjectPart._uid, true ); } break; @@ -1212,7 +1212,7 @@ void Maps::Tiles::setOwnershipFlag( const MP2::MapObjectType objectType, int col objectSpriteIndex += 28; if ( isValidDirection( _index, Direction::TOP_RIGHT ) ) { Tiles & tile = world.GetTiles( GetDirectionIndex( _index, Direction::TOP_RIGHT ) ); - tile.updateFlag( color, objectSpriteIndex, _mainAddon._uid, true ); + tile.updateFlag( color, objectSpriteIndex, _mainObjectPart._uid, true ); } break; @@ -1225,13 +1225,13 @@ void Maps::Tiles::setOwnershipFlag( const MP2::MapObjectType objectType, int col objectSpriteIndex *= 2; if ( isValidDirection( _index, Direction::LEFT ) ) { Tiles & tile = world.GetTiles( GetDirectionIndex( _index, Direction::LEFT ) ); - tile.updateFlag( color, objectSpriteIndex, _mainAddon._uid, true ); + tile.updateFlag( color, objectSpriteIndex, _mainObjectPart._uid, true ); } objectSpriteIndex += 1; if ( isValidDirection( _index, Direction::RIGHT ) ) { Tiles & tile = world.GetTiles( GetDirectionIndex( _index, Direction::RIGHT ) ); - tile.updateFlag( color, objectSpriteIndex, _mainAddon._uid, true ); + tile.updateFlag( color, objectSpriteIndex, _mainObjectPart._uid, true ); } break; @@ -1244,35 +1244,35 @@ void Maps::Tiles::updateFlag( const int color, const uint8_t objectSpriteIndex, { // Flag deletion or installation must be done in relation to object UID as flag is attached to the object. if ( color == Color::NONE ) { - const auto isFlag = [uid]( const auto & addon ) { return addon._uid == uid && addon._objectIcnType == MP2::OBJ_ICN_TYPE_FLAG32; }; - _addonBottomLayer.remove_if( isFlag ); - _addonTopLayer.remove_if( isFlag ); + const auto isFlag = [uid]( const auto & part ) { return part._uid == uid && part._objectIcnType == MP2::OBJ_ICN_TYPE_FLAG32; }; + _groundObjectPart.remove_if( isFlag ); + _topObjectPart.remove_if( isFlag ); return; } - TilesAddon * addon = getAddonWithFlag( uid ); - if ( addon != nullptr ) { + ObjectPart * part = getObjectPartWithFlag( uid ); + if ( part != nullptr ) { // Replace an existing flag. - addon->_imageIndex = objectSpriteIndex; + part->_imageIndex = objectSpriteIndex; } else if ( setOnUpperLayer ) { - _addonTopLayer.emplace_back( OBJECT_LAYER, uid, MP2::OBJ_ICN_TYPE_FLAG32, objectSpriteIndex ); + _topObjectPart.emplace_back( OBJECT_LAYER, uid, MP2::OBJ_ICN_TYPE_FLAG32, objectSpriteIndex ); } else { - _addonBottomLayer.emplace_back( OBJECT_LAYER, uid, MP2::OBJ_ICN_TYPE_FLAG32, objectSpriteIndex ); + _groundObjectPart.emplace_back( OBJECT_LAYER, uid, MP2::OBJ_ICN_TYPE_FLAG32, objectSpriteIndex ); } } void Maps::Tiles::_updateRoadFlag() { - _isTileMarkedAsRoad = isSpriteRoad( _mainAddon._objectIcnType, _mainAddon._imageIndex ); + _isTileMarkedAsRoad = isSpriteRoad( _mainObjectPart._objectIcnType, _mainObjectPart._imageIndex ); if ( _isTileMarkedAsRoad ) { return; } - for ( const auto & addon : _addonBottomLayer ) { - if ( isSpriteRoad( addon._objectIcnType, addon._imageIndex ) ) { + for ( const auto & part : _groundObjectPart ) { + if ( isSpriteRoad( part._objectIcnType, part._imageIndex ) ) { _isTileMarkedAsRoad = true; return; } @@ -1284,7 +1284,7 @@ void Maps::Tiles::fixMP2MapTileObjectType( Tiles & tile ) const MP2::MapObjectType originalObjectType = tile.GetObject( false ); // Left tile of a skeleton on Desert should be marked as non-action tile. - if ( originalObjectType == MP2::OBJ_SKELETON && tile._mainAddon._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNDSRT && tile._mainAddon._imageIndex == 83 ) { + if ( originalObjectType == MP2::OBJ_SKELETON && tile._mainObjectPart._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNDSRT && tile._mainObjectPart._imageIndex == 83 ) { tile.SetObject( MP2::OBJ_NON_ACTION_SKELETON ); // There is no need to check the rest of things as we fixed this object. @@ -1292,17 +1292,17 @@ void Maps::Tiles::fixMP2MapTileObjectType( Tiles & tile ) } // Oasis object has 2 top tiles being marked as part of bottom object layer while in reality they should be at the top level. - if ( originalObjectType == MP2::OBJ_NON_ACTION_OASIS && tile._mainAddon._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNDSRT - && ( tile._mainAddon._imageIndex == 105 || tile._mainAddon._imageIndex == 106 ) ) { - tile._addonTopLayer.emplace_back(); - std::swap( tile._addonTopLayer.back(), tile._mainAddon ); + if ( originalObjectType == MP2::OBJ_NON_ACTION_OASIS && tile._mainObjectPart._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNDSRT + && ( tile._mainObjectPart._imageIndex == 105 || tile._mainObjectPart._imageIndex == 106 ) ) { + tile._topObjectPart.emplace_back(); + std::swap( tile._topObjectPart.back(), tile._mainObjectPart ); return; } // Original Editor marks Reefs as Stones. We're fixing this issue by changing the type of the object without changing the content of a tile. // This is also required in order to properly calculate Reefs' passability. - if ( originalObjectType == MP2::OBJ_ROCK && isValidReefsSprite( tile._mainAddon._objectIcnType, tile._mainAddon._imageIndex ) ) { + if ( originalObjectType == MP2::OBJ_ROCK && isValidReefsSprite( tile._mainObjectPart._objectIcnType, tile._mainObjectPart._imageIndex ) ) { tile.SetObject( MP2::OBJ_REEFS ); // There is no need to check the rest of things as we fixed this object. @@ -1327,7 +1327,7 @@ void Maps::Tiles::fixMP2MapTileObjectType( Tiles & tile ) // On some maps (apparently created by some non-standard editors), the object type on tiles with random monsters does not match the index // of the monster placeholder sprite. While this engine looks at the object type when placing an actual monster on a tile, the original // HoMM2 apparently looks at the placeholder sprite, so we need to keep them in sync. - if ( tile._mainAddon._objectIcnType == MP2::OBJ_ICN_TYPE_MONS32 ) { + if ( tile._mainObjectPart._objectIcnType == MP2::OBJ_ICN_TYPE_MONS32 ) { MP2::MapObjectType monsterObjectType = originalObjectType; const uint8_t originalObjectSpriteIndex = tile.getMainObjectPart()._imageIndex; @@ -1376,15 +1376,15 @@ void Maps::Tiles::fixMP2MapTileObjectType( Tiles & tile ) case MP2::OBJ_EXPANSION_OBJECT: { // The type of expansion action object or dwelling is stored in object metadata. // However, we just ignore it. - MP2::MapObjectType objectType = getLoyaltyObject( tile._mainAddon._objectIcnType, tile._mainAddon._imageIndex ); + MP2::MapObjectType objectType = getLoyaltyObject( tile._mainObjectPart._objectIcnType, tile._mainObjectPart._imageIndex ); if ( objectType != MP2::OBJ_NONE ) { tile.SetObject( objectType ); break; } // Add-ons of level 1 shouldn't even exist if no top object is present. However, let's play safe and verify it as well. - for ( const auto & addon : tile._addonBottomLayer ) { - objectType = getLoyaltyObject( addon._objectIcnType, addon._imageIndex ); + for ( const auto & part : tile._groundObjectPart ) { + objectType = getLoyaltyObject( part._objectIcnType, part._imageIndex ); if ( objectType != MP2::OBJ_NONE ) break; } @@ -1394,8 +1394,8 @@ void Maps::Tiles::fixMP2MapTileObjectType( Tiles & tile ) break; } - for ( const auto & addon : tile._addonTopLayer ) { - objectType = getLoyaltyObject( addon._objectIcnType, addon._imageIndex ); + for ( const auto & part : tile._topObjectPart ) { + objectType = getLoyaltyObject( part._objectIcnType, part._imageIndex ); if ( objectType != MP2::OBJ_NONE ) break; } @@ -1407,7 +1407,7 @@ void Maps::Tiles::fixMP2MapTileObjectType( Tiles & tile ) DEBUG_LOG( DBG_GAME, DBG_WARN, "Invalid object type index " << tile._index << ": type " << MP2::StringObject( originalObjectType ) << ", icn ID " - << static_cast( tile._mainAddon._imageIndex ) ) + << static_cast( tile._mainObjectPart._imageIndex ) ) break; } @@ -1419,21 +1419,21 @@ void Maps::Tiles::fixMP2MapTileObjectType( Tiles & tile ) bool Maps::Tiles::removeObjectPartsByUID( const uint32_t objectUID ) { bool isObjectPartRemoved = false; - if ( _mainAddon._uid == objectUID ) { - _mainAddon = {}; + if ( _mainObjectPart._uid == objectUID ) { + _mainObjectPart = {}; isObjectPartRemoved = true; } - size_t addonCountBefore = _addonBottomLayer.size(); - _addonBottomLayer.remove_if( [objectUID]( const auto & v ) { return v._uid == objectUID; } ); - if ( addonCountBefore != _addonBottomLayer.size() ) { + size_t partCountBefore = _groundObjectPart.size(); + _groundObjectPart.remove_if( [objectUID]( const auto & v ) { return v._uid == objectUID; } ); + if ( partCountBefore != _groundObjectPart.size() ) { isObjectPartRemoved = true; } - addonCountBefore = _addonTopLayer.size(); - _addonTopLayer.remove_if( [objectUID]( const auto & v ) { return v._uid == objectUID; } ); - if ( addonCountBefore != _addonTopLayer.size() ) { + partCountBefore = _topObjectPart.size(); + _topObjectPart.remove_if( [objectUID]( const auto & v ) { return v._uid == objectUID; } ); + if ( partCountBefore != _topObjectPart.size() ) { isObjectPartRemoved = true; } @@ -1462,11 +1462,11 @@ bool Maps::Tiles::removeObjectPartsByUID( const uint32_t objectUID ) void Maps::Tiles::removeObjects( const MP2::ObjectIcnType objectIcnType ) { - _addonBottomLayer.remove_if( [objectIcnType]( const auto & addon ) { return addon._objectIcnType == objectIcnType; } ); - _addonTopLayer.remove_if( [objectIcnType]( const auto & addon ) { return addon._objectIcnType == objectIcnType; } ); + _groundObjectPart.remove_if( [objectIcnType]( const auto & part ) { return part._objectIcnType == objectIcnType; } ); + _topObjectPart.remove_if( [objectIcnType]( const auto & part ) { return part._objectIcnType == objectIcnType; } ); - if ( _mainAddon._objectIcnType == objectIcnType ) { - _mainAddon = {}; + if ( _mainObjectPart._objectIcnType == objectIcnType ) { + _mainObjectPart = {}; } _updateRoadFlag(); @@ -1478,50 +1478,50 @@ void Maps::Tiles::replaceObject( const uint32_t objectUid, const MP2::ObjectIcnT const uint8_t originalImageIndex, const uint8_t newImageIndex ) { // We can immediately return from the function as only one object per tile can have the same UID. - for ( auto & addon : _addonBottomLayer ) { - if ( addon._uid == objectUid && addon._objectIcnType == originalObjectIcnType && addon._imageIndex == originalImageIndex ) { - addon._objectIcnType = newObjectIcnType; - addon._imageIndex = newImageIndex; + for ( auto & part : _groundObjectPart ) { + if ( part._uid == objectUid && part._objectIcnType == originalObjectIcnType && part._imageIndex == originalImageIndex ) { + part._objectIcnType = newObjectIcnType; + part._imageIndex = newImageIndex; return; } } - for ( auto & addon : _addonTopLayer ) { - if ( addon._uid == objectUid && addon._objectIcnType == originalObjectIcnType && addon._imageIndex == originalImageIndex ) { - addon._objectIcnType = newObjectIcnType; - addon._imageIndex = newImageIndex; + for ( auto & part : _topObjectPart ) { + if ( part._uid == objectUid && part._objectIcnType == originalObjectIcnType && part._imageIndex == originalImageIndex ) { + part._objectIcnType = newObjectIcnType; + part._imageIndex = newImageIndex; return; } } - if ( _mainAddon._uid == objectUid && _mainAddon._objectIcnType == originalObjectIcnType && _mainAddon._imageIndex == originalImageIndex ) { - _mainAddon._objectIcnType = newObjectIcnType; - _mainAddon._imageIndex = newImageIndex; + if ( _mainObjectPart._uid == objectUid && _mainObjectPart._objectIcnType == originalObjectIcnType && _mainObjectPart._imageIndex == originalImageIndex ) { + _mainObjectPart._objectIcnType = newObjectIcnType; + _mainObjectPart._imageIndex = newImageIndex; } } void Maps::Tiles::updateObjectImageIndex( const uint32_t objectUid, const MP2::ObjectIcnType objectIcnType, const int imageIndexOffset ) { // We can immediately return from the function as only one object per tile can have the same UID. - for ( auto & addon : _addonBottomLayer ) { - if ( addon._uid == objectUid && addon._objectIcnType == objectIcnType ) { - assert( addon._imageIndex + imageIndexOffset >= 0 && addon._imageIndex + imageIndexOffset < 255 ); - addon._imageIndex = static_cast( addon._imageIndex + imageIndexOffset ); + for ( auto & part : _groundObjectPart ) { + if ( part._uid == objectUid && part._objectIcnType == objectIcnType ) { + assert( part._imageIndex + imageIndexOffset >= 0 && part._imageIndex + imageIndexOffset < 255 ); + part._imageIndex = static_cast( part._imageIndex + imageIndexOffset ); return; } } - for ( auto & addon : _addonTopLayer ) { - if ( addon._uid == objectUid && addon._objectIcnType == objectIcnType ) { - assert( addon._imageIndex + imageIndexOffset >= 0 && addon._imageIndex + imageIndexOffset < 255 ); - addon._imageIndex = static_cast( addon._imageIndex + imageIndexOffset ); + for ( auto & part : _topObjectPart ) { + if ( part._uid == objectUid && part._objectIcnType == objectIcnType ) { + assert( part._imageIndex + imageIndexOffset >= 0 && part._imageIndex + imageIndexOffset < 255 ); + part._imageIndex = static_cast( part._imageIndex + imageIndexOffset ); return; } } - if ( _mainAddon._uid == objectUid && _mainAddon._objectIcnType == objectIcnType ) { - assert( _mainAddon._imageIndex + imageIndexOffset >= 0 && _mainAddon._imageIndex + imageIndexOffset < 255 ); - _mainAddon._imageIndex = static_cast( _mainAddon._imageIndex + imageIndexOffset ); + if ( _mainObjectPart._uid == objectUid && _mainObjectPart._objectIcnType == objectIcnType ) { + assert( _mainObjectPart._imageIndex + imageIndexOffset >= 0 && _mainObjectPart._imageIndex + imageIndexOffset < 255 ); + _mainObjectPart._imageIndex = static_cast( _mainObjectPart._imageIndex + imageIndexOffset ); } } @@ -1537,12 +1537,12 @@ void Maps::Tiles::ClearFog( const int colors ) void Maps::Tiles::updateTileObjectIcnIndex( Maps::Tiles & tile, const uint32_t uid, const uint8_t newIndex ) { - TilesAddon * addon = tile.getBottomLayerAddon( uid ); - if ( addon != nullptr ) { - addon->_imageIndex = newIndex; + ObjectPart * part = tile.getGroundObjectPart( uid ); + if ( part != nullptr ) { + part->_imageIndex = newIndex; } - else if ( tile._mainAddon._uid == uid ) { - tile._mainAddon._imageIndex = newIndex; + else if ( tile._mainObjectPart._uid == uid ) { + tile._mainObjectPart._imageIndex = newIndex; } tile._updateRoadFlag(); @@ -1550,17 +1550,17 @@ void Maps::Tiles::updateTileObjectIcnIndex( Maps::Tiles & tile, const uint32_t u void Maps::Tiles::updateObjectType() { - // After removing an object there could be an object part in the main addon. - MP2::MapObjectType objectType = getObjectTypeByIcn( _mainAddon._objectIcnType, _mainAddon._imageIndex ); + // After removing an object there could be an object part in the main object part. + MP2::MapObjectType objectType = getObjectTypeByIcn( _mainObjectPart._objectIcnType, _mainObjectPart._imageIndex ); if ( MP2::isOffGameActionObject( objectType ) ) { // Set object type only when this is an interactive object type to make sure that interaction can be done. SetObject( objectType ); return; } - // And sometimes even in the bottom layer addons. + // And sometimes even in the ground layer object parts. // Take a note that we iterate object parts from back to front as the latest object part has higher priority. - for ( auto iter = _addonBottomLayer.rbegin(); iter != _addonBottomLayer.rend(); ++iter ) { + for ( auto iter = _groundObjectPart.rbegin(); iter != _groundObjectPart.rend(); ++iter ) { const MP2::MapObjectType type = getObjectTypeByIcn( iter->_objectIcnType, iter->_imageIndex ); if ( type == MP2::OBJ_NONE ) { continue; @@ -1577,9 +1577,9 @@ void Maps::Tiles::updateObjectType() } } - // Or object part can be in the top layer addons. + // Or object part can be in the top layer object parts. // Take a note that we iterate object parts from back to front as the latest object part has higher priority. - for ( auto iter = _addonTopLayer.rbegin(); iter != _addonTopLayer.rend(); ++iter ) { + for ( auto iter = _topObjectPart.rbegin(); iter != _topObjectPart.rend(); ++iter ) { const MP2::MapObjectType type = getObjectTypeByIcn( iter->_objectIcnType, iter->_imageIndex ); if ( type != MP2::OBJ_NONE ) { @@ -1621,19 +1621,19 @@ void Maps::Tiles::updateObjectType() uint32_t Maps::Tiles::getObjectIdByObjectIcnType( const MP2::ObjectIcnType objectIcnType ) const { - if ( _mainAddon._objectIcnType == objectIcnType ) { - return _mainAddon._uid; + if ( _mainObjectPart._objectIcnType == objectIcnType ) { + return _mainObjectPart._uid; } - for ( const auto & addon : _addonBottomLayer ) { - if ( addon._objectIcnType == objectIcnType ) { - return addon._uid; + for ( const auto & part : _groundObjectPart ) { + if ( part._objectIcnType == objectIcnType ) { + return part._uid; } } - for ( const auto & addon : _addonTopLayer ) { - if ( addon._objectIcnType == objectIcnType ) { - return addon._uid; + for ( const auto & part : _topObjectPart ) { + if ( part._objectIcnType == objectIcnType ) { + return part._uid; } } @@ -1644,22 +1644,22 @@ std::vector Maps::Tiles::getValidObjectIcnTypes() const { std::vector objectIcnTypes; - if ( _mainAddon._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) { - objectIcnTypes.emplace_back( _mainAddon._objectIcnType ); + if ( _mainObjectPart._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) { + objectIcnTypes.emplace_back( _mainObjectPart._objectIcnType ); } - for ( const auto & addon : _addonBottomLayer ) { - // If this assertion blows up then you put an empty object into an addon which makes no sense! - assert( addon._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ); + for ( const auto & part : _groundObjectPart ) { + // If this assertion blows up then you put an empty object into an object part which makes no sense! + assert( part._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ); - objectIcnTypes.emplace_back( addon._objectIcnType ); + objectIcnTypes.emplace_back( part._objectIcnType ); } - for ( const auto & addon : _addonTopLayer ) { - // If this assertion blows up then you put an empty object into an addon which makes no sense! - assert( addon._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ); + for ( const auto & part : _topObjectPart ) { + // If this assertion blows up then you put an empty object into an object part which makes no sense! + assert( part._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ); - objectIcnTypes.emplace_back( addon._objectIcnType ); + objectIcnTypes.emplace_back( part._objectIcnType ); } return objectIcnTypes; @@ -1668,18 +1668,18 @@ std::vector Maps::Tiles::getValidObjectIcnTypes() const bool Maps::Tiles::containsAnyObjectIcnType( const std::vector & objectIcnTypes ) const { for ( const MP2::ObjectIcnType objectIcnType : objectIcnTypes ) { - if ( _mainAddon._objectIcnType == objectIcnType ) { + if ( _mainObjectPart._objectIcnType == objectIcnType ) { return true; } - for ( const auto & addon : _addonBottomLayer ) { - if ( addon._objectIcnType == objectIcnType ) { + for ( const auto & part : _groundObjectPart ) { + if ( part._objectIcnType == objectIcnType ) { return true; } } - for ( const auto & addon : _addonTopLayer ) { - if ( addon._objectIcnType == objectIcnType ) { + for ( const auto & part : _topObjectPart ) { + if ( part._objectIcnType == objectIcnType ) { return true; } } @@ -1690,17 +1690,17 @@ bool Maps::Tiles::containsAnyObjectIcnType( const std::vector tileUIDs; - if ( _mainAddon._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN && _mainAddon._uid != 0 && !_mainAddon.isPassabilityTransparent() ) { - tileUIDs.emplace_back( _mainAddon._uid ); + if ( _mainObjectPart._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN && _mainObjectPart._uid != 0 && !_mainObjectPart.isPassabilityTransparent() ) { + tileUIDs.emplace_back( _mainObjectPart._uid ); } - for ( const auto & addon : _addonBottomLayer ) { - if ( addon._uid != 0 && !addon.isPassabilityTransparent() ) { - tileUIDs.emplace_back( addon._uid ); + for ( const auto & part : _groundObjectPart ) { + if ( part._uid != 0 && !part.isPassabilityTransparent() ) { + tileUIDs.emplace_back( part._uid ); } } - for ( const auto & addon : _addonTopLayer ) { - if ( addon._uid != 0 && !addon.isPassabilityTransparent() ) { - tileUIDs.emplace_back( addon._uid ); + for ( const auto & part : _topObjectPart ) { + if ( part._uid != 0 && !part.isPassabilityTransparent() ) { + tileUIDs.emplace_back( part._uid ); } } const Tiles & topTile = world.GetTiles( GetDirectionIndex( _index, Direction::TOP ) ); for ( const uint32_t tileUID : tileUIDs ) { - if ( topTile._mainAddon._uid == tileUID && !isAddonShadow( topTile._mainAddon ) ) { + if ( topTile._mainObjectPart._uid == tileUID && !isObjectPartShadow( topTile._mainObjectPart ) ) { return true; } - for ( const auto & addon : topTile._addonBottomLayer ) { - if ( addon._uid == tileUID && !isAddonShadow( addon ) ) { + for ( const auto & part : topTile._groundObjectPart ) { + if ( part._uid == tileUID && !isObjectPartShadow( part ) ) { return true; } } - for ( const auto & addon : topTile._addonTopLayer ) { - if ( addon._uid == tileUID && !isAddonShadow( addon ) ) { + for ( const auto & part : topTile._topObjectPart ) { + if ( part._uid == tileUID && !isObjectPartShadow( part ) ) { return true; } } @@ -1766,12 +1766,12 @@ int32_t Maps::Tiles::getIndexOfMainTile( const Maps::Tiles & tile ) std::set uids; uids.insert( tile.getMainObjectPart()._uid ); - for ( const auto & addon : tile.getBottomLayerAddons() ) { - uids.insert( addon._uid ); + for ( const auto & part : tile.getGroundObjectParts() ) { + uids.insert( part._uid ); } - for ( const auto & addon : tile.getTopLayerAddons() ) { - uids.insert( addon._uid ); + for ( const auto & part : tile.getTopObjectParts() ) { + uids.insert( part._uid ); } const int32_t tileIndex = tile.GetIndex(); @@ -1822,25 +1822,25 @@ bool Maps::Tiles::isDetachedObject() const } const uint32_t objectUID = world.GetTiles( mainTileIndex ).getMainObjectPart()._uid; - if ( _mainAddon._uid == objectUID ) { - return !_mainAddon.isPassabilityTransparent(); + if ( _mainObjectPart._uid == objectUID ) { + return !_mainObjectPart.isPassabilityTransparent(); } - for ( const auto & addon : _addonBottomLayer ) { - if ( addon._uid == objectUID ) { - return !addon.isPassabilityTransparent(); + for ( const auto & part : _groundObjectPart ) { + if ( part._uid == objectUID ) { + return !part.isPassabilityTransparent(); } } return false; } -OStreamBase & Maps::operator<<( OStreamBase & stream, const TilesAddon & ta ) +OStreamBase & Maps::operator<<( OStreamBase & stream, const ObjectPart & ta ) { return stream << ta._layerType << ta._uid << ta._objectIcnType << ta._imageIndex; } -IStreamBase & Maps::operator>>( IStreamBase & stream, TilesAddon & ta ) +IStreamBase & Maps::operator>>( IStreamBase & stream, ObjectPart & ta ) { stream >> ta._layerType; @@ -1862,15 +1862,15 @@ IStreamBase & Maps::operator>>( IStreamBase & stream, TilesAddon & ta ) OStreamBase & Maps::operator<<( OStreamBase & stream, const Tiles & tile ) { - // TODO: use operator<<() for _mainAddon. - return stream << tile._index << tile._terrainImageIndex << tile._terrainFlags << tile._tilePassabilityDirections << tile._mainAddon._uid - << tile._mainAddon._objectIcnType << tile._mainAddon._imageIndex << tile._mainObjectType << tile._fogColors << tile._metadata << tile._occupantHeroId - << tile._isTileMarkedAsRoad << tile._addonBottomLayer << tile._addonTopLayer << tile._mainAddon._layerType << tile._boatOwnerColor; + // TODO: use operator<<() for _mainObjectPart. + return stream << tile._index << tile._terrainImageIndex << tile._terrainFlags << tile._tilePassabilityDirections << tile._mainObjectPart._uid + << tile._mainObjectPart._objectIcnType << tile._mainObjectPart._imageIndex << tile._mainObjectType << tile._fogColors << tile._metadata << tile._occupantHeroId + << tile._isTileMarkedAsRoad << tile._groundObjectPart << tile._topObjectPart << tile._mainObjectPart._layerType << tile._boatOwnerColor; } IStreamBase & Maps::operator>>( IStreamBase & stream, Tiles & tile ) { - stream >> tile._index >> tile._terrainImageIndex >> tile._terrainFlags >> tile._tilePassabilityDirections >> tile._mainAddon._uid >> tile._mainAddon._objectIcnType; + stream >> tile._index >> tile._terrainImageIndex >> tile._terrainFlags >> tile._tilePassabilityDirections >> tile._mainObjectPart._uid >> tile._mainObjectPart._objectIcnType; static_assert( LAST_SUPPORTED_FORMAT_VERSION < FORMAT_VERSION_PRE2_1009_RELEASE, "Remove the logic below." ); if ( Game::GetVersionOfCurrentSaveFile() < FORMAT_VERSION_PRE2_1009_RELEASE ) { @@ -1878,7 +1878,7 @@ IStreamBase & Maps::operator>>( IStreamBase & stream, Tiles & tile ) stream >> temp >> temp; } - stream >> tile._mainAddon._imageIndex; + stream >> tile._mainObjectPart._imageIndex; static_assert( LAST_SUPPORTED_FORMAT_VERSION < FORMAT_VERSION_PRE3_1100_RELEASE, "Remove the logic below." ); if ( Game::GetVersionOfCurrentSaveFile() < FORMAT_VERSION_PRE3_1100_RELEASE ) { @@ -1891,6 +1891,6 @@ IStreamBase & Maps::operator>>( IStreamBase & stream, Tiles & tile ) stream >> tile._mainObjectType; } - return stream >> tile._fogColors >> tile._metadata >> tile._occupantHeroId >> tile._isTileMarkedAsRoad >> tile._addonBottomLayer >> tile._addonTopLayer - >> tile._mainAddon._layerType >> tile._boatOwnerColor; + return stream >> tile._fogColors >> tile._metadata >> tile._occupantHeroId >> tile._isTileMarkedAsRoad >> tile._groundObjectPart >> tile._topObjectPart + >> tile._mainObjectPart._layerType >> tile._boatOwnerColor; } diff --git a/src/fheroes2/maps/maps_tiles.h b/src/fheroes2/maps/maps_tiles.h index a5c0eb227a..97c92a1999 100644 --- a/src/fheroes2/maps/maps_tiles.h +++ b/src/fheroes2/maps/maps_tiles.h @@ -50,11 +50,11 @@ namespace Maps TERRAIN_LAYER = 3 // roads, water flaws and cracks. Essentially everything what is a part of terrain. }; - struct TilesAddon + struct ObjectPart { - TilesAddon() = default; + ObjectPart() = default; - TilesAddon( const uint8_t layerType, const uint32_t uid, const MP2::ObjectIcnType objectIcnType, const uint8_t imageIndex ) + ObjectPart( const uint8_t layerType, const uint32_t uid, const MP2::ObjectIcnType objectIcnType, const uint8_t imageIndex ) : _uid( uid ) , _layerType( layerType ) , _objectIcnType( objectIcnType ) @@ -63,19 +63,19 @@ namespace Maps // Do nothing. } - TilesAddon( const TilesAddon & ) = default; + ObjectPart( const ObjectPart & ) = default; - ~TilesAddon() = default; + ~ObjectPart() = default; - // Returns true if it can be passed be hero/boat: addon's layer type is SHADOW or TERRAIN. + // Returns true if it can be passed be hero/boat: part's layer type is SHADOW or TERRAIN. bool isPassabilityTransparent() const { return _layerType == SHADOW_LAYER || _layerType == TERRAIN_LAYER; } - bool operator==( const TilesAddon & addon ) const + bool operator==( const ObjectPart & part ) const { - return ( _uid == addon._uid ) && ( _layerType == addon._layerType ) && ( _objectIcnType == addon._objectIcnType ) && ( _imageIndex == addon._imageIndex ); + return ( _uid == part._uid ) && ( _layerType == part._layerType ) && ( _objectIcnType == part._objectIcnType ) && ( _imageIndex == part._imageIndex ); } // Unique identifier of an object. UID can be shared among multiple object parts if an object is bigger than 1 tile. @@ -98,8 +98,8 @@ namespace Maps bool operator==( const Tiles & tile ) const { - return ( _addonBottomLayer == tile._addonBottomLayer ) && ( _addonTopLayer == tile._addonTopLayer ) && ( _index == tile._index ) - && ( _terrainImageIndex == tile._terrainImageIndex ) && ( _terrainFlags == tile._terrainFlags ) && ( _mainAddon == tile._mainAddon ) + return ( _groundObjectPart == tile._groundObjectPart ) && ( _topObjectPart == tile._topObjectPart ) && ( _index == tile._index ) + && ( _terrainImageIndex == tile._terrainImageIndex ) && ( _terrainFlags == tile._terrainFlags ) && ( _mainObjectPart == tile._mainObjectPart ) && ( _mainObjectType == tile._mainObjectType ) && ( _metadata == tile._metadata ) && ( _tilePassabilityDirections == tile._tilePassabilityDirections ) && ( _isTileMarkedAsRoad == tile._isTileMarkedAsRoad ) && ( _occupantHeroId == tile._occupantHeroId ); } @@ -125,14 +125,14 @@ namespace Maps MP2::MapObjectType GetObject( bool ignoreObjectUnderHero = true ) const; - const TilesAddon & getMainObjectPart() const + const ObjectPart & getMainObjectPart() const { - return _mainAddon; + return _mainObjectPart; } - TilesAddon & getMainObjectPart() + ObjectPart & getMainObjectPart() { - return _mainAddon; + return _mainObjectPart; } uint16_t GetPassable() const @@ -155,7 +155,7 @@ namespace Maps return objectType == _mainObjectType; } - // Returns true if tile's main and bottom layer addons do not contain any objects: layer type is SHADOW or TERRAIN. + // Returns true if tile's main and ground layer object parts do not contain any objects: layer type is SHADOW or TERRAIN. bool isPassabilityTransparent() const; // Checks whether it is possible to move into this tile from the specified direction @@ -181,8 +181,8 @@ namespace Maps bool isStream() const; bool GoodForUltimateArtifact() const; - TilesAddon * getBottomLayerAddon( const uint32_t uid ); - TilesAddon * getTopLayerAddon( const uint32_t uid ); + ObjectPart * getGroundObjectPart( const uint32_t uid ); + ObjectPart * getTopObjectPart( const uint32_t uid ); void SetObject( const MP2::MapObjectType objectType ); @@ -201,7 +201,7 @@ namespace Maps void resetMainObjectPart() { - _mainAddon = {}; + _mainObjectPart = {}; } uint32_t GetRegion() const @@ -225,41 +225,41 @@ namespace Maps return _fogDirection; } - void pushBottomLayerAddon( const MP2::MP2AddonInfo & ma ); + void pushGroundObjectPart( const MP2::MP2AddonInfo & ma ); - void pushBottomLayerAddon( TilesAddon ta ); + void pushGroundObjectPart( ObjectPart ta ); - void pushTopLayerAddon( const MP2::MP2AddonInfo & ma ); + void pushTopObjectPart( const MP2::MP2AddonInfo & ma ); - void pushTopLayerAddon( TilesAddon ta ) + void pushTopObjectPart( ObjectPart ta ) { - _addonTopLayer.emplace_back( ta ); + _topObjectPart.emplace_back( ta ); } - const std::list & getBottomLayerAddons() const + const std::list & getGroundObjectParts() const { - return _addonBottomLayer; + return _groundObjectPart; } - std::list & getBottomLayerAddons() + std::list & getGroundObjectParts() { - return _addonBottomLayer; + return _groundObjectPart; } - const std::list & getTopLayerAddons() const + const std::list & getTopObjectParts() const { - return _addonTopLayer; + return _topObjectPart; } - void moveMainAddonToBottomLayer() + void moveMainObjectPartToGroundLevel() { - if ( _mainAddon._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) { - _addonBottomLayer.emplace_back( _mainAddon ); - _mainAddon = {}; + if ( _mainObjectPart._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) { + _groundObjectPart.emplace_back( _mainObjectPart ); + _mainObjectPart = {}; } } - void AddonsSort(); + void sortObjectParts(); // Returns true if any object part was removed. bool removeObjectPartsByUID( const uint32_t objectUID ); @@ -337,7 +337,7 @@ namespace Maps private: bool isShadow() const; - TilesAddon * getAddonWithFlag( const uint32_t uid ); + ObjectPart * getObjectPartWithFlag( const uint32_t uid ); // Set or remove a flag which belongs to UID of the object. void updateFlag( const int color, const uint8_t objectSpriteIndex, const uint32_t uid, const bool setOnUpperLayer ); @@ -359,11 +359,11 @@ namespace Maps // The following members are used in the Editor and in the game. - TilesAddon _mainAddon; + ObjectPart _mainObjectPart; - std::list _addonBottomLayer; + std::list _groundObjectPart; - std::list _addonTopLayer; + std::list _topObjectPart; int32_t _index{ 0 }; @@ -395,9 +395,9 @@ namespace Maps uint32_t _region{ REGION_NODE_BLOCKED }; }; - OStreamBase & operator<<( OStreamBase & stream, const TilesAddon & ta ); + OStreamBase & operator<<( OStreamBase & stream, const ObjectPart & ta ); OStreamBase & operator<<( OStreamBase & stream, const Tiles & tile ); - IStreamBase & operator>>( IStreamBase & stream, TilesAddon & ta ); + IStreamBase & operator>>( IStreamBase & stream, ObjectPart & ta ); IStreamBase & operator>>( IStreamBase & stream, Tiles & tile ); } diff --git a/src/fheroes2/maps/maps_tiles_helper.cpp b/src/fheroes2/maps/maps_tiles_helper.cpp index 945520e9cc..0c435b78de 100644 --- a/src/fheroes2/maps/maps_tiles_helper.cpp +++ b/src/fheroes2/maps/maps_tiles_helper.cpp @@ -825,9 +825,9 @@ namespace [¤tTile]( const uint8_t index ) { return currentTile.getMainObjectPart()._imageIndex == index; } ); } - for ( const Maps::TilesAddon & addon : currentTile.getBottomLayerAddons() ) { - if ( addon._objectIcnType == MP2::OBJ_ICN_TYPE_ROAD ) { - return std::any_of( roadIcnIndexes.begin(), roadIcnIndexes.end(), [&addon]( const uint8_t index ) { return addon._imageIndex == index; } ); + for ( const Maps::ObjectPart & part : currentTile.getGroundObjectParts() ) { + if ( part._objectIcnType == MP2::OBJ_ICN_TYPE_ROAD ) { + return std::any_of( roadIcnIndexes.begin(), roadIcnIndexes.end(), [&part]( const uint8_t index ) { return part._imageIndex == index; } ); } } @@ -1015,7 +1015,7 @@ namespace const uint32_t roadUid = tile.getObjectIdByObjectIcnType( MP2::OBJ_ICN_TYPE_ROAD ); if ( roadUid == 0 ) { - tile.pushBottomLayerAddon( Maps::TilesAddon( Maps::TERRAIN_LAYER, Maps::getNewObjectUID(), MP2::OBJ_ICN_TYPE_ROAD, imageIndex ) ); + tile.pushGroundObjectPart( Maps::ObjectPart( Maps::TERRAIN_LAYER, Maps::getNewObjectUID(), MP2::OBJ_ICN_TYPE_ROAD, imageIndex ) ); } else { Maps::Tiles::updateTileObjectIcnIndex( tile, roadUid, imageIndex ); @@ -1140,7 +1140,7 @@ namespace const uint32_t streamUid = tile.getObjectIdByObjectIcnType( MP2::OBJ_ICN_TYPE_STREAM ); if ( streamUid == 0 ) { - tile.pushBottomLayerAddon( Maps::TilesAddon( Maps::TERRAIN_LAYER, Maps::getNewObjectUID(), MP2::OBJ_ICN_TYPE_STREAM, imageIndex ) ); + tile.pushGroundObjectPart( Maps::ObjectPart( Maps::TERRAIN_LAYER, Maps::getNewObjectUID(), MP2::OBJ_ICN_TYPE_STREAM, imageIndex ) ); } else { Maps::Tiles::updateTileObjectIcnIndex( tile, streamUid, imageIndex ); @@ -1211,8 +1211,8 @@ namespace // The first case if the existing tile has no object type being set. const MP2::MapObjectType tileObjectType = currentTile.GetObject(); - // Always move the current object part to the back of the bottom layer list to make proper sorting later. - currentTile.moveMainAddonToBottomLayer(); + // Always move the current object part to the back of the ground layer list to make proper sorting later. + currentTile.moveMainObjectPartToGroundLevel(); if ( tileObjectType == MP2::OBJ_NONE ) { setObjectType = ( partInfo.objectType != MP2::OBJ_NONE ); @@ -1227,7 +1227,7 @@ namespace // We need to run through each object part present at the tile and see if it has "higher" layer object. bool higherObjectFound = false; - for ( const auto & topPart : currentTile.getTopLayerAddons() ) { + for ( const auto & topPart : currentTile.getTopObjectParts() ) { const MP2::MapObjectType type = Maps::getObjectTypeByIcn( topPart._objectIcnType, topPart._imageIndex ); if ( type != MP2::OBJ_NONE ) { // A top object part is present. @@ -1237,7 +1237,7 @@ namespace } if ( !higherObjectFound ) { - for ( const auto & groundPart : currentTile.getBottomLayerAddons() ) { + for ( const auto & groundPart : currentTile.getGroundObjectParts() ) { if ( groundPart._layerType >= partInfo.layerType ) { // A ground object part is has "lower" or equal layer type. Skip it. continue; @@ -1258,17 +1258,17 @@ namespace #if defined( WITH_DEBUG ) // Check that we don't put the same object part. - for ( const auto & groundPart : currentTile.getBottomLayerAddons() ) { + for ( const auto & groundPart : currentTile.getGroundObjectParts() ) { assert( groundPart._uid != uid || groundPart._imageIndex != static_cast( partInfo.icnIndex ) || groundPart._objectIcnType != partInfo.icnType || groundPart._layerType != partInfo.layerType ); } #endif // Push the object to the ground (bottom) object parts. - currentTile.pushBottomLayerAddon( Maps::TilesAddon( partInfo.layerType, uid, partInfo.icnType, static_cast( partInfo.icnIndex ) ) ); + currentTile.pushGroundObjectPart( Maps::ObjectPart( partInfo.layerType, uid, partInfo.icnType, static_cast( partInfo.icnIndex ) ) ); // Sort all objects. - currentTile.AddonsSort(); + currentTile.sortObjectParts(); // Set object type if needed. if ( setObjectType ) { @@ -1286,7 +1286,7 @@ namespace Maps::Tiles & currentTile = world.GetTiles( pos.x, pos.y ); // Top object parts do not need sorting. - currentTile.pushTopLayerAddon( Maps::TilesAddon( Maps::OBJECT_LAYER, uid, partInfo.icnType, static_cast( partInfo.icnIndex ) ) ); + currentTile.pushTopObjectPart( Maps::ObjectPart( Maps::OBJECT_LAYER, uid, partInfo.icnType, static_cast( partInfo.icnIndex ) ) ); // Set object type only if the current object part has a type and the object is not an action object. if ( partInfo.objectType != MP2::OBJ_NONE && !MP2::isOffGameActionObject( currentTile.GetObject() ) ) { @@ -1593,7 +1593,7 @@ namespace Maps return 0; } - const TilesAddon * getObjectPartByActionType( const Tiles & tile, const MP2::MapObjectType type ) + const ObjectPart * getObjectPartByActionType( const Tiles & tile, const MP2::MapObjectType type ) { if ( !MP2::isOffGameActionObject( type ) ) { return nullptr; @@ -1604,7 +1604,7 @@ namespace Maps return &tile.getMainObjectPart(); } - for ( const auto & objectPart : tile.getBottomLayerAddons() ) { + for ( const auto & objectPart : tile.getGroundObjectParts() ) { objectType = getObjectTypeByIcn( objectPart._objectIcnType, objectPart._imageIndex ); if ( objectType == type ) { return &objectPart; @@ -2185,10 +2185,10 @@ namespace Maps artifactSpriteIndex = tile.getMainObjectPart()._imageIndex; } else { - // On some hacked original maps artifact can be placed to the bottom layer addons. - for ( const auto & addon : tile.getBottomLayerAddons() ) { - if ( addon._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNARTI ) { - artifactSpriteIndex = addon._imageIndex; + // On some hacked original maps artifact can be placed to the ground layer object parts. + for ( const auto & part : tile.getGroundObjectParts() ) { + if ( part._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNARTI ) { + artifactSpriteIndex = part._imageIndex; break; } } @@ -2243,9 +2243,9 @@ namespace Maps resourceType = Resource::FromIndexSprite( tile.getMainObjectPart()._imageIndex ); } else { - for ( const auto & addon : tile.getBottomLayerAddons() ) { - if ( addon._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNRSRC ) { - resourceType = Resource::FromIndexSprite( addon._imageIndex ); + for ( const auto & part : tile.getGroundObjectParts() ) { + if ( part._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNRSRC ) { + resourceType = Resource::FromIndexSprite( part._imageIndex ); // If this happens we are in trouble. It looks like that map maker put the resource under an object which is impossible to do. // Let's update the tile's object type to properly show the action object. tile.updateObjectType(); @@ -2756,27 +2756,27 @@ namespace Maps { tile.SetObject( MP2::OBJ_MONSTER ); - Maps::TilesAddon & mainAddon = tile.getMainObjectPart(); + Maps::ObjectPart & mainObjectPart = tile.getMainObjectPart(); - if ( mainAddon._objectIcnType != MP2::OBJ_ICN_TYPE_MONS32 ) { - if ( mainAddon._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) { + if ( mainObjectPart._objectIcnType != MP2::OBJ_ICN_TYPE_MONS32 ) { + if ( mainObjectPart._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN ) { // If there is another object sprite here (shadow for example) push it down to add-ons. - tile.pushBottomLayerAddon( mainAddon ); + tile.pushGroundObjectPart( mainObjectPart ); } // Set unique UID for placed monster. - mainAddon._uid = getNewObjectUID(); - mainAddon._objectIcnType = MP2::OBJ_ICN_TYPE_MONS32; - mainAddon._layerType = OBJECT_LAYER; + mainObjectPart._uid = getNewObjectUID(); + mainObjectPart._objectIcnType = MP2::OBJ_ICN_TYPE_MONS32; + mainObjectPart._layerType = OBJECT_LAYER; } - using TileImageIndexType = decltype( mainAddon._imageIndex ); + using TileImageIndexType = decltype( mainObjectPart._imageIndex ); static_assert( std::is_same_v, "Type of _imageIndex has been changed, check the logic below" ); const uint32_t monsSpriteIndex = mons.GetSpriteIndex(); assert( monsSpriteIndex >= std::numeric_limits::min() && monsSpriteIndex <= std::numeric_limits::max() ); - mainAddon._imageIndex = static_cast( monsSpriteIndex ); + mainObjectPart._imageIndex = static_cast( monsSpriteIndex ); const bool setDefinedCount = ( count > 0 ); @@ -2957,8 +2957,8 @@ namespace Maps if ( Maps::isValidDirection( tile.GetIndex(), directionVector ) ) { Tiles & mineTile = world.GetTiles( Maps::GetDirectionIndex( tile.GetIndex(), directionVector ) ); if ( ( mineTile.GetObject() == MP2::OBJ_NON_ACTION_ABANDONED_MINE ) - && ( mineTile.getMainObjectPart()._uid == tile.getMainObjectPart()._uid || mineTile.getBottomLayerAddon( tile.getMainObjectPart()._uid ) - || mineTile.getTopLayerAddon( tile.getMainObjectPart()._uid ) ) ) { + && ( mineTile.getMainObjectPart()._uid == tile.getMainObjectPart()._uid || mineTile.getGroundObjectPart( tile.getMainObjectPart()._uid ) + || mineTile.getTopObjectPart( tile.getMainObjectPart()._uid ) ) ) { mineTile.SetObject( MP2::OBJ_NON_ACTION_MINE ); } } @@ -2971,9 +2971,9 @@ namespace Maps tile.getMainObjectPart()._objectIcnType = objectIcnTypeTemp; tile.getMainObjectPart()._imageIndex = imageIndexTemp; - for ( auto & addon : tile.getBottomLayerAddons() ) { - if ( addon._uid == tile.getMainObjectPart()._uid ) { - restoreLeftSprite( addon._objectIcnType, addon._imageIndex ); + for ( auto & part : tile.getGroundObjectParts() ) { + if ( part._uid == tile.getMainObjectPart()._uid ) { + restoreLeftSprite( part._objectIcnType, part._imageIndex ); } } @@ -2989,10 +2989,10 @@ namespace Maps rightTile.getMainObjectPart()._imageIndex = imageIndexTemp; } - TilesAddon * addon = rightTile.getBottomLayerAddon( tile.getMainObjectPart()._uid ); + ObjectPart * part = rightTile.getGroundObjectPart( tile.getMainObjectPart()._uid ); - if ( addon ) { - restoreRightSprite( addon->_objectIcnType, addon->_imageIndex ); + if ( part ) { + restoreRightSprite( part->_objectIcnType, part->_imageIndex ); } } @@ -3020,7 +3020,7 @@ namespace Maps } if ( objectUID == 0 ) { - for ( auto iter = tile.getTopLayerAddons().rbegin(); iter != tile.getTopLayerAddons().rend(); ++iter ) { + for ( auto iter = tile.getTopObjectParts().rbegin(); iter != tile.getTopObjectParts().rend(); ++iter ) { if ( Maps::getObjectTypeByIcn( iter->_objectIcnType, iter->_imageIndex ) == objectType ) { objectUID = iter->_uid; break; @@ -3029,7 +3029,7 @@ namespace Maps } if ( objectUID == 0 ) { - for ( auto iter = tile.getBottomLayerAddons().rbegin(); iter != tile.getBottomLayerAddons().rend(); ++iter ) { + for ( auto iter = tile.getGroundObjectParts().rbegin(); iter != tile.getGroundObjectParts().rend(); ++iter ) { if ( Maps::getObjectTypeByIcn( iter->_objectIcnType, iter->_imageIndex ) == objectType ) { objectUID = iter->_uid; break; @@ -3311,9 +3311,9 @@ namespace Maps objectsUids.insert( currentTile.getMainObjectPart()._uid ); } - for ( const auto & addon : currentTile.getBottomLayerAddons() ) { - if ( addon._uid != 0 && ( addon._layerType != SHADOW_LAYER ) ) { - objectsUids.insert( addon._uid ); + for ( const auto & part : currentTile.getGroundObjectParts() ) { + if ( part._uid != 0 && ( part._layerType != SHADOW_LAYER ) ) { + objectsUids.insert( part._uid ); } } diff --git a/src/fheroes2/maps/maps_tiles_helper.h b/src/fheroes2/maps/maps_tiles_helper.h index 59f97d8e0f..fc96732eb7 100644 --- a/src/fheroes2/maps/maps_tiles_helper.h +++ b/src/fheroes2/maps/maps_tiles_helper.h @@ -42,7 +42,7 @@ namespace MP2 namespace Maps { class Tiles; - struct TilesAddon; + struct ObjectPart; struct ObjectInfo; @@ -106,7 +106,7 @@ namespace Maps int getColorFromTravellerTentSprite( const MP2::ObjectIcnType objectIcnType, const uint8_t icnIndex ); // Only works for action type of objects (ignoring top layer objects parts). - const TilesAddon * getObjectPartByActionType( const Tiles & tile, const MP2::MapObjectType type ); + const ObjectPart * getObjectPartByActionType( const Tiles & tile, const MP2::MapObjectType type ); Monster getMonsterFromTile( const Tiles & tile ); diff --git a/src/fheroes2/maps/maps_tiles_render.cpp b/src/fheroes2/maps/maps_tiles_render.cpp index 4a0763a5b0..7721db4d95 100644 --- a/src/fheroes2/maps/maps_tiles_render.cpp +++ b/src/fheroes2/maps/maps_tiles_render.cpp @@ -81,7 +81,7 @@ namespace return false; } - bool isAddonDirectRenderingRestricted( const int icnId ) + bool isObjectPartDirectRenderingRestricted( const int icnId ) { switch ( icnId ) { case ICN::UNKNOWN: @@ -97,18 +97,18 @@ namespace return false; } - void renderAddonObject( fheroes2::Image & output, const Interface::GameArea & area, const fheroes2::Point & offset, const Maps::TilesAddon & addon ) + void renderObjectPart( fheroes2::Image & output, const Interface::GameArea & area, const fheroes2::Point & offset, const Maps::ObjectPart & part ) { - assert( addon._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN && addon._imageIndex != 255 ); + assert( part._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN && part._imageIndex != 255 ); - const int icn = MP2::getIcnIdFromObjectIcnType( addon._objectIcnType ); - if ( isAddonDirectRenderingRestricted( icn ) ) { + const int icn = MP2::getIcnIdFromObjectIcnType( part._objectIcnType ); + if ( isObjectPartDirectRenderingRestricted( icn ) ) { return; } - const uint8_t alphaValue = area.getObjectAlphaValue( addon._uid ); + const uint8_t alphaValue = area.getObjectAlphaValue( part._uid ); - const fheroes2::Sprite & sprite = fheroes2::AGG::GetICN( icn, addon._imageIndex ); + const fheroes2::Sprite & sprite = fheroes2::AGG::GetICN( icn, part._imageIndex ); // Ideally we need to check that the image is within a tile area. However, flags are among those for which this rule doesn't apply. if ( icn == ICN::FLAG32 ) { @@ -120,7 +120,7 @@ namespace area.BlitOnTile( output, sprite, sprite.x(), sprite.y(), offset, false, alphaValue ); - const uint32_t animationIndex = ICN::getAnimatedIcnIndex( icn, addon._imageIndex, Game::getAdventureMapAnimationIndex() ); + const uint32_t animationIndex = ICN::getAnimatedIcnIndex( icn, part._imageIndex, Game::getAdventureMapAnimationIndex() ); if ( animationIndex > 0 ) { const fheroes2::Sprite & animationSprite = fheroes2::AGG::GetICN( icn, animationIndex ); @@ -670,7 +670,7 @@ namespace Maps if ( renderFlyingGhosts ) { // This sprite is bigger than tileWidthPx but rendering is correct for heroes and boats. - // TODO: consider adding this sprite as a part of an addon. + // TODO: consider adding this sprite as a part of an object part. const fheroes2::Sprite & image = fheroes2::AGG::GetICN( ICN::OBJNHAUN, Game::getAdventureMapAnimationIndex() % 15 ); const uint8_t alphaValue = area.getObjectAlphaValue( tile.getMainObjectPart()._uid ); @@ -679,13 +679,13 @@ namespace Maps } } - void redrawTopLayerObject( const Tiles & tile, fheroes2::Image & dst, const bool isPuzzleDraw, const Interface::GameArea & area, const TilesAddon & addon ) + void redrawTopLayerObject( const Tiles & tile, fheroes2::Image & dst, const bool isPuzzleDraw, const Interface::GameArea & area, const ObjectPart & part ) { - if ( isPuzzleDraw && MP2::isHiddenForPuzzle( tile.GetGround(), addon._objectIcnType, addon._imageIndex ) ) { + if ( isPuzzleDraw && MP2::isHiddenForPuzzle( tile.GetGround(), part._objectIcnType, part._imageIndex ) ) { return; } - renderAddonObject( dst, area, Maps::GetPoint( tile.GetIndex() ), addon ); + renderObjectPart( dst, area, Maps::GetPoint( tile.GetIndex() ), part ); } void drawFog( const Tiles & tile, fheroes2::Image & dst, const Interface::GameArea & area ) @@ -935,34 +935,34 @@ namespace Maps const fheroes2::Point & mp = Maps::GetPoint( tile.GetIndex() ); // Since the original game stores information about objects in a very weird way and this is how it is implemented for us we need to do the following procedure: - // - run through all bottom objects first which are stored in the addon stack + // - run through all ground object parts first // - check the main object which is on the tile - // Some addons must be rendered after the main object on the tile. This applies for flags. + // Some object parts must be rendered after the main object on the tile. This applies for flags. // Since this method is called intensively during rendering we have to avoid memory allocation on heap. - const size_t maxPostRenderAddons = 16; - std::array postRenderingAddon{}; - size_t postRenderAddonCount = 0; + const size_t maxPostRenderPart = 16; + std::array postRenderingPart{}; + size_t postRenderObjectCount = 0; - for ( const auto & addon : tile.getBottomLayerAddons() ) { - if ( addon._layerType != level ) { + for ( const auto & part : tile.getGroundObjectParts() ) { + if ( part._layerType != level ) { continue; } - if ( isPuzzleDraw && MP2::isHiddenForPuzzle( tile.GetGround(), addon._objectIcnType, addon._imageIndex ) ) { + if ( isPuzzleDraw && MP2::isHiddenForPuzzle( tile.GetGround(), part._objectIcnType, part._imageIndex ) ) { continue; } - if ( addon._objectIcnType == MP2::OBJ_ICN_TYPE_FLAG32 ) { + if ( part._objectIcnType == MP2::OBJ_ICN_TYPE_FLAG32 ) { // Based on logically thinking it is impossible to have more than 16 flags on a single tile. - assert( postRenderAddonCount < maxPostRenderAddons ); + assert( postRenderObjectCount < maxPostRenderPart ); - postRenderingAddon[postRenderAddonCount] = &addon; - ++postRenderAddonCount; + postRenderingPart[postRenderObjectCount] = ∂ + ++postRenderObjectCount; continue; } - renderAddonObject( dst, area, mp, addon ); + renderObjectPart( dst, area, mp, part ); } if ( tile.getMainObjectPart()._objectIcnType != MP2::OBJ_ICN_TYPE_UNKNOWN && tile.getMainObjectPart()._layerType == level @@ -970,10 +970,10 @@ namespace Maps renderMainObject( dst, area, mp, tile ); } - for ( size_t i = 0; i < postRenderAddonCount; ++i ) { - assert( postRenderingAddon[i] != nullptr ); + for ( size_t i = 0; i < postRenderObjectCount; ++i ) { + assert( postRenderingPart[i] != nullptr ); - renderAddonObject( dst, area, mp, *postRenderingAddon[i] ); + renderObjectPart( dst, area, mp, *postRenderingPart[i] ); } } @@ -981,9 +981,9 @@ namespace Maps { const fheroes2::Point & tileOffset = Maps::GetPoint( tile.GetIndex() ); - for ( const auto & addon : tile.getBottomLayerAddons() ) { - if ( addon._objectIcnType == objectIcnType ) { - renderAddonObject( output, area, tileOffset, addon ); + for ( const auto & part : tile.getGroundObjectParts() ) { + if ( part._objectIcnType == objectIcnType ) { + renderObjectPart( output, area, tileOffset, part ); } } @@ -991,9 +991,9 @@ namespace Maps renderMainObject( output, area, tileOffset, tile ); } - for ( const auto & addon : tile.getTopLayerAddons() ) { - if ( addon._objectIcnType == objectIcnType ) { - renderAddonObject( output, area, tileOffset, addon ); + for ( const auto & part : tile.getTopObjectParts() ) { + if ( part._objectIcnType == objectIcnType ) { + renderObjectPart( output, area, tileOffset, part ); } } } diff --git a/src/fheroes2/maps/maps_tiles_render.h b/src/fheroes2/maps/maps_tiles_render.h index 9275ecec51..bd3065ed15 100644 --- a/src/fheroes2/maps/maps_tiles_render.h +++ b/src/fheroes2/maps/maps_tiles_render.h @@ -46,12 +46,12 @@ namespace MP2 namespace Maps { class Tiles; - struct TilesAddon; + struct ObjectPart; void redrawEmptyTile( fheroes2::Image & dst, const fheroes2::Point & mp, const Interface::GameArea & area ); void redrawTopLayerExtraObjects( const Tiles & tile, fheroes2::Image & dst, const bool isPuzzleDraw, const Interface::GameArea & area ); - void redrawTopLayerObject( const Tiles & tile, fheroes2::Image & dst, const bool isPuzzleDraw, const Interface::GameArea & area, const TilesAddon & addon ); + void redrawTopLayerObject( const Tiles & tile, fheroes2::Image & dst, const bool isPuzzleDraw, const Interface::GameArea & area, const ObjectPart & part ); void drawFog( const Tiles & tile, fheroes2::Image & dst, const Interface::GameArea & area ); diff --git a/src/fheroes2/world/world.cpp b/src/fheroes2/world/world.cpp index 39665bcb8e..57a49f6901 100644 --- a/src/fheroes2/world/world.cpp +++ b/src/fheroes2/world/world.cpp @@ -791,7 +791,7 @@ MapsIndexes World::GetTeleportEndPoints( const int32_t index ) const return result; } - const Maps::TilesAddon * entranceObjectPart = Maps::getObjectPartByActionType( entranceTile, MP2::OBJ_STONE_LITHS ); + const Maps::ObjectPart * entranceObjectPart = Maps::getObjectPartByActionType( entranceTile, MP2::OBJ_STONE_LITHS ); if ( entranceObjectPart == nullptr ) { // This tile is marked as Stone Liths but somehow it doesn't even have Stone Liths' object parts. assert( 0 ); @@ -835,7 +835,7 @@ MapsIndexes World::GetWhirlpoolEndPoints( const int32_t index ) const return result; } - const Maps::TilesAddon * entranceObjectPart = Maps::getObjectPartByActionType( entranceTile, MP2::OBJ_WHIRLPOOL ); + const Maps::ObjectPart * entranceObjectPart = Maps::getObjectPartByActionType( entranceTile, MP2::OBJ_WHIRLPOOL ); if ( entranceObjectPart == nullptr ) { // This tile is marked as Whirlpool but somehow it doesn't even have whirlpool's object parts. assert( 0 ); @@ -848,7 +848,7 @@ MapsIndexes World::GetWhirlpoolEndPoints( const int32_t index ) const continue; } - const Maps::TilesAddon * destinationObjectPart = Maps::getObjectPartByActionType( whirlpoolTile, MP2::OBJ_WHIRLPOOL ); + const Maps::ObjectPart * destinationObjectPart = Maps::getObjectPartByActionType( whirlpoolTile, MP2::OBJ_WHIRLPOOL ); if ( destinationObjectPart == nullptr ) { // This tile is marked as Whirlpool but somehow it doesn't even have whirlpool's object parts. assert( 0 ); @@ -964,7 +964,7 @@ bool World::DiggingForUltimateArtifact( const fheroes2::Point & center ) return false; } - tile.pushBottomLayerAddon( Maps::TilesAddon( Maps::BACKGROUND_LAYER, Maps::getNewObjectUID(), objectIcnType, imageIndex ) ); + tile.pushGroundObjectPart( Maps::ObjectPart( Maps::BACKGROUND_LAYER, Maps::getNewObjectUID(), objectIcnType, imageIndex ) ); if ( ultimate_artifact.isPosition( tile.GetIndex() ) && !ultimate_artifact.isFound() ) { ultimate_artifact.markAsFound(); @@ -1388,12 +1388,12 @@ void World::PostLoad( const bool setTilePassabilities, const bool updateUidCount for ( const Maps::Tiles & tile : vec_tiles ) { maxUid = std::max( tile.getMainObjectPart()._uid, maxUid ); - for ( const auto & addon : tile.getBottomLayerAddons() ) { - maxUid = std::max( addon._uid, maxUid ); + for ( const auto & part : tile.getGroundObjectParts() ) { + maxUid = std::max( part._uid, maxUid ); } - for ( const auto & addon : tile.getTopLayerAddons() ) { - maxUid = std::max( addon._uid, maxUid ); + for ( const auto & part : tile.getTopObjectParts() ) { + maxUid = std::max( part._uid, maxUid ); } } diff --git a/src/fheroes2/world/world_loadmap.cpp b/src/fheroes2/world/world_loadmap.cpp index 47cf47e5f1..b8c06e566f 100644 --- a/src/fheroes2/world/world_loadmap.cpp +++ b/src/fheroes2/world/world_loadmap.cpp @@ -275,12 +275,12 @@ bool World::LoadMapMP2( const std::string & filename, const bool isOriginalMp2Fi DEBUG_LOG( DBG_GAME, DBG_WARN, "Invalid MP2 format: incorrect addon index " << addonIndex ) break; } - tile.pushBottomLayerAddon( vec_mp2addons[addonIndex] ); - tile.pushTopLayerAddon( vec_mp2addons[addonIndex] ); + tile.pushGroundObjectPart( vec_mp2addons[addonIndex] ); + tile.pushTopObjectPart( vec_mp2addons[addonIndex] ); addonIndex = vec_mp2addons[addonIndex].nextAddonIndex; } - tile.AddonsSort(); + tile.sortObjectParts(); if ( MP2::doesObjectNeedExtendedMetadata( tile.GetObject() ) ) { vec_object.push_back( i ); From f282c0dbc150597563b27acf3b63841956440016 Mon Sep 17 00:00:00 2001 From: Ihar Hubchyk Date: Tue, 22 Oct 2024 23:07:24 +0800 Subject: [PATCH 2/2] Code style fixes --- src/fheroes2/maps/maps_tiles.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/fheroes2/maps/maps_tiles.cpp b/src/fheroes2/maps/maps_tiles.cpp index c1fc9ea9ce..454555b7f1 100644 --- a/src/fheroes2/maps/maps_tiles.cpp +++ b/src/fheroes2/maps/maps_tiles.cpp @@ -752,7 +752,8 @@ void Maps::Tiles::updatePassability() return part._objectIcnType != MP2::OBJ_ICN_TYPE_ROAD && part._objectIcnType != MP2::OBJ_ICN_TYPE_STREAM; } ); - const bool singleObjectTile = ( validBottomLayerObjects == 0 ) && _topObjectPart.empty() && ( bottomTile._mainObjectPart._objectIcnType != _mainObjectPart._objectIcnType ); + const bool singleObjectTile + = ( validBottomLayerObjects == 0 ) && _topObjectPart.empty() && ( bottomTile._mainObjectPart._objectIcnType != _mainObjectPart._objectIcnType ); // TODO: we might need to simplify the logic below as singleObjectTile might cover most of it. if ( !singleObjectTile && !isDetachedObject() && !bottomTile._mainObjectPart.isPassabilityTransparent() @@ -1090,8 +1091,7 @@ bool Maps::Tiles::isStream() const { for ( const auto & part : _groundObjectPart ) { if ( part._objectIcnType == MP2::OBJ_ICN_TYPE_STREAM - || ( part._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNMUL2 - && ( part._imageIndex < 14 || ( part._imageIndex > 217 && part._imageIndex < ( 218 + 14 ) ) ) ) ) { + || ( part._objectIcnType == MP2::OBJ_ICN_TYPE_OBJNMUL2 && ( part._imageIndex < 14 || ( part._imageIndex > 217 && part._imageIndex < ( 218 + 14 ) ) ) ) ) { return true; } } @@ -1864,13 +1864,15 @@ OStreamBase & Maps::operator<<( OStreamBase & stream, const Tiles & tile ) { // TODO: use operator<<() for _mainObjectPart. return stream << tile._index << tile._terrainImageIndex << tile._terrainFlags << tile._tilePassabilityDirections << tile._mainObjectPart._uid - << tile._mainObjectPart._objectIcnType << tile._mainObjectPart._imageIndex << tile._mainObjectType << tile._fogColors << tile._metadata << tile._occupantHeroId - << tile._isTileMarkedAsRoad << tile._groundObjectPart << tile._topObjectPart << tile._mainObjectPart._layerType << tile._boatOwnerColor; + << tile._mainObjectPart._objectIcnType << tile._mainObjectPart._imageIndex << tile._mainObjectType << tile._fogColors << tile._metadata + << tile._occupantHeroId << tile._isTileMarkedAsRoad << tile._groundObjectPart << tile._topObjectPart << tile._mainObjectPart._layerType + << tile._boatOwnerColor; } IStreamBase & Maps::operator>>( IStreamBase & stream, Tiles & tile ) { - stream >> tile._index >> tile._terrainImageIndex >> tile._terrainFlags >> tile._tilePassabilityDirections >> tile._mainObjectPart._uid >> tile._mainObjectPart._objectIcnType; + stream >> tile._index >> tile._terrainImageIndex >> tile._terrainFlags >> tile._tilePassabilityDirections >> tile._mainObjectPart._uid + >> tile._mainObjectPart._objectIcnType; static_assert( LAST_SUPPORTED_FORMAT_VERSION < FORMAT_VERSION_PRE2_1009_RELEASE, "Remove the logic below." ); if ( Game::GetVersionOfCurrentSaveFile() < FORMAT_VERSION_PRE2_1009_RELEASE ) {