diff --git a/data/Memory-ng.xml b/data/Memory-ng.xml index a221f5c5a..a8cf7e6f3 100644 --- a/data/Memory-ng.xml +++ b/data/Memory-ng.xml @@ -730,6 +730,7 @@
+ @@ -1961,6 +1962,7 @@ + diff --git a/library/include/dfhack/modules/Maps.h b/library/include/dfhack/modules/Maps.h index 942219591..41f572c0e 100644 --- a/library/include/dfhack/modules/Maps.h +++ b/library/include/dfhack/modules/Maps.h @@ -7,6 +7,8 @@ #include "dfhack/DFExport.h" #include "dfhack/DFModule.h" +#include "Vegetation.h" + namespace DFHack { /*************************************************************************** @@ -431,7 +433,8 @@ namespace DFHack std::vector* splatter = 0, std::vector* grass = 0 ); - + /// read all plants in this block + bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector* plants); private: struct Private; Private *d; diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 1657b3498..d236cf623 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -59,6 +59,7 @@ struct Maps::Private bool Started; bool hasGeology; bool hasFeatures; + bool hasVeggies; // map between feature address and the read object map local_feature_store; @@ -76,7 +77,7 @@ Maps::Maps(DFContextShared* _d) DFHack::VersionInfo * mem = p->getDescriptor(); Server::Maps::maps_offsets &off = d->offsets; - d->hasFeatures = d->hasGeology = true; + d->hasFeatures = d->hasGeology = d->hasVeggies = true; // get the offsets once here OffsetGroup *OG_Maps = mem->getGroup("Maps"); @@ -127,6 +128,16 @@ Maps::Maps(DFContextShared* _d) { d->hasFeatures = false; } + try + { + OffsetGroup * OG_Veg = d->d->offset_descriptor->getGroup("Vegetation"); + off.vegvector = OG_MapBlock->getOffset ("vegetation_vector"); + off.tree_desc_offset = OG_Veg->getOffset ("tree_desc_offset"); + } + catch(Error::AllMemdef &) + { + d->hasVeggies = false; + } } d->OG_vector = mem->getGroup("vector"); @@ -901,3 +912,25 @@ bool Maps::ReadGlobalFeatures( std::vector & features) return true; } +bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector* plants) +{ + if(!d->hasVeggies || !d->Started) + return false; + uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z]; + if(!addr) + return false; + + t_tree shrubbery; + plants->clear(); + + Server::Maps::maps_offsets & off = d->offsets; + DfVector vegptrs(d->owner, addr + off.vegvector); + for(int i = 0; i < vegptrs.size(); i++) + { + d->owner->read (vegptrs[i] + off.tree_desc_offset, sizeof (t_tree), (uint8_t *) &shrubbery); + shrubbery.address = vegptrs[i]; + plants->push_back(shrubbery); + } + if(plants->empty()) return false; + return true; +} \ No newline at end of file diff --git a/library/shm/mod-maps.h b/library/shm/mod-maps.h index 46c8894eb..56c717b18 100644 --- a/library/shm/mod-maps.h +++ b/library/shm/mod-maps.h @@ -34,7 +34,7 @@ namespace DFHack namespace Maps { // increment on every change -#define MAPS_VERSION 4 +#define MAPS_VERSION 5 typedef struct { uint32_t map_offset;// = d->offset_descriptor->getAddress ("map_data"); @@ -49,6 +49,7 @@ typedef struct uint32_t occupancy_offset;// = d->offset_descriptor->getOffset ("occupancy"); uint32_t biome_stuffs;// = d->offset_descriptor->getOffset ("biome_stuffs"); uint32_t veinvector;// = d->offset_descriptor->getOffset ("v_vein"); + uint32_t vegvector; uint32_t temperature1_offset; uint32_t temperature2_offset; uint32_t global_feature_offset; @@ -73,6 +74,11 @@ typedef struct uint32_t world_size_y;// = minfo->getOffset ("world_size_y"); uint32_t geolayer_geoblock_offset;// = minfo->getOffset ("geolayer_geoblock_offset"); uint32_t type_inside_geolayer;// = mem->getOffset ("type_inside_geolayer"); + + /* + * Vegetation + */ + uint32_t tree_desc_offset; } maps_offsets; typedef struct diff --git a/tools/examples/treedump.cpp b/tools/examples/treedump.cpp index 410587173..793bb5966 100644 --- a/tools/examples/treedump.cpp +++ b/tools/examples/treedump.cpp @@ -12,6 +12,29 @@ using namespace std; #define DFHACK_WANT_MISCUTILS #include +void print_tree( DFHack::Context * DF , DFHack::t_tree & tree) +{ + DFHack::Materials * mat = DF->getMaterials(); + + printf("%d:%d = ",tree.type,tree.material); + if(tree.type == 1 || tree.type == 3) + { + cout << "near-water "; + } + cout << mat->organic[tree.material].id << " "; + if(tree.type == 0 || tree.type == 1) + { + cout << "tree"; + } + if(tree.type == 2 || tree.type == 3) + { + cout << "shrub"; + } + cout << endl; + printf("Address: 0x%x\n", tree.address); + hexdump(DF,tree.address,13); +} + int main (int numargs, const char ** args) { uint32_t addr; @@ -40,6 +63,7 @@ int main (int numargs, const char ** args) DFHack::VersionInfo* mem = DF->getMemoryInfo(); DFHack::Position * pos = DF->getPosition(); DFHack::Vegetation * v = DF->getVegetation(); + DFHack::Maps * mps = DF->getMaps(); DFHack::Materials * mat = DF->getMaterials(); mat->ReadOrganicMaterials(); @@ -60,30 +84,34 @@ int main (int numargs, const char ** args) } else { - cout << "----==== Tree at "<< x << "/" << y << "/" << z << " ====----" << endl; + // new method, gets the vector of trees in a block. can show farm plants + if(mps->Start()) + { + vector alltrees; + if(mps->ReadVegetation(x/16,y/16,z,&alltrees)) + { + for(int i = 0 ; i < alltrees.size(); i++) + { + DFHack::t_tree & tree = alltrees[i]; + // you could take the tree coords from the struct and % them with 16 for use in loops over the whole block + if(tree.x == x && tree.y == y && tree.z == z) + { + cout << "----==== Tree at "<< x << "/" << y << "/" << z << " ====----" << endl; + print_tree(DF, tree); + break; + } + } + } + } + // old method, gets the tree from the global vegetation vector. can't show farm plants for(uint32_t i =0; i < numVegs; i++) { DFHack::t_tree tree; v->Read(i,tree); if(tree.x == x && tree.y == y && tree.z == z) { - printf("%d:%d = ",tree.type,tree.material); - if(tree.type == 1 || tree.type == 3) - { - cout << "near-water "; - } - cout << mat->organic[tree.material].id << " "; - if(tree.type == 0 || tree.type == 1) - { - cout << "tree"; - } - if(tree.type == 2 || tree.type == 3) - { - cout << "shrub"; - } - cout << endl; - printf("Address: 0x%x\n", tree.address); - hexdump(DF,tree.address,13); + cout << "----==== Tree at "<< x << "/" << y << "/" << z << " ====----" << endl; + print_tree(DF, tree); break; } }