Get rid of some obsolete api functions, and restructure MapCache.

develop
Alexander Gavrilov 2012-04-10 18:21:19 +04:00
parent 249be0c1a0
commit b15d2da819
11 changed files with 414 additions and 682 deletions

@ -39,3 +39,7 @@ coord2d operator%(int number) const
{ {
return coord2d((x+number)%number, (y+number)%number); return coord2d((x+number)%number, (y+number)%number);
} }
coord2d operator&(int number) const
{
return coord2d(x&number, y&number);
}

@ -33,251 +33,167 @@ distribution.
#include "df/map_block.h" #include "df/map_block.h"
#include "df/block_square_event_mineralst.h" #include "df/block_square_event_mineralst.h"
#include "df/construction.h" #include "df/construction.h"
using namespace DFHack; using namespace DFHack;
namespace MapExtras namespace MapExtras
{ {
void SquashVeins (DFCoord bcoord, mapblock40d & mb, t_blockmaterials & materials)
{
memset(materials,-1,sizeof(materials));
std::vector <df::block_square_event_mineralst *> veins;
Maps::SortBlockEvents(bcoord.x,bcoord.y,bcoord.z,&veins);
for (uint32_t x = 0;x<16;x++) for (uint32_t y = 0; y< 16;y++)
{
df::tiletype tt = mb.tiletypes[x][y];
if (tileMaterial(tt) == tiletype_material::MINERAL)
{
for (size_t i = 0; i < veins.size(); i++)
{
if (veins[i]->getassignment(x,y))
materials[x][y] = veins[i]->inorganic_mat;
}
}
}
}
void SquashFrozenLiquids (DFCoord bcoord, mapblock40d & mb, tiletypes40d & frozen) class DFHACK_EXPORT MapCache;
{
std::vector <df::block_square_event_frozen_liquidst *> ices;
Maps::SortBlockEvents(bcoord.x,bcoord.y,bcoord.z,NULL,&ices);
for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
{
df::tiletype tt = mb.tiletypes[x][y];
frozen[x][y] = tiletype::Void;
if (tileMaterial(tt) == tiletype_material::FROZEN_LIQUID)
{
for (size_t i = 0; i < ices.size(); i++)
{
df::tiletype tt2 = ices[i]->tiles[x][y];
if (tt2 != tiletype::Void)
{
frozen[x][y] = tt2;
break;
}
}
}
}
}
void SquashConstructions (DFCoord bcoord, mapblock40d & mb, tiletypes40d & constructions) template<class R, class T> inline R index_tile(T &v, df::coord2d p) {
{ return v[p.x&15][p.y&15];
for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
{
df::tiletype tt = mb.tiletypes[x][y];
constructions[x][y] = tiletype::Void;
if (tileMaterial(tt) == tiletype_material::CONSTRUCTION)
{
DFCoord coord(bcoord.x*16 + x, bcoord.y*16 + y, bcoord.z);
df::construction *con = df::construction::find(coord);
if (con)
constructions[x][y] = con->original_tile;
}
}
} }
void SquashRocks ( std::vector< std::vector <uint16_t> > * layerassign, mapblock40d & mb, t_blockmaterials & materials) class DFHACK_EXPORT Block
{ {
// get the layer materials public:
for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++) Block(MapCache *parent, DFCoord _bcoord);
{
materials[x][y] = -1;
uint8_t test = mb.designation[x][y].bits.biome;
if ((test < sizeof(mb.biome_indices)) && (mb.biome_indices[test] < layerassign->size()))
materials[x][y] = layerassign->at(mb.biome_indices[test])[mb.designation[x][y].bits.geolayer_index];
}
}
class Block /*
{ * All coordinates are taken mod 16.
public: */
Block(DFCoord _bcoord, std::vector< std::vector <uint16_t> > * layerassign = 0)
{ //Arbitrary tag field for flood fills etc.
dirty_designations = false; int16_t &tag(df::coord2d p) {
dirty_tiletypes = false; return index_tile<int16_t&>(tags, p);
dirty_temperatures = false;
dirty_blockflags = false;
dirty_occupancies = false;
valid = false;
bcoord = _bcoord;
if(Maps::ReadBlock40d(bcoord.x,bcoord.y,bcoord.z,&raw))
{
Maps::ReadTemperatures(bcoord.x,bcoord.y, bcoord.z,&temp1,&temp2);
SquashVeins(bcoord,raw,veinmats);
SquashConstructions(bcoord, raw, contiles);
SquashFrozenLiquids(bcoord, raw, icetiles);
if(layerassign)
SquashRocks(layerassign,raw,basemats);
else
memset(basemats,-1,sizeof(basemats));
valid = true;
}
} }
int16_t veinMaterialAt(df::coord2d p) int16_t veinMaterialAt(df::coord2d p)
{ {
return veinmats[p.x][p.y]; return index_tile<int16_t>(veinmats,p);
} }
int16_t baseMaterialAt(df::coord2d p) int16_t baseMaterialAt(df::coord2d p)
{ {
return basemats[p.x][p.y]; return index_tile<int16_t>(basemats,p);
}
// the clear methods are used by the floodfill in digv and digl to mark tiles which were processed
void ClearBaseMaterialAt(df::coord2d p)
{
basemats[p.x][p.y] = -1;
}
void ClearVeinMaterialAt(df::coord2d p)
{
veinmats[p.x][p.y] = -1;
} }
df::tiletype BaseTileTypeAt(df::coord2d p) df::tiletype BaseTileTypeAt(df::coord2d p)
{ {
if (contiles[p.x][p.y] != tiletype::Void) auto tt = index_tile<df::tiletype>(contiles,p);
return contiles[p.x][p.y]; if (tt != tiletype::Void) return tt;
else if (icetiles[p.x][p.y] != tiletype::Void) tt = index_tile<df::tiletype>(icetiles,p);
return icetiles[p.x][p.y]; if (tt != tiletype::Void) return tt;
else return index_tile<df::tiletype>(rawtiles,p);
return raw.tiletypes[p.x][p.y];
} }
df::tiletype TileTypeAt(df::coord2d p) df::tiletype TileTypeAt(df::coord2d p)
{ {
return raw.tiletypes[p.x][p.y]; return index_tile<df::tiletype>(rawtiles,p);
} }
bool setTiletypeAt(df::coord2d p, df::tiletype tiletype) bool setTiletypeAt(df::coord2d p, df::tiletype tiletype)
{ {
if(!valid) return false; if(!valid) return false;
dirty_tiletypes = true; dirty_tiletypes = true;
//printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y); //printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y);
raw.tiletypes[p.x][p.y] = tiletype; index_tile<df::tiletype&>(rawtiles,p) = tiletype;
return true; return true;
} }
uint16_t temperature1At(df::coord2d p) uint16_t temperature1At(df::coord2d p)
{ {
return temp1[p.x][p.y]; return index_tile<uint16_t>(temp1,p);
} }
bool setTemp1At(df::coord2d p, uint16_t temp) bool setTemp1At(df::coord2d p, uint16_t temp)
{ {
if(!valid) return false; if(!valid) return false;
dirty_temperatures = true; dirty_temperatures = true;
temp1[p.x][p.y] = temp; index_tile<uint16_t&>(temp1,p) = temp;
return true; return true;
} }
uint16_t temperature2At(df::coord2d p) uint16_t temperature2At(df::coord2d p)
{ {
return temp2[p.x][p.y]; return index_tile<uint16_t>(temp2,p);
} }
bool setTemp2At(df::coord2d p, uint16_t temp) bool setTemp2At(df::coord2d p, uint16_t temp)
{ {
if(!valid) return false; if(!valid) return false;
dirty_temperatures = true; dirty_temperatures = true;
temp2[p.x][p.y] = temp; index_tile<uint16_t&>(temp2,p) = temp;
return true; return true;
} }
df::tile_designation DesignationAt(df::coord2d p) df::tile_designation DesignationAt(df::coord2d p)
{ {
return raw.designation[p.x][p.y]; return index_tile<df::tile_designation>(designation,p);
} }
bool setDesignationAt(df::coord2d p, df::tile_designation des) bool setDesignationAt(df::coord2d p, df::tile_designation des)
{ {
if(!valid) return false; if(!valid) return false;
dirty_designations = true; dirty_designations = true;
//printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y); //printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y);
raw.designation[p.x][p.y] = des; index_tile<df::tile_designation&>(designation,p) = des;
if(des.bits.dig) if(des.bits.dig)
{ {
dirty_blockflags = true; dirty_blockflags = true;
raw.blockflags.bits.designated = true; blockflags.bits.designated = true;
} }
return true; return true;
} }
df::tile_occupancy OccupancyAt(df::coord2d p) df::tile_occupancy OccupancyAt(df::coord2d p)
{ {
return raw.occupancy[p.x][p.y]; return index_tile<df::tile_occupancy>(occupancy,p);
} }
bool setOccupancyAt(df::coord2d p, df::tile_occupancy des) bool setOccupancyAt(df::coord2d p, df::tile_occupancy des)
{ {
if(!valid) return false; if(!valid) return false;
dirty_occupancies = true; dirty_occupancies = true;
raw.occupancy[p.x][p.y] = des; index_tile<df::tile_occupancy&>(occupancy,p) = des;
return true; return true;
} }
t_blockflags BlockFlags() t_blockflags BlockFlags()
{ {
return raw.blockflags; return blockflags;
} }
bool setBlockFlags(t_blockflags des) bool setBlockFlags(t_blockflags des)
{ {
if(!valid) return false; if(!valid) return false;
dirty_blockflags = true; dirty_blockflags = true;
//printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y); //printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y);
raw.blockflags = des; blockflags = des;
return true; return true;
} }
bool Write () bool Write();
{
if(!valid) return false; int16_t GeoIndexAt(df::coord2d p);
if(dirty_designations)
{ bool GetGlobalFeature(t_feature *out);
Maps::WriteDesignations(bcoord.x,bcoord.y,bcoord.z, &raw.designation); bool GetLocalFeature(t_feature *out);
Maps::WriteDirtyBit(bcoord.x,bcoord.y,bcoord.z,true);
dirty_designations = false; bool is_valid() { return valid; }
} df::map_block *getRaw() { return block; }
if(dirty_tiletypes)
{ private:
Maps::WriteTileTypes(bcoord.x,bcoord.y,bcoord.z, &raw.tiletypes); friend class MapCache;
dirty_tiletypes = false;
} MapCache *parent;
if(dirty_temperatures) df::map_block *block;
{
Maps::WriteTemperatures(bcoord.x,bcoord.y,bcoord.z, &temp1, &temp2); static void SquashVeins(df::map_block *mb, t_blockmaterials & materials);
dirty_temperatures = false; static void SquashFrozenLiquids (df::map_block *mb, tiletypes40d & frozen);
} static void SquashConstructions (df::map_block *mb, tiletypes40d & constructions);
if(dirty_blockflags) static void SquashRocks (df::map_block *mb, t_blockmaterials & materials,
{ std::vector< std::vector <int16_t> > * layerassign);
Maps::WriteBlockFlags(bcoord.x,bcoord.y,bcoord.z,raw.blockflags);
dirty_blockflags = false; bool valid;
}
if(dirty_occupancies)
{
Maps::WriteOccupancy(bcoord.x,bcoord.y,bcoord.z,&raw.occupancy);
dirty_occupancies = false;
}
return true;
}
bool valid:1;
bool dirty_designations:1; bool dirty_designations:1;
bool dirty_tiletypes:1; bool dirty_tiletypes:1;
bool dirty_temperatures:1; bool dirty_temperatures:1;
bool dirty_blockflags:1; bool dirty_blockflags:1;
bool dirty_occupancies:1; bool dirty_occupancies:1;
mapblock40d raw;
DFCoord bcoord; DFCoord bcoord;
int16_t tags[16][16];
tiletypes40d rawtiles;
designations40d designation;
occupancies40d occupancy;
t_blockflags blockflags;
t_blockmaterials veinmats; t_blockmaterials veinmats;
t_blockmaterials basemats; t_blockmaterials basemats;
t_temperatures temp1; t_temperatures temp1;
@ -286,14 +202,15 @@ class Block
tiletypes40d icetiles; // what's underneath ice tiletypes40d icetiles; // what's underneath ice
}; };
class MapCache class DFHACK_EXPORT MapCache
{ {
public: public:
MapCache() MapCache()
{ {
valid = 0; valid = 0;
Maps::getSize(x_bmax, y_bmax, z_max); Maps::getSize(x_bmax, y_bmax, z_max);
validgeo = Maps::ReadGeology( layerassign ); x_tmax = x_bmax*16; y_tmax = y_bmax*16;
validgeo = Maps::ReadGeology(&layer_mats, &geoidx);
valid = true; valid = true;
}; };
~MapCache() ~MapCache()
@ -304,192 +221,107 @@ class MapCache
{ {
return valid; return valid;
} }
/// get the map block at a *block* coord. Block coord = tile coord / 16 /// get the map block at a *block* coord. Block coord = tile coord / 16
Block * BlockAt (DFCoord blockcoord) Block *BlockAt(DFCoord blockcoord);
{ /// get the map block at a tile coord.
if(!valid) Block *BlockAtTile(DFCoord coord) {
return 0; return BlockAt(df::coord(coord.x>>4,coord.y>>4,coord.z));
std::map <DFCoord, Block*>::iterator iter = blocks.find(blockcoord);
if(iter != blocks.end())
{
return (*iter).second;
}
else
{
if(blockcoord.x >= 0 && blockcoord.x < x_bmax &&
blockcoord.y >= 0 && blockcoord.y < y_bmax &&
blockcoord.z >= 0 && blockcoord.z < z_max)
{
Block * nblo;
if(validgeo)
nblo = new Block(blockcoord, &layerassign);
else
nblo = new Block(blockcoord);
blocks[blockcoord] = nblo;
return nblo;
}
return 0;
}
} }
df::tiletype baseTiletypeAt (DFCoord tilecoord) df::tiletype baseTiletypeAt (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAtTile(tilecoord);
if(b && b->valid) return b ? b->BaseTileTypeAt(tilecoord) : tiletype::Void;
{
return b->BaseTileTypeAt(tilecoord % 16);
}
return tiletype::Void;
} }
df::tiletype tiletypeAt (DFCoord tilecoord) df::tiletype tiletypeAt (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAtTile(tilecoord);
if(b && b->valid) return b ? b->TileTypeAt(tilecoord) : tiletype::Void;
{
return b->TileTypeAt(tilecoord % 16);
}
return tiletype::Void;
} }
bool setTiletypeAt(DFCoord tilecoord, df::tiletype tiletype) bool setTiletypeAt(DFCoord tilecoord, df::tiletype tiletype)
{ {
Block * b= BlockAt(tilecoord / 16); if (Block * b= BlockAtTile(tilecoord))
if(b && b->valid) return b->setTiletypeAt(tilecoord, tiletype);
{
b->setTiletypeAt(tilecoord % 16, tiletype);
return true;
}
return false; return false;
} }
uint16_t temperature1At (DFCoord tilecoord) uint16_t temperature1At (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAtTile(tilecoord);
if(b && b->valid) return b ? b->temperature1At(tilecoord) : 0;
{
return b->temperature1At(tilecoord % 16);
}
return 0;
} }
bool setTemp1At(DFCoord tilecoord, uint16_t temperature) bool setTemp1At(DFCoord tilecoord, uint16_t temperature)
{ {
Block * b= BlockAt(tilecoord / 16); if (Block * b= BlockAtTile(tilecoord))
if(b && b->valid) return b->setTemp1At(tilecoord, temperature);
{
b->setTemp1At(tilecoord % 16, temperature);
return true;
}
return false; return false;
} }
uint16_t temperature2At (DFCoord tilecoord) uint16_t temperature2At (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAtTile(tilecoord);
if(b && b->valid) return b ? b->temperature2At(tilecoord) : 0;
{
return b->temperature2At(tilecoord % 16);
}
return 0;
} }
bool setTemp2At(DFCoord tilecoord, uint16_t temperature) bool setTemp2At(DFCoord tilecoord, uint16_t temperature)
{ {
Block * b= BlockAt(tilecoord / 16); if (Block * b= BlockAtTile(tilecoord))
if(b && b->valid) return b->setTemp2At(tilecoord, temperature);
{
b->setTemp2At(tilecoord % 16, temperature);
return true;
}
return false; return false;
} }
int16_t veinMaterialAt (DFCoord tilecoord) int16_t veinMaterialAt (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAtTile(tilecoord);
if(b && b->valid) return b ? b->veinMaterialAt(tilecoord) : -1;
{
return b->veinMaterialAt(tilecoord % 16);
}
return 0;
} }
int16_t baseMaterialAt (DFCoord tilecoord) int16_t baseMaterialAt (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAtTile(tilecoord);
if(b && b->valid) return b ? b->baseMaterialAt(tilecoord) : -1;
{
return b->baseMaterialAt(tilecoord % 16);
}
return 0;
} }
bool clearVeinMaterialAt (DFCoord tilecoord)
{ int16_t tagAt(DFCoord tilecoord)
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{ {
b->ClearVeinMaterialAt(tilecoord % 16); Block * b= BlockAtTile(tilecoord);
return b ? b->tag(tilecoord) : 0;
} }
return 0; void setTagAt(DFCoord tilecoord, int16_t val)
}
bool clearBaseMaterialAt (DFCoord tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{ {
b->ClearBaseMaterialAt(tilecoord % 16); Block * b= BlockAtTile(tilecoord);
} if (b) b->tag(tilecoord) = val;
return 0;
} }
df::tile_designation designationAt (DFCoord tilecoord) df::tile_designation designationAt (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAtTile(tilecoord);
if(b && b->valid) return b ? b->DesignationAt(tilecoord) : df::tile_designation(0);
{
return b->DesignationAt(tilecoord % 16);
}
df::tile_designation temp;
temp.whole = 0;
return temp;
} }
bool setDesignationAt (DFCoord tilecoord, df::tile_designation des) bool setDesignationAt (DFCoord tilecoord, df::tile_designation des)
{ {
Block * b= BlockAt(tilecoord / 16); if(Block * b= BlockAtTile(tilecoord))
if(b && b->valid) return b->setDesignationAt(tilecoord, des);
{
b->setDesignationAt(tilecoord % 16, des);
return true;
}
return false; return false;
} }
df::tile_occupancy occupancyAt (DFCoord tilecoord) df::tile_occupancy occupancyAt (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAtTile(tilecoord);
if(b && b->valid) return b ? b->OccupancyAt(tilecoord) : df::tile_occupancy(0);
{
return b->OccupancyAt(tilecoord % 16);
}
df::tile_occupancy temp;
temp.whole = 0;
return temp;
} }
bool setOccupancyAt (DFCoord tilecoord, df::tile_occupancy occ) bool setOccupancyAt (DFCoord tilecoord, df::tile_occupancy occ)
{ {
Block * b= BlockAt(tilecoord / 16); if (Block * b= BlockAtTile(tilecoord))
if(b && b->valid) return b->setOccupancyAt(tilecoord, occ);
{
b->setOccupancyAt(tilecoord % 16, occ);
return true;
}
return false; return false;
} }
bool testCoord (DFCoord tilecoord) bool testCoord (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAtTile(tilecoord);
if(b && b->valid) return (b && b->valid);
{
return true;
}
return false;
} }
bool WriteAll() bool WriteAll()
{ {
std::map<DFCoord, Block *>::iterator p; std::map<DFCoord, Block *>::iterator p;
@ -508,15 +340,25 @@ class MapCache
} }
blocks.clear(); blocks.clear();
} }
private:
volatile bool valid; uint32_t maxBlockX() { return x_bmax; }
volatile bool validgeo; uint32_t maxBlockY() { return y_bmax; }
uint32_t maxTileX() { return x_tmax; }
uint32_t maxTileY() { return y_tmax; }
uint32_t maxZ() { return z_max; }
private:
friend class Block;
bool valid;
bool validgeo;
uint32_t x_bmax; uint32_t x_bmax;
uint32_t y_bmax; uint32_t y_bmax;
uint32_t x_tmax; uint32_t x_tmax;
uint32_t y_tmax; uint32_t y_tmax;
uint32_t z_max; uint32_t z_max;
std::vector< std::vector <uint16_t> > layerassign; std::vector<int16_t> geoidx;
std::vector< std::vector <int16_t> > layer_mats;
std::map<DFCoord, Block *> blocks; std::map<DFCoord, Block *> blocks;
}; };
} }

@ -103,31 +103,11 @@ enum BiomeOffset
eBiomeCount eBiomeCount
}; };
/**
* map block flags
* \ingroup grp_maps
*/
struct naked_blockflags
{
/// designated for jobs (digging and stuff like that)
unsigned int designated : 1;
/// possibly related to the designated flag
unsigned int unk_1 : 1;
/// two flags required for liquid flow.
unsigned int liquid_1 : 1;
unsigned int liquid_2 : 1;
/// rest of the flags is completely unknown
unsigned int unk_2: 4;
};
/** /**
* map block flags wrapper * map block flags wrapper
* \ingroup grp_maps * \ingroup grp_maps
*/ */
union t_blockflags typedef df::block_flags t_blockflags;
{
uint32_t whole;
naked_blockflags bits;
};
/** /**
* 16x16 array of tile types * 16x16 array of tile types
@ -161,30 +141,6 @@ typedef uint8_t biome_indices40d [9];
* \ingroup grp_maps * \ingroup grp_maps
*/ */
typedef uint16_t t_temperatures [16][16]; typedef uint16_t t_temperatures [16][16];
/**
* structure for holding whole blocks
* \ingroup grp_maps
*/
typedef struct
{
DFCoord position;
/// type of the tiles
tiletypes40d tiletypes;
/// flags determining the state of the tiles
designations40d designation;
/// flags determining what's on the tiles
occupancies40d occupancy;
/// values used for geology/biome assignment
biome_indices40d biome_indices;
/// the address where the block came from
df::map_block * origin;
t_blockflags blockflags;
/// index into the global feature vector
int32_t global_feature;
/// index into the local feature vector... complicated
int32_t local_feature;
int32_t mystery;
} mapblock40d;
/** /**
* The Maps module * The Maps module
@ -231,16 +187,8 @@ void DfMap::applyGeoMatgloss(Block * b)
* @endcode * @endcode
*/ */
extern DFHACK_EXPORT bool ReadGeology( std::vector < std::vector <uint16_t> >& assign ); extern DFHACK_EXPORT bool ReadGeology(std::vector<std::vector<int16_t> > *layer_mats,
std::vector<int16_t> *geoidx);
/**
* Get the feature indexes of a block
*/
extern DFHACK_EXPORT bool ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int32_t & local, int32_t & global);
/**
* Set the feature indexes of a block
*/
extern DFHACK_EXPORT bool WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int32_t & local, const int32_t & global);
/** /**
* Get pointers to features of a block * Get pointers to features of a block
*/ */
@ -248,7 +196,7 @@ extern DFHACK_EXPORT bool ReadFeatures(uint32_t x, uint32_t y, uint32_t z, t_fea
/** /**
* Get pointers to features of an already read block * Get pointers to features of an already read block
*/ */
extern DFHACK_EXPORT bool ReadFeatures(mapblock40d * block,t_feature * local, t_feature * global); extern DFHACK_EXPORT bool ReadFeatures(df::map_block * block,t_feature * local, t_feature * global);
/** /**
* Read a specific global or local feature directly * Read a specific global or local feature directly
@ -274,43 +222,12 @@ extern DFHACK_EXPORT df::map_block * getBlockAbs (int32_t x, int32_t y, int32_t
inline df::map_block * getBlock (df::coord pos) { return getBlock(pos.x, pos.y, pos.z); } inline df::map_block * getBlock (df::coord pos) { return getBlock(pos.x, pos.y, pos.z); }
inline df::map_block * getBlockAbs (df::coord pos) { return getBlockAbs(pos.x, pos.y, pos.z); } inline df::map_block * getBlockAbs (df::coord pos) { return getBlockAbs(pos.x, pos.y, pos.z); }
/// copy the whole map block at block coords (see DFTypes.h for the block structure)
extern DFHACK_EXPORT bool ReadBlock40d(uint32_t blockx, uint32_t blocky, uint32_t blockz, mapblock40d * buffer);
/// copy/write block tile types
extern DFHACK_EXPORT bool ReadTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, tiletypes40d *buffer);
extern DFHACK_EXPORT bool WriteTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, tiletypes40d *buffer);
/// copy/write block designations
extern DFHACK_EXPORT bool ReadDesignations(uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer);
extern DFHACK_EXPORT bool WriteDesignations (uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer);
/// copy/write temperatures
extern DFHACK_EXPORT bool ReadTemperatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2);
extern DFHACK_EXPORT bool WriteTemperatures (uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2);
/// copy/write block occupancies
extern DFHACK_EXPORT bool ReadOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer);
extern DFHACK_EXPORT bool WriteOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer);
/// copy/write the block dirty bit - this is used to mark a map block so that DF scans it for designated jobs like digging
extern DFHACK_EXPORT bool ReadDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool &dirtybit);
extern DFHACK_EXPORT bool WriteDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool dirtybit);
/// copy/write the block flags
extern DFHACK_EXPORT bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags &blockflags);
extern DFHACK_EXPORT bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags blockflags);
/// copy/write features
extern DFHACK_EXPORT bool SetBlockLocalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int32_t local = -1);
extern DFHACK_EXPORT bool SetBlockGlobalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int32_t global = -1);
/// copy region offsets of a block - used for determining layer stone matgloss /// copy region offsets of a block - used for determining layer stone matgloss
extern DFHACK_EXPORT bool ReadRegionOffsets(uint32_t blockx, uint32_t blocky, uint32_t blockz, biome_indices40d *buffer); extern DFHACK_EXPORT bool ReadRegionOffsets(uint32_t blockx, uint32_t blocky, uint32_t blockz, biome_indices40d *buffer);
/// sorts the block event vector into multiple vectors by type /// sorts the block event vector into multiple vectors by type
/// mineral veins, what's under ice, blood smears and mud /// mineral veins, what's under ice, blood smears and mud
extern DFHACK_EXPORT bool SortBlockEvents(uint32_t x, uint32_t y, uint32_t z, extern DFHACK_EXPORT bool SortBlockEvents(df::map_block *block,
std::vector<df::block_square_event_mineralst *>* veins, std::vector<df::block_square_event_mineralst *>* veins,
std::vector<df::block_square_event_frozen_liquidst *>* ices = 0, std::vector<df::block_square_event_frozen_liquidst *>* ices = 0,
std::vector<df::block_square_event_material_spatterst *>* splatter = 0, std::vector<df::block_square_event_material_spatterst *>* splatter = 0,

@ -33,11 +33,13 @@ distribution.
using namespace std; using namespace std;
#include "modules/Maps.h" #include "modules/Maps.h"
#include "modules/MapCache.h"
#include "Error.h" #include "Error.h"
#include "VersionInfo.h" #include "VersionInfo.h"
#include "MemAccess.h" #include "MemAccess.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "Core.h" #include "Core.h"
#include "MiscUtils.h"
#include "DataDefs.h" #include "DataDefs.h"
#include "df/world_data.h" #include "df/world_data.h"
@ -136,182 +138,6 @@ df::map_block *Maps::getBlockAbs (int32_t x, int32_t y, int32_t z)
return world->map.block_index[x >> 4][y >> 4][z]; return world->map.block_index[x >> 4][y >> 4][z];
} }
bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer)
{
df::map_block * block = getBlock(x,y,z);
if (block)
{
buffer->position = DFCoord(x,y,z);
memcpy(buffer->tiletypes,block->tiletype, sizeof(tiletypes40d));
memcpy(buffer->designation,block->designation, sizeof(designations40d));
memcpy(buffer->occupancy,block->occupancy, sizeof(occupancies40d));
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->unk2;
buffer->origin = block;
buffer->blockflags.whole = block->flags.whole;
return true;
}
return false;
}
/*
* Tiletypes
*/
bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
memcpy(buffer, block->tiletype, sizeof(tiletypes40d));
return true;
}
return false;
}
bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
memcpy(block->tiletype, buffer, sizeof(tiletypes40d));
return true;
}
return false;
}
/*
* Dirty bit
*/
bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
dirtybit = block->flags.bits.designated;
return true;
}
return false;
}
bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
block->flags.bits.designated = true;
return true;
}
return false;
}
/*
* Block flags
*/
// FIXME: maybe truncates, still bullshit
bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &blockflags)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
blockflags.whole = block->flags.whole;
return true;
}
return false;
}
//FIXME: maybe truncated, still bullshit
bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
block->flags.whole = blockflags.whole;
return true;
}
return false;
}
/*
* Designations
*/
bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
memcpy(buffer, block->designation, sizeof(designations40d));
return true;
}
return false;
}
bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
memcpy(block->designation, buffer, sizeof(designations40d));
return true;
}
return false;
}
/*
* Occupancies
*/
bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
memcpy(buffer, block->occupancy, sizeof(occupancies40d));
return true;
}
return false;
}
bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
memcpy(block->occupancy, buffer, sizeof(occupancies40d));
return true;
}
return false;
}
/*
* Temperatures
*/
bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
if(temp1)
memcpy(temp1, block->temperature_1, sizeof(t_temperatures));
if(temp2)
memcpy(temp2, block->temperature_2, sizeof(t_temperatures));
return true;
}
return false;
}
bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
if(temp1)
memcpy(block->temperature_1, temp1, sizeof(t_temperatures));
if(temp2)
memcpy(block->temperature_2, temp2, sizeof(t_temperatures));
return true;
}
return false;
}
/* /*
* Region Offsets - used for layer geology * Region Offsets - used for layer geology
*/ */
@ -381,58 +207,15 @@ bool Maps::GetLocalFeature(t_feature &feature, df::coord2d coord, int32_t index)
return true; return true;
} }
bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int32_t & local, int32_t & global)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
local = block->local_feature;
global = block->global_feature;
return true;
}
return false;
}
bool Maps::WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int32_t & local, const int32_t & global)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
block->local_feature = local;
block->global_feature = global;
return true;
}
return false;
}
bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, t_feature *local, t_feature *global) bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, t_feature *local, t_feature *global)
{ {
int32_t loc, glob; df::map_block *block = getBlock(x,y,z);
if (!ReadFeatures(x, y, z, loc, glob)) if (!block)
return false; return false;
return ReadFeatures(block, local, global);
bool result = true;
if (global)
{
if (glob != -1)
result &= GetGlobalFeature(*global, glob);
else
global->type = (df::feature_type)-1;
}
if (local)
{
if (loc != -1)
{
df::coord2d coord(x,y);
result &= GetLocalFeature(*local, coord, loc);
}
else
local->type = (df::feature_type)-1;
}
return result;
} }
bool Maps::ReadFeatures(mapblock40d * block, t_feature * local, t_feature * global) bool Maps::ReadFeatures(df::map_block * block, t_feature * local, t_feature * global)
{ {
bool result = true; bool result = true;
if (global) if (global)
@ -445,39 +228,17 @@ bool Maps::ReadFeatures(mapblock40d * block, t_feature * local, t_feature * glob
if (local) if (local)
{ {
if (block->local_feature != -1) if (block->local_feature != -1)
result &= GetLocalFeature(*local, block->position, block->local_feature); result &= GetLocalFeature(*local, block->map_pos/16, block->local_feature);
else else
local->type = (df::feature_type)-1; local->type = (df::feature_type)-1;
} }
return result; return result;
} }
bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int32_t local)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
block->local_feature = local;
return true;
}
return false;
}
bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int32_t global)
{
df::map_block *block = getBlock(x,y,z);
if (block)
{
block->global_feature = global;
return true;
}
return false;
}
/* /*
* Block events * Block events
*/ */
bool Maps::SortBlockEvents(uint32_t x, uint32_t y, uint32_t z, bool Maps::SortBlockEvents(df::map_block *block,
vector <df::block_square_event_mineralst *>* veins, vector <df::block_square_event_mineralst *>* veins,
vector <df::block_square_event_frozen_liquidst *>* ices, vector <df::block_square_event_frozen_liquidst *>* ices,
vector <df::block_square_event_material_spatterst *> *splatter, vector <df::block_square_event_material_spatterst *> *splatter,
@ -495,7 +256,6 @@ bool Maps::SortBlockEvents(uint32_t x, uint32_t y, uint32_t z,
if (constructions) if (constructions)
constructions->clear(); constructions->clear();
df::map_block * block = getBlock(x,y,z);
if (!block) if (!block)
return false; return false;
@ -535,27 +295,35 @@ bool Maps::RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square
df::map_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (!block) if (!block)
return false; return false;
for (size_t i = 0; i < block->block_events.size(); i++)
{ int idx = linear_index(block->block_events, which);
if (block->block_events[i] == which) if (idx >= 0)
{ {
delete which; delete which;
block->block_events.erase(block->block_events.begin() + i); vector_erase_at(block->block_events, idx);
return true; return true;
} }
} else
return false; return false;
} }
/* /*
* Layer geology * Layer geology
*/ */
bool Maps::ReadGeology (vector < vector <uint16_t> >& assign) bool Maps::ReadGeology(vector<vector<int16_t> > *layer_mats, vector<int16_t> *geoidx)
{ {
if (!world->world_data) if (!world->world_data)
return false; return false;
vector<uint16_t> v_geology[eBiomeCount]; layer_mats->resize(eBiomeCount);
geoidx->resize(eBiomeCount);
for (int i = 0; i < eBiomeCount; i++)
{
(*layer_mats)[i].clear();
(*geoidx)[i] = -1;
}
// iterate over 8 surrounding regions + local region // iterate over 8 surrounding regions + local region
for (int i = eNorthWest; i < eBiomeCount; i++) for (int i = eNorthWest; i < eBiomeCount; i++)
{ {
@ -571,7 +339,9 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
if (bioRY >= world->world_data->world_height) bioRY = world->world_data->world_height - 1; if (bioRY >= world->world_data->world_height) bioRY = world->world_data->world_height - 1;
// get index into geoblock vector // get index into geoblock vector
uint16_t geoindex = world->world_data->region_map[bioRX][bioRY].geo_index; int16_t geoindex = world->world_data->region_map[bioRX][bioRY].geo_index;
(*geoidx)[i] = geoindex;
/// geology blocks have a vector of layer descriptors /// geology blocks have a vector of layer descriptors
// get the vector with pointer to layers // get the vector with pointer to layers
@ -579,20 +349,17 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
if (!geo_biome) if (!geo_biome)
continue; continue;
vector <df::world_geo_layer*> &geolayers = geo_biome->layers; auto &geolayers = geo_biome->layers;
auto &matvec = (*layer_mats)[i];
/// layer descriptor has a field that determines the type of stone/soil /// layer descriptor has a field that determines the type of stone/soil
v_geology[i].reserve(geolayers.size()); matvec.resize(geolayers.size());
// finally, read the layer matgloss // finally, read the layer matgloss
for (size_t j = 0; j < geolayers.size(); j++) for (size_t j = 0; j < geolayers.size(); j++)
v_geology[i].push_back(geolayers[j]->mat_index); matvec[j] = geolayers[j]->mat_index;
} }
assign.clear();
assign.reserve(eBiomeCount);
for (int i = 0; i < eBiomeCount; i++)
assign.push_back(v_geology[i]);
return true; return true;
} }
@ -605,3 +372,212 @@ bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df::pl
plants = &block->plants; plants = &block->plants;
return true; return true;
} }
#define COPY(a,b) memcpy(&a,&b,sizeof(a))
MapExtras::Block::Block(MapCache *parent, DFCoord _bcoord) : parent(parent)
{
dirty_designations = false;
dirty_tiletypes = false;
dirty_temperatures = false;
dirty_blockflags = false;
dirty_occupancies = false;
valid = false;
bcoord = _bcoord;
block = Maps::getBlock(bcoord);
memset(tags,0,sizeof(tags));
if(block)
{
COPY(rawtiles, block->tiletype);
COPY(designation, block->designation);
COPY(occupancy, block->occupancy);
blockflags = block->flags;
COPY(temp1, block->temperature_1);
COPY(temp2, block->temperature_2);
SquashVeins(block,veinmats);
SquashConstructions(block, contiles);
SquashFrozenLiquids(block, icetiles);
if(parent->validgeo)
SquashRocks(block,basemats,&parent->layer_mats);
else
memset(basemats,-1,sizeof(basemats));
valid = true;
}
else
{
blockflags.whole = 0;
memset(rawtiles,0,sizeof(rawtiles));
memset(designation,0,sizeof(designation));
memset(occupancy,0,sizeof(occupancy));
memset(temp1,0,sizeof(temp1));
memset(temp2,0,sizeof(temp2));
memset(veinmats,-1,sizeof(veinmats));
memset(contiles,0,sizeof(contiles));
memset(icetiles,0,sizeof(icetiles));
memset(basemats,-1,sizeof(basemats));
}
}
bool MapExtras::Block::Write ()
{
if(!valid) return false;
if(dirty_blockflags)
{
block->flags = blockflags;
dirty_blockflags = false;
}
if(dirty_designations)
{
COPY(block->designation, designation);
block->flags.bits.designated = true;
dirty_designations = false;
}
if(dirty_tiletypes)
{
COPY(block->tiletype, rawtiles);
dirty_tiletypes = false;
}
if(dirty_temperatures)
{
COPY(block->temperature_1, temp1);
COPY(block->temperature_2, temp2);
dirty_temperatures = false;
}
if(dirty_occupancies)
{
COPY(block->occupancy, occupancy);
dirty_occupancies = false;
}
return true;
}
void MapExtras::Block::SquashVeins(df::map_block *mb, t_blockmaterials & materials)
{
memset(materials,-1,sizeof(materials));
std::vector <df::block_square_event_mineralst *> veins;
Maps::SortBlockEvents(mb,&veins);
for (uint32_t x = 0;x<16;x++) for (uint32_t y = 0; y< 16;y++)
{
df::tiletype tt = mb->tiletype[x][y];
if (tileMaterial(tt) == tiletype_material::MINERAL)
{
for (size_t i = 0; i < veins.size(); i++)
{
if (veins[i]->getassignment(x,y))
materials[x][y] = veins[i]->inorganic_mat;
}
}
}
}
void MapExtras::Block::SquashFrozenLiquids(df::map_block *mb, tiletypes40d & frozen)
{
std::vector <df::block_square_event_frozen_liquidst *> ices;
Maps::SortBlockEvents(mb,NULL,&ices);
for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
{
df::tiletype tt = mb->tiletype[x][y];
frozen[x][y] = tiletype::Void;
if (tileMaterial(tt) == tiletype_material::FROZEN_LIQUID)
{
for (size_t i = 0; i < ices.size(); i++)
{
df::tiletype tt2 = ices[i]->tiles[x][y];
if (tt2 != tiletype::Void)
{
frozen[x][y] = tt2;
break;
}
}
}
}
}
void MapExtras::Block::SquashConstructions (df::map_block *mb, tiletypes40d & constructions)
{
for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
{
df::tiletype tt = mb->tiletype[x][y];
constructions[x][y] = tiletype::Void;
if (tileMaterial(tt) == tiletype_material::CONSTRUCTION)
{
DFCoord coord = mb->map_pos + df::coord(x,y,0);
df::construction *con = df::construction::find(coord);
if (con)
constructions[x][y] = con->original_tile;
}
}
}
void MapExtras::Block::SquashRocks (df::map_block *mb, t_blockmaterials & materials,
std::vector< std::vector <int16_t> > * layerassign)
{
// get the layer materials
for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
{
materials[x][y] = -1;
uint8_t test = mb->designation[x][y].bits.biome;
if (test >= 9)
continue;
uint8_t idx = mb->region_offset[test];
if (idx < layerassign->size())
materials[x][y] = layerassign->at(idx)[mb->designation[x][y].bits.geolayer_index];
}
}
int16_t MapExtras::Block::GeoIndexAt(df::coord2d p)
{
auto des = index_tile<df::tile_designation>(designation,p);
uint8_t idx = des.bits.biome;
if (idx >= 9)
return -1;
idx = block->region_offset[idx];
if (idx >= parent->geoidx.size())
return -1;
return parent->geoidx[idx];
}
bool MapExtras::Block::GetGlobalFeature(t_feature *out)
{
out->type = (df::feature_type)-1;
if (!valid || block->global_feature < 0)
return false;
return Maps::GetGlobalFeature(*out, block->global_feature);
}
bool MapExtras::Block::GetLocalFeature(t_feature *out)
{
out->type = (df::feature_type)-1;
if (!valid || block->local_feature < 0)
return false;
return Maps::GetLocalFeature(*out, block->map_pos/16, block->local_feature);
}
MapExtras::Block *MapExtras::MapCache::BlockAt(DFCoord blockcoord)
{
if(!valid)
return 0;
std::map <DFCoord, Block*>::iterator iter = blocks.find(blockcoord);
if(iter != blocks.end())
{
return (*iter).second;
}
else
{
if(blockcoord.x >= 0 && blockcoord.x < x_bmax &&
blockcoord.y >= 0 && blockcoord.y < y_bmax &&
blockcoord.z >= 0 && blockcoord.z < z_max)
{
Block * nblo = new Block(this, blockcoord);
blocks[blockcoord] = nblo;
return nblo;
}
return 0;
}
}

@ -272,7 +272,7 @@ static command_result autodump_main(color_ostream &out, vector <string> & parame
// write map changes back to DF. // write map changes back to DF.
MC.WriteAll(); MC.WriteAll();
// Is this necessary? Is "forbid" a dirtyable attribute like "dig" is? // Is this necessary? Is "forbid" a dirtyable attribute like "dig" is?
Maps::WriteDirtyBit(cx/16, cy/16, cz, true); //Maps::WriteDirtyBit(cx/16, cy/16, cz, true);
} }
out.print("Done. %d items %s.\n", dumped_total, destroy ? "marked for destruction" : "quickdumped"); out.print("Done. %d items %s.\n", dumped_total, destroy ? "marked for destruction" : "quickdumped");
return CR_OK; return CR_OK;

@ -189,13 +189,13 @@ command_result changelayer (color_ostream &out, std::vector <std::string> & para
uint32_t tileY = cursorY % 16; uint32_t tileY = cursorY % 16;
MapExtras::Block * b = mc.BlockAt(cursor/16); MapExtras::Block * b = mc.BlockAt(cursor/16);
if(!b && !b->valid) if(!b || !b->is_valid())
{ {
out.printerr("No data.\n"); out.printerr("No data.\n");
return CR_OK; return CR_OK;
} }
mapblock40d & block = b->raw;
df::tile_designation &des = block.designation[tileX][tileY]; df::tile_designation des = b->DesignationAt(cursor%16);
// get biome and geolayer at cursor position // get biome and geolayer at cursor position
uint32_t biome = des.bits.biome; uint32_t biome = des.bits.biome;

@ -90,7 +90,7 @@ bool dig (MapExtras::MapCache & MCache,
{ {
DFCoord at (x,y,z); DFCoord at (x,y,z);
auto b = MCache.BlockAt(at/16); auto b = MCache.BlockAt(at/16);
if(!b || !b->valid) if(!b || !b->is_valid())
return false; return false;
if(x == 0 || x == x_max * 16 - 1) if(x == 0 || x == x_max * 16 - 1)
{ {
@ -1027,6 +1027,8 @@ command_result digv (color_ostream &out, vector <string> & parameters)
{ {
DFHack::DFCoord current = flood.top(); DFHack::DFCoord current = flood.top();
flood.pop(); flood.pop();
if (MCache->tagAt(current))
continue;
int16_t vmat2 = MCache->veinMaterialAt(current); int16_t vmat2 = MCache->veinMaterialAt(current);
tt = MCache->tiletypeAt(current); tt = MCache->tiletypeAt(current);
if(!DFHack::isWallTerrain(tt)) if(!DFHack::isWallTerrain(tt))
@ -1061,7 +1063,8 @@ command_result digv (color_ostream &out, vector <string> & parameters)
} }
if(MCache->testCoord(current)) if(MCache->testCoord(current))
{ {
MCache->clearVeinMaterialAt(current); MCache->setTagAt(current, 1);
if(current.x < tx_max - 2) if(current.x < tx_max - 2)
{ {
flood.push(DFHack::DFCoord(current.x + 1, current.y, current.z)); flood.push(DFHack::DFCoord(current.x + 1, current.y, current.z));
@ -1209,6 +1212,8 @@ command_result digl (color_ostream &out, vector <string> & parameters)
{ {
DFHack::DFCoord current = flood.top(); DFHack::DFCoord current = flood.top();
flood.pop(); flood.pop();
if (MCache->tagAt(current))
continue;
int16_t vmat2 = MCache->veinMaterialAt(current); int16_t vmat2 = MCache->veinMaterialAt(current);
int16_t bmat2 = MCache->baseMaterialAt(current); int16_t bmat2 = MCache->baseMaterialAt(current);
tt = MCache->tiletypeAt(current); tt = MCache->tiletypeAt(current);
@ -1239,7 +1244,7 @@ command_result digl (color_ostream &out, vector <string> & parameters)
if(MCache->testCoord(current)) if(MCache->testCoord(current))
{ {
MCache->clearBaseMaterialAt(current); MCache->setTagAt(current, 1);
if(current.x < tx_max - 2) if(current.x < tx_max - 2)
{ {
flood.push(DFHack::DFCoord(current.x + 1, current.y, current.z)); flood.push(DFHack::DFCoord(current.x + 1, current.y, current.z));

@ -413,8 +413,8 @@ command_result df_liquids_execute(color_ostream &out)
Block * b = mcache.BlockAt((*iter)/16); Block * b = mcache.BlockAt((*iter)/16);
DFHack::t_blockflags bf = b->BlockFlags(); DFHack::t_blockflags bf = b->BlockFlags();
bf.bits.liquid_1 = true; bf.bits.update_liquid = true;
bf.bits.liquid_2 = true; bf.bits.update_liquid_twice = true;
b->setBlockFlags(bf); b->setBlockFlags(bf);
iter++; iter++;
@ -500,20 +500,20 @@ command_result df_liquids_execute(color_ostream &out)
DFHack::t_blockflags bflags = (*biter)->BlockFlags(); DFHack::t_blockflags bflags = (*biter)->BlockFlags();
if(flowmode == "f+") if(flowmode == "f+")
{ {
bflags.bits.liquid_1 = true; bflags.bits.update_liquid = true;
bflags.bits.liquid_2 = true; bflags.bits.update_liquid_twice = true;
(*biter)->setBlockFlags(bflags); (*biter)->setBlockFlags(bflags);
} }
else if(flowmode == "f-") else if(flowmode == "f-")
{ {
bflags.bits.liquid_1 = false; bflags.bits.update_liquid = false;
bflags.bits.liquid_2 = false; bflags.bits.update_liquid_twice = false;
(*biter)->setBlockFlags(bflags); (*biter)->setBlockFlags(bflags);
} }
else else
{ {
out << "flow bit 1 = " << bflags.bits.liquid_1 << endl; out << "flow bit 1 = " << bflags.bits.update_liquid << endl;
out << "flow bit 2 = " << bflags.bits.liquid_2 << endl; out << "flow bit 2 = " << bflags.bits.update_liquid_twice << endl;
} }
biter ++; biter ++;
} }

@ -151,7 +151,7 @@ command_result mapexport (color_ostream &out, std::vector <std::string> & parame
// Get the map block // Get the map block
df::coord2d blockCoord(b_x, b_y); df::coord2d blockCoord(b_x, b_y);
MapExtras::Block *b = map.BlockAt(DFHack::DFCoord(b_x, b_y, z)); MapExtras::Block *b = map.BlockAt(DFHack::DFCoord(b_x, b_y, z));
if (!b || !b->valid) if (!b || !b->is_valid())
{ {
continue; continue;
} }
@ -161,15 +161,9 @@ command_result mapexport (color_ostream &out, std::vector <std::string> & parame
protoblock.set_y(b_y); protoblock.set_y(b_y);
protoblock.set_z(z); protoblock.set_z(z);
{ // Find features // Find features
uint32_t index = b->raw.global_feature; b->GetGlobalFeature(&blockFeatureGlobal);
if (index != -1) b->GetLocalFeature(&blockFeatureLocal);
Maps::GetGlobalFeature(blockFeatureGlobal, index);
index = b->raw.local_feature;
if (index != -1)
Maps::GetLocalFeature(blockFeatureLocal, blockCoord, index);
}
int global_z = df::global::world->map.region_z + z; int global_z = df::global::world->map.region_z + z;

@ -127,13 +127,14 @@ command_result df_probe (color_ostream &out, vector <string> & parameters)
uint32_t tileY = cursorY % 16; uint32_t tileY = cursorY % 16;
MapExtras::Block * b = mc.BlockAt(cursor/16); MapExtras::Block * b = mc.BlockAt(cursor/16);
if(!b && !b->valid) if(!b || !b->is_valid())
{ {
out.printerr("No data.\n"); out.printerr("No data.\n");
return CR_OK; return CR_OK;
} }
mapblock40d & block = b->raw;
out.print("block addr: 0x%x\n\n", block.origin); auto &block = *b->getRaw();
out.print("block addr: 0x%x\n\n", &block);
/* /*
if (showBlock) if (showBlock)
{ {
@ -250,7 +251,7 @@ command_result df_probe (color_ostream &out, vector <string> & parameters)
t_feature local; t_feature local;
t_feature global; t_feature global;
Maps::ReadFeatures(&(b->raw),&local,&global); Maps::ReadFeatures(&block,&local,&global);
PRINT_FLAG( des, feature_local ); PRINT_FLAG( des, feature_local );
if(local.type != -1) if(local.type != -1)
{ {
@ -273,7 +274,6 @@ command_result df_probe (color_ostream &out, vector <string> & parameters)
<< endl; << endl;
out << "global feature idx: " << block.global_feature out << "global feature idx: " << block.global_feature
<< endl; << endl;
out << "mystery: " << block.mystery << endl;
out << std::endl; out << std::endl;
return CR_OK; return CR_OK;
} }

@ -426,20 +426,14 @@ command_result prospector (color_ostream &con, vector <string> & parameters)
// Get the map block // Get the map block
df::coord2d blockCoord(b_x, b_y); df::coord2d blockCoord(b_x, b_y);
MapExtras::Block *b = map.BlockAt(DFHack::DFCoord(b_x, b_y, z)); MapExtras::Block *b = map.BlockAt(DFHack::DFCoord(b_x, b_y, z));
if (!b || !b->valid) if (!b || !b->is_valid())
{ {
continue; continue;
} }
{ // Find features // Find features
uint32_t index = b->raw.global_feature; b->GetGlobalFeature(&blockFeatureGlobal);
if (index != -1) b->GetLocalFeature(&blockFeatureLocal);
Maps::GetGlobalFeature(blockFeatureGlobal, index);
index = b->raw.local_feature;
if (index != -1)
Maps::GetLocalFeature(blockFeatureLocal, blockCoord, index);
}
int global_z = world->map.region_z + z; int global_z = world->map.region_z + z;