From 4b87f1bcaca65b7fa7542dfa6e638413c5b6d48f Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Thu, 19 Apr 2012 19:17:07 +0400 Subject: [PATCH] Refactor MapCache: make it parse everything that is known re tiles & mats. --- library/include/modules/MapCache.h | 249 +++++++++++++---- library/include/modules/Materials.h | 10 + library/modules/Maps.cpp | 410 ++++++++++++++++++++++++---- library/xml | 2 +- plugins/dig.cpp | 8 +- plugins/mapexport/mapexport.cpp | 4 +- plugins/probe.cpp | 58 ++-- plugins/prospector.cpp | 4 +- 8 files changed, 601 insertions(+), 144 deletions(-) diff --git a/library/include/modules/MapCache.h b/library/include/modules/MapCache.h index 8eac514be..4ddf0c984 100644 --- a/library/include/modules/MapCache.h +++ b/library/include/modules/MapCache.h @@ -31,12 +31,17 @@ distribution. #include #include #include "df/map_block.h" +#include "df/tile_bitmask.h" #include "df/block_square_event_mineralst.h" #include "df/construction.h" #include "df/item.h" using namespace DFHack; +namespace df { + struct world_region_details; +} + namespace MapExtras { @@ -50,6 +55,38 @@ inline bool is_valid_tile_coord(df::coord2d p) { return (p.x & ~15) == 0 && (p.y & ~15) == 0; } +class Block; + +class BlockInfo +{ + Block *mblock; + MapCache *parent; + df::map_block *block; + +public: + t_blockmaterials veinmats; + t_blockmaterials basemats; + t_blockmaterials grass; + std::map plants; + + df::feature_init *global_feature; + df::feature_init *local_feature; + + BlockInfo() + : mblock(NULL), parent(NULL), block(NULL), + global_feature(NULL), local_feature(NULL) {} + + void prepare(Block *mblock); + + t_matpair getBaseMaterial(df::tiletype tt, df::coord2d pos); + + static void SquashVeins(df::map_block *mb, t_blockmaterials & materials); + static void SquashFrozenLiquids (df::map_block *mb, tiletypes40d & frozen); + static void SquashRocks (df::map_block *mb, t_blockmaterials & materials, + std::vector< std::vector > * layerassign); + static void SquashGrass(df::map_block *mb, t_blockmaterials &materials); +}; + class DFHACK_EXPORT Block { public: @@ -62,39 +99,81 @@ public: //Arbitrary tag field for flood fills etc. int16_t &tag(df::coord2d p) { + if (!tags) init_tags(); return index_tile(tags, p); } + // Base layer + df::tiletype baseTiletypeAt(df::coord2d p) + { + if (!tiles) init_tiles(); + return index_tile(tiles->base_tiles,p); + } + t_matpair baseMaterialAt(df::coord2d p) + { + if (!basemats) init_tiles(true); + return t_matpair( + index_tile(basemats->mattype,p), + index_tile(basemats->matindex,p) + ); + } + bool isVeinAt(df::coord2d p) + { + using namespace df::enums::tiletype_material; + auto tm = tileMaterial(baseTiletypeAt(p)); + return tm == MINERAL; + } + bool isLayerAt(df::coord2d p) + { + using namespace df::enums::tiletype_material; + auto tm = tileMaterial(baseTiletypeAt(p)); + return tm == STONE || tm == SOIL; + } + int16_t veinMaterialAt(df::coord2d p) { - return index_tile(veinmats,p); + return isVeinAt(p) ? baseMaterialAt(p).mat_index : -1; } - int16_t baseMaterialAt(df::coord2d p) + int16_t layerMaterialAt(df::coord2d p) { - return index_tile(basemats,p); + if (!basemats) init_tiles(true); + return index_tile(basemats->layermat,p); } - df::tiletype BaseTileTypeAt(df::coord2d p) + // Static layer (base + constructions) + df::tiletype staticTiletypeAt(df::coord2d p) { - auto tt = index_tile(contiles,p); - if (tt != tiletype::Void) return tt; - tt = index_tile(icetiles,p); - if (tt != tiletype::Void) return tt; - return index_tile(rawtiles,p); + if (!tiles) init_tiles(); + if (tiles->con_info) + return index_tile(tiles->con_info->tiles,p); + return baseTiletypeAt(p); } - df::tiletype TileTypeAt(df::coord2d p) + t_matpair staticMaterialAt(df::coord2d p) { - return index_tile(rawtiles,p); + if (!basemats) init_tiles(true); + if (tiles->con_info) + return t_matpair( + index_tile(tiles->con_info->mattype,p), + index_tile(tiles->con_info->matindex,p) + ); + return baseMaterialAt(p); } - bool setTiletypeAt(df::coord2d p, df::tiletype tiletype) + bool hasConstructionAt(df::coord2d p) { - if(!valid) return false; - dirty_tiletypes = true; - //printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y); - index_tile(rawtiles,p) = tiletype; - return true; + if (!tiles) init_tiles(); + return tiles->con_info && + tiles->con_info->constructed.getassignment(p); } + df::tiletype tiletypeAt(df::coord2d p) + { + if (!block) return tiletype::Void; + if (tiles) + return index_tile(tiles->raw_tiles,p); + return index_tile(block->tiletype,p); + } + bool setTiletypeAt(df::coord2d, df::tiletype tt, bool force = false); + uint16_t temperature1At(df::coord2d p) { return index_tile(temp1,p); @@ -179,29 +258,29 @@ public: bool is_valid() { return valid; } df::map_block *getRaw() { return block; } + MapCache *getParent() { return parent; } + private: friend class MapCache; MapCache *parent; df::map_block *block; - static void SquashVeins(df::map_block *mb, t_blockmaterials & materials); - static void SquashFrozenLiquids (df::map_block *mb, tiletypes40d & frozen); - static void SquashConstructions (df::map_block *mb, tiletypes40d & constructions); - static void SquashRocks (df::map_block *mb, t_blockmaterials & materials, - std::vector< std::vector > * layerassign); - bool valid; bool dirty_designations:1; - bool dirty_tiletypes:1; + bool dirty_tiles:1; bool dirty_temperatures:1; bool dirty_blockflags:1; bool dirty_occupancies:1; DFCoord bcoord; - int16_t tags[16][16]; + // Custom tags for floodfill + typedef int16_t T_tags[16]; + T_tags *tags; + void init_tags(); + // On-ground item count info typedef int T_item_counts[16]; T_item_counts *item_counts; void init_item_counts(); @@ -209,30 +288,53 @@ private: bool addItemOnGround(df::item *item); bool removeItemOnGround(df::item *item); - tiletypes40d rawtiles; + struct ConInfo { + df::tile_bitmask constructed; + df::tiletype tiles[16][16]; + t_blockmaterials mattype; + t_blockmaterials matindex; + }; + struct TileInfo { + df::tile_bitmask frozen; + df::tile_bitmask dirty_raw; + df::tiletype raw_tiles[16][16]; + + ConInfo *con_info; + + df::tile_bitmask dirty_base; + df::tiletype base_tiles[16][16]; + + TileInfo(); + ~TileInfo(); + + void init_coninfo(); + }; + struct BasematInfo { + df::tile_bitmask dirty; + t_blockmaterials mattype; + t_blockmaterials matindex; + t_blockmaterials layermat; + + BasematInfo(); + }; + TileInfo *tiles; + BasematInfo *basemats; + void init_tiles(bool basemat = false); + void ParseTiles(TileInfo *tiles); + void ParseBasemats(TileInfo *tiles, BasematInfo *bmats); + designations40d designation; occupancies40d occupancy; t_blockflags blockflags; - t_blockmaterials veinmats; - t_blockmaterials basemats; t_temperatures temp1; t_temperatures temp2; - tiletypes40d contiles; // what's underneath constructions - tiletypes40d icetiles; // what's underneath ice }; class DFHACK_EXPORT MapCache { public: - MapCache() - { - valid = 0; - Maps::getSize(x_bmax, y_bmax, z_max); - x_tmax = x_bmax*16; y_tmax = y_bmax*16; - validgeo = Maps::ReadGeology(&layer_mats, &geoidx); - valid = true; - }; + MapCache(); ~MapCache() { trash(); @@ -251,19 +353,60 @@ class DFHACK_EXPORT MapCache df::tiletype baseTiletypeAt (DFCoord tilecoord) { - Block * b= BlockAtTile(tilecoord); - return b ? b->BaseTileTypeAt(tilecoord) : tiletype::Void; + Block *b = BlockAtTile(tilecoord); + return b ? b->baseTiletypeAt(tilecoord) : tiletype::Void; + } + t_matpair baseMaterialAt (DFCoord tilecoord) + { + Block *b = BlockAtTile(tilecoord); + return b ? b->baseMaterialAt(tilecoord) : t_matpair(); + } + int16_t veinMaterialAt (DFCoord tilecoord) + { + Block *b = BlockAtTile(tilecoord); + return b ? b->veinMaterialAt(tilecoord) : -1; + } + int16_t layerMaterialAt (DFCoord tilecoord) + { + Block *b = BlockAtTile(tilecoord); + return b ? b->layerMaterialAt(tilecoord) : -1; + } + bool isVeinAt (DFCoord tilecoord) + { + Block *b = BlockAtTile(tilecoord); + return b && b->isVeinAt(tilecoord); } + bool isLayerAt (DFCoord tilecoord) + { + Block *b = BlockAtTile(tilecoord); + return b && b->isLayerAt(tilecoord); + } + + df::tiletype staticTiletypeAt (DFCoord tilecoord) + { + Block *b = BlockAtTile(tilecoord); + return b ? b->staticTiletypeAt(tilecoord) : tiletype::Void; + } + t_matpair staticMaterialAt (DFCoord tilecoord) + { + Block *b = BlockAtTile(tilecoord); + return b ? b->staticMaterialAt(tilecoord) : t_matpair(); + } + bool hasConstructionAt (DFCoord tilecoord) + { + Block *b = BlockAtTile(tilecoord); + return b && b->hasConstructionAt(tilecoord); + } + df::tiletype tiletypeAt (DFCoord tilecoord) { - Block * b= BlockAtTile(tilecoord); - return b ? b->TileTypeAt(tilecoord) : tiletype::Void; + Block *b = BlockAtTile(tilecoord); + return b ? b->tiletypeAt(tilecoord) : tiletype::Void; } - bool setTiletypeAt(DFCoord tilecoord, df::tiletype tiletype) + bool setTiletypeAt (DFCoord tilecoord, df::tiletype tt, bool force = false) { - if (Block * b= BlockAtTile(tilecoord)) - return b->setTiletypeAt(tilecoord, tiletype); - return false; + Block *b = BlockAtTile(tilecoord); + return b && b->setTiletypeAt(tilecoord, tt, force); } uint16_t temperature1At (DFCoord tilecoord) @@ -290,17 +433,6 @@ class DFHACK_EXPORT MapCache return false; } - int16_t veinMaterialAt (DFCoord tilecoord) - { - Block * b= BlockAtTile(tilecoord); - return b ? b->veinMaterialAt(tilecoord) : -1; - } - int16_t baseMaterialAt (DFCoord tilecoord) - { - Block * b= BlockAtTile(tilecoord); - return b ? b->baseMaterialAt(tilecoord) : -1; - } - int16_t tagAt(DFCoord tilecoord) { Block * b= BlockAtTile(tilecoord); @@ -311,6 +443,7 @@ class DFHACK_EXPORT MapCache Block * b= BlockAtTile(tilecoord); if (b) b->tag(tilecoord) = val; } + void resetTags(); df::tile_designation designationAt (DFCoord tilecoord) { @@ -378,6 +511,7 @@ class DFHACK_EXPORT MapCache private: friend class Block; + friend class BlockInfo; bool valid; bool validgeo; @@ -388,6 +522,7 @@ private: uint32_t z_max; std::vector geoidx; std::vector< std::vector > layer_mats; + std::map region_details; std::map blocks; }; } diff --git a/library/include/modules/Materials.h b/library/include/modules/Materials.h index 3d70dc9fa..76c89de30 100644 --- a/library/include/modules/Materials.h +++ b/library/include/modules/Materials.h @@ -60,6 +60,14 @@ namespace df namespace DFHack { + struct t_matpair { + int16_t mat_type; + int32_t mat_index; + + t_matpair(int16_t type = -1, int32_t index = -1) + : mat_type(type), mat_index(index) {} + }; + struct DFHACK_EXPORT MaterialInfo { static const int NUM_BUILTIN = 19; static const int GROUP_SIZE = 200; @@ -91,6 +99,7 @@ namespace DFHack public: MaterialInfo(int16_t type = -1, int32_t index = -1) { decode(type, index); } + MaterialInfo(const t_matpair &mp) { decode(mp.mat_type, mp.mat_index); } template MaterialInfo(T *ptr) { decode(ptr); } bool isValid() const { return material != NULL; } @@ -107,6 +116,7 @@ namespace DFHack bool decode(int16_t type, int32_t index = -1); bool decode(df::item *item); bool decode(const df::material_vec_ref &vr, int idx); + bool decode(const t_matpair &mp) { return decode(mp.mat_type, mp.mat_index); } template bool decode(T *ptr) { // Assume and exploit a certain naming convention diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index e795659ca..06e525fea 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -51,6 +51,9 @@ using namespace std; #include "df/burrow.h" #include "df/block_burrow.h" #include "df/block_burrow_link.h" +#include "df/world_region_details.h" +#include "df/builtin_mats.h" +#include "df/block_square_event_grassst.h" using namespace DFHack; using namespace df::enums; @@ -158,7 +161,7 @@ df::world_data::T_region_map *Maps::getRegionBiome(df::coord2d rgn_pos) df::feature_init *Maps::getGlobalInitFeature(int32_t index) { auto data = world->world_data; - if (!data) + if (!data || index < 0) return NULL; auto rgn = vector_get(data->underground_regions, index); @@ -186,7 +189,7 @@ bool Maps::GetGlobalFeature(t_feature &feature, int32_t index) df::feature_init *Maps::getLocalInitFeature(df::coord2d rgn_pos, int32_t index) { auto data = world->world_data; - if (!data) + if (!data || index < 0) return NULL; if (rgn_pos.x < 0 || rgn_pos.x >= data->world_width || @@ -353,7 +356,7 @@ bool Maps::ReadGeology(vector > *layer_mats, vector int bioRX = world->map.region_x / 16 + ((i % 3) - 1); int bioRY = world->map.region_y / 16 + ((i / 3) - 1); - df::coord2d rgn_pos(clip_range(bioRX,0,world_width-1),clip_range(bioRX,0,world_height-1)); + df::coord2d rgn_pos(clip_range(bioRX,0,world_width-1),clip_range(bioRY,0,world_height-1)); (*geoidx)[i] = rgn_pos; @@ -389,7 +392,7 @@ bool Maps::ReadGeology(vector > *layer_mats, vector MapExtras::Block::Block(MapCache *parent, DFCoord _bcoord) : parent(parent) { dirty_designations = false; - dirty_tiletypes = false; + dirty_tiles = false; dirty_temperatures = false; dirty_blockflags = false; dirty_occupancies = false; @@ -397,12 +400,12 @@ MapExtras::Block::Block(MapCache *parent, DFCoord _bcoord) : parent(parent) bcoord = _bcoord; block = Maps::getBlock(bcoord); item_counts = NULL; - - memset(tags,0,sizeof(tags)); + tags = NULL; + tiles = NULL; + basemats = NULL; if(block) { - COPY(rawtiles, block->tiletype); COPY(designation, block->designation); COPY(occupancy, block->occupancy); blockflags = block->flags; @@ -410,33 +413,189 @@ MapExtras::Block::Block(MapCache *parent, DFCoord _bcoord) : parent(parent) COPY(temp1, block->temperature_1); COPY(temp2, block->temperature_2); - SquashVeins(block,veinmats); - SquashConstructions(block, contiles); - SquashFrozenLiquids(block, icetiles); - if(parent->validgeo) - SquashRocks(block,basemats,&parent->layer_mats); - else - memset(basemats,-1,sizeof(basemats)); valid = true; } else { blockflags.whole = 0; - memset(rawtiles,0,sizeof(rawtiles)); memset(designation,0,sizeof(designation)); memset(occupancy,0,sizeof(occupancy)); memset(temp1,0,sizeof(temp1)); memset(temp2,0,sizeof(temp2)); - memset(veinmats,-1,sizeof(veinmats)); - memset(contiles,0,sizeof(contiles)); - memset(icetiles,0,sizeof(icetiles)); - memset(basemats,-1,sizeof(basemats)); } } MapExtras::Block::~Block() { delete[] item_counts; + delete[] tags; + delete tiles; + delete basemats; +} + +void MapExtras::Block::init_tags() +{ + if (!tags) + tags = new T_tags[16]; + memset(tags,0,sizeof(T_tags)*16); +} + +void MapExtras::Block::init_tiles(bool basemat) +{ + if (!tiles) + { + tiles = new TileInfo(); + + if (block) + ParseTiles(tiles); + } + + if (basemat && !basemats) + { + basemats = new BasematInfo(); + + if (block) + ParseBasemats(tiles, basemats); + } +} + +MapExtras::Block::TileInfo::TileInfo() +{ + frozen.clear(); + dirty_raw.clear(); + memset(raw_tiles,0,sizeof(raw_tiles)); + con_info = NULL; + dirty_base.clear(); + memset(base_tiles,0,sizeof(base_tiles)); +} + +MapExtras::Block::TileInfo::~TileInfo() +{ + delete con_info; +} + +void MapExtras::Block::TileInfo::init_coninfo() +{ + if (con_info) + return; + + con_info = new ConInfo(); + con_info->constructed.clear(); + COPY(con_info->tiles, base_tiles); + memset(con_info->mattype, -1, sizeof(con_info->mattype)); + memset(con_info->matindex, -1, sizeof(con_info->matindex)); +} + +MapExtras::Block::BasematInfo::BasematInfo() +{ + dirty.clear(); + memset(mattype,0,sizeof(mattype)); + memset(matindex,-1,sizeof(matindex)); + memset(layermat,-1,sizeof(layermat)); +} + +bool MapExtras::Block::setTiletypeAt(df::coord2d pos, df::tiletype tt, bool force) +{ + if (!block) + return false; + + if (!basemats) + init_tiles(true); + + pos = pos & 15; + + dirty_tiles = true; + tiles->raw_tiles[pos.x][pos.y] = tt; + tiles->dirty_raw.setassignment(pos, true); + + return true; +} + +void MapExtras::Block::ParseTiles(TileInfo *tiles) +{ + tiletypes40d icetiles; + BlockInfo::SquashFrozenLiquids(block, icetiles); + + COPY(tiles->raw_tiles, block->tiletype); + + for (int x = 0; x < 16; x++) + { + for (int y = 0; y < 16; y++) + { + using namespace df::enums::tiletype_material; + + df::tiletype tt = tiles->raw_tiles[x][y]; + df::coord coord = block->map_pos + df::coord(x,y,0); + + // Frozen liquid comes topmost + if (tileMaterial(tt) == FROZEN_LIQUID) + { + tiles->frozen.setassignment(x,y,true); + if (icetiles[x][y] != tiletype::Void) + { + tt = icetiles[x][y]; + } + } + + // The next layer may be construction + bool is_con = false; + + if (tileMaterial(tt) == CONSTRUCTION) + { + df::construction *con = df::construction::find(coord); + if (con) + { + if (!tiles->con_info) + tiles->init_coninfo(); + + is_con = true; + tiles->con_info->constructed.setassignment(x,y,true); + tiles->con_info->tiles[x][y] = tt; + tiles->con_info->mattype[x][y] = con->mat_type; + tiles->con_info->matindex[x][y] = con->mat_index; + + tt = con->original_tile; + } + } + + // Finally, base material + tiles->base_tiles[x][y] = tt; + + // Copy base info back to construction layer + if (tiles->con_info && !is_con) + tiles->con_info->tiles[x][y] = tt; + } + } +} + +void MapExtras::Block::ParseBasemats(TileInfo *tiles, BasematInfo *bmats) +{ + BlockInfo info; + + info.prepare(this); + + COPY(bmats->layermat, info.basemats); + + for (int x = 0; x < 16; x++) + { + for (int y = 0; y < 16; y++) + { + using namespace df::enums::tiletype_material; + + auto tt = tiles->base_tiles[x][y]; + auto mat = info.getBaseMaterial(tt, df::coord2d(x,y)); + + bmats->mattype[x][y] = mat.mat_type; + bmats->matindex[x][y] = mat.mat_index; + + // Copy base info back to construction layer + if (tiles->con_info && !tiles->con_info->constructed.getassignment(x,y)) + { + tiles->con_info->mattype[x][y] = mat.mat_type; + tiles->con_info->matindex[x][y] = mat.mat_index; + } + } + } } bool MapExtras::Block::Write () @@ -454,10 +613,21 @@ bool MapExtras::Block::Write () block->flags.bits.designated = true; dirty_designations = false; } - if(dirty_tiletypes) + if(dirty_tiles && tiles) { - COPY(block->tiletype, rawtiles); - dirty_tiletypes = false; + dirty_tiles = false; + + for (int x = 0; x < 16; x++) + { + for (int y = 0; y < 16; y++) + { + if (tiles->dirty_raw.getassignment(x,y)) + block->tiletype[x][y] = tiles->raw_tiles[x][y]; + } + } + + delete tiles; tiles = NULL; + delete basemats; basemats = NULL; } if(dirty_temperatures) { @@ -473,65 +643,145 @@ bool MapExtras::Block::Write () return true; } -void MapExtras::Block::SquashVeins(df::map_block *mb, t_blockmaterials & materials) +void MapExtras::BlockInfo::prepare(Block *mblock) { - memset(materials,-1,sizeof(materials)); - std::vector veins; - Maps::SortBlockEvents(mb,&veins); - for (uint32_t x = 0;x<16;x++) for (uint32_t y = 0; y< 16;y++) + this->mblock = mblock; + + block = mblock->getRaw(); + parent = mblock->getParent(); + + SquashVeins(block,veinmats); + SquashGrass(block, grass); + + if (parent->validgeo) + SquashRocks(block,basemats,&parent->layer_mats); + else + memset(basemats,-1,sizeof(basemats)); + + for (size_t i = 0; i < block->plants.size(); i++) { - df::tiletype tt = mb->tiletype[x][y]; - if (tileMaterial(tt) == tiletype_material::MINERAL) + auto pp = block->plants[i]; + plants[pp->pos] = pp; + } + + global_feature = Maps::getGlobalInitFeature(block->global_feature); + local_feature = Maps::getLocalInitFeature(block->region_pos, block->local_feature); +} + +t_matpair MapExtras::BlockInfo::getBaseMaterial(df::tiletype tt, df::coord2d pos) +{ + using namespace df::enums::tiletype_material; + + t_matpair rv(0,-1); + int x = pos.x, y = pos.y; + + switch (tileMaterial(tt)) { + case CONSTRUCTION: // just a fallback + case SOIL: + case STONE: + rv.mat_index = basemats[x][y]; + break; + + case MINERAL: + rv.mat_index = veinmats[x][y]; + break; + + case LAVA_STONE: + if (auto details = parent->region_details[mblock->biomeRegionAt(pos)]) + rv.mat_index = details->lava_stone; + break; + + case PLANT: + rv.mat_type = MaterialInfo::PLANT_BASE; + if (auto plant = plants[block->map_pos + df::coord(x,y,0)]) { - for (size_t i = 0; i < veins.size(); i++) + if (auto raw = df::plant_raw::find(plant->material)) { - if (veins[i]->getassignment(x,y)) - materials[x][y] = veins[i]->inorganic_mat; + rv.mat_type = raw->material_defs.type_basic_mat; + rv.mat_index = raw->material_defs.idx_basic_mat; } } + break; + + case GRASS_LIGHT: + case GRASS_DARK: + case GRASS_DRY: + case GRASS_DEAD: + rv.mat_type = MaterialInfo::PLANT_BASE; + if (auto raw = df::plant_raw::find(grass[x][y])) + { + rv.mat_type = raw->material_defs.type_basic_mat; + rv.mat_index = raw->material_defs.idx_basic_mat; + } + break; + + case FEATURE: + { + auto dsgn = block->designation[x][y]; + + if (dsgn.bits.feature_local && local_feature) + local_feature->getMaterial(&rv.mat_type, &rv.mat_index); + else if (dsgn.bits.feature_global && global_feature) + global_feature->getMaterial(&rv.mat_type, &rv.mat_index); + + break; } + + case FROZEN_LIQUID: + case POOL: + case BROOK: + case RIVER: + rv.mat_type = builtin_mats::WATER; + break; + + case ASHES: + case FIRE: + case CAMPFIRE: + rv.mat_type = builtin_mats::ASH; + break; + + default: + rv.mat_type = -1; + } + + return rv; } -void MapExtras::Block::SquashFrozenLiquids(df::map_block *mb, tiletypes40d & frozen) +void MapExtras::BlockInfo::SquashVeins(df::map_block *mb, t_blockmaterials & materials) { - std::vector ices; - Maps::SortBlockEvents(mb,NULL,&ices); - for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++) + std::vector veins; + Maps::SortBlockEvents(mb,&veins); + memset(materials,-1,sizeof(materials)); + for (uint32_t x = 0;x<16;x++) for (uint32_t y = 0; y< 16;y++) { - df::tiletype tt = mb->tiletype[x][y]; - frozen[x][y] = tiletype::Void; - if (tileMaterial(tt) == tiletype_material::FROZEN_LIQUID) + for (size_t i = 0; i < veins.size(); i++) { - for (size_t i = 0; i < ices.size(); i++) - { - df::tiletype tt2 = ices[i]->tiles[x][y]; - if (tt2 != tiletype::Void) - { - frozen[x][y] = tt2; - break; - } - } + if (veins[i]->getassignment(x,y)) + materials[x][y] = veins[i]->inorganic_mat; } } } -void MapExtras::Block::SquashConstructions (df::map_block *mb, tiletypes40d & constructions) +void MapExtras::BlockInfo::SquashFrozenLiquids(df::map_block *mb, tiletypes40d & frozen) { + std::vector ices; + Maps::SortBlockEvents(mb,NULL,&ices); + memset(frozen,0,sizeof(frozen)); for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++) { - df::tiletype tt = mb->tiletype[x][y]; - constructions[x][y] = tiletype::Void; - if (tileMaterial(tt) == tiletype_material::CONSTRUCTION) + for (size_t i = 0; i < ices.size(); i++) { - DFCoord coord = mb->map_pos + df::coord(x,y,0); - df::construction *con = df::construction::find(coord); - if (con) - constructions[x][y] = con->original_tile; + df::tiletype tt2 = ices[i]->tiles[x][y]; + if (tt2 != tiletype::Void) + { + frozen[x][y] = tt2; + break; + } } } } -void MapExtras::Block::SquashRocks (df::map_block *mb, t_blockmaterials & materials, +void MapExtras::BlockInfo::SquashRocks (df::map_block *mb, t_blockmaterials & materials, std::vector< std::vector > * layerassign) { // get the layer materials @@ -547,6 +797,25 @@ void MapExtras::Block::SquashRocks (df::map_block *mb, t_blockmaterials & materi } } +void MapExtras::BlockInfo::SquashGrass(df::map_block *mb, t_blockmaterials &materials) +{ + std::vector grasses; + Maps::SortBlockEvents(mb, NULL, NULL, NULL, &grasses); + memset(materials,-1,sizeof(materials)); + for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++) + { + int amount = 0; + for (size_t i = 0; i < grasses.size(); i++) + { + if (grasses[i]->amount[x][y] >= amount) + { + amount = grasses[i]->amount[x][y]; + materials[x][y] = grasses[i]->plant_index; + } + } + } +} + df::coord2d MapExtras::Block::biomeRegionAt(df::coord2d p) { if (!block) @@ -662,6 +931,24 @@ bool MapExtras::Block::removeItemOnGround(df::item *item) return true; } +MapExtras::MapCache::MapCache() +{ + valid = 0; + Maps::getSize(x_bmax, y_bmax, z_max); + x_tmax = x_bmax*16; y_tmax = y_bmax*16; + validgeo = Maps::ReadGeology(&layer_mats, &geoidx); + valid = true; + + if (auto data = df::global::world->world_data) + { + for (size_t i = 0; i < data->region_details.size(); i++) + { + auto info = data->region_details[i]; + region_details[info->pos] = info; + } + } +} + MapExtras::Block *MapExtras::MapCache::BlockAt(DFCoord blockcoord) { if(!valid) @@ -685,6 +972,15 @@ MapExtras::Block *MapExtras::MapCache::BlockAt(DFCoord blockcoord) } } +void MapExtras::MapCache::resetTags() +{ + for (auto it = blocks.begin(); it != blocks.end(); ++it) + { + delete[] it->second->tags; + it->second->tags = NULL; + } +} + df::burrow *Maps::findBurrowByName(std::string name) { auto &vec = df::burrow::get_vector(); diff --git a/library/xml b/library/xml index a1e342afe..25c2a3dad 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit a1e342afe5a5e1e07672cd8b6553953bc251a05d +Subproject commit 25c2a3dad964abbcceb5abd41558b71fb113e83b diff --git a/plugins/dig.cpp b/plugins/dig.cpp index 64161a3aa..21c199102 100644 --- a/plugins/dig.cpp +++ b/plugins/dig.cpp @@ -1196,7 +1196,7 @@ command_result digl (color_ostream &out, vector & parameters) df::tile_designation des = MCache->designationAt(xy); df::tiletype tt = MCache->tiletypeAt(xy); int16_t veinmat = MCache->veinMaterialAt(xy); - int16_t basemat = MCache->baseMaterialAt(xy); + int16_t basemat = MCache->layerMaterialAt(xy); if( veinmat != -1 ) { con.printerr("This is a vein. Use vdig instead!\n"); @@ -1215,7 +1215,7 @@ command_result digl (color_ostream &out, vector & parameters) if (MCache->tagAt(current)) continue; int16_t vmat2 = MCache->veinMaterialAt(current); - int16_t bmat2 = MCache->baseMaterialAt(current); + int16_t bmat2 = MCache->layerMaterialAt(current); tt = MCache->tiletypeAt(current); if(!DFHack::isWallTerrain(tt)) @@ -1282,7 +1282,7 @@ command_result digl (color_ostream &out, vector & parameters) //below = 1; des_minus = MCache->designationAt(current-1); vmat_minus = MCache->veinMaterialAt(current-1); - bmat_minus = MCache->baseMaterialAt(current-1); + bmat_minus = MCache->layerMaterialAt(current-1); tt_minus = MCache->tiletypeAt(current-1); if ( tileMaterial(tt_minus)==tiletype_material::STONE || tileMaterial(tt_minus)==tiletype_material::SOIL) @@ -1293,7 +1293,7 @@ command_result digl (color_ostream &out, vector & parameters) //above = 1; des_plus = MCache->designationAt(current+1); vmat_plus = MCache->veinMaterialAt(current+1); - bmat_plus = MCache->baseMaterialAt(current+1); + bmat_plus = MCache->layerMaterialAt(current+1); tt_plus = MCache->tiletypeAt(current+1); if ( tileMaterial(tt_plus)==tiletype_material::STONE || tileMaterial(tt_plus)==tiletype_material::SOIL) diff --git a/plugins/mapexport/mapexport.cpp b/plugins/mapexport/mapexport.cpp index e0a7e5e69..592c526db 100644 --- a/plugins/mapexport/mapexport.cpp +++ b/plugins/mapexport/mapexport.cpp @@ -193,7 +193,7 @@ command_result mapexport (color_ostream &out, std::vector & parame prototile->set_flow_size(des.bits.flow_size); } - df::tiletype type = b->TileTypeAt(coord); + df::tiletype type = b->tiletypeAt(coord); prototile->set_type((dfproto::Tile::TileType)tileShape(type)); prototile->set_tile_material((dfproto::Tile::TileMaterialType)tileMaterial(type)); @@ -204,7 +204,7 @@ command_result mapexport (color_ostream &out, std::vector & parame case tiletype_material::SOIL: case tiletype_material::STONE: prototile->set_material_type(0); - prototile->set_material_index(b->baseMaterialAt(coord)); + prototile->set_material_index(b->layerMaterialAt(coord)); break; case tiletype_material::MINERAL: prototile->set_material_type(0); diff --git a/plugins/probe.cpp b/plugins/probe.cpp index 4e041f180..8240d91f3 100644 --- a/plugins/probe.cpp +++ b/plugins/probe.cpp @@ -103,6 +103,30 @@ command_result df_cprobe (color_ostream &out, vector & parameters) return CR_OK; } +void describeTile(color_ostream &out, df::tiletype tiletype) +{ + out.print("%d", tiletype); + if(tileName(tiletype)) + out.print(" = %s",tileName(tiletype)); + out.print("\n"); + + df::tiletype_shape shape = tileShape(tiletype); + df::tiletype_material material = tileMaterial(tiletype); + df::tiletype_special special = tileSpecial(tiletype); + df::tiletype_variant variant = tileVariant(tiletype); + out.print("%-10s: %4d %s\n","Class" ,shape, + ENUM_KEY_STR(tiletype_shape, shape).c_str()); + out.print("%-10s: %4d %s\n","Material" , + material, ENUM_KEY_STR(tiletype_material, material).c_str()); + out.print("%-10s: %4d %s\n","Special" , + special, ENUM_KEY_STR(tiletype_special, special).c_str()); + out.print("%-10s: %4d %s\n" ,"Variant" , + variant, ENUM_KEY_STR(tiletype_variant, variant).c_str()); + out.print("%-10s: %s\n" ,"Direction", + tileDirection(tiletype).getStr()); + out.print("\n"); +} + command_result df_probe (color_ostream &out, vector & parameters) { //bool showBlock, showDesig, showOccup, showTile, showMisc; @@ -186,26 +210,12 @@ command_result df_probe (color_ostream &out, vector & parameters) */ // tiletype - out.print("tiletype: %d", tiletype); - if(tileName(tiletype)) - out.print(" = %s",tileName(tiletype)); - out.print("\n"); - - df::tiletype_shape shape = tileShape(tiletype); - df::tiletype_material material = tileMaterial(tiletype); - df::tiletype_special special = tileSpecial(tiletype); - df::tiletype_variant variant = tileVariant(tiletype); - out.print("%-10s: %4d %s\n","Class" ,shape, - ENUM_KEY_STR(tiletype_shape, shape).c_str()); - out.print("%-10s: %4d %s\n","Material" , - material, ENUM_KEY_STR(tiletype_material, material).c_str()); - out.print("%-10s: %4d %s\n","Special" , - special, ENUM_KEY_STR(tiletype_special, special).c_str()); - out.print("%-10s: %4d %s\n" ,"Variant" , - variant, ENUM_KEY_STR(tiletype_variant, variant).c_str()); - out.print("%-10s: %s\n" ,"Direction", - tileDirection(tiletype).getStr()); - out.print("\n"); + out.print("tiletype: "); + describeTile(out, tiletype); + out.print("static: "); + describeTile(out, mc.staticTiletypeAt(cursor)); + out.print("base: "); + describeTile(out, mc.baseTiletypeAt(cursor)); out.print("temperature1: %d U\n",mc.temperature1At(cursor)); out.print("temperature2: %d U\n",mc.temperature2At(cursor)); @@ -214,7 +224,7 @@ command_result df_probe (color_ostream &out, vector & parameters) out << "biome: " << des.bits.biome << std::endl; out << "geolayer: " << des.bits.geolayer_index << std::endl; - int16_t base_rock = mc.baseMaterialAt(cursor); + int16_t base_rock = mc.layerMaterialAt(cursor); if(base_rock != -1) { out << "Layer material: " << dec << base_rock; @@ -238,6 +248,12 @@ command_result df_probe (color_ostream &out, vector & parameters) else out << endl; } + MaterialInfo minfo(mc.baseMaterialAt(cursor)); + if (minfo.isValid()) + out << "Base material: " << minfo.getToken() << " / " << minfo.toString() << endl; + minfo.decode(mc.staticMaterialAt(cursor)); + if (minfo.isValid()) + out << "Static material: " << minfo.getToken() << " / " << minfo.toString() << endl; // liquids if(des.bits.flow_size) { diff --git a/plugins/prospector.cpp b/plugins/prospector.cpp index c90a66c5a..e2f1e9534 100644 --- a/plugins/prospector.cpp +++ b/plugins/prospector.cpp @@ -474,7 +474,7 @@ command_result prospector (color_ostream &con, vector & parameters) liquidWater.add(global_z); } - df::tiletype type = b->TileTypeAt(coord); + df::tiletype type = b->tiletypeAt(coord); df::tiletype_shape tileshape = tileShape(type); df::tiletype_material tilemat = tileMaterial(type); @@ -506,7 +506,7 @@ command_result prospector (color_ostream &con, vector & parameters) { case tiletype_material::SOIL: case tiletype_material::STONE: - layerMats[b->baseMaterialAt(coord)].add(global_z); + layerMats[b->layerMaterialAt(coord)].add(global_z); break; case tiletype_material::MINERAL: veinMats[b->veinMaterialAt(coord)].add(global_z);