More maps tweaks, function for block event removal, added cleanmap version that nukes spatter objects instead of rewriting their

bitmaps.
develop
Petr Mrázek 2011-07-07 09:49:58 +02:00
parent 4ff5db06be
commit 8b298f8d91
6 changed files with 165 additions and 90 deletions

@ -36,7 +36,7 @@ void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d &
{
memset(materials,-1,sizeof(materials));
std::vector <DFHack::t_vein *> 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++)
{

@ -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<t_vein *>* veins,
std::vector<t_frozenliquidvein *>* ices = 0,
std::vector<t_spattervein *>* splatter = 0,
std::vector<t_grassvein *>* grass = 0,
std::vector<t_worldconstruction *>* 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<df_plant *>*& plants);
private:

@ -30,6 +30,7 @@ distribution.
#include <map>
#include <set>
#include <cassert>
#include <cstdlib>
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<DFHack::df_block*> & arr2d = mdata->map[x];//[y][z];
df_array<DFHack::df_block*> & 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) &block;
//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 <t_feature *> * 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 <t_vein *>* veins, vector <t_frozenliquidvein *>* ices, vector <t_spattervein *> *splatter, vector <t_grassvein *> *grass, vector <t_worldconstruction *> *constructions)
bool Maps::SortBlockEvents(uint32_t x, uint32_t y, uint32_t z, vector <t_vein *>* veins, vector <t_frozenliquidvein *>* ices, vector <t_spattervein *> *splatter, vector <t_grassvein *> *grass, vector <t_worldconstruction *> *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 <t_vein *>* 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<ax>(__int16 block_X<cx>, int X<ebx>, __int16 block_Y<di>, int block_addr<esi>, int Y)
{
@ -1068,7 +1051,7 @@ bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_pla
{
if(!d->hasVeggies || !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;

@ -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)

@ -0,0 +1,95 @@
#include <dfhack/Core.h>
#include <dfhack/Console.h>
#include <dfhack/Export.h>
#include <dfhack/PluginManager.h>
#include <dfhack/modules/Maps.h>
#include <vector>
#include <string>
#include <string.h>
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 <string> & parameters);
DFhackCExport const char * plugin_name ( void )
{
return "cleanmap";
}
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &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 <string> & 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<DFHack::t_spattervein *> 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;
}

@ -96,7 +96,6 @@ DFhackCExport command_result plugin_shutdown ( Core * c )
DFhackCExport command_result reveal(DFHack::Core * c, std::vector<std::string> & 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<std::string> &
{
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<std::string> &
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<std::string> &
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<std::string>
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();