From 0b32d374db8a58547d554d758e4e77ad850f54c5 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Thu, 19 Apr 2012 23:02:30 +0400 Subject: [PATCH] Implement SOIL/STONE substitution logic, and add compat in mapexport. --- library/include/modules/MapCache.h | 5 ++ library/modules/Maps.cpp | 81 ++++++++++++++++++++++++++++-- plugins/mapexport/mapexport.cpp | 44 +++++++++++++++- 3 files changed, 123 insertions(+), 7 deletions(-) diff --git a/library/include/modules/MapCache.h b/library/include/modules/MapCache.h index 4ddf0c984..0b4e78b21 100644 --- a/library/include/modules/MapCache.h +++ b/library/include/modules/MapCache.h @@ -262,10 +262,13 @@ public: private: friend class MapCache; + friend class BlockInfo; MapCache *parent; df::map_block *block; + int biomeIndexAt(df::coord2d p); + bool valid; bool dirty_designations:1; bool dirty_tiles:1; @@ -521,6 +524,8 @@ private: uint32_t y_tmax; uint32_t z_max; std::vector geoidx; + std::vector default_soil; + std::vector default_stone; std::vector< std::vector > layer_mats; std::map region_details; std::map blocks; diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 06e525fea..e130915d6 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -676,11 +676,42 @@ t_matpair MapExtras::BlockInfo::getBaseMaterial(df::tiletype tt, df::coord2d pos int x = pos.x, y = pos.y; switch (tileMaterial(tt)) { - case CONSTRUCTION: // just a fallback + case DRIFTWOOD: case SOIL: + { + rv.mat_index = basemats[x][y]; + + if (auto raw = df::inorganic_raw::find(rv.mat_index)) + { + if (raw->flags.is_set(inorganic_flags::SOIL_ANY)) + break; + + int biome = mblock->biomeIndexAt(pos); + int idx = vector_get(parent->default_soil, biome, -1); + if (idx >= 0) + rv.mat_index = idx; + } + + break; + } + case STONE: + { rv.mat_index = basemats[x][y]; + + if (auto raw = df::inorganic_raw::find(rv.mat_index)) + { + if (!raw->flags.is_set(inorganic_flags::SOIL_ANY)) + break; + + int biome = mblock->biomeIndexAt(pos); + int idx = vector_get(parent->default_stone, biome, -1); + if (idx >= 0) + rv.mat_index = idx; + } + break; + } case MINERAL: rv.mat_index = veinmats[x][y]; @@ -727,11 +758,17 @@ t_matpair MapExtras::BlockInfo::getBaseMaterial(df::tiletype tt, df::coord2d pos break; } + case CONSTRUCTION: // just a fallback + break; + case FROZEN_LIQUID: + rv.mat_type = builtin_mats::WATER; + break; + case POOL: case BROOK: case RIVER: - rv.mat_type = builtin_mats::WATER; + rv.mat_index = basemats[x][y]; break; case ASHES: @@ -816,18 +853,30 @@ void MapExtras::BlockInfo::SquashGrass(df::map_block *mb, t_blockmaterials &mate } } -df::coord2d MapExtras::Block::biomeRegionAt(df::coord2d p) +int MapExtras::Block::biomeIndexAt(df::coord2d p) { if (!block) - return df::coord2d(-30000,-30000); + return -1; auto des = index_tile(designation,p); uint8_t idx = des.bits.biome; if (idx >= 9) - return block->region_pos; + return -1; idx = block->region_offset[idx]; if (idx >= parent->geoidx.size()) + return -1; + return idx; +} + +df::coord2d MapExtras::Block::biomeRegionAt(df::coord2d p) +{ + if (!block) + return df::coord2d(-30000,-30000); + + int idx = biomeIndexAt(p); + if (idx < 0) return block->region_pos; + return parent->geoidx[idx]; } @@ -947,6 +996,28 @@ MapExtras::MapCache::MapCache() region_details[info->pos] = info; } } + + default_soil.resize(layer_mats.size()); + default_stone.resize(layer_mats.size()); + + for (size_t i = 0; i < layer_mats.size(); i++) + { + default_soil[i] = -1; + default_stone[i] = -1; + + for (size_t j = 0; j < layer_mats[i].size(); j++) + { + auto raw = df::inorganic_raw::find(layer_mats[i][j]); + if (!raw) + continue; + + bool is_soil = raw->flags.is_set(inorganic_flags::SOIL_ANY); + if (is_soil) + default_soil[i] = layer_mats[i][j]; + else if (default_stone[i] == -1) + default_stone[i] = layer_mats[i][j]; + } + } } MapExtras::Block *MapExtras::MapCache::BlockAt(DFCoord blockcoord) diff --git a/plugins/mapexport/mapexport.cpp b/plugins/mapexport/mapexport.cpp index 592c526db..fa1736ed7 100644 --- a/plugins/mapexport/mapexport.cpp +++ b/plugins/mapexport/mapexport.cpp @@ -2,7 +2,7 @@ #include "Console.h" #include "Export.h" #include "PluginManager.h" -#include "modules/MapCache.h" +#include "modules/MapCache.h"f using namespace DFHack; #include @@ -39,6 +39,46 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out ) return CR_OK; } +static dfproto::Tile::TileMaterialType toProto(df::tiletype_material mat) +{ + /* + * This is surely ugly, but casting enums without officially + * defined numerical values to protobuf enums is against the + * way protobufs are supposed to be used, because it defeats + * the backward compatible nature of the protocols. + */ + switch (mat) + { +#define CONVERT(name) case tiletype_material::name: return dfproto::Tile::name; + CONVERT(AIR) + case tiletype_material::PLANT: + CONVERT(SOIL) + CONVERT(STONE) + CONVERT(FEATURE) + CONVERT(LAVA_STONE) + CONVERT(MINERAL) + CONVERT(FROZEN_LIQUID) + CONVERT(CONSTRUCTION) + CONVERT(GRASS_LIGHT) + CONVERT(GRASS_DARK) + CONVERT(GRASS_DRY) + CONVERT(GRASS_DEAD) + CONVERT(HFS) + CONVERT(CAMPFIRE) + CONVERT(FIRE) + CONVERT(ASHES) + case tiletype_material::MAGMA: + return dfproto::Tile::MAGMA_TYPE; + CONVERT(DRIFTWOOD) + CONVERT(POOL) + CONVERT(BROOK) + CONVERT(RIVER) +#undef CONVERT + default: + return dfproto::Tile::AIR; + } +} + command_result mapexport (color_ostream &out, std::vector & parameters) { bool showHidden = false; @@ -195,7 +235,7 @@ command_result mapexport (color_ostream &out, std::vector & parame df::tiletype type = b->tiletypeAt(coord); prototile->set_type((dfproto::Tile::TileType)tileShape(type)); - prototile->set_tile_material((dfproto::Tile::TileMaterialType)tileMaterial(type)); + prototile->set_tile_material(toProto(tileMaterial(type))); df::coord map_pos = df::coord(b_x*16+x,b_y*16+y,z);