diff --git a/library/include/dfhack/extra/MapExtras.h b/library/include/dfhack/extra/MapExtras.h index f8a954fbf..d0ea3597c 100644 --- a/library/include/dfhack/extra/MapExtras.h +++ b/library/include/dfhack/extra/MapExtras.h @@ -36,7 +36,7 @@ void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d & { memset(materials,-1,sizeof(materials)); std::vector veins; - m->ReadVeins(bcoord.x,bcoord.y,bcoord.z,&veins); + m->SortBlockEvents(bcoord.x,bcoord.y,bcoord.z,&veins); //iterate through block rows for(uint32_t j = 0;j<16;j++) { diff --git a/library/include/dfhack/modules/Maps.h b/library/include/dfhack/modules/Maps.h index dd214b77e..ba4c44ad3 100644 --- a/library/include/dfhack/modules/Maps.h +++ b/library/include/dfhack/modules/Maps.h @@ -710,58 +710,56 @@ namespace DFHack void getPosition(int32_t& x, int32_t& y, int32_t& z); /** - * Return false/0 on failure, buffer allocated by client app, 256 items long + * Get the map block or NULL if block is not valid */ - bool isValidBlock(uint32_t blockx, uint32_t blocky, uint32_t blockz); + df_block * getBlock (uint32_t blockx, uint32_t blocky, uint32_t blockz); - /** - * Get the address of a block or 0 if block is not valid - */ - df_block * getBlockPtr (uint32_t blockx, uint32_t blocky, uint32_t blockz); - - /// read the whole map block at block coords (see DFTypes.h for the block structure) + /// copy the whole map block at block coords (see DFTypes.h for the block structure) bool ReadBlock40d(uint32_t blockx, uint32_t blocky, uint32_t blockz, mapblock40d * buffer); - /// read/write block tile types + /// copy/write block tile types bool ReadTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, tiletypes40d *buffer); bool WriteTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, tiletypes40d *buffer); - /// read/write block designations + /// copy/write block designations bool ReadDesignations(uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer); bool WriteDesignations (uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer); - /// read/write temperatures + /// copy/write temperatures bool ReadTemperatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2); bool WriteTemperatures (uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2); - /// read/write block occupancies + /// copy/write block occupancies bool ReadOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer); bool WriteOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer); - /// read/write the block dirty bit - this is used to mark a map block so that DF scans it for designated jobs like digging + /// copy/write the block dirty bit - this is used to mark a map block so that DF scans it for designated jobs like digging bool ReadDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool &dirtybit); bool WriteDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool dirtybit); - /// read/write the block flags + /// copy/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 + /// copy/write features 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 + /// copy region offsets of a block - used for determining layer stone matgloss bool ReadRegionOffsets(uint32_t blockx, uint32_t blocky, uint32_t blockz, biome_indices40d *buffer); - /// block event reading - mineral veins, what's under ice, blood smears and mud - bool ReadVeins(uint32_t x, uint32_t y, uint32_t z, + /// sorts the block event vector into multiple vectors by type + /// mineral veins, what's under ice, blood smears and mud + bool SortBlockEvents(uint32_t x, uint32_t y, uint32_t z, std::vector* veins, std::vector* ices = 0, std::vector* splatter = 0, std::vector* grass = 0, std::vector* constructions = 0 ); + /// remove a block event from the block by address + bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, t_virtual * which ); /// read all plants in this block bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector*& plants); private: diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index a13f0b4c0..e306eacd4 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -30,6 +30,7 @@ distribution. #include #include #include +#include using namespace std; #include "dfhack/modules/Maps.h" @@ -269,35 +270,11 @@ bool Maps::Finish() * Block reading */ -bool Maps::isValidBlock (uint32_t x, uint32_t y, uint32_t z) -{ - MAPS_GUARD - if(x >= mdata->x_size_blocks || y >= mdata->y_size_blocks || z >= mdata->z_size_blocks) - return false; - return mdata->map[x][y][z] != 0; -} - -df_block* Maps::getBlockPtr (uint32_t x, uint32_t y, uint32_t z) +df_block* Maps::getBlock (uint32_t x, uint32_t y, uint32_t z) { MAPS_GUARD if(x >= mdata->x_size_blocks || y >= mdata->y_size_blocks || z >= mdata->z_size_blocks) return 0; - /* - cerr << hex; - cerr << "Map data address = " << mdata << endl; - cerr << "3D = " << &mdata->map << endl; - cerr << "3D array start = " << mdata->map.array << endl; - */ - df_2darray & arr2d = mdata->map[x];//[y][z]; - df_array & arr = arr2d[y]; - /*df_block * b= arr[z]; - cerr << "2D address = " << &arr2d << endl; - cerr << "2D array start = " << arr2d.array << endl; - cerr << "1D address = " << &arr << endl; - cerr << "1D array start = " << arr.array << endl; - cerr << "block address = " << b << endl; - cerr << "-----------------------------" << endl; - cerr << dec << flush;*/ return mdata->map[x][y][z]; } @@ -305,31 +282,17 @@ bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer { MAPS_GUARD Process *p = d->owner; - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { buffer->position = DFCoord(x,y,z); - - //p->read (addr + d->offsets.tile_type_offset, sizeof (buffer->tiletypes), (uint8_t *) buffer->tiletypes); memcpy(buffer->tiletypes,block->tiletype, sizeof(tiletypes40d)); - - //p->read (addr + d->offsets.designation_offset, sizeof (buffer->designation), (uint8_t *) buffer->designation); memcpy(buffer->designation,block->designation, sizeof(designations40d)); - - //p->read (addr + d->offsets.occupancy_offset, sizeof (buffer->occupancy), (uint8_t *) buffer->occupancy); memcpy(buffer->occupancy,block->occupancy, sizeof(occupancies40d)); - - //p->read (addr + d->offsets.biome_stuffs, sizeof (biome_indices40d), (uint8_t *) buffer->biome_indices); memcpy(buffer->biome_indices,block->region_offset, sizeof(block->region_offset)); - buffer->global_feature = block->global_feature; buffer->local_feature = block->local_feature; buffer->mystery = block->mystery; - /* - p->readWord(addr + d->offsets.global_feature_offset, (uint16_t&) buffer->global_feature); - p->readWord(addr + d->offsets.local_feature_offset, (uint16_t&)buffer->local_feature); - p->readDWord(addr + d->offsets.mystery, (uint32_t&)buffer->mystery); - */ // FIXME: not 64-bit safe buffer->origin = (uint32_t) █ //uint32_t addr_of_struct = p->readDWord(addr); @@ -346,7 +309,7 @@ bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { memcpy(buffer, block->tiletype, sizeof(tiletypes40d)); @@ -358,7 +321,7 @@ bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buff bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { memcpy(block->tiletype, buffer, sizeof(tiletypes40d)); @@ -375,7 +338,7 @@ bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buf bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { if(!block->flagarray) @@ -389,7 +352,7 @@ bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit) bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { if(!block->flagarray) @@ -408,7 +371,7 @@ bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit) bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &blockflags) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { if(!block->flagarray) @@ -422,7 +385,7 @@ bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &bloc bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { if(!block->flagarray) @@ -440,7 +403,7 @@ bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags bloc bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { memcpy(buffer, block->designation, sizeof(designations40d)); @@ -452,7 +415,7 @@ bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { memcpy(block->designation, buffer, sizeof(designations40d)); @@ -467,7 +430,7 @@ bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40 bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { memcpy(buffer, block->occupancy, sizeof(occupancies40d)); @@ -479,7 +442,7 @@ bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *bu bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { memcpy(block->occupancy, buffer, sizeof(occupancies40d)); @@ -494,7 +457,7 @@ bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *b bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { if(temp1) @@ -508,7 +471,7 @@ bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures * bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { if(temp1) @@ -526,7 +489,7 @@ bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices40d *buffer) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { memcpy(buffer, block->region_offset,sizeof(biome_indices40d)); @@ -717,7 +680,7 @@ std::vector * Maps::GetLocalFeatures(DFCoord coord) bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int16_t & global) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { local = block->local_feature; @@ -730,7 +693,7 @@ bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int bool Maps::WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int16_t & local, const int16_t & global) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { block->local_feature = local; @@ -791,7 +754,7 @@ bool Maps::ReadFeatures(mapblock40d * block, t_feature ** local, t_feature ** gl bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { block->local_feature = local; @@ -803,7 +766,7 @@ bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t loca bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global) { MAPS_GUARD - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if (block) { block->global_feature = global; @@ -815,12 +778,12 @@ bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t glo /* * Block events */ -bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector * veins, vector * ices, vector *splatter, vector *grass, vector *constructions) +bool Maps::SortBlockEvents(uint32_t x, uint32_t y, uint32_t z, vector * veins, vector * ices, vector *splatter, vector *grass, vector *constructions) { MAPS_GUARD Process* p = d->owner; - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if(veins) veins->clear(); if(ices) ices->clear(); if(splatter) splatter->clear(); @@ -908,6 +871,26 @@ bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector * vein return true; } +bool Maps::RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, t_virtual * which) +{ + MAPS_GUARD + Process* p = d->owner; + + df_block * block = getBlock(x,y,z); + if(block) + { + for(int i = 0; i < block->block_events.size();i++) + { + if (block->block_events[i] == which) + { + free(which); + block->block_events.erase(block->block_events.begin() + i); + return true; + } + } + } + return false; +} /* __int16 __userpurge GetGeologicalRegion(__int16 block_X, int X, __int16 block_Y, int block_addr, int Y) { @@ -1068,7 +1051,7 @@ bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vectorhasVeggies || !d->Started) return false; - df_block * block = getBlockPtr(x,y,z); + df_block * block = getBlock(x,y,z); if(!block) return false; Private::t_offsets &off = d->offsets; diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 9510aca6d..42f60d724 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -27,3 +27,4 @@ ENDMACRO() DFHACK_PLUGIN(reveal reveal.cpp) DFHACK_PLUGIN(kittens kittens.cpp) DFHACK_PLUGIN(prospector prospector.cpp) +DFHACK_PLUGIN(cleanmap cleanmap.cpp) diff --git a/plugins/cleanmap.cpp b/plugins/cleanmap.cpp new file mode 100644 index 000000000..45c5f9af5 --- /dev/null +++ b/plugins/cleanmap.cpp @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +using std::vector; +using std::string; +using namespace DFHack; + +const uint32_t water_idx = 6; +const uint32_t mud_idx = 12; + +DFhackCExport command_result cleanmap (Core * c, vector & parameters); + +DFhackCExport const char * plugin_name ( void ) +{ + return "cleanmap"; +} + +DFhackCExport command_result plugin_init ( Core * c, std::vector &commands) +{ + commands.clear(); + commands.push_back(PluginCommand("cleanmap","Cleans the map from various substances. Options: 'snow' for removing snow, 'mud' for mud.",cleanmap)); + return CR_OK; +} + +DFhackCExport command_result plugin_shutdown ( Core * c ) +{ + return CR_OK; +} + +DFhackCExport command_result cleanmap (Core * c, vector & parameters) +{ + bool snow = false; + bool mud = false; + for(int i = 0; i < parameters.size();i++) + { + if(parameters[i] == "snow") + snow = true; + else if(parameters[i] == "mud") + mud = true; + } + vector splatter; + DFHack::Maps *Mapz = c->getMaps(); + + // init the map + if(!Mapz->Start()) + { + dfout << "Can't init map." << std::endl; + return CR_FAILURE; + } + + uint32_t x_max,y_max,z_max; + Mapz->getSize(x_max,y_max,z_max); + + uint8_t zeroes [16][16] = {{0}}; + DFHack::occupancies40d occ; + // walk the map + for(uint32_t x = 0; x< x_max;x++) + { + for(uint32_t y = 0; y< y_max;y++) + { + for(uint32_t z = 0; z< z_max;z++) + { + df_block * block = Mapz->getBlock(x,y,z); + if(block) + { + Mapz->SortBlockEvents(x,y,z,0,0,&splatter); + for(int i = 0; i < 16; i++) + for(int j = 0; j < 16; j++) + { + block->occupancy[i][j].bits.arrow_color = 0; + block->occupancy[i][j].bits.broken_arrows_variant = 0; + } + for(uint32_t i = 0; i < splatter.size(); i++) + { + DFHack::t_spattervein * vein = splatter[i]; + // filter snow + if(!snow && vein->mat1 == water_idx && vein->matter_state == DFHack::state_powder) + continue; + // filter mud + if(!mud && vein->mat1 == mud_idx && vein->matter_state == DFHack::state_solid) + continue; + Mapz->RemoveBlockEvent(x,y,z,(t_virtual *) vein); + } + } + } + } + } + return CR_OK; +} diff --git a/plugins/reveal.cpp b/plugins/reveal.cpp index 452ceb100..1f1165ac6 100644 --- a/plugins/reveal.cpp +++ b/plugins/reveal.cpp @@ -96,7 +96,6 @@ DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result reveal(DFHack::Core * c, std::vector & params) { - DFHack::designations40d designations; bool no_hell = false; if(params[0] == "safe") { @@ -142,7 +141,8 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector & { for(uint32_t z = 0; z< z_max;z++) { - if(Maps->isValidBlock(x,y,z)) + df_block *block = Maps->getBlock(x,y,z); + if(block) { // in 'no-hell'/'safe' mode, don't reveal blocks with hell and adamantine if (no_hell && !isSafe(x, y, z, Maps)) @@ -151,17 +151,16 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector & hb.x = x; hb.y = y; hb.z = z; - // read block designations - Maps->ReadDesignations(x,y,z, &designations); - // change the hidden flag to 0 + DFHack::designations40d & designations = block->designation; + // for each tile in block for (uint32_t i = 0; i < 16;i++) for (uint32_t j = 0; j < 16;j++) { + // save hidden state of tile hb.hiddens[i][j] = designations[i][j].bits.hidden; + // set to revealed designations[i][j].bits.hidden = 0; } hidesaved.push_back(hb); - // write the designations back - Maps->WriteDesignations(x,y,z, &designations); } } } @@ -178,7 +177,7 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector & c->Resume(); dfout << "Map revealed." << std::endl; if(!no_hell) - dfout << "Unpausing can unleash the forces of hell, so it has beed temporarily disabled!" << std::endl; + dfout << "Unpausing can unleash the forces of hell, so it has been temporarily disabled!" << std::endl; dfout << "Run 'unreveal' to revert to previous state." << std::endl; return CR_OK; } @@ -225,12 +224,11 @@ DFhackCExport command_result unreveal(DFHack::Core * c, std::vector for(size_t i = 0; i < hidesaved.size();i++) { hideblock & hb = hidesaved[i]; - Maps->ReadDesignations(hb.x,hb.y,hb.z, &designations); + df_block * b = Maps->getBlock(hb.x,hb.y,hb.z); for (uint32_t i = 0; i < 16;i++) for (uint32_t j = 0; j < 16;j++) { - designations[i][j].bits.hidden = hb.hiddens[i][j]; + b->designation[i][j].bits.hidden = hb.hiddens[i][j]; } - Maps->WriteDesignations(hb.x,hb.y,hb.z, &designations); } // give back memory. hidesaved.clear();