diff --git a/library/include/dfhack/DFTileTypes.h b/library/include/dfhack/DFTileTypes.h index b7fd9d865..37fd78cf1 100644 --- a/library/include/dfhack/DFTileTypes.h +++ b/library/include/dfhack/DFTileTypes.h @@ -655,10 +655,10 @@ namespace DFHack MAPTILE_FEATSTONE_WALL_WORN2, MAPTILE_FEATSTONE_WALL_WORN3, MAPTILE_FEATSTONE_WALL,*/ - {"cracked featstone wall",WALL,STONE,VAR_1, TILE_CRACKED }, - {"damaged featstone wall",WALL,STONE,VAR_1, TILE_DAMAGED }, - {"worn featstone wall",WALL,STONE,VAR_1, TILE_WORN }, - {"featstone wall",WALL,STONE,VAR_1}, + {"cracked featstone wall",WALL,FEATSTONE,VAR_1, TILE_CRACKED }, + {"damaged featstone wall",WALL,FEATSTONE,VAR_1, TILE_DAMAGED }, + {"worn featstone wall",WALL,FEATSTONE,VAR_1, TILE_WORN }, + {"featstone wall",WALL,FEATSTONE,VAR_1}, {"stone floor",FLOOR,STONE,VAR_1}, {"stone floor",FLOOR,STONE,VAR_2}, {"stone floor",FLOOR,STONE,VAR_3}, @@ -992,6 +992,7 @@ namespace DFHack } return -1; } + /* //Convenience version of the above, to pass strings as the direction inline int32_t findTileType( const TileClass tclass, const TileMaterial tmat, const TileVariant tvar, const TileSpecial tspecial, const char *tdirStr ) @@ -1003,7 +1004,7 @@ namespace DFHack return findTileType(tclass,tmat,tvar,tspecial, 0 ); } } - +*/ //zilpin: Find a tile type similar to the one given, but with a different class. //Useful for tile-editing operations. diff --git a/library/include/dfhack/modules/Maps.h b/library/include/dfhack/modules/Maps.h index 857b9c274..cfbec42e4 100644 --- a/library/include/dfhack/modules/Maps.h +++ b/library/include/dfhack/modules/Maps.h @@ -527,13 +527,38 @@ namespace DFHack @endcode */ bool ReadGeology( std::vector < std::vector >& assign ); - std::vector global_features; - // map between feature address and the read object - std::map local_feature_store; - // map between mangled coords and pointer to feature + /** + * Initialize the map feature caches, if possible + */ + bool StartFeatures(); + /** + * Get a global feature with the given index. + */ + t_feature * GetGlobalFeature(int16_t index); + /** + * Get all valid local features for a x/y block coord. + */ + std::vector * GetLocalFeatures(DFCoord coord); + /** + * Get the feature indexes of a block + */ + bool ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int16_t & global); + /** + * Get pointers to features of a block + */ + bool ReadFeatures(uint32_t x, uint32_t y, uint32_t z, t_feature ** local, t_feature ** global); + /** + * @deprecated + * @todo: remove + */ bool ReadGlobalFeatures( std::vector & features); + /** + * @deprecated + * @todo: remove + */ bool ReadLocalFeatures( std::map > & local_features ); + /* * BLOCK DATA */ @@ -577,10 +602,10 @@ namespace DFHack /// read/write the block flags bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags &blockflags); bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags blockflags); + /// read/write features - bool ReadFeatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t & local, int16_t & global); - bool WriteLocalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1); - bool WriteGlobalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1); + bool SetBlockLocalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1); + bool SetBlockGlobalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1); /// read region offsets of a block - used for determining layer stone matgloss bool ReadRegionOffsets(uint32_t blockx, uint32_t blocky, uint32_t blockz, diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 631ea86d7..79280bdf8 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -128,6 +128,7 @@ struct Maps::Private Process * owner; OffsetGroup *OG_vector; bool Inited; + bool FeaturesStarted; bool Started; bool hasGeology; bool hasFeatures; @@ -139,6 +140,8 @@ struct Maps::Private // map between feature address and the read object map local_feature_store; + map > m_local_feature; + vector v_global_feature; vector v_geology[eBiomeCount]; }; @@ -148,7 +151,7 @@ Maps::Maps(DFContextShared* _d) d = new Private; d->d = _d; Process *p = d->owner = _d->p; - d->Inited = d->Started = false; + d->Inited = d->FeaturesStarted = d->Started = false; d->block = NULL; d->usesWorldDataPtr = false; @@ -350,10 +353,15 @@ void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z) z = d->z_block_count; } -// invalidates local and global features! bool Maps::Finish() { - d->local_feature_store.clear(); + if(d->FeaturesStarted) + { + d->local_feature_store.clear(); + d->v_global_feature.clear(); + d->m_local_feature.clear(); + d->FeaturesStarted = false; + } if (d->block != NULL) { delete [] d->block; @@ -597,6 +605,166 @@ bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices4 return false; } +bool Maps::StartFeatures() +{ + MAPS_GUARD + if(d->FeaturesStarted) return true; + if(!d->hasFeatures) return false; + // can't be used without a map! + if(!d->block) + return false; + + Process * p = d->owner; + Private::t_offsets &off = d->offsets; + uint32_t base = 0; + uint32_t global_feature_vector = 0; + + if(d->usesWorldDataPtr) + { + uint32_t world = p->readDWord(off.world_data); + if(!world) return false; + base = p->readDWord(world + off.local_f_start); + global_feature_vector = p->readDWord(off.world_data) + off.global_vector; + } + else + { + base = p->readDWord(off.local_f_start); + global_feature_vector = off.global_vector; + } + + // deref pointer to the humongo-structure + if(!base) + return false; + const uint32_t sizeof_vec = d->OG_vector->getHexValue("sizeof"); + const uint32_t sizeof_elem = 16; + const uint32_t offset_elem = 4; + const uint32_t loc_main_mat_offset = off.local_material; + const uint32_t loc_sub_mat_offset = off.local_submaterial; + + for(uint32_t blockX = 0; blockX < d->x_block_count; blockX ++) + for(uint32_t blockY = 0; blockY < d->x_block_count; blockY ++) + { + // region X coord (48x48 tiles) + uint16_t region_x_local = ( (blockX / 3) + d->regionX ) / 16; + // region Y coord (48x48 tiles) + uint64_t region_y_local = ( (blockY / 3) + d->regionY ) / 16; + + // this is just a few pointers to arrays of 16B (4 DWORD) structs + uint32_t array_elem = p->readDWord(base + (region_x_local / 16) * 4); + + // 16B structs, second DWORD of the struct is a pointer + uint32_t wtf = p->readDWord(array_elem + ( sizeof_elem * ( (uint32_t)region_y_local/16)) + offset_elem); + if(wtf) + { + // wtf + sizeof(vector) * crap; + uint32_t feat_vector = wtf + sizeof_vec * (16 * (region_x_local % 16) + (region_y_local % 16)); + DfVector p_features(p, feat_vector); + uint32_t size = p_features.size(); + DFCoord pc(blockX,blockY); + std::vector tempvec; + for(uint32_t i = 0; i < size; i++) + { + uint32_t cur_ptr = p_features[i]; + + map ::iterator it; + it = d->local_feature_store.find(cur_ptr); + // do we already have the feature? + if(it != d->local_feature_store.end()) + { + // push pointer to existing feature + tempvec.push_back(&((*it).second)); + } + // no? + else + { + // create, add to store + t_feature tftemp; + tftemp.discovered = false; //= p->readDWord(cur_ptr + 4); + tftemp.origin = cur_ptr; + string name = p->readClassName(p->readDWord( cur_ptr )); + if(name == "feature_init_deep_special_tubest") + { + tftemp.main_material = p->readWord( cur_ptr + loc_main_mat_offset ); + tftemp.sub_material = p->readDWord( cur_ptr + loc_sub_mat_offset ); + tftemp.type = feature_Adamantine_Tube; + } + else if(name == "feature_init_deep_surface_portalst") + { + tftemp.main_material = p->readWord( cur_ptr + loc_main_mat_offset ); + tftemp.sub_material = p->readDWord( cur_ptr + loc_sub_mat_offset ); + tftemp.type = feature_Hell_Temple; + } + else + { + tftemp.main_material = -1; + tftemp.sub_material = -1; + tftemp.type = feature_Other; + } + d->local_feature_store[cur_ptr] = tftemp; + // push pointer + tempvec.push_back(&(d->local_feature_store[cur_ptr])); + } + } + d->m_local_feature[pc] = tempvec; + } + } + // deref pointer to the humongo-structure + const uint32_t global_feature_funcptr = off.global_funcptr; + const uint32_t glob_main_mat_offset = off.global_material; + const uint32_t glob_sub_mat_offset = off.global_submaterial; + DfVector p_features (p,global_feature_vector); + + d->v_global_feature.clear(); + uint32_t size = p_features.size(); + d->v_global_feature.reserve(size); + for(uint32_t i = 0; i < size; i++) + { + t_feature temp; + uint32_t feat_ptr = p->readDWord(p_features[i] + global_feature_funcptr ); + temp.origin = feat_ptr; + //temp.discovered = p->readDWord( feat_ptr + 4 ); // maybe, placeholder + temp.discovered = false; + + // FIXME: use the memory_info cache mechanisms + string name = p->readClassName(p->readDWord( feat_ptr)); + if(name == "feature_init_underworld_from_layerst") + { + temp.main_material = p->readWord( feat_ptr + glob_main_mat_offset ); + temp.sub_material = p->readDWord( feat_ptr + glob_sub_mat_offset ); + temp.type = feature_Underworld; + } + else + { + temp.main_material = -1; + temp.sub_material = -1; + temp.type = feature_Other; + } + d->v_global_feature.push_back(temp); + } + d->FeaturesStarted = true; + return true; +} + +t_feature * Maps::GetGlobalFeature(int16_t index) +{ + if(!d->FeaturesStarted) return 0; + if(index < 0 || index >= d->v_global_feature.size()) + return 0; + return &(d->v_global_feature[index]); +} + +std::vector * Maps::GetLocalFeatures(DFCoord coord) +{ + if(!d->FeaturesStarted) return 0; + coord.z = 0; // just making sure + map >::iterator iter = d->m_local_feature.find(coord); + if(iter != d->m_local_feature.end()) + { + return &((*iter).second); + } + return 0; +} + bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int16_t & global) { MAPS_GUARD @@ -611,7 +779,36 @@ bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int return false; } -bool Maps::WriteLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local) +bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, t_feature ** local, t_feature ** global) +{ + if(!d->FeaturesStarted) return false; + int16_t loc, glob; + if(ReadFeatures(x,y,z,loc,glob)) + { + if(glob != -1) + *global = &(d->v_global_feature[glob]); + else + *global = 0; + if(loc != -1) + { + DFCoord foo(x,y,0); + map >::iterator iter = d->m_local_feature.find(foo); + if(iter != d->m_local_feature.end()) + { + *local = ((*iter).second)[loc]; + } + else *local = 0; + } + else + *local = 0; + return true; + } + *local = 0; + *global = 0; + return false; +} + +bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local) { MAPS_GUARD uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; @@ -624,7 +821,7 @@ bool Maps::WriteLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local) return false; } -bool Maps::WriteGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global) +bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global) { MAPS_GUARD uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; @@ -895,159 +1092,26 @@ bool Maps::ReadGeology (vector < vector >& assign) bool Maps::ReadLocalFeatures( std::map > & local_features ) { - MAPS_GUARD - if(!d->hasFeatures) return false; - // can't be used without a map! - if(!d->block) - return false; - - Process * p = d->owner; - Private::t_offsets &off = d->offsets; - uint32_t base = 0; - if(d->usesWorldDataPtr) - { - uint32_t world = p->readDWord(off.world_data); - if(!world) return false; - base = p->readDWord(world + off.local_f_start); - } - else - { - base = p->readDWord(off.local_f_start); - } - // deref pointer to the humongo-structure - if(!base) - return false; - const uint32_t sizeof_vec = d->OG_vector->getHexValue("sizeof"); - const uint32_t sizeof_elem = 16; - const uint32_t offset_elem = 4; - const uint32_t main_mat_offset = off.local_material; - const uint32_t sub_mat_offset = off.local_submaterial; - - local_features.clear(); - - for(uint32_t blockX = 0; blockX < d->x_block_count; blockX ++) - for(uint32_t blockY = 0; blockY < d->x_block_count; blockY ++) + if(!d->FeaturesStarted) + StartFeatures(); + if(d->FeaturesStarted) { - // region X coord (48x48 tiles) - uint16_t region_x_local = ( (blockX / 3) + d->regionX ) / 16; - // region Y coord (48x48 tiles) - uint64_t region_y_local = ( (blockY / 3) + d->regionY ) / 16; - - // this is just a few pointers to arrays of 16B (4 DWORD) structs - uint32_t array_elem = p->readDWord(base + (region_x_local / 16) * 4); - - // 16B structs, second DWORD of the struct is a pointer - uint32_t wtf = p->readDWord(array_elem + ( sizeof_elem * ( (uint32_t)region_y_local/16)) + offset_elem); - if(wtf) - { - // wtf + sizeof(vector) * crap; - uint32_t feat_vector = wtf + sizeof_vec * (16 * (region_x_local % 16) + (region_y_local % 16)); - DfVector p_features(p, feat_vector); - uint32_t size = p_features.size(); - DFCoord pc(blockX,blockY); - std::vector tempvec; - for(uint32_t i = 0; i < size; i++) - { - uint32_t cur_ptr = p_features[i]; - - map ::iterator it; - it = d->local_feature_store.find(cur_ptr); - // do we already have the feature? - if(it != d->local_feature_store.end()) - { - // push pointer to existing feature - tempvec.push_back(&((*it).second)); - } - // no? - else - { - // create, add to store - t_feature tftemp; - tftemp.discovered = false; //= p->readDWord(cur_ptr + 4); - tftemp.origin = cur_ptr; - string name = p->readClassName(p->readDWord( cur_ptr )); - if(name == "feature_init_deep_special_tubest") - { - tftemp.main_material = p->readWord( cur_ptr + main_mat_offset ); - tftemp.sub_material = p->readDWord( cur_ptr + sub_mat_offset ); - tftemp.type = feature_Adamantine_Tube; - } - else if(name == "feature_init_deep_surface_portalst") - { - tftemp.main_material = p->readWord( cur_ptr + main_mat_offset ); - tftemp.sub_material = p->readDWord( cur_ptr + sub_mat_offset ); - tftemp.type = feature_Hell_Temple; - } - else - { - tftemp.main_material = -1; - tftemp.sub_material = -1; - tftemp.type = feature_Other; - } - d->local_feature_store[cur_ptr] = tftemp; - // push pointer - tempvec.push_back(&(d->local_feature_store[cur_ptr])); - } - } - local_features[pc] = tempvec; - } + local_features = d->m_local_feature; + return true; } - return true; + return false; } bool Maps::ReadGlobalFeatures( std::vector & features) { - MAPS_GUARD - if(!d->hasFeatures) return false; - // can't be used without a map! - if(!d->block) - return false; - - Process * p = d->owner; - Private::t_offsets &off = d->offsets; - uint32_t global_feature_vector; - if(d->usesWorldDataPtr) + if(!d->FeaturesStarted) + StartFeatures(); + if(d->FeaturesStarted) { - global_feature_vector = p->readDWord(off.world_data) + off.global_vector; - } - else - { - global_feature_vector = off.global_vector; - } - // deref pointer to the humongo-structure - const uint32_t global_feature_funcptr = off.global_funcptr; - const uint32_t main_mat_offset = off.global_material; - const uint32_t sub_mat_offset = off.global_submaterial; - DfVector p_features (p,global_feature_vector); - - features.clear(); - uint32_t size = p_features.size(); - features.reserve(size); - for(uint32_t i = 0; i < size; i++) - { - t_feature temp; - uint32_t feat_ptr = p->readDWord(p_features[i] + global_feature_funcptr ); - temp.origin = feat_ptr; - //temp.discovered = p->readDWord( feat_ptr + 4 ); // maybe, placeholder - temp.discovered = false; - - // FIXME: use the memory_info cache mechanisms - string name = p->readClassName(p->readDWord( feat_ptr)); - if(name == "feature_init_underworld_from_layerst") - { - temp.main_material = p->readWord( feat_ptr + main_mat_offset ); - temp.sub_material = p->readDWord( feat_ptr + sub_mat_offset ); - temp.type = feature_Underworld; - } - else - { - temp.main_material = -1; - temp.sub_material = -1; - temp.type = feature_Other; - } - features.push_back(temp); + features = d->v_global_feature; + return true; } - return true; + return false; } bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector* plants) diff --git a/library/modules/Maps_C.cpp b/library/modules/Maps_C.cpp index 1e0239aed..67e4ed355 100644 --- a/library/modules/Maps_C.cpp +++ b/library/modules/Maps_C.cpp @@ -335,7 +335,7 @@ int Maps_WriteLocalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t { if(maps != NULL) { - return ((DFHack::Maps*)maps)->WriteLocalFeature(x, y, z, local); + return ((DFHack::Maps*)maps)->SetBlockLocalFeature(x, y, z, local); } return -1; @@ -345,7 +345,7 @@ int Maps_WriteEmptyLocalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint { if(maps != NULL) { - return ((DFHack::Maps*)maps)->WriteLocalFeature(x, y, z, -1); + return ((DFHack::Maps*)maps)->SetBlockLocalFeature(x, y, z, -1); } return -1; @@ -355,7 +355,7 @@ int Maps_WriteGlobalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t { if(maps != NULL) { - return ((DFHack::Maps*)maps)->WriteGlobalFeature(x, y, z, local); + return ((DFHack::Maps*)maps)->SetBlockGlobalFeature(x, y, z, local); } return -1; @@ -365,7 +365,7 @@ int Maps_WriteEmptyGlobalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uin { if(maps != NULL) { - return ((DFHack::Maps*)maps)->WriteGlobalFeature(x, y, z, -1); + return ((DFHack::Maps*)maps)->SetBlockGlobalFeature(x, y, z, -1); } return -1; diff --git a/tools/supported/CMakeLists.txt b/tools/supported/CMakeLists.txt index 78c094680..ee18953e7 100644 --- a/tools/supported/CMakeLists.txt +++ b/tools/supported/CMakeLists.txt @@ -74,6 +74,9 @@ DFHACK_TOOL(dfdoffsets dumpoffsets.cpp) # change the weather DFHACK_TOOL(dfweather weather.cpp) +# refill adamantine veins +DFHACK_TOOL(dftubefill dftubefill.cpp) + # deramp # Author: zilpin # seeks entire map for 'remove ramp' designation, makes a floor, removes designation.