Kill the Maps module

develop
Quietust 2012-01-19 21:44:17 -06:00
parent e7dcd4c66a
commit e7ecda1434
17 changed files with 769 additions and 1072 deletions

@ -1090,7 +1090,6 @@ TYPE * Core::get##TYPE() \
MODULE_GETTER(Units); MODULE_GETTER(Units);
MODULE_GETTER(Engravings); MODULE_GETTER(Engravings);
MODULE_GETTER(Maps);
MODULE_GETTER(Gui); MODULE_GETTER(Gui);
MODULE_GETTER(World); MODULE_GETTER(World);
MODULE_GETTER(Materials); MODULE_GETTER(Materials);

@ -54,7 +54,6 @@ namespace DFHack
class Module; class Module;
class Units; class Units;
class Engravings; class Engravings;
class Maps;
class Gui; class Gui;
class World; class World;
class Materials; class Materials;
@ -102,8 +101,6 @@ namespace DFHack
Units * getUnits(); Units * getUnits();
/// get the engravings module /// get the engravings module
Engravings * getEngravings(); Engravings * getEngravings();
/// get the maps module
Maps * getMaps();
/// get the gui module /// get the gui module
Gui * getGui(); Gui * getGui();
/// get the world module /// get the world module
@ -166,7 +163,6 @@ namespace DFHack
{ {
Units * pUnits; Units * pUnits;
Engravings * pEngravings; Engravings * pEngravings;
Maps * pMaps;
Gui * pGui; Gui * pGui;
World * pWorld; World * pWorld;
Materials * pMaterials; Materials * pMaterials;

@ -39,7 +39,6 @@ namespace DFHack
Module* createVegetation(); Module* createVegetation();
Module* createBuildings(); Module* createBuildings();
Module* createConstructions(); Module* createConstructions();
Module* createMaps();
Module* createNotes(); Module* createNotes();
Module* createGraphic(); Module* createGraphic();
} }

@ -32,13 +32,15 @@ distribution.
#include <cstring> #include <cstring>
#include "df/map_block.h" #include "df/map_block.h"
#include "df/block_square_event_mineralst.h" #include "df/block_square_event_mineralst.h"
using namespace DFHack;
using namespace DFHack::Simple;
namespace MapExtras namespace MapExtras
{ {
void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d & mb, DFHack::t_blockmaterials & materials) void SquashVeins (DFCoord bcoord, mapblock40d & mb, t_blockmaterials & materials)
{ {
memset(materials,-1,sizeof(materials)); memset(materials,-1,sizeof(materials));
std::vector <df::block_square_event_mineralst *> veins; std::vector <df::block_square_event_mineralst *> veins;
m->SortBlockEvents(bcoord.x,bcoord.y,bcoord.z,&veins); Maps::SortBlockEvents(bcoord.x,bcoord.y,bcoord.z,&veins);
//iterate through block rows //iterate through block rows
for(uint32_t j = 0;j<16;j++) for(uint32_t j = 0;j<16;j++)
{ {
@ -83,9 +85,8 @@ void SquashRocks ( std::vector< std::vector <uint16_t> > * layerassign, DFHack::
class Block class Block
{ {
public: public:
Block(DFHack::Maps *_m, DFHack::DFCoord _bcoord, std::vector< std::vector <uint16_t> > * layerassign = 0) Block(DFHack::DFCoord _bcoord, std::vector< std::vector <uint16_t> > * layerassign = 0)
{ {
m = _m;
dirty_designations = false; dirty_designations = false;
dirty_tiletypes = false; dirty_tiletypes = false;
dirty_temperatures = false; dirty_temperatures = false;
@ -93,10 +94,10 @@ class Block
dirty_occupancies = false; dirty_occupancies = false;
valid = false; valid = false;
bcoord = _bcoord; bcoord = _bcoord;
if(m->ReadBlock40d(bcoord.x,bcoord.y,bcoord.z,&raw)) if(Maps::ReadBlock40d(bcoord.x,bcoord.y,bcoord.z,&raw))
{ {
m->ReadTemperatures(bcoord.x,bcoord.y, bcoord.z,&temp1,&temp2); Maps::ReadTemperatures(bcoord.x,bcoord.y, bcoord.z,&temp1,&temp2);
SquashVeins(m,bcoord,raw,veinmats); SquashVeins(bcoord,raw,veinmats);
if(layerassign) if(layerassign)
SquashRocks(layerassign,raw,basemats); SquashRocks(layerassign,raw,basemats);
else else
@ -202,28 +203,28 @@ class Block
if(!valid) return false; if(!valid) return false;
if(dirty_designations) if(dirty_designations)
{ {
m->WriteDesignations(bcoord.x,bcoord.y,bcoord.z, &raw.designation); Maps::WriteDesignations(bcoord.x,bcoord.y,bcoord.z, &raw.designation);
m->WriteDirtyBit(bcoord.x,bcoord.y,bcoord.z,true); Maps::WriteDirtyBit(bcoord.x,bcoord.y,bcoord.z,true);
dirty_designations = false; dirty_designations = false;
} }
if(dirty_tiletypes) if(dirty_tiletypes)
{ {
m->WriteTileTypes(bcoord.x,bcoord.y,bcoord.z, &raw.tiletypes); Maps::WriteTileTypes(bcoord.x,bcoord.y,bcoord.z, &raw.tiletypes);
dirty_tiletypes = false; dirty_tiletypes = false;
} }
if(dirty_temperatures) if(dirty_temperatures)
{ {
m->WriteTemperatures(bcoord.x,bcoord.y,bcoord.z, &temp1, &temp2); Maps::WriteTemperatures(bcoord.x,bcoord.y,bcoord.z, &temp1, &temp2);
dirty_temperatures = false; dirty_temperatures = false;
} }
if(dirty_blockflags) if(dirty_blockflags)
{ {
m->WriteBlockFlags(bcoord.x,bcoord.y,bcoord.z,raw.blockflags); Maps::WriteBlockFlags(bcoord.x,bcoord.y,bcoord.z,raw.blockflags);
dirty_blockflags = false; dirty_blockflags = false;
} }
if(dirty_occupancies) if(dirty_occupancies)
{ {
m->WriteOccupancy(bcoord.x,bcoord.y,bcoord.z,&raw.occupancy); Maps::WriteOccupancy(bcoord.x,bcoord.y,bcoord.z,&raw.occupancy);
dirty_occupancies = false; dirty_occupancies = false;
} }
return true; return true;
@ -234,7 +235,6 @@ class Block
bool dirty_temperatures:1; bool dirty_temperatures:1;
bool dirty_blockflags:1; bool dirty_blockflags:1;
bool dirty_occupancies:1; bool dirty_occupancies:1;
DFHack::Maps * m;
DFHack::mapblock40d raw; DFHack::mapblock40d raw;
DFHack::DFCoord bcoord; DFHack::DFCoord bcoord;
DFHack::t_blockmaterials veinmats; DFHack::t_blockmaterials veinmats;
@ -246,12 +246,11 @@ class Block
class MapCache class MapCache
{ {
public: public:
MapCache(DFHack::Maps * Maps) MapCache()
{ {
valid = 0; valid = 0;
this->Maps = Maps; Maps::getSize(x_bmax, y_bmax, z_max);
Maps->getSize(x_bmax, y_bmax, z_max); validgeo = Maps::ReadGeology( layerassign );
validgeo = Maps->ReadGeology( layerassign );
valid = true; valid = true;
}; };
~MapCache() ~MapCache()
@ -278,9 +277,9 @@ class MapCache
{ {
Block * nblo; Block * nblo;
if(validgeo) if(validgeo)
nblo = new Block(Maps,blockcoord, &layerassign); nblo = new Block(blockcoord, &layerassign);
else else
nblo = new Block(Maps,blockcoord); nblo = new Block(blockcoord);
blocks[blockcoord] = nblo; blocks[blockcoord] = nblo;
return nblo; return nblo;
} }
@ -455,7 +454,6 @@ class MapCache
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< std::vector <uint16_t> > layerassign;
DFHack::Maps * Maps;
std::map<DFHack::DFCoord, Block *> blocks; std::map<DFHack::DFCoord, Block *> blocks;
}; };
} }

@ -58,364 +58,340 @@ distribution.
namespace DFHack namespace DFHack
{ {
/*************************************************************************** /***************************************************************************
T Y P E S T Y P E S
***************************************************************************/ ***************************************************************************/
/** /**
* Function for translating feature index to its name * Function for translating feature index to its name
* \ingroup grp_maps * \ingroup grp_maps
*/ */
extern DFHACK_EXPORT const char * sa_feature(df::feature_type index); extern DFHACK_EXPORT const char * sa_feature(df::feature_type index);
/** /**
* Class for holding a world coordinate. Can do math with coordinates and can be used as an index for std::map * Class for holding a world coordinate. Can do math with coordinates and can be used as an index for std::map
* \ingroup grp_maps * \ingroup grp_maps
*/ */
class DFCoord class DFCoord
{
public:
DFCoord(uint16_t _x, uint16_t _y, uint16_t _z = 0): x(_x), y(_y), z(_z) {}
DFCoord()
{ {
public: comparate = 0;
DFCoord(uint16_t _x, uint16_t _y, uint16_t _z = 0): x(_x), y(_y), z(_z) {} }
DFCoord() bool operator==(const DFCoord &other) const
{
comparate = 0;
}
bool operator==(const DFCoord &other) const
{
return (other.comparate == comparate);
}
bool operator!=(const DFCoord &other) const
{
return (other.comparate != comparate);
}
// FIXME: <tomprince> peterix_: you could probably get away with not defining operator< if you defined a std::less specialization for Vertex.
bool operator<(const DFCoord &other) const
{
return comparate < other.comparate;
}
DFCoord operator/(int number) const
{
return DFCoord(x/number, y/number, z);
}
DFCoord operator*(int number) const
{
return DFCoord(x*number, y*number, z);
}
DFCoord operator%(int number) const
{
return DFCoord(x%number, y%number, z);
}
DFCoord operator-(int number) const
{
return DFCoord(x,y,z-number);
}
DFCoord operator+(int number) const
{
return DFCoord(x,y,z+number);
}
// this is a hack. beware.
// x,y,z share the same space with comparate. comparate can be used for fast comparisons
union
{
// new shiny DFCoord struct. notice the ludicrous space for Z-levels
struct
{
uint16_t x;
uint16_t y;
uint32_t z;
};
// old planeccord struct for compatibility
struct
{
uint16_t x;
uint16_t y;
} dim;
// comparing thing
uint64_t comparate;
};
};
/**
* \ingroup grp_maps
*/
typedef DFCoord planecoord;
/**
* A local or global map feature
* \ingroup grp_maps
*/
struct t_feature
{ {
df::feature_type type; return (other.comparate == comparate);
/// main material type - decides between stuff like bodily fluids, inorganics, vomit, amber, etc. }
int16_t main_material; bool operator!=(const DFCoord &other) const
/// generally some index to a vector of material types.
int32_t sub_material;
/// placeholder
bool discovered;
/// this is NOT part of the DF feature, but an address of the feature as seen by DFhack.
void * origin;
};
/**
* \ingroup grp_maps
*/
enum BiomeOffset
{ {
eNorthWest, return (other.comparate != comparate);
eNorth, }
eNorthEast, // FIXME: <tomprince> peterix_: you could probably get away with not defining operator< if you defined a std::less specialization for Vertex.
eWest, bool operator<(const DFCoord &other) const
eHere,
eEast,
eSouthWest,
eSouth,
eSouthEast,
eBiomeCount
};
/**
* map block flags
* \ingroup grp_maps
*/
struct naked_blockflags
{ {
/// designated for jobs (digging and stuff like that) return comparate < other.comparate;
unsigned int designated : 1; }
/// possibly related to the designated flag DFCoord operator/(int number) const
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
* \ingroup grp_maps
*/
union t_blockflags
{ {
uint32_t whole; return DFCoord(x/number, y/number, z);
naked_blockflags bits; }
}; DFCoord operator*(int number) const
{
/** return DFCoord(x*number, y*number, z);
* 16x16 array of tile types }
* \ingroup grp_maps DFCoord operator%(int number) const
*/ {
typedef int16_t tiletypes40d [16][16]; return DFCoord(x%number, y%number, z);
/** }
* 16x16 array used for squashed block materials DFCoord operator-(int number) const
* \ingroup grp_maps
*/
typedef int16_t t_blockmaterials [16][16];
/**
* 16x16 array of designation flags
* \ingroup grp_maps
*/
typedef df::tile_designation designations40d [16][16];
/**
* 16x16 array of occupancy flags
* \ingroup grp_maps
*/
typedef df::tile_occupancy occupancies40d [16][16];
/**
* array of 16 biome indexes valid for the block
* \ingroup grp_maps
*/
typedef uint8_t biome_indices40d [9];
/**
* 16x16 array of temperatures
* \ingroup grp_maps
*/
typedef uint16_t t_temperatures [16][16];
/**
* structure for holding whole blocks
* \ingroup grp_maps
*/
typedef struct
{ {
DFCoord position; return DFCoord(x,y,z-number);
/// type of the tiles }
tiletypes40d tiletypes; DFCoord operator+(int number) const
/// 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
void * 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
* \ingroup grp_modules
* \ingroup grp_maps
*/
class DFHACK_EXPORT Maps : public Module
{ {
public: return DFCoord(x,y,z+number);
Maps(); }
~Maps(); // this is a hack. beware.
bool Start(); // x,y,z share the same space with comparate. comparate can be used for fast comparisons
bool Finish(); union
{
// read region surroundings, get their vectors of geolayers so we can do translation (or just hand the translation table to the client) // new shiny DFCoord struct. notice the ludicrous space for Z-levels
// returns an array of 9 vectors of indices into stone matgloss struct
/** {
Method for reading the geological surrounding of the currently loaded region. uint16_t x;
assign is a reference to an array of nine vectors of unsigned words that are to be filled with the data uint16_t y;
array is indexed by the BiomeOffset enum uint32_t z;
};
I omitted resolving the layer matgloss in this API, because it would // old planeccord struct for compatibility
introduce overhead by calling some method for each tile. You have to do it struct
yourself. {
uint16_t x;
First get the stuff from ReadGeology and then for each block get the RegionOffsets. uint16_t y;
For each tile get the real region from RegionOffsets and cross-reference it with } dim;
the geology stuff (region -- array of vectors, depth -- vector). // comparing thing
I'm thinking about turning that Geology stuff into a two-dimensional array uint64_t comparate;
with static size.
this is the algorithm for applying matgloss:
@code
void DfMap::applyGeoMatgloss(Block * b)
{
// load layer matgloss
for(int x_b = 0; x_b < BLOCK_SIZE; x_b++)
{
for(int y_b = 0; y_b < BLOCK_SIZE; y_b++)
{
int geolayer = b->designation[x_b][y_b].bits.geolayer_index;
int biome = b->designation[x_b][y_b].bits.biome;
b->material[x_b][y_b].type = Mat_Stone;
b->material[x_b][y_b].index = v_geology[b->RegionOffsets[biome]][geolayer];
}
}
}
@endcode
*/
bool ReadGeology( std::vector < std::vector <uint16_t> >& assign );
/**
* Initialize the map feature caches, if possible
*/
bool StartFeatures();
/**
* Free the feature cache
*/
bool StopFeatures();
/**
* Get a global feature with the given index.
*/
t_feature * GetGlobalFeature(int16_t index);
/**
* Get all valid local features for a x/y block coord.
*/
std::vector <t_feature *> * GetLocalFeatures(DFCoord coord);
/**
* Get the feature indexes of a block
*/
bool ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int16_t & global);
/**
* Set the feature indexes of a block
*/
bool WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int16_t & local, const int16_t & global);
/**
* Get pointers to features of a block
*/
bool ReadFeatures(uint32_t x, uint32_t y, uint32_t z, t_feature ** local, t_feature ** global);
/**
* Get pointers to features of an already read block
*/
bool ReadFeatures(mapblock40d * block, t_feature ** local, t_feature ** global);
/**
* @deprecated
* @todo: remove
*/
bool ReadGlobalFeatures( std::vector <t_feature> & features);
/**
* @deprecated
* @todo: remove
*/
bool ReadLocalFeatures( std::map <DFCoord, std::vector<t_feature *> > & local_features );
/*
* BLOCK DATA
*/
/// get size of the map in tiles
void getSize(uint32_t& x, uint32_t& y, uint32_t& z);
/// get the position of the map on world map
void getPosition(int32_t& x, int32_t& y, int32_t& z);
/**
* Get the map block or NULL if block is not valid
*/
df::map_block * getBlock (int32_t blockx, int32_t blocky, int32_t blockz);
df::map_block * getBlockAbs (int32_t x, int32_t y, int32_t z);
/// 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);
/// 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);
/// 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);
/// 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);
/// 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);
/// 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);
/// 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);
/// 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);
/// 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);
/// 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<df::block_square_event_mineralst *>* veins,
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_grassst *>* grass = 0,
std::vector<df::block_square_event_world_constructionst *>* constructions = 0
);
/// remove a block event from the block by address
bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square_event * which );
/// read all plants in this block
bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_plant *>*& plants);
private:
struct Private;
Private *d;
}; };
};
/**
* \ingroup grp_maps
*/
typedef DFCoord planecoord;
/**
* A local or global map feature
* \ingroup grp_maps
*/
struct t_feature
{
df::feature_type type;
/// main material type - decides between stuff like bodily fluids, inorganics, vomit, amber, etc.
int16_t main_material;
/// generally some index to a vector of material types.
int32_t sub_material;
/// placeholder
bool discovered;
/// this is NOT part of the DF feature, but an address of the feature as seen by DFhack.
void * origin;
};
/**
* \ingroup grp_maps
*/
enum BiomeOffset
{
eNorthWest,
eNorth,
eNorthEast,
eWest,
eHere,
eEast,
eSouthWest,
eSouth,
eSouthEast,
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
* \ingroup grp_maps
*/
union t_blockflags
{
uint32_t whole;
naked_blockflags bits;
};
/**
* 16x16 array of tile types
* \ingroup grp_maps
*/
typedef int16_t tiletypes40d [16][16];
/**
* 16x16 array used for squashed block materials
* \ingroup grp_maps
*/
typedef int16_t t_blockmaterials [16][16];
/**
* 16x16 array of designation flags
* \ingroup grp_maps
*/
typedef df::tile_designation designations40d [16][16];
/**
* 16x16 array of occupancy flags
* \ingroup grp_maps
*/
typedef df::tile_occupancy occupancies40d [16][16];
/**
* array of 16 biome indexes valid for the block
* \ingroup grp_maps
*/
typedef uint8_t biome_indices40d [9];
/**
* 16x16 array of temperatures
* \ingroup grp_maps
*/
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
void * 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
* \ingroup grp_modules
* \ingroup grp_maps
*/
namespace Simple
{
namespace Maps
{
extern DFHACK_EXPORT bool IsValid();
/**
* Method for reading the geological surrounding of the currently loaded region.
* assign is a reference to an array of nine vectors of unsigned words that are to be filled with the data
* array is indexed by the BiomeOffset enum
*
* I omitted resolving the layer matgloss in this API, because it would
* introduce overhead by calling some method for each tile. You have to do it
* yourself.
*
* First get the stuff from ReadGeology and then for each block get the RegionOffsets.
* For each tile get the real region from RegionOffsets and cross-reference it with
* the geology stuff (region -- array of vectors, depth -- vector).
* I'm thinking about turning that Geology stuff into a two-dimensional array
* with static size.
*
* this is the algorithm for applying matgloss:
* @code
void DfMap::applyGeoMatgloss(Block * b)
{
// load layer matgloss
for(int x_b = 0; x_b < BLOCK_SIZE; x_b++)
{
for(int y_b = 0; y_b < BLOCK_SIZE; y_b++)
{
int geolayer = b->designation[x_b][y_b].bits.geolayer_index;
int biome = b->designation[x_b][y_b].bits.biome;
b->material[x_b][y_b].type = Mat_Stone;
b->material[x_b][y_b].index = v_geology[b->RegionOffsets[biome]][geolayer];
}
}
}
* @endcode
*/
extern DFHACK_EXPORT bool ReadGeology( std::vector < std::vector <uint16_t> >& assign );
/**
* 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
*/
extern DFHACK_EXPORT bool ReadFeatures(uint32_t x, uint32_t y, uint32_t z, t_feature * local, t_feature * global);
/**
* Get pointers to features of an already read block
*/
extern DFHACK_EXPORT bool ReadFeatures(mapblock40d * block, t_feature * local, t_feature * global);
/**
* Read a specific global or local feature directly
*/
extern DFHACK_EXPORT bool GetGlobalFeature(t_feature &feature, int32_t index);
extern DFHACK_EXPORT bool GetLocalFeature(t_feature &feature, DFCoord coord, int32_t index);
/*
* BLOCK DATA
*/
/// get size of the map in tiles
extern DFHACK_EXPORT void getSize(uint32_t& x, uint32_t& y, uint32_t& z);
/// get the position of the map on world map
extern DFHACK_EXPORT void getPosition(int32_t& x, int32_t& y, int32_t& z);
/**
* Get the map block or NULL if block is not valid
*/
extern DFHACK_EXPORT df::map_block * getBlock (int32_t blockx, int32_t blocky, int32_t blockz);
extern DFHACK_EXPORT df::map_block * getBlockAbs (int32_t x, int32_t y, int32_t 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
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
/// mineral veins, what's under ice, blood smears and mud
extern DFHACK_EXPORT bool SortBlockEvents(uint32_t x, uint32_t y, uint32_t z,
std::vector<df::block_square_event_mineralst *>* veins,
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_grassst *>* grass = 0,
std::vector<df::block_square_event_world_constructionst *>* constructions = 0
);
/// remove a block event from the block by address
extern DFHACK_EXPORT bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square_event * which );
/// read all plants in this block
extern DFHACK_EXPORT bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_plant *>*& plants);
}
}
} }
#endif #endif

@ -45,16 +45,9 @@ using namespace std;
#include "df/world_underground_region.h" #include "df/world_underground_region.h"
#include "df/feature_init.h" #include "df/feature_init.h"
using df::global::world;
#define MAPS_GUARD if(!d->Started) throw DFHack::Error::ModuleNotInitialized();
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
Module* DFHack::createMaps() using df::global::world;
{
return new Maps();
}
const char * DFHack::sa_feature(df::feature_type index) const char * DFHack::sa_feature(df::feature_type index)
{ {
@ -85,78 +78,12 @@ const char * DFHack::sa_feature(df::feature_type index)
} }
}; };
struct Maps::Private bool Maps::IsValid ()
{
uint32_t worldSizeX, worldSizeY;
uint32_t maps_module;
Process * owner;
bool Inited;
bool FeaturesStarted;
bool Started;
bool hasGeology;
bool hasFeatures;
bool hasVeggies;
// map between feature address and the read object
map <void *, t_feature> local_feature_store;
map <DFCoord, vector <t_feature *> > m_local_feature;
vector <t_feature> v_global_feature;
vector<uint16_t> v_geology[eBiomeCount];
};
Maps::Maps()
{ {
Core & c = Core::getInstance(); return (world->map.block_index != NULL);
d = new Private;
Process *p = d->owner = c.p;
d->Inited = d->FeaturesStarted = d->Started = false;
DFHack::VersionInfo * mem = c.vinfo;
d->hasFeatures = d->hasGeology = d->hasVeggies = true;
d->Inited = true;
}
Maps::~Maps()
{
if(d->FeaturesStarted)
StopFeatures();
if(d->Started)
Finish();
delete d;
} }
/*-----------------------------------* #define MAPS_GUARD if(!IsValid()) throw DFHack::Error::ModuleNotInitialized();
* Init the mapblock pointer array *
*-----------------------------------*/
bool Maps::Start()
{
if(!d->Inited)
return false;
if(d->Started)
Finish();
Process *p = d->owner;
// get the size
int32_t & mx = world->map.x_count_block;
int32_t & my = world->map.y_count_block;
int32_t & mz = world->map.z_count_block;
// test for wrong map dimensions
if (mx == 0 || mx > 48 || my == 0 || my > 48 || mz == 0)
{
cerr << hex << &mx << " " << &my << " " << &mz << endl;
cerr << dec << mx << " "<< my << " "<< mz << endl;
return false;
}
d->Started = true;
return true;
}
// getter for map size // getter for map size
void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z) void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z)
@ -176,16 +103,11 @@ void Maps::getPosition (int32_t& x, int32_t& y, int32_t& z)
z = world->map.region_z; z = world->map.region_z;
} }
bool Maps::Finish()
{
return true;
}
/* /*
* Block reading * Block reading
*/ */
df::map_block* Maps::getBlock (int32_t blockx, int32_t blocky, int32_t blockz) df::map_block *Maps::getBlock (int32_t blockx, int32_t blocky, int32_t blockz)
{ {
if ((blockx < 0) || (blocky < 0) || (blockz < 0)) if ((blockx < 0) || (blocky < 0) || (blockz < 0))
return NULL; return NULL;
@ -206,7 +128,6 @@ df::map_block *Maps::getBlockAbs (int32_t x, int32_t y, int32_t z)
bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer) bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer)
{ {
MAPS_GUARD MAPS_GUARD
Process *p = d->owner;
df::map_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
@ -218,10 +139,7 @@ bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer
buffer->global_feature = block->global_feature; buffer->global_feature = block->global_feature;
buffer->local_feature = block->local_feature; buffer->local_feature = block->local_feature;
buffer->mystery = block->unk2; buffer->mystery = block->unk2;
// FIXME: not 64-bit safe
buffer->origin = &block; buffer->origin = &block;
//uint32_t addr_of_struct = p->readDWord(addr);
// FIXME: maybe truncates
buffer->blockflags.whole = block->flags; buffer->blockflags.whole = block->flags;
return true; return true;
} }
@ -235,7 +153,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) bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(buffer, block->tiletype, sizeof(tiletypes40d)); memcpy(buffer, block->tiletype, sizeof(tiletypes40d));
@ -247,7 +165,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) bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(block->tiletype, buffer, sizeof(tiletypes40d)); memcpy(block->tiletype, buffer, sizeof(tiletypes40d));
@ -262,7 +180,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) bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
dirtybit = block->flags.is_set(df::block_flags::Designated); dirtybit = block->flags.is_set(df::block_flags::Designated);
@ -274,7 +192,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) bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
block->flags.set(df::block_flags::Designated, dirtybit); block->flags.set(df::block_flags::Designated, dirtybit);
@ -290,7 +208,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) bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &blockflags)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
blockflags.whole = block->flags; blockflags.whole = block->flags;
@ -302,7 +220,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) bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
return (block->flags = blockflags.whole); return (block->flags = blockflags.whole);
@ -316,7 +234,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) bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(buffer, block->designation, sizeof(designations40d)); memcpy(buffer, block->designation, sizeof(designations40d));
@ -328,7 +246,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) bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(block->designation, buffer, sizeof(designations40d)); memcpy(block->designation, buffer, sizeof(designations40d));
@ -343,7 +261,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) bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(buffer, block->occupancy, sizeof(occupancies40d)); memcpy(buffer, block->occupancy, sizeof(occupancies40d));
@ -355,7 +273,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) bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(block->occupancy, buffer, sizeof(occupancies40d)); memcpy(block->occupancy, buffer, sizeof(occupancies40d));
@ -370,7 +288,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) bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
if(temp1) if(temp1)
@ -384,7 +302,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) bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
if(temp1) if(temp1)
@ -402,7 +320,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) bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(buffer, block->region_offset,sizeof(biome_indices40d)); memcpy(buffer, block->region_offset,sizeof(biome_indices40d));
@ -410,126 +328,64 @@ bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices4
} }
return false; return false;
} }
bool Maps::StopFeatures()
bool Maps::GetGlobalFeature(t_feature &feature, int32_t index)
{ {
if(d->FeaturesStarted) feature.type = (df::feature_type)-1;
{ MAPS_GUARD
d->local_feature_store.clear();
d->v_global_feature.clear(); if ((index < 0) || (index >= world->world_data->underground_regions.size()))
d->m_local_feature.clear(); return false;
d->FeaturesStarted = false;
return true; df::feature_init *f = world->world_data->underground_regions[index]->feature_init;
}
return false; feature.discovered = false;
feature.origin = f;
feature.type = f->getType();
f->getMaterial(&feature.main_material, &feature.sub_material);
return true;
} }
bool Maps::StartFeatures() bool Maps::GetLocalFeature(t_feature &feature, DFCoord coord, int32_t index)
{ {
feature.type = (df::feature_type)-1;
MAPS_GUARD MAPS_GUARD
if(d->FeaturesStarted) return true;
if(!d->hasFeatures) return false;
// regionX and regionY are in embark squares! // regionX and regionY are in embark squares!
// we convert to full region tiles // we convert to full region tiles
// this also works in adventure mode // this also works in adventure mode
// region X coord - whole regions // region X coord - whole regions
uint32_t region_x = ( (coord.x / 3) + world->map.region_x ) / 16;
// region Y coord - whole regions
uint32_t region_y = ( (coord.y / 3) + world->map.region_y ) / 16;
for(uint32_t blockX = 0; blockX < world->map.x_count_block; blockX ++) uint32_t bigregion_x = region_x / 16;
for(uint32_t blockY = 0; blockY < world->map.y_count_block; blockY ++) uint32_t bigregion_y = region_y / 16;
{
// regionX and regionY are in embark squares!
// we convert to full region tiles
// this also works in adventure mode
// region X coord - whole regions
uint32_t region_x = ( (blockX / 3) + world->map.region_x ) / 16;
// region Y coord - whole regions
uint32_t region_y = ( (blockY / 3) + world->map.region_y ) / 16;
uint32_t bigregion_x = region_x / 16;
uint32_t bigregion_y = region_y / 16;
uint32_t sub_x = region_x % 16;
uint32_t sub_y = region_y % 16;
// megaregions = 16x16 squares of regions = 256x256 squares of embark squares
// base = pointer to local feature structure (inside world data struct)
// bigregion is 16x16 regions. for each bigregion in X dimension:
if(world->world_data->unk_204[bigregion_x][bigregion_y].features)
{
vector <df::feature_init *> *features = &world->world_data->unk_204[bigregion_x][bigregion_y].features->feature_init[sub_x][sub_y];
uint32_t size = features->size();
DFCoord pc(blockX,blockY);
std::vector<t_feature *> tempvec;
for(uint32_t i = 0; i < size; i++)
{
df::feature_init * cur_ptr = features->at(i);
map <void *, t_feature>::iterator it;
it = d->local_feature_store.find(cur_ptr);
// do we already have the feature?
if(it != d->local_feature_store.end())
{
// push pointer to existing feature
tempvec.push_back(&((*it).second));
}
// no?
else
{
t_feature tftemp;
tftemp.discovered = false;
tftemp.origin = cur_ptr;
tftemp.type = cur_ptr->getType();
cur_ptr->getMaterial(&tftemp.main_material, &tftemp.sub_material);
d->local_feature_store[cur_ptr] = tftemp;
// push pointer
tempvec.push_back(&(d->local_feature_store[cur_ptr]));
}
}
d->m_local_feature[pc] = tempvec;
}
}
// enumerate global features uint32_t sub_x = region_x % 16;
uint32_t size = world->world_data->underground_regions.size(); uint32_t sub_y = region_y % 16;
d->v_global_feature.clear(); // megaregions = 16x16 squares of regions = 256x256 squares of embark squares
d->v_global_feature.reserve(size);
for (uint32_t i = 0; i < size; i++)
{
t_feature temp;
df::feature_init * feat_ptr = world->world_data->underground_regions[i]->feature_init;
temp.origin = feat_ptr;
temp.discovered = false;
temp.type = feat_ptr->getType();
feat_ptr->getMaterial(&temp.main_material, &temp.sub_material);
d->v_global_feature.push_back(temp);
}
d->FeaturesStarted = true;
return true;
}
t_feature * Maps::GetGlobalFeature(int16_t index) // bigregion is 16x16 regions. for each bigregion in X dimension:
{ if (!world->world_data->unk_204[bigregion_x][bigregion_y].features)
if(!d->FeaturesStarted) return 0; return false;
if(index < 0 || uint16_t(index) >= d->v_global_feature.size())
return 0;
return &(d->v_global_feature[index]);
}
std::vector <t_feature *> * Maps::GetLocalFeatures(DFCoord coord) vector <df::feature_init *> &features = world->world_data->unk_204[bigregion_x][bigregion_y].features->feature_init[sub_x][sub_y];
{ if ((index < 0) || (index >= features.size()))
if(!d->FeaturesStarted) return 0; return false;
coord.z = 0; // just making sure df::feature_init *f = features[index];
map <DFCoord, std::vector <t_feature* > >::iterator iter = d->m_local_feature.find(coord);
if(iter != d->m_local_feature.end()) feature.discovered = false;
{ feature.origin = f;
return &((*iter).second); feature.type = f->getType();
} f->getMaterial(&feature.main_material, &feature.sub_material);
return 0; return true;
} }
bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int16_t & global) bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int32_t & local, int32_t & global)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
local = block->local_feature; local = block->local_feature;
@ -539,10 +395,10 @@ bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int
return false; return false;
} }
bool Maps::WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int16_t & local, const int16_t & global) bool Maps::WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int32_t & local, const int32_t & global)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
block->local_feature = local; block->local_feature = local;
@ -552,58 +408,56 @@ bool Maps::WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int16_t & loc
return false; 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)
{ {
if(!d->FeaturesStarted) return false; MAPS_GUARD
int16_t loc, glob;
if(!ReadFeatures(x,y,z,loc,glob)) return false;
if(global && glob != -1) int32_t loc, glob;
*global = &(d->v_global_feature[glob]); if (!ReadFeatures(x, y, z, loc, glob))
else if (global) return false;
*global = 0;
if(local && loc != -1) bool result = true;
if (global)
{
if (glob != -1)
result &= GetGlobalFeature(*global, glob);
else
global->type = (df::feature_type)-1;
}
if (local)
{ {
DFCoord foo(x,y,0); if (loc != -1)
map <DFCoord, std::vector <t_feature* > >::iterator iter = d->m_local_feature.find(foo);
if(iter != d->m_local_feature.end())
{ {
*local = ((*iter).second)[loc]; DFCoord coord(x,y,0);
result &= GetLocalFeature(*local, coord, loc);
} }
else *local = 0; else
local->type = (df::feature_type)-1;
} }
else if(local) return result;
*local = 0;
return true;
} }
bool Maps::ReadFeatures(mapblock40d * block, t_feature ** local, t_feature ** global) bool Maps::ReadFeatures(mapblock40d * block, t_feature * local, t_feature * global)
{ {
if(!block) return false; MAPS_GUARD
if(!d->FeaturesStarted) return false;
DFCoord c = block->position; if (global)
c.z = 0;
*global = 0;
*local = 0;
if(block->global_feature != -1)
*global = &(d->v_global_feature[block->global_feature]);
if(local && block->local_feature != -1)
{ {
map <DFCoord, std::vector <t_feature* > >::iterator iter = d->m_local_feature.find(c); if (block->global_feature != -1)
if(iter != d->m_local_feature.end()) GetGlobalFeature(*global, block->global_feature);
{ }
*local = ((*iter).second)[block->local_feature]; if (local)
} {
else *local = 0; if (block->local_feature != -1)
GetLocalFeature(*local, block->position, block->local_feature);
} }
return true; return true;
} }
bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local) bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int32_t local)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
block->local_feature = local; block->local_feature = local;
@ -612,10 +466,10 @@ bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t loca
return false; return false;
} }
bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global) bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int32_t global)
{ {
MAPS_GUARD MAPS_GUARD
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if (block) if (block)
{ {
block->global_feature = global; block->global_feature = global;
@ -635,19 +489,24 @@ bool Maps::SortBlockEvents(uint32_t x, uint32_t y, uint32_t z,
vector <df::block_square_event_world_constructionst *> *constructions) vector <df::block_square_event_world_constructionst *> *constructions)
{ {
MAPS_GUARD MAPS_GUARD
Process* p = d->owner;
df::map_block * block = getBlock(x,y,z); if (veins)
if(veins) veins->clear(); veins->clear();
if(ices) ices->clear(); if (ices)
if(splatter) splatter->clear(); ices->clear();
if(grass) grass->clear(); if (splatter)
if(constructions) constructions->clear(); splatter->clear();
if (grass)
grass->clear();
if (constructions)
constructions->clear();
df::map_block * block = getBlock(x,y,z);
if (!block) if (!block)
return false; return false;
uint32_t size = block->block_events.size(); uint32_t size = block->block_events.size();
// read all veins // read all events
for (uint32_t i = 0; i < size;i++) for (uint32_t i = 0; i < size;i++)
{ {
df::block_square_event *evt = block->block_events[i]; df::block_square_event *evt = block->block_events[i];
@ -681,19 +540,17 @@ bool Maps::SortBlockEvents(uint32_t x, uint32_t y, uint32_t z,
bool Maps::RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square_event * which) bool Maps::RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square_event * which)
{ {
MAPS_GUARD MAPS_GUARD
Process* p = d->owner;
df::map_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if(block) if (!block)
return false;
for (uint32_t i = 0; i < block->block_events.size(); i++)
{ {
for(int i = 0; i < block->block_events.size();i++) if (block->block_events[i] == which)
{ {
if (block->block_events[i] == which) delete which;
{ block->block_events.erase(block->block_events.begin() + i);
free(which); return true;
block->block_events.erase(block->block_events.begin() + i);
return true;
}
} }
} }
return false; return false;
@ -705,8 +562,8 @@ bool Maps::RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square
bool Maps::ReadGeology (vector < vector <uint16_t> >& assign) bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
{ {
MAPS_GUARD MAPS_GUARD
if(!d->hasGeology) return false;
vector<uint16_t> v_geology[eBiomeCount];
// 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++)
{ {
@ -726,55 +583,29 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
/// 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
vector <df::world_data::T_unk_190::T_unk_4 *> *geolayers = &world->world_data->unk_190[geoindex]->unk_4; vector <df::world_data::T_unk_190::T_unk_4 *> &geolayers = world->world_data->unk_190[geoindex]->unk_4;
/// layer descriptor has a field that determines the type of stone/soil /// layer descriptor has a field that determines the type of stone/soil
d->v_geology[i].reserve (geolayers->size()); v_geology[i].reserve(geolayers.size());
// finally, read the layer matgloss // finally, read the layer matgloss
for (uint32_t j = 0;j < geolayers->size();j++) for (uint32_t j = 0; j < geolayers.size(); j++)
{ v_geology[i].push_back(geolayers[j]->unk_4);
d->v_geology[i].push_back (geolayers->at(j)->unk_4);
}
} }
assign.clear(); assign.clear();
assign.reserve (eBiomeCount); assign.reserve(eBiomeCount);
for (int i = 0; i < eBiomeCount;i++) for (int i = 0; i < eBiomeCount; i++)
{ assign.push_back(v_geology[i]);
assign.push_back (d->v_geology[i]);
}
return true; return true;
} }
bool Maps::ReadLocalFeatures( std::map <DFCoord, std::vector<t_feature *> > & local_features )
{
StopFeatures();
StartFeatures();
if(d->FeaturesStarted)
{
local_features = d->m_local_feature;
return true;
}
return false;
}
bool Maps::ReadGlobalFeatures( std::vector <t_feature> & features )
{
StopFeatures();
StartFeatures();
if(d->FeaturesStarted)
{
features = d->v_global_feature;
return true;
}
return false;
}
bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_plant *>*& plants) bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_plant *>*& plants)
{ {
if(!d->hasVeggies || !d->Started) MAPS_GUARD
return false;
df::map_block * block = getBlock(x,y,z); df::map_block *block = getBlock(x,y,z);
if(!block) if (!block)
return false; return false;
plants = (vector<DFHack::df_plant *> *)&block->plants; plants = (vector<DFHack::df_plant *> *)&block->plants;

@ -96,17 +96,14 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
DFHack::VersionInfo *mem = c->vinfo; DFHack::VersionInfo *mem = c->vinfo;
DFHack::Gui * Gui = c->getGui(); DFHack::Gui * Gui = c->getGui();
DFHack::Maps *Maps = c->getMaps(); if (!Maps::IsValid())
std::size_t numItems = world->items.all.size();
// init the map
if(!Maps->Start())
{ {
c->con.printerr("Can't initialize map.\n"); c->con.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
MapCache MC (Maps); std::size_t numItems = world->items.all.size();
MapCache MC;
int i = 0; int i = 0;
int dumped_total = 0; int dumped_total = 0;
@ -185,8 +182,8 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
{ {
// yes... // yes...
cerr << "Moving from block to block!" << endl; cerr << "Moving from block to block!" << endl;
df::map_block * bl_src = Maps->getBlock(itm->pos.x /16, itm->pos.y/16, itm->pos.z); df::map_block * bl_src = Maps::getBlockAbs(itm->pos.x, itm->pos.y, itm->pos.z);
df::map_block * bl_tgt = Maps->getBlock(cx /16, cy/16, cz); df::map_block * bl_tgt = Maps::getBlockAbs(cx, cy, cz);
if(bl_src) if(bl_src)
{ {
std::remove(bl_src->items.begin(), bl_src->items.end(),itm->id); std::remove(bl_src->items.begin(), bl_src->items.end(),itm->id);
@ -255,7 +252,7 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
// 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);
} }
c->con.print("Done. %d items %s.\n", dumped_total, destroy ? "marked for destruction" : "quickdumped"); c->con.print("Done. %d items %s.\n", dumped_total, destroy ? "marked for destruction" : "quickdumped");
return CR_OK; return CR_OK;

@ -2,12 +2,9 @@
#include "Console.h" #include "Console.h"
#include "Export.h" #include "Export.h"
#include "PluginManager.h" #include "PluginManager.h"
#include "modules/Maps.h"
#include "DataDefs.h" #include "DataDefs.h"
#include "df/world.h"
#include "df/map_block.h"
#include "df/block_square_event.h"
#include "df/block_square_event_material_spatterst.h"
#include "df/item_actual.h" #include "df/item_actual.h"
#include "df/unit.h" #include "df/unit.h"
#include "df/unit_spatter.h" #include "df/unit_spatter.h"
@ -19,6 +16,7 @@
using std::vector; using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
using namespace DFHack::Simple;
using df::global::world; using df::global::world;
using df::global::cursor; using df::global::cursor;
@ -115,16 +113,6 @@ command_result cleanunits (Core * c)
return CR_OK; return CR_OK;
} }
// This is slightly different from what's in the Maps module - it takes tile coordinates rather than block coordinates
df::map_block *getBlock (int32_t x, int32_t y, int32_t z)
{
if ((x < 0) || (y < 0) || (z < 0))
return NULL;
if ((x >= world->map.x_count) || (y >= world->map.y_count) || (z >= world->map.z_count))
return NULL;
return world->map.block_index[x >> 4][y >> 4][z];
}
DFhackCExport command_result spotclean (Core * c, vector <string> & parameters) DFhackCExport command_result spotclean (Core * c, vector <string> & parameters)
{ {
// HOTKEY COMMAND: CORE ALREADY SUSPENDED // HOTKEY COMMAND: CORE ALREADY SUSPENDED
@ -133,7 +121,7 @@ DFhackCExport command_result spotclean (Core * c, vector <string> & parameters)
c->con.printerr("The cursor is not active.\n"); c->con.printerr("The cursor is not active.\n");
return CR_FAILURE; return CR_FAILURE;
} }
df::map_block *block = getBlock(cursor->x, cursor->y, cursor->z); df::map_block *block = Maps::getBlockAbs(cursor->x, cursor->y, cursor->z);
if (block == NULL) if (block == NULL)
{ {
c->con.printerr("Invalid map block selected!\n"); c->con.printerr("Invalid map block selected!\n");

@ -17,7 +17,7 @@ using MapExtras::MapCache;
using namespace DFHack; using namespace DFHack;
//Function pointer type for whole-map tile checks. //Function pointer type for whole-map tile checks.
typedef void (*checkTile)(DFHack::DFCoord, MapExtras::MapCache *); typedef void (*checkTile)(DFHack::DFCoord, MapExtras::MapCache &);
//Forward Declarations for Commands //Forward Declarations for Commands
DFhackCExport command_result filltraffic(DFHack::Core * c, std::vector<std::string> & params); DFhackCExport command_result filltraffic(DFHack::Core * c, std::vector<std::string> & params);
@ -28,10 +28,10 @@ DFhackCExport command_result setAllMatching(DFHack::Core * c, checkTile checkPro
DFHack::DFCoord minCoord = DFHack::DFCoord(0, 0, 0), DFHack::DFCoord minCoord = DFHack::DFCoord(0, 0, 0),
DFHack::DFCoord maxCoord = DFHack::DFCoord(0xFFFF, 0xFFFF, 0xFFFF)); DFHack::DFCoord maxCoord = DFHack::DFCoord(0xFFFF, 0xFFFF, 0xFFFF));
void allHigh(DFHack::DFCoord coord, MapExtras::MapCache * map); void allHigh(DFHack::DFCoord coord, MapExtras::MapCache & map);
void allNormal(DFHack::DFCoord coord, MapExtras::MapCache * map); void allNormal(DFHack::DFCoord coord, MapExtras::MapCache & map);
void allLow(DFHack::DFCoord coord, MapExtras::MapCache * map); void allLow(DFHack::DFCoord coord, MapExtras::MapCache & map);
void allRestricted(DFHack::DFCoord coord, MapExtras::MapCache * map); void allRestricted(DFHack::DFCoord coord, MapExtras::MapCache & map);
DFhackCExport const char * plugin_name ( void ) DFhackCExport const char * plugin_name ( void )
{ {
@ -108,18 +108,16 @@ DFhackCExport command_result filltraffic(DFHack::Core * c, std::vector<std::stri
//Initialization. //Initialization.
c->Suspend(); c->Suspend();
DFHack::Maps * Maps = c->getMaps();
DFHack::Gui * Gui = c->getGui(); DFHack::Gui * Gui = c->getGui();
// init the map if (!Maps::IsValid())
if(!Maps->Start())
{ {
c->con.printerr("Can't init map. Make sure you have a map loaded in DF.\n"); c->con.printerr("Map is not available!\n");
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
int32_t cx, cy, cz; int32_t cx, cy, cz;
Maps->getSize(x_max,y_max,z_max); Maps::getSize(x_max,y_max,z_max);
uint32_t tx_max = x_max * 16; uint32_t tx_max = x_max * 16;
uint32_t ty_max = y_max * 16; uint32_t ty_max = y_max * 16;
Gui->getCursorCoords(cx,cy,cz); Gui->getCursorCoords(cx,cy,cz);
@ -131,20 +129,19 @@ DFhackCExport command_result filltraffic(DFHack::Core * c, std::vector<std::stri
} }
DFHack::DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz); DFHack::DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz);
MapExtras::MapCache * MCache = new MapExtras::MapCache(Maps); MapExtras::MapCache MCache;
df::tile_designation des = MCache->designationAt(xy); df::tile_designation des = MCache.designationAt(xy);
int16_t tt = MCache->tiletypeAt(xy); int16_t tt = MCache.tiletypeAt(xy);
df::tile_occupancy oc; df::tile_occupancy oc;
if (checkbuilding) if (checkbuilding)
oc = MCache->occupancyAt(xy); oc = MCache.occupancyAt(xy);
source = (df::tile_traffic)des.bits.traffic; source = (df::tile_traffic)des.bits.traffic;
if(source == target) if(source == target)
{ {
c->con.printerr("This tile is already set to the target traffic type.\n"); c->con.printerr("This tile is already set to the target traffic type.\n");
delete MCache;
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
@ -152,7 +149,6 @@ DFhackCExport command_result filltraffic(DFHack::Core * c, std::vector<std::stri
if(DFHack::isWallTerrain(tt)) if(DFHack::isWallTerrain(tt))
{ {
c->con.printerr("This tile is a wall. Please select a passable tile.\n"); c->con.printerr("This tile is a wall. Please select a passable tile.\n");
delete MCache;
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
@ -160,7 +156,6 @@ DFhackCExport command_result filltraffic(DFHack::Core * c, std::vector<std::stri
if(checkpit && DFHack::isOpenTerrain(tt)) if(checkpit && DFHack::isOpenTerrain(tt))
{ {
c->con.printerr("This tile is a hole. Please select a passable tile.\n"); c->con.printerr("This tile is a hole. Please select a passable tile.\n");
delete MCache;
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
@ -168,7 +163,6 @@ DFhackCExport command_result filltraffic(DFHack::Core * c, std::vector<std::stri
if(checkbuilding && oc.bits.building) if(checkbuilding && oc.bits.building)
{ {
c->con.printerr("This tile contains a building. Please select an empty tile.\n"); c->con.printerr("This tile contains a building. Please select an empty tile.\n");
delete MCache;
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
@ -184,25 +178,25 @@ DFhackCExport command_result filltraffic(DFHack::Core * c, std::vector<std::stri
xy = flood.top(); xy = flood.top();
flood.pop(); flood.pop();
des = MCache->designationAt(xy); des = MCache.designationAt(xy);
if (des.bits.traffic != source) continue; if (des.bits.traffic != source) continue;
tt = MCache->tiletypeAt(xy); tt = MCache.tiletypeAt(xy);
if(DFHack::isWallTerrain(tt)) continue; if(DFHack::isWallTerrain(tt)) continue;
if(checkpit && DFHack::isOpenTerrain(tt)) continue; if(checkpit && DFHack::isOpenTerrain(tt)) continue;
if (checkbuilding) if (checkbuilding)
{ {
oc = MCache->occupancyAt(xy); oc = MCache.occupancyAt(xy);
if(oc.bits.building) continue; if(oc.bits.building) continue;
} }
//This tile is ready. Set its traffic level and add surrounding tiles. //This tile is ready. Set its traffic level and add surrounding tiles.
if (MCache->testCoord(xy)) if (MCache.testCoord(xy))
{ {
des.bits.traffic = target; des.bits.traffic = target;
MCache->setDesignationAt(xy,des); MCache.setDesignationAt(xy,des);
if (xy.x > 0) if (xy.x > 0)
{ {
@ -236,7 +230,7 @@ DFhackCExport command_result filltraffic(DFHack::Core * c, std::vector<std::stri
} }
} }
MCache->WriteAll(); MCache.WriteAll();
c->Resume(); c->Resume();
return CR_OK; return CR_OK;
} }
@ -245,7 +239,7 @@ enum e_checktype {no_check, check_equal, check_nequal};
DFhackCExport command_result alltraffic(DFHack::Core * c, std::vector<std::string> & params) DFhackCExport command_result alltraffic(DFHack::Core * c, std::vector<std::string> & params)
{ {
void (*proc)(DFHack::DFCoord, MapExtras::MapCache *) = allNormal; void (*proc)(DFHack::DFCoord, MapExtras::MapCache &) = allNormal;
//Loop through parameters //Loop through parameters
for(int i = 0; i < params.size();i++) for(int i = 0; i < params.size();i++)
@ -289,19 +283,17 @@ DFhackCExport command_result setAllMatching(DFHack::Core * c, checkTile checkPro
//Initialization. //Initialization.
c->Suspend(); c->Suspend();
DFHack::Maps * Maps = c->getMaps();
DFHack::Gui * Gui = c->getGui(); DFHack::Gui * Gui = c->getGui();
// init the map if (!Maps::IsValid())
if(!Maps->Start())
{ {
c->con.printerr("Can't init map. Make sure you have a map loaded in DF.\n"); c->con.printerr("Map is not available!\n");
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
//Maximum map size. //Maximum map size.
uint32_t x_max,y_max,z_max; uint32_t x_max,y_max,z_max;
Maps->getSize(x_max,y_max,z_max); Maps::getSize(x_max,y_max,z_max);
uint32_t tx_max = x_max * 16; uint32_t tx_max = x_max * 16;
uint32_t ty_max = y_max * 16; uint32_t ty_max = y_max * 16;
@ -330,7 +322,7 @@ DFhackCExport command_result setAllMatching(DFHack::Core * c, checkTile checkPro
return CR_FAILURE; return CR_FAILURE;
} }
MapExtras::MapCache * MCache = new MapExtras::MapCache(Maps); MapExtras::MapCache MCache;
c->con.print("Setting traffic...\n"); c->con.print("Setting traffic...\n");
@ -347,34 +339,34 @@ DFhackCExport command_result setAllMatching(DFHack::Core * c, checkTile checkPro
} }
} }
MCache->WriteAll(); MCache.WriteAll();
c->con.print("Complete!\n"); c->con.print("Complete!\n");
c->Resume(); c->Resume();
return CR_OK; return CR_OK;
} }
//Unconditionally set map to target traffic type //Unconditionally set map to target traffic type
void allHigh(DFHack::DFCoord coord, MapExtras::MapCache * map) void allHigh(DFHack::DFCoord coord, MapExtras::MapCache &map)
{ {
df::tile_designation des = map->designationAt(coord); df::tile_designation des = map.designationAt(coord);
des.bits.traffic = df::tile_traffic::High; des.bits.traffic = df::tile_traffic::High;
map->setDesignationAt(coord, des); map.setDesignationAt(coord, des);
} }
void allNormal(DFHack::DFCoord coord, MapExtras::MapCache * map) void allNormal(DFHack::DFCoord coord, MapExtras::MapCache &map)
{ {
df::tile_designation des = map->designationAt(coord); df::tile_designation des = map.designationAt(coord);
des.bits.traffic = df::tile_traffic::Normal; des.bits.traffic = df::tile_traffic::Normal;
map->setDesignationAt(coord, des); map.setDesignationAt(coord, des);
} }
void allLow(DFHack::DFCoord coord, MapExtras::MapCache * map) void allLow(DFHack::DFCoord coord, MapExtras::MapCache &map)
{ {
df::tile_designation des = map->designationAt(coord); df::tile_designation des = map.designationAt(coord);
des.bits.traffic = df::tile_traffic::Low; des.bits.traffic = df::tile_traffic::Low;
map->setDesignationAt(coord, des); map.setDesignationAt(coord, des);
} }
void allRestricted(DFHack::DFCoord coord, MapExtras::MapCache * map) void allRestricted(DFHack::DFCoord coord, MapExtras::MapCache &map)
{ {
df::tile_designation des = map->designationAt(coord); df::tile_designation des = map.designationAt(coord);
des.bits.traffic = df::tile_traffic::Restricted; des.bits.traffic = df::tile_traffic::Restricted;
map->setDesignationAt(coord, des); map.setDesignationAt(coord, des);
} }

@ -169,7 +169,6 @@ DFhackCExport command_result df_liquids (Core * c, vector <string> & parameters)
int32_t x,y,z; int32_t x,y,z;
uint32_t x_max,y_max,z_max; uint32_t x_max,y_max,z_max;
DFHack::Maps * Maps;
DFHack::Gui * Position; DFHack::Gui * Position;
for(int i = 0; i < parameters.size();i++) for(int i = 0; i < parameters.size();i++)
{ {
@ -360,16 +359,14 @@ DFhackCExport command_result df_liquids (Core * c, vector <string> & parameters)
else if(command.empty()) else if(command.empty())
{ {
c->Suspend(); c->Suspend();
Maps = c->getMaps(); Maps::getSize(x_max,y_max,z_max);
Maps->Start();
Maps->getSize(x_max,y_max,z_max);
Position = c->getGui(); Position = c->getGui();
do do
{ {
if(!Maps->Start()) if (!Maps::IsValid())
{ {
c->con << "Can't see any DF map loaded." << endl; c->con << "Can't see any DF map loaded." << endl;
break; break;;
} }
if(!Position->getCursorCoords(x,y,z)) if(!Position->getCursorCoords(x,y,z))
{ {
@ -377,7 +374,7 @@ DFhackCExport command_result df_liquids (Core * c, vector <string> & parameters)
break; break;
} }
c->con << "cursor coords: " << x << "/" << y << "/" << z << endl; c->con << "cursor coords: " << x << "/" << y << "/" << z << endl;
MapCache mcache(Maps); MapCache mcache;
DFHack::DFCoord cursor(x,y,z); DFHack::DFCoord cursor(x,y,z);
coord_vec all_tiles = brush->points(mcache,cursor); coord_vec all_tiles = brush->points(mcache,cursor);
c->con << "working..." << endl; c->con << "working..." << endl;
@ -530,7 +527,6 @@ DFhackCExport command_result df_liquids (Core * c, vector <string> & parameters)
c->con << "OK" << endl; c->con << "OK" << endl;
else else
c->con << "Something failed horribly! RUN!" << endl; c->con << "Something failed horribly! RUN!" << endl;
Maps->Finish();
} while (0); } while (0);
c->Resume(); c->Resume();
} }

@ -99,17 +99,16 @@ static command_result immolations (Core * c, do_what what, bool shrubs, bool tre
return CR_OK; return CR_OK;
} }
c->Suspend(); c->Suspend();
DFHack::Maps *maps = c->getMaps(); if (!Maps::IsValid())
if (!maps->Start())
{ {
c->con.printerr( "Cannot get map info!\n"); c->con.printerr("Map is not available!\n");
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
DFHack::Gui * Gui = c->getGui(); DFHack::Gui * Gui = c->getGui();
uint32_t x_max, y_max, z_max; uint32_t x_max, y_max, z_max;
maps->getSize(x_max, y_max, z_max); Maps::getSize(x_max, y_max, z_max);
MapExtras::MapCache map(maps); MapExtras::MapCache map;
DFHack::Vegetation *veg = c->getVegetation(); DFHack::Vegetation *veg = c->getVegetation();
if (!veg->all_plants) if (!veg->all_plants)
{ {
@ -138,7 +137,7 @@ static command_result immolations (Core * c, do_what what, bool shrubs, bool tre
if(Gui->getCursorCoords(x,y,z)) if(Gui->getCursorCoords(x,y,z))
{ {
vector<DFHack::df_plant *> * alltrees; vector<DFHack::df_plant *> * alltrees;
if(maps->ReadVegetation(x/16,y/16,z,alltrees)) if(Maps::ReadVegetation(x/16,y/16,z,alltrees))
{ {
bool didit = false; bool didit = false;
for(size_t i = 0 ; i < alltrees->size(); i++) for(size_t i = 0 ; i < alltrees->size(); i++)
@ -168,7 +167,6 @@ static command_result immolations (Core * c, do_what what, bool shrubs, bool tre
} }
// Cleanup // Cleanup
veg->Finish(); veg->Finish();
maps->Finish();
c->Resume(); c->Resume();
return CR_OK; return CR_OK;
} }
@ -212,16 +210,14 @@ DFhackCExport command_result df_grow (Core * c, vector <string> & parameters)
} }
} }
c->Suspend(); c->Suspend();
DFHack::Maps *maps = c->getMaps();
Console & con = c->con; Console & con = c->con;
if (!maps->Start()) if (!Maps::IsValid())
{ {
con.printerr("Cannot get map info!\n"); c->con.printerr("Map is not available!\n");
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
//maps->getSize(x_max, y_max, z_max); MapExtras::MapCache map;
MapExtras::MapCache map(maps);
DFHack::Vegetation *veg = c->getVegetation(); DFHack::Vegetation *veg = c->getVegetation();
if (!veg->all_plants) if (!veg->all_plants)
{ {
@ -234,7 +230,7 @@ DFhackCExport command_result df_grow (Core * c, vector <string> & parameters)
if(Gui->getCursorCoords(x,y,z)) if(Gui->getCursorCoords(x,y,z))
{ {
vector<DFHack::df_plant *> * alltrees; vector<DFHack::df_plant *> * alltrees;
if(maps->ReadVegetation(x/16,y/16,z,alltrees)) if(Maps::ReadVegetation(x/16,y/16,z,alltrees))
{ {
for(size_t i = 0 ; i < alltrees->size(); i++) for(size_t i = 0 ; i < alltrees->size(); i++)
{ {
@ -266,7 +262,6 @@ DFhackCExport command_result df_grow (Core * c, vector <string> & parameters)
// Cleanup // Cleanup
veg->Finish(); veg->Finish();
maps->Finish();
c->Resume(); c->Resume();
return CR_OK; return CR_OK;
} }

@ -99,196 +99,182 @@ DFhackCExport command_result df_probe (Core * c, vector <string> & parameters)
DFHack::Gui *Gui = c->getGui(); DFHack::Gui *Gui = c->getGui();
DFHack::Materials *Materials = c->getMaterials(); DFHack::Materials *Materials = c->getMaterials();
DFHack::VersionInfo* mem = c->vinfo; DFHack::VersionInfo* mem = c->vinfo;
DFHack::Maps *Maps = c->getMaps();
std::vector<t_matglossInorganic> inorganic; std::vector<t_matglossInorganic> inorganic;
bool hasmats = Materials->CopyInorganicMaterials(inorganic); bool hasmats = Materials->CopyInorganicMaterials(inorganic);
if(!Maps->Start()) if (!Maps::IsValid())
{ {
con.printerr("Unable to access map data!\n"); c->con.printerr("Map is not available!\n");
c->Resume();
return CR_FAILURE;
} }
else MapExtras::MapCache mc;
{
MapExtras::MapCache mc (Maps);
int32_t regionX, regionY, regionZ; int32_t regionX, regionY, regionZ;
Maps->getPosition(regionX,regionY,regionZ); Maps::getPosition(regionX,regionY,regionZ);
bool have_features = Maps->StartFeatures(); int32_t cursorX, cursorY, cursorZ;
Gui->getCursorCoords(cursorX,cursorY,cursorZ);
int32_t cursorX, cursorY, cursorZ; if(cursorX == -30000)
Gui->getCursorCoords(cursorX,cursorY,cursorZ); {
if(cursorX == -30000) con.printerr("No cursor; place cursor over tile to probe.\n");
{ c->Resume();
con.printerr("No cursor; place cursor over tile to probe.\n"); return CR_FAILURE;
} }
else DFCoord cursor (cursorX,cursorY,cursorZ);
{
DFCoord cursor (cursorX,cursorY,cursorZ);
uint32_t blockX = cursorX / 16; uint32_t blockX = cursorX / 16;
uint32_t tileX = cursorX % 16; uint32_t tileX = cursorX % 16;
uint32_t blockY = cursorY / 16; uint32_t blockY = cursorY / 16;
uint32_t tileY = cursorY % 16; uint32_t tileY = cursorY % 16;
MapExtras::Block * b = mc.BlockAt(cursor/16); MapExtras::Block * b = mc.BlockAt(cursor/16);
mapblock40d & block = b->raw; if(!b && !b->valid)
if(b && b->valid) {
{ con.printerr("No data.\n");
con.print("block addr: 0x%x\n\n", block.origin); c->Resume();
return CR_OK;
}
mapblock40d & block = b->raw;
con.print("block addr: 0x%x\n\n", block.origin);
/* /*
if (showBlock) if (showBlock)
{ {
con.print("block flags:\n"); con.print("block flags:\n");
print_bits<uint32_t>(block.blockflags.whole,con); print_bits<uint32_t>(block.blockflags.whole,con);
con.print("\n\n"); con.print("\n\n");
} }
*/ */
int16_t tiletype = mc.tiletypeAt(cursor); int16_t tiletype = mc.tiletypeAt(cursor);
df::tile_designation &des = block.designation[tileX][tileY]; df::tile_designation &des = block.designation[tileX][tileY];
/* /*
if(showDesig) if(showDesig)
{ {
con.print("designation\n"); con.print("designation\n");
print_bits<uint32_t>(block.designation[tileX][tileY].whole, print_bits<uint32_t>(block.designation[tileX][tileY].whole,
con); con);
con.print("\n\n"); con.print("\n\n");
} }
if(showOccup) if(showOccup)
{ {
con.print("occupancy\n"); con.print("occupancy\n");
print_bits<uint32_t>(block.occupancy[tileX][tileY].whole, print_bits<uint32_t>(block.occupancy[tileX][tileY].whole,
con); con);
con.print("\n\n"); con.print("\n\n");
} }
*/ */
// tiletype // tiletype
con.print("tiletype: %d", tiletype); con.print("tiletype: %d", tiletype);
if(tileName(tiletype)) if(tileName(tiletype))
con.print(" = %s",tileName(tiletype)); con.print(" = %s",tileName(tiletype));
con.print("\n"); con.print("\n");
DFHack::TileShape shape = tileShape(tiletype); DFHack::TileShape shape = tileShape(tiletype);
DFHack::TileMaterial material = tileMaterial(tiletype); DFHack::TileMaterial material = tileMaterial(tiletype);
DFHack::TileSpecial special = tileSpecial(tiletype); DFHack::TileSpecial special = tileSpecial(tiletype);
con.print("%-10s: %4d %s\n","Class" ,shape, con.print("%-10s: %4d %s\n","Class" ,shape,
TileShapeString[ shape ]); TileShapeString[ shape ]);
con.print("%-10s: %4d %s\n","Material" , con.print("%-10s: %4d %s\n","Material" ,
material,TileMaterialString[ material ]); material,TileMaterialString[ material ]);
con.print("%-10s: %4d %s\n","Special" , con.print("%-10s: %4d %s\n","Special" ,
special, TileSpecialString[ special ]); special, TileSpecialString[ special ]);
con.print("%-10s: %4d\n" ,"Variant" , con.print("%-10s: %4d\n" ,"Variant" ,
tileVariant(tiletype)); tileVariant(tiletype));
con.print("%-10s: %s\n" ,"Direction", con.print("%-10s: %s\n" ,"Direction",
tileDirection(tiletype).getStr()); tileDirection(tiletype).getStr());
con.print("\n"); con.print("\n");
con.print("temperature1: %d U\n",mc.temperature1At(cursor)); con.print("temperature1: %d U\n",mc.temperature1At(cursor));
con.print("temperature2: %d U\n",mc.temperature2At(cursor)); con.print("temperature2: %d U\n",mc.temperature2At(cursor));
// biome, geolayer // biome, geolayer
con << "biome: " << des.bits.biome << std::endl; con << "biome: " << des.bits.biome << std::endl;
con << "geolayer: " << des.bits.geolayer_index con << "geolayer: " << des.bits.geolayer_index
<< std::endl; << std::endl;
int16_t base_rock = mc.baseMaterialAt(cursor); int16_t base_rock = mc.baseMaterialAt(cursor);
if(base_rock != -1) if(base_rock != -1)
{ {
con << "Layer material: " << dec << base_rock; con << "Layer material: " << dec << base_rock;
if(hasmats) if(hasmats)
con << " / " << inorganic[base_rock].id con << " / " << inorganic[base_rock].id
<< " / " << " / "
<< inorganic[base_rock].name << inorganic[base_rock].name
<< endl; << endl;
else else
con << endl; con << endl;
} }
int16_t vein_rock = mc.veinMaterialAt(cursor); int16_t vein_rock = mc.veinMaterialAt(cursor);
if(vein_rock != -1) if(vein_rock != -1)
{ {
con << "Vein material (final): " << dec << vein_rock; con << "Vein material (final): " << dec << vein_rock;
if(hasmats) if(hasmats)
con << " / " << inorganic[vein_rock].id con << " / " << inorganic[vein_rock].id
<< " / " << " / "
<< inorganic[vein_rock].name << inorganic[vein_rock].name
<< endl; << endl;
else else
con << endl; con << endl;
} }
// liquids // liquids
if(des.bits.flow_size) if(des.bits.flow_size)
{ {
if(des.bits.liquid_type == df::tile_liquid::Magma) if(des.bits.liquid_type == df::tile_liquid::Magma)
con <<"magma: "; con <<"magma: ";
else con <<"water: "; else con <<"water: ";
con << des.bits.flow_size << std::endl; con << des.bits.flow_size << std::endl;
} }
if(des.bits.flow_forbid) if(des.bits.flow_forbid)
con << "flow forbid" << std::endl; con << "flow forbid" << std::endl;
if(des.bits.pile) if(des.bits.pile)
con << "stockpile?" << std::endl; con << "stockpile?" << std::endl;
if(des.bits.rained) if(des.bits.rained)
con << "rained?" << std::endl; con << "rained?" << std::endl;
if(des.bits.smooth) if(des.bits.smooth)
con << "smooth?" << std::endl; con << "smooth?" << std::endl;
if(des.bits.water_salt) if(des.bits.water_salt)
con << "salty" << endl; con << "salty" << endl;
if(des.bits.water_stagnant) if(des.bits.water_stagnant)
con << "stagnant" << endl; con << "stagnant" << endl;
#define PRINT_FLAG( X ) con.print("%-16s= %c\n", #X , ( des.X ? 'Y' : ' ' ) ) #define PRINT_FLAG( X ) con.print("%-16s= %c\n", #X , ( des.X ? 'Y' : ' ' ) )
PRINT_FLAG( bits.hidden ); PRINT_FLAG( bits.hidden );
PRINT_FLAG( bits.light ); PRINT_FLAG( bits.light );
PRINT_FLAG( bits.outside ); PRINT_FLAG( bits.outside );
PRINT_FLAG( bits.subterranean ); PRINT_FLAG( bits.subterranean );
PRINT_FLAG( bits.water_table ); PRINT_FLAG( bits.water_table );
PRINT_FLAG( bits.rained ); PRINT_FLAG( bits.rained );
DFCoord pc(blockX, blockY); DFCoord pc(blockX, blockY);
if(have_features) t_feature local;
{ t_feature global;
t_feature * local = 0; Maps::ReadFeatures(&(b->raw),&local,&global);
t_feature * global = 0; PRINT_FLAG( bits.feature_local );
Maps->ReadFeatures(&(b->raw),&local,&global); if(local.type != -1)
PRINT_FLAG( bits.feature_local ); {
if(local) con.print("%-16s", "");
{ con.print(" %4d", block.local_feature);
con.print("%-16s", ""); con.print(" (%2d)", local.type);
con.print(" %4d", block.local_feature); con.print(" addr 0x%X ", local.origin);
con.print(" (%2d)", local->type); con.print(" %s\n", sa_feature(local.type));
con.print(" addr 0x%X ", local->origin); }
con.print(" %s\n", sa_feature(local->type)); PRINT_FLAG( bits.feature_global );
} if(global.type != -1)
PRINT_FLAG( bits.feature_global ); {
if(global) con.print("%-16s", "");
{ con.print(" %4d", block.global_feature);
con.print("%-16s", ""); con.print(" (%2d)", global.type);
con.print(" %4d", block.global_feature); con.print(" %s\n", sa_feature(global.type));
con.print(" (%2d)", global->type);
con.print(" %s\n", sa_feature(global->type));
}
}
else
{
PRINT_FLAG( bits.feature_local );
PRINT_FLAG( bits.feature_global );
}
#undef PRINT_FLAG
con << "local feature idx: " << block.local_feature
<< endl;
con << "global feature idx: " << block.global_feature
<< endl;
con << "mystery: " << block.mystery << endl;
con << std::endl;
}
else
{
con.printerr("No data.\n");
}
}
} }
#undef PRINT_FLAG
con << "local feature idx: " << block.local_feature
<< endl;
con << "global feature idx: " << block.global_feature
<< endl;
con << "mystery: " << block.mystery << endl;
con << std::endl;
c->Resume(); c->Resume();
return CR_OK; return CR_OK;
} }

@ -68,9 +68,6 @@ bool operator>(const matdata & q1, const matdata & q2)
typedef std::map<int16_t, matdata> MatMap; typedef std::map<int16_t, matdata> MatMap;
typedef std::vector< pair<int16_t, matdata> > MatSorter; typedef std::vector< pair<int16_t, matdata> > MatSorter;
typedef std::vector<DFHack::t_feature> FeatureList;
typedef std::vector<DFHack::t_feature*> FeatureListPointer;
typedef std::map<DFHack::DFCoord, FeatureListPointer> FeatureMap;
typedef std::vector<DFHack::df_plant *> PlantList; typedef std::vector<DFHack::df_plant *> PlantList;
#define TO_PTR_VEC(obj_vec, ptr_vec) \ #define TO_PTR_VEC(obj_vec, ptr_vec) \
@ -221,15 +218,14 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
} }
uint32_t x_max = 0, y_max = 0, z_max = 0; uint32_t x_max = 0, y_max = 0, z_max = 0;
c->Suspend(); c->Suspend();
DFHack::Maps *maps = c->getMaps(); if (!Maps::IsValid())
if (!maps->Start())
{ {
con.printerr("Cannot get map info!\n"); c->con.printerr("Map is not available!\n");
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
maps->getSize(x_max, y_max, z_max); Maps::getSize(x_max, y_max, z_max);
MapExtras::MapCache map(maps); MapExtras::MapCache map;
DFHack::Materials *mats = c->getMaterials(); DFHack::Materials *mats = c->getMaterials();
if (!mats->df_inorganic) if (!mats->df_inorganic)
@ -244,10 +240,8 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
showPlants = false; showPlants = false;
} }
FeatureList globalFeatures; DFHack::t_feature blockFeatureGlobal;
FeatureMap localFeatures; DFHack::t_feature blockFeatureLocal;
DFHack::t_feature *blockFeatureGlobal = 0;
DFHack::t_feature *blockFeatureLocal = 0;
bool hasAquifer = false; bool hasAquifer = false;
bool hasDemonTemple = false; bool hasDemonTemple = false;
@ -262,16 +256,6 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
matdata liquidMagma; matdata liquidMagma;
matdata aquiferTiles; matdata aquiferTiles;
if (!(showSlade && maps->ReadGlobalFeatures(globalFeatures)))
{
con.printerr("Unable to read global features; slade won't be listed!\n");
}
if (!maps->ReadLocalFeatures(localFeatures))
{
con.printerr("Unable to read local features; adamantine and demon temples won't be listed.\n" );
}
uint32_t vegCount = 0; uint32_t vegCount = 0;
DFHack::Vegetation *veg = c->getVegetation(); DFHack::Vegetation *veg = c->getVegetation();
if (showPlants && !veg->Start()) if (showPlants && !veg->Start())
@ -294,23 +278,13 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
} }
{ // Find features { // Find features
uint16_t index = b->raw.global_feature; uint32_t index = b->raw.global_feature;
if (index != -1 && index < globalFeatures.size()) if (index != -1)
{ Maps::GetGlobalFeature(blockFeatureGlobal, index);
blockFeatureGlobal = &globalFeatures[index];
}
index = b->raw.local_feature; index = b->raw.local_feature;
FeatureMap::const_iterator it = localFeatures.find(blockCoord); if (index != -1)
if (it != localFeatures.end()) Maps::GetLocalFeature(blockFeatureLocal, blockCoord, index);
{
FeatureListPointer features = it->second;
if (index != -1 && index < features.size())
{
blockFeatureLocal = features[index];
}
}
} }
int global_z = df::global::world->map.region_z + z; int global_z = df::global::world->map.region_z + z;
@ -386,25 +360,25 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
veinMats[b->veinMaterialAt(coord)].add(global_z); veinMats[b->veinMaterialAt(coord)].add(global_z);
break; break;
case DFHack::FEATSTONE: case DFHack::FEATSTONE:
if (blockFeatureLocal && des.bits.feature_local) if (blockFeatureLocal.type != -1 && des.bits.feature_local)
{ {
if (blockFeatureLocal->type == df::feature_type::deep_special_tube if (blockFeatureLocal.type == df::feature_type::deep_special_tube
&& blockFeatureLocal->main_material == 0) // stone && blockFeatureLocal.main_material == 0) // stone
{ {
veinMats[blockFeatureLocal->sub_material].add(global_z); veinMats[blockFeatureLocal.sub_material].add(global_z);
} }
else if (showTemple else if (showTemple
&& blockFeatureLocal->type == df::feature_type::deep_surface_portal) && blockFeatureLocal.type == df::feature_type::deep_surface_portal)
{ {
hasDemonTemple = true; hasDemonTemple = true;
} }
} }
if (showSlade && blockFeatureGlobal && des.bits.feature_global if (showSlade && blockFeatureGlobal.type != -1 && des.bits.feature_global
&& blockFeatureGlobal->type == df::feature_type::feature_underworld_from_layer && blockFeatureGlobal.type == df::feature_type::feature_underworld_from_layer
&& blockFeatureGlobal->main_material == 0) // stone && blockFeatureGlobal.main_material == 0) // stone
{ {
layerMats[blockFeatureGlobal->sub_material].add(global_z); layerMats[blockFeatureGlobal.sub_material].add(global_z);
} }
break; break;
case DFHack::OBSIDIAN: case DFHack::OBSIDIAN:
@ -419,7 +393,7 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
if (showPlants) if (showPlants)
{ {
PlantList * plants; PlantList * plants;
if (maps->ReadVegetation(b_x, b_y, z, plants)) if (Maps::ReadVegetation(b_x, b_y, z, plants))
{ {
for (PlantList::const_iterator it = plants->begin(); it != plants->end(); it++) for (PlantList::const_iterator it = plants->begin(); it != plants->end(); it++)
{ {
@ -508,7 +482,6 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
veg->Finish(); veg->Finish();
} }
mats->Finish(); mats->Finish();
maps->Finish();
c->Resume(); c->Resume();
con << std::endl; con << std::endl;
return CR_OK; return CR_OK;

@ -16,21 +16,20 @@ using namespace DFHack;
/* /*
* Anything that might reveal Hell is unsafe. * Anything that might reveal Hell is unsafe.
*/ */
bool isSafe(uint32_t x, uint32_t y, uint32_t z, DFHack::Maps *Maps) bool isSafe(uint32_t x, uint32_t y, uint32_t z)
{ {
DFHack::t_feature *local_feature = NULL; DFHack::t_feature local_feature;
DFHack::t_feature *global_feature = NULL; DFHack::t_feature global_feature;
// get features of block // get features of block
// error -> obviously not safe to manipulate // error -> obviously not safe to manipulate
if(!Maps->ReadFeatures(x,y,z,&local_feature,&global_feature)) if(!Maps::ReadFeatures(x,y,z,&local_feature,&global_feature))
{
return false; return false;
}
// Adamantine tubes and temples lead to Hell // Adamantine tubes and temples lead to Hell
if (local_feature && (local_feature->type == df::feature_type::deep_special_tube || local_feature->type == df::feature_type::deep_surface_portal)) if (local_feature.type == df::feature_type::deep_special_tube || local_feature.type == df::feature_type::deep_surface_portal)
return false; return false;
// And Hell *is* Hell. // And Hell *is* Hell.
if (global_feature && global_feature->type == df::feature_type::feature_underworld_from_layer) if (global_feature.type == df::feature_type::feature_underworld_from_layer)
return false; return false;
// otherwise it's safe. // otherwise it's safe.
return true; return true;
@ -160,7 +159,6 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector<std::string> &
} }
c->Suspend(); c->Suspend();
DFHack::Maps *Maps =c->getMaps();
DFHack::World *World =c->getWorld(); DFHack::World *World =c->getWorld();
t_gamemodes gm; t_gamemodes gm;
World->ReadGameMode(gm); World->ReadGameMode(gm);
@ -170,21 +168,14 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector<std::string> &
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
if(!Maps->Start()) if (!Maps::IsValid())
{ {
con.printerr("Can't init map.\n"); c->con.printerr("Map is not available!\n");
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
if(no_hell && !Maps->StartFeatures()) Maps::getSize(x_max,y_max,z_max);
{
con.printerr("Unable to read local features; can't reveal map safely.\n");
c->Resume();
return CR_FAILURE;
}
Maps->getSize(x_max,y_max,z_max);
hidesaved.reserve(x_max * y_max * z_max); hidesaved.reserve(x_max * y_max * z_max);
for(uint32_t x = 0; x< x_max;x++) for(uint32_t x = 0; x< x_max;x++)
{ {
@ -192,11 +183,11 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector<std::string> &
{ {
for(uint32_t z = 0; z< z_max;z++) for(uint32_t z = 0; z< z_max;z++)
{ {
df::map_block *block = Maps->getBlock(x,y,z); df::map_block *block = Maps::getBlock(x,y,z);
if(block) if(block)
{ {
// in 'no-hell'/'safe' mode, don't reveal blocks with hell and adamantine // in 'no-hell'/'safe' mode, don't reveal blocks with hell and adamantine
if (no_hell && !isSafe(x, y, z, Maps)) if (no_hell && !isSafe(x, y, z))
continue; continue;
hideblock hb; hideblock hb;
hb.x = x; hb.x = x;
@ -255,7 +246,7 @@ DFhackCExport command_result unreveal(DFHack::Core * c, std::vector<std::string>
return CR_FAILURE; return CR_FAILURE;
} }
c->Suspend(); c->Suspend();
DFHack::Maps *Maps =c->getMaps();
DFHack::World *World =c->getWorld(); DFHack::World *World =c->getWorld();
t_gamemodes gm; t_gamemodes gm;
World->ReadGameMode(gm); World->ReadGameMode(gm);
@ -265,17 +256,16 @@ DFhackCExport command_result unreveal(DFHack::Core * c, std::vector<std::string>
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
Maps = c->getMaps(); if (!Maps::IsValid())
if(!Maps->Start())
{ {
con.printerr("Can't init map.\n"); c->con.printerr("Map is not available!\n");
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
// Sanity check: map size // Sanity check: map size
uint32_t x_max_b, y_max_b, z_max_b; uint32_t x_max_b, y_max_b, z_max_b;
Maps->getSize(x_max_b,y_max_b,z_max_b); Maps::getSize(x_max_b,y_max_b,z_max_b);
if(x_max != x_max_b || y_max != y_max_b || z_max != z_max_b) if(x_max != x_max_b || y_max != y_max_b || z_max != z_max_b)
{ {
con.printerr("The map is not of the same size...\n"); con.printerr("The map is not of the same size...\n");
@ -288,7 +278,7 @@ DFhackCExport command_result unreveal(DFHack::Core * c, std::vector<std::string>
for(size_t i = 0; i < hidesaved.size();i++) for(size_t i = 0; i < hidesaved.size();i++)
{ {
hideblock & hb = hidesaved[i]; hideblock & hb = hidesaved[i];
df::map_block * b = Maps->getBlock(hb.x,hb.y,hb.z); df::map_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++) for (uint32_t i = 0; i < 16;i++) for (uint32_t j = 0; j < 16;j++)
{ {
b->designation[i][j].bits.hidden = hb.hiddens[i][j]; b->designation[i][j].bits.hidden = hb.hiddens[i][j];
@ -336,13 +326,11 @@ DFhackCExport command_result revflood(DFHack::Core * c, std::vector<std::string>
} }
c->Suspend(); c->Suspend();
uint32_t x_max,y_max,z_max; uint32_t x_max,y_max,z_max;
Maps * Maps = c->getMaps();
Gui * Gui = c->getGui(); Gui * Gui = c->getGui();
World * World = c->getWorld(); World * World = c->getWorld();
// init the map if (!Maps::IsValid())
if(!Maps->Start())
{ {
c->con.printerr("Can't init map. Make sure you have a map loaded in DF.\n"); c->con.printerr("Map is not available!\n");
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
@ -361,7 +349,7 @@ DFhackCExport command_result revflood(DFHack::Core * c, std::vector<std::string>
return CR_FAILURE; return CR_FAILURE;
} }
int32_t cx, cy, cz; int32_t cx, cy, cz;
Maps->getSize(x_max,y_max,z_max); Maps::getSize(x_max,y_max,z_max);
uint32_t tx_max = x_max * 16; uint32_t tx_max = x_max * 16;
uint32_t ty_max = y_max * 16; uint32_t ty_max = y_max * 16;
@ -373,7 +361,7 @@ DFhackCExport command_result revflood(DFHack::Core * c, std::vector<std::string>
return CR_FAILURE; return CR_FAILURE;
} }
DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz); DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz);
MapCache * MCache = new MapCache(Maps); MapCache * MCache = new MapCache;
int16_t tt = MCache->tiletypeAt(xy); int16_t tt = MCache->tiletypeAt(xy);
if(isWallTerrain(tt)) if(isWallTerrain(tt))
{ {
@ -383,7 +371,7 @@ DFhackCExport command_result revflood(DFHack::Core * c, std::vector<std::string>
return CR_FAILURE; return CR_FAILURE;
} }
// hide all tiles, flush cache // hide all tiles, flush cache
Maps->getSize(x_max,y_max,z_max); Maps::getSize(x_max,y_max,z_max);
for(uint32_t x = 0; x< x_max;x++) for(uint32_t x = 0; x< x_max;x++)
{ {
@ -391,7 +379,7 @@ DFhackCExport command_result revflood(DFHack::Core * c, std::vector<std::string>
{ {
for(uint32_t z = 0; z< z_max;z++) for(uint32_t z = 0; z< z_max;z++)
{ {
df::map_block * b = Maps->getBlock(x,y,z); df::map_block * b = Maps::getBlock(x,y,z);
if(b) if(b)
{ {
// change the hidden flag to 0 // change the hidden flag to 0

@ -641,7 +641,6 @@ DFhackCExport command_result df_tiletypes (Core * c, vector <string> & parameter
uint32_t x_max = 0, y_max = 0, z_max = 0; uint32_t x_max = 0, y_max = 0, z_max = 0;
int32_t x = 0, y = 0, z = 0; int32_t x = 0, y = 0, z = 0;
DFHack::Maps *maps;
DFHack::Gui *gui; DFHack::Gui *gui;
for(int i = 0; i < parameters.size();i++) for(int i = 0; i < parameters.size();i++)
{ {
@ -755,15 +754,14 @@ DFhackCExport command_result df_tiletypes (Core * c, vector <string> & parameter
} }
c->Suspend(); c->Suspend();
maps = c->getMaps();
gui = c->getGui(); gui = c->getGui();
if (!maps->Start()) if (!Maps::IsValid())
{ {
c->con.printerr("Cannot get map info!\n"); c->con.printerr("Map is not available!\n");
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
maps->getSize(x_max, y_max, z_max); Maps::getSize(x_max, y_max, z_max);
if (!(gui->Start() && gui->getCursorCoords(x,y,z))) if (!(gui->Start() && gui->getCursorCoords(x,y,z)))
{ {
@ -774,7 +772,7 @@ DFhackCExport command_result df_tiletypes (Core * c, vector <string> & parameter
c->con.print("Cursor coords: (%d, %d, %d)\n",x,y,z); c->con.print("Cursor coords: (%d, %d, %d)\n",x,y,z);
DFHack::DFCoord cursor(x,y,z); DFHack::DFCoord cursor(x,y,z);
MapExtras::MapCache map(maps); MapExtras::MapCache map;
coord_vec all_tiles = brush->points(map, cursor); coord_vec all_tiles = brush->points(map, cursor);
c->con.print("working...\n"); c->con.print("working...\n");
@ -892,7 +890,6 @@ DFhackCExport command_result df_tiletypes (Core * c, vector <string> & parameter
{ {
c->con.printerr("Something failed horribly! RUN!\n"); c->con.printerr("Something failed horribly! RUN!\n");
} }
maps->Finish();
c->Resume(); c->Resume();
} }
} }

@ -55,23 +55,14 @@ DFhackCExport command_result tubefill(DFHack::Core * c, std::vector<std::string>
} }
} }
c->Suspend(); c->Suspend();
DFHack::Maps *Mapz = c->getMaps(); if (!Maps::IsValid())
// init the map
if (!Mapz->Start())
{ {
c->con.printerr("Can't init map.\n"); c->con.printerr("Map is not available!\n");
c->Resume(); c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
Mapz->getSize(x_max,y_max,z_max); Maps::getSize(x_max,y_max,z_max);
if(!Mapz->StartFeatures())
{
c->con.printerr("Can't get map features.\n");
c->Resume();
return CR_FAILURE;
}
// walk the map // walk the map
for (uint32_t x = 0; x< x_max;x++) for (uint32_t x = 0; x< x_max;x++)
@ -80,17 +71,17 @@ DFhackCExport command_result tubefill(DFHack::Core * c, std::vector<std::string>
{ {
for (uint32_t z = 0; z< z_max;z++) for (uint32_t z = 0; z< z_max;z++)
{ {
DFHack::t_feature * locf = 0; DFHack::t_feature locf;
DFHack::t_feature * glof = 0; DFHack::t_feature glof;
if (Mapz->ReadFeatures(x,y,z,&locf,&glof)) if (Maps::ReadFeatures(x,y,z,&locf,&glof))
{ {
// we're looking for addy tubes // we're looking for addy tubes
if(!locf) continue; if(locf.type == -1) continue;
if(locf->type != df::feature_type::deep_special_tube) continue; if(locf.type != df::feature_type::deep_special_tube) continue;
dirty=0; dirty=0;
Mapz->ReadDesignations(x,y,z, &designations); Maps::ReadDesignations(x,y,z, &designations);
Mapz->ReadTileTypes(x,y,z, &tiles); Maps::ReadTileTypes(x,y,z, &tiles);
for (uint32_t ty=0;ty<16;++ty) for (uint32_t ty=0;ty<16;++ty)
{ {
@ -117,7 +108,7 @@ DFhackCExport command_result tubefill(DFHack::Core * c, std::vector<std::string>
//If anything was changed, write it all. //If anything was changed, write it all.
if (dirty) if (dirty)
{ {
Mapz->WriteTileTypes(x,y,z, &tiles); Maps::WriteTileTypes(x,y,z, &tiles);
} }
} }
} }

@ -275,18 +275,17 @@ DFhackCExport command_result digcircle (Core * c, vector <string> & parameters)
int32_t cx, cy, cz; int32_t cx, cy, cz;
c->Suspend(); c->Suspend();
Gui * gui = c->getGui(); Gui * gui = c->getGui();
Maps * maps = c->getMaps(); if (!Maps::IsValid())
if(!maps->Start())
{ {
c->con.printerr("Map is not available!\n");
c->Resume(); c->Resume();
c->con.printerr("Can't init the map...\n");
return CR_FAILURE; return CR_FAILURE;
} }
uint32_t x_max, y_max, z_max; uint32_t x_max, y_max, z_max;
maps->getSize(x_max,y_max,z_max); Maps::getSize(x_max,y_max,z_max);
MapExtras::MapCache MCache (maps); MapExtras::MapCache MCache;
if(!gui->getCursorCoords(cx,cy,cz) || cx == -30000) if(!gui->getCursorCoords(cx,cy,cz) || cx == -30000)
{ {
c->Resume(); c->Resume();
@ -726,13 +725,12 @@ enum explo_what
EXPLO_DESIGNATED, EXPLO_DESIGNATED,
}; };
bool stamp_pattern (DFHack::Maps * maps, bool stamp_pattern (uint32_t bx, uint32_t by, int z_level,
uint32_t bx, uint32_t by, int z_level,
digmask & dm, explo_how how, explo_what what, digmask & dm, explo_how how, explo_what what,
int x_max, int y_max int x_max, int y_max
) )
{ {
df::map_block * bl = maps->getBlock(bx,by,z_level); df::map_block * bl = Maps::getBlock(bx,by,z_level);
if(!bl) if(!bl)
return false; return false;
int x = 0,mx = 16; int x = 0,mx = 16;
@ -854,15 +852,14 @@ DFhackCExport command_result expdig (Core * c, vector <string> & parameters)
} }
c->Suspend(); c->Suspend();
Gui * gui = c->getGui(); Gui * gui = c->getGui();
Maps * maps = c->getMaps();
uint32_t x_max, y_max, z_max; uint32_t x_max, y_max, z_max;
if(!maps->Start()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n");
c->Resume(); c->Resume();
c->con.printerr("Can't init the map...\n");
return CR_FAILURE; return CR_FAILURE;
} }
maps->getSize(x_max,y_max,z_max); Maps::getSize(x_max,y_max,z_max);
int32_t xzzz,yzzz,z_level; int32_t xzzz,yzzz,z_level;
if(!gui->getViewCoords(xzzz,yzzz,z_level)) if(!gui->getViewCoords(xzzz,yzzz,z_level))
{ {
@ -878,7 +875,7 @@ DFhackCExport command_result expdig (Core * c, vector <string> & parameters)
for(int32_t y = 0 ; y < y_max; y++) for(int32_t y = 0 ; y < y_max; y++)
{ {
which = (4*x + y) % 5; which = (4*x + y) % 5;
stamp_pattern(maps, x,y_max - 1 - y, z_level, diag5[which], stamp_pattern(x,y_max - 1 - y, z_level, diag5[which],
how, what, x_max, y_max); how, what, x_max, y_max);
} }
} }
@ -891,7 +888,7 @@ DFhackCExport command_result expdig (Core * c, vector <string> & parameters)
for(int32_t y = 0 ; y < y_max; y++) for(int32_t y = 0 ; y < y_max; y++)
{ {
which = (4*x + 1000-y) % 5; which = (4*x + 1000-y) % 5;
stamp_pattern(maps, x,y_max - 1 - y, z_level, diag5r[which], stamp_pattern(x,y_max - 1 - y, z_level, diag5r[which],
how, what, x_max, y_max); how, what, x_max, y_max);
} }
} }
@ -904,7 +901,7 @@ DFhackCExport command_result expdig (Core * c, vector <string> & parameters)
which = x % 3; which = x % 3;
for(int32_t y = 0 ; y < y_max; y++) for(int32_t y = 0 ; y < y_max; y++)
{ {
stamp_pattern(maps, x, y, z_level, ladder[which], stamp_pattern(x, y, z_level, ladder[which],
how, what, x_max, y_max); how, what, x_max, y_max);
} }
} }
@ -917,7 +914,7 @@ DFhackCExport command_result expdig (Core * c, vector <string> & parameters)
which = y % 3; which = y % 3;
for(uint32_t x = 0; x < x_max; x++) for(uint32_t x = 0; x < x_max; x++)
{ {
stamp_pattern(maps, x, y, z_level, ladderr[which], stamp_pattern(x, y, z_level, ladderr[which],
how, what, x_max, y_max); how, what, x_max, y_max);
} }
} }
@ -927,7 +924,7 @@ DFhackCExport command_result expdig (Core * c, vector <string> & parameters)
// middle + recentering for the image // middle + recentering for the image
int xmid = x_max * 8 - 8; int xmid = x_max * 8 - 8;
int ymid = y_max * 8 - 8; int ymid = y_max * 8 - 8;
MapExtras::MapCache mx (maps); MapExtras::MapCache mx;
for(int x = 0; x < 16; x++) for(int x = 0; x < 16; x++)
for(int y = 0; y < 16; y++) for(int y = 0; y < 16; y++)
{ {
@ -952,7 +949,7 @@ DFhackCExport command_result expdig (Core * c, vector <string> & parameters)
{ {
for(int32_t y = 0 ; y < y_max; y++) for(int32_t y = 0 ; y < y_max; y++)
{ {
stamp_pattern(maps, x, y, z_level, all_tiles, stamp_pattern(x, y, z_level, all_tiles,
how, what, x_max, y_max); how, what, x_max, y_max);
} }
} }
@ -983,17 +980,15 @@ DFhackCExport command_result vdig (Core * c, vector <string> & parameters)
Console & con = c->con; Console & con = c->con;
DFHack::Maps * Maps = c->getMaps();
DFHack::Gui * Gui = c->getGui(); DFHack::Gui * Gui = c->getGui();
// init the map if (!Maps::IsValid())
if(!Maps->Start())
{ {
con.printerr("Can't init map. Make sure you have a map loaded in DF.\n"); c->con.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
int32_t cx, cy, cz; int32_t cx, cy, cz;
Maps->getSize(x_max,y_max,z_max); Maps::getSize(x_max,y_max,z_max);
uint32_t tx_max = x_max * 16; uint32_t tx_max = x_max * 16;
uint32_t ty_max = y_max * 16; uint32_t ty_max = y_max * 16;
Gui->getCursorCoords(cx,cy,cz); Gui->getCursorCoords(cx,cy,cz);
@ -1008,7 +1003,7 @@ DFhackCExport command_result vdig (Core * c, vector <string> & parameters)
con.printerr("I won't dig the borders. That would be cheating!\n"); con.printerr("I won't dig the borders. That would be cheating!\n");
return CR_FAILURE; return CR_FAILURE;
} }
MapExtras::MapCache * MCache = new MapExtras::MapCache(Maps); MapExtras::MapCache * MCache = new MapExtras::MapCache;
df::tile_designation des = MCache->designationAt(xy); df::tile_designation des = MCache->designationAt(xy);
int16_t tt = MCache->tiletypeAt(xy); int16_t tt = MCache->tiletypeAt(xy);
int16_t veinmat = MCache->veinMaterialAt(xy); int16_t veinmat = MCache->veinMaterialAt(xy);