From a14caa53d0377d8ea829792d7a145146a3b372d6 Mon Sep 17 00:00:00 2001 From: JapaMala Date: Sun, 20 Jul 2014 16:41:20 +0530 Subject: [PATCH] Fixed mapcache reading plants in for 0.40.01 onwards. --- library/include/modules/MapCache.h | 2 ++ library/include/modules/Maps.h | 2 ++ library/modules/MapCache.cpp | 46 ++++++++++++++++++++++++++++-- library/modules/Maps.cpp | 11 +++++++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/library/include/modules/MapCache.h b/library/include/modules/MapCache.h index 5f5d43b9e..153f819a8 100644 --- a/library/include/modules/MapCache.h +++ b/library/include/modules/MapCache.h @@ -31,6 +31,7 @@ distribution. #include #include #include "df/map_block.h" +#include "df/map_block_column.h" #include "df/tile_bitmask.h" #include "df/block_square_event_mineralst.h" #include "df/construction.h" @@ -71,6 +72,7 @@ class BlockInfo Block *mblock; MapCache *parent; df::map_block *block; + df::map_block_column *column; //for plants public: enum GroundType { diff --git a/library/include/modules/Maps.h b/library/include/modules/Maps.h index ed0a7bf6a..bf0271527 100644 --- a/library/include/modules/Maps.h +++ b/library/include/modules/Maps.h @@ -257,6 +257,8 @@ extern DFHACK_EXPORT df::map_block * getBlock (int32_t blockx, int32_t blocky, i extern DFHACK_EXPORT df::map_block * getTileBlock (int32_t x, int32_t y, int32_t z); extern DFHACK_EXPORT df::map_block * ensureTileBlock (int32_t x, int32_t y, int32_t z); +extern DFHACK_EXPORT df::map_block_column * getBlockColumn(int32_t blockx, int32_t blocky); + inline df::map_block * getBlock (df::coord pos) { return getBlock(pos.x, pos.y, pos.z); } inline df::map_block * getTileBlock (df::coord pos) { return getTileBlock(pos.x, pos.y, pos.z); } inline df::map_block * ensureTileBlock (df::coord pos) { return ensureTileBlock(pos.x, pos.y, pos.z); } diff --git a/library/modules/MapCache.cpp b/library/modules/MapCache.cpp index db3b4cdd9..da7683351 100644 --- a/library/modules/MapCache.cpp +++ b/library/modules/MapCache.cpp @@ -63,6 +63,8 @@ using namespace std; #include "df/region_map_entry.h" #include "df/flow_info.h" #include "df/plant.h" +#include "df/plant_tree_info.h" +#include "df/plant_tree_tile.h" #include "df/building_type.h" using namespace DFHack; @@ -726,14 +728,50 @@ void MapExtras::BlockInfo::prepare(Block *mblock) block = mblock->getRaw(); parent = mblock->getParent(); + column = Maps::getBlockColumn((block->map_pos.x/48)*3, (block->map_pos.y/48)*3); SquashVeins(block,veinmats,veintype); SquashGrass(block, grass); - for (size_t i = 0; i < block->plants.size(); i++) + for (size_t i = 0; i < column->plants.size(); i++) { - auto pp = block->plants[i]; - plants[pp->pos] = pp; + auto pp = column->plants[i]; + // A plant without tree_info is single tile + // TODO: verify that x any y lie inside the block. + if(!pp->tree_info) + { + if(pp->pos.z == block->map_pos.z) + plants[pp->pos] = pp; + continue; + } + + // tree_info contains vertical slices of the tree. This ensures there's a slice for our Z-level. + df::plant_tree_info * info = pp->tree_info; + if(!((pp->pos.z-1 <= block->map_pos.z) && ((pp->pos.z+info->z_dim) > block->map_pos.z))) + continue; + + // Parse through a single horizontal slice of the tree. + for(int xx = 0; xx < info->x_dim;xx++) + for(int yy = 0; yy < info->y_dim;yy++) + { + // Any non-zero value here other than blocked means there's some sort of branch here. + // If the block is at or above the plant's base level, we use the body array + // otherwise we use the roots. + // TODO: verify that the tree bounds intersect the block. + df::plant_tree_tile tile; + int z_diff = block->map_pos.z-pp->pos.z; + if(z_diff >= 0) + tile = info->body[z_diff][xx+(yy*info->x_dim)]; + else tile = info->roots[0][xx+(yy*info->x_dim)]; + if(tile.whole && !(tile.bits.blocked)) + { + df::coord pos=pp->pos; + pos.x = pos.x - (info->x_dim/2) + xx; + pos.y = pos.y - (info->y_dim/2) + yy; + pos.z = block->map_pos.z; + plants[pos] = pp; + } + } } global_feature = Maps::getGlobalInitFeature(block->global_feature); @@ -804,6 +842,8 @@ t_matpair MapExtras::BlockInfo::getBaseMaterial(df::tiletype tt, df::coord2d pos rv.mat_index = mblock->biomeInfoAt(pos).lava_stone; break; + case ROOT: + case TREE: case PLANT: rv.mat_type = MaterialInfo::PLANT_BASE; if (auto plant = plants[block->map_pos + df::coord(x,y,0)]) diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index fd1ccc523..2ad1f7821 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -143,6 +143,17 @@ df::map_block *Maps::getBlock (int32_t blockx, int32_t blocky, int32_t blockz) return world->map.block_index[blockx][blocky][blockz]; } +df::map_block_column *Maps::getBlockColumn(int32_t blockx, int32_t blocky) +{ + if (!IsValid()) + return NULL; + if ((blockx < 0) || (blocky < 0)) + return NULL; + if ((blockx >= world->map.x_count_block) || (blocky >= world->map.y_count_block)) + return NULL; + return world->map.column_index[blockx][blocky]; +} + bool Maps::isValidTilePos(int32_t x, int32_t y, int32_t z) { if (!IsValid())