Added cache for map features inside the Maps module along with convenience feature getter for blocks. Adamantine vein refiller tool.

develop
Petr Mrázek 2011-03-24 04:00:23 +01:00
parent 64d3f248c5
commit 64a578b204
5 changed files with 259 additions and 166 deletions

@ -655,10 +655,10 @@ namespace DFHack
MAPTILE_FEATSTONE_WALL_WORN2,
MAPTILE_FEATSTONE_WALL_WORN3,
MAPTILE_FEATSTONE_WALL,*/
{"cracked featstone wall",WALL,STONE,VAR_1, TILE_CRACKED },
{"damaged featstone wall",WALL,STONE,VAR_1, TILE_DAMAGED },
{"worn featstone wall",WALL,STONE,VAR_1, TILE_WORN },
{"featstone wall",WALL,STONE,VAR_1},
{"cracked featstone wall",WALL,FEATSTONE,VAR_1, TILE_CRACKED },
{"damaged featstone wall",WALL,FEATSTONE,VAR_1, TILE_DAMAGED },
{"worn featstone wall",WALL,FEATSTONE,VAR_1, TILE_WORN },
{"featstone wall",WALL,FEATSTONE,VAR_1},
{"stone floor",FLOOR,STONE,VAR_1},
{"stone floor",FLOOR,STONE,VAR_2},
{"stone floor",FLOOR,STONE,VAR_3},
@ -992,6 +992,7 @@ namespace DFHack
}
return -1;
}
/*
//Convenience version of the above, to pass strings as the direction
inline
int32_t findTileType( const TileClass tclass, const TileMaterial tmat, const TileVariant tvar, const TileSpecial tspecial, const char *tdirStr )
@ -1003,7 +1004,7 @@ namespace DFHack
return findTileType(tclass,tmat,tvar,tspecial, 0 );
}
}
*/
//zilpin: Find a tile type similar to the one given, but with a different class.
//Useful for tile-editing operations.

@ -527,13 +527,38 @@ namespace DFHack
@endcode
*/
bool ReadGeology( std::vector < std::vector <uint16_t> >& assign );
std::vector <t_feature> global_features;
// map between feature address and the read object
std::map <uint32_t, t_feature> local_feature_store;
// map between mangled coords and pointer to feature
/**
* Initialize the map feature caches, if possible
*/
bool StartFeatures();
/**
* 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);
/**
* Get pointers to features of a block
*/
bool ReadFeatures(uint32_t x, uint32_t y, uint32_t z, 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
*/
@ -577,10 +602,10 @@ namespace DFHack
/// read/write the block flags
bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags &blockflags);
bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags blockflags);
/// read/write features
bool ReadFeatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t & local, int16_t & global);
bool WriteLocalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1);
bool WriteGlobalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1);
bool SetBlockLocalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1);
bool SetBlockGlobalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1);
/// read region offsets of a block - used for determining layer stone matgloss
bool ReadRegionOffsets(uint32_t blockx, uint32_t blocky, uint32_t blockz,

@ -128,6 +128,7 @@ struct Maps::Private
Process * owner;
OffsetGroup *OG_vector;
bool Inited;
bool FeaturesStarted;
bool Started;
bool hasGeology;
bool hasFeatures;
@ -139,6 +140,8 @@ struct Maps::Private
// map between feature address and the read object
map <uint32_t, 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];
};
@ -148,7 +151,7 @@ Maps::Maps(DFContextShared* _d)
d = new Private;
d->d = _d;
Process *p = d->owner = _d->p;
d->Inited = d->Started = false;
d->Inited = d->FeaturesStarted = d->Started = false;
d->block = NULL;
d->usesWorldDataPtr = false;
@ -350,10 +353,15 @@ void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z)
z = d->z_block_count;
}
// invalidates local and global features!
bool Maps::Finish()
{
if(d->FeaturesStarted)
{
d->local_feature_store.clear();
d->v_global_feature.clear();
d->m_local_feature.clear();
d->FeaturesStarted = false;
}
if (d->block != NULL)
{
delete [] d->block;
@ -597,6 +605,166 @@ bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices4
return false;
}
bool Maps::StartFeatures()
{
MAPS_GUARD
if(d->FeaturesStarted) return true;
if(!d->hasFeatures) return false;
// can't be used without a map!
if(!d->block)
return false;
Process * p = d->owner;
Private::t_offsets &off = d->offsets;
uint32_t base = 0;
uint32_t global_feature_vector = 0;
if(d->usesWorldDataPtr)
{
uint32_t world = p->readDWord(off.world_data);
if(!world) return false;
base = p->readDWord(world + off.local_f_start);
global_feature_vector = p->readDWord(off.world_data) + off.global_vector;
}
else
{
base = p->readDWord(off.local_f_start);
global_feature_vector = off.global_vector;
}
// deref pointer to the humongo-structure
if(!base)
return false;
const uint32_t sizeof_vec = d->OG_vector->getHexValue("sizeof");
const uint32_t sizeof_elem = 16;
const uint32_t offset_elem = 4;
const uint32_t loc_main_mat_offset = off.local_material;
const uint32_t loc_sub_mat_offset = off.local_submaterial;
for(uint32_t blockX = 0; blockX < d->x_block_count; blockX ++)
for(uint32_t blockY = 0; blockY < d->x_block_count; blockY ++)
{
// region X coord (48x48 tiles)
uint16_t region_x_local = ( (blockX / 3) + d->regionX ) / 16;
// region Y coord (48x48 tiles)
uint64_t region_y_local = ( (blockY / 3) + d->regionY ) / 16;
// this is just a few pointers to arrays of 16B (4 DWORD) structs
uint32_t array_elem = p->readDWord(base + (region_x_local / 16) * 4);
// 16B structs, second DWORD of the struct is a pointer
uint32_t wtf = p->readDWord(array_elem + ( sizeof_elem * ( (uint32_t)region_y_local/16)) + offset_elem);
if(wtf)
{
// wtf + sizeof(vector<ptr>) * crap;
uint32_t feat_vector = wtf + sizeof_vec * (16 * (region_x_local % 16) + (region_y_local % 16));
DfVector<uint32_t> p_features(p, feat_vector);
uint32_t size = p_features.size();
DFCoord pc(blockX,blockY);
std::vector<t_feature *> tempvec;
for(uint32_t i = 0; i < size; i++)
{
uint32_t cur_ptr = p_features[i];
map <uint32_t, 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
{
// create, add to store
t_feature tftemp;
tftemp.discovered = false; //= p->readDWord(cur_ptr + 4);
tftemp.origin = cur_ptr;
string name = p->readClassName(p->readDWord( cur_ptr ));
if(name == "feature_init_deep_special_tubest")
{
tftemp.main_material = p->readWord( cur_ptr + loc_main_mat_offset );
tftemp.sub_material = p->readDWord( cur_ptr + loc_sub_mat_offset );
tftemp.type = feature_Adamantine_Tube;
}
else if(name == "feature_init_deep_surface_portalst")
{
tftemp.main_material = p->readWord( cur_ptr + loc_main_mat_offset );
tftemp.sub_material = p->readDWord( cur_ptr + loc_sub_mat_offset );
tftemp.type = feature_Hell_Temple;
}
else
{
tftemp.main_material = -1;
tftemp.sub_material = -1;
tftemp.type = feature_Other;
}
d->local_feature_store[cur_ptr] = tftemp;
// push pointer
tempvec.push_back(&(d->local_feature_store[cur_ptr]));
}
}
d->m_local_feature[pc] = tempvec;
}
}
// deref pointer to the humongo-structure
const uint32_t global_feature_funcptr = off.global_funcptr;
const uint32_t glob_main_mat_offset = off.global_material;
const uint32_t glob_sub_mat_offset = off.global_submaterial;
DfVector<uint32_t> p_features (p,global_feature_vector);
d->v_global_feature.clear();
uint32_t size = p_features.size();
d->v_global_feature.reserve(size);
for(uint32_t i = 0; i < size; i++)
{
t_feature temp;
uint32_t feat_ptr = p->readDWord(p_features[i] + global_feature_funcptr );
temp.origin = feat_ptr;
//temp.discovered = p->readDWord( feat_ptr + 4 ); // maybe, placeholder
temp.discovered = false;
// FIXME: use the memory_info cache mechanisms
string name = p->readClassName(p->readDWord( feat_ptr));
if(name == "feature_init_underworld_from_layerst")
{
temp.main_material = p->readWord( feat_ptr + glob_main_mat_offset );
temp.sub_material = p->readDWord( feat_ptr + glob_sub_mat_offset );
temp.type = feature_Underworld;
}
else
{
temp.main_material = -1;
temp.sub_material = -1;
temp.type = feature_Other;
}
d->v_global_feature.push_back(temp);
}
d->FeaturesStarted = true;
return true;
}
t_feature * Maps::GetGlobalFeature(int16_t index)
{
if(!d->FeaturesStarted) return 0;
if(index < 0 || index >= d->v_global_feature.size())
return 0;
return &(d->v_global_feature[index]);
}
std::vector <t_feature *> * Maps::GetLocalFeatures(DFCoord coord)
{
if(!d->FeaturesStarted) return 0;
coord.z = 0; // just making sure
map <DFCoord, std::vector <t_feature* > >::iterator iter = d->m_local_feature.find(coord);
if(iter != d->m_local_feature.end())
{
return &((*iter).second);
}
return 0;
}
bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int16_t & global)
{
MAPS_GUARD
@ -611,7 +779,36 @@ bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int
return false;
}
bool Maps::WriteLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local)
bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, t_feature ** local, t_feature ** global)
{
if(!d->FeaturesStarted) return false;
int16_t loc, glob;
if(ReadFeatures(x,y,z,loc,glob))
{
if(glob != -1)
*global = &(d->v_global_feature[glob]);
else
*global = 0;
if(loc != -1)
{
DFCoord foo(x,y,0);
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];
}
else *local = 0;
}
else
*local = 0;
return true;
}
*local = 0;
*global = 0;
return false;
}
bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
@ -624,7 +821,7 @@ bool Maps::WriteLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local)
return false;
}
bool Maps::WriteGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global)
bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global)
{
MAPS_GUARD
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
@ -895,159 +1092,26 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
bool Maps::ReadLocalFeatures( std::map <DFCoord, std::vector<t_feature *> > & local_features )
{
MAPS_GUARD
if(!d->hasFeatures) return false;
// can't be used without a map!
if(!d->block)
return false;
Process * p = d->owner;
Private::t_offsets &off = d->offsets;
uint32_t base = 0;
if(d->usesWorldDataPtr)
if(!d->FeaturesStarted)
StartFeatures();
if(d->FeaturesStarted)
{
uint32_t world = p->readDWord(off.world_data);
if(!world) return false;
base = p->readDWord(world + off.local_f_start);
}
else
{
base = p->readDWord(off.local_f_start);
local_features = d->m_local_feature;
return true;
}
// deref pointer to the humongo-structure
if(!base)
return false;
const uint32_t sizeof_vec = d->OG_vector->getHexValue("sizeof");
const uint32_t sizeof_elem = 16;
const uint32_t offset_elem = 4;
const uint32_t main_mat_offset = off.local_material;
const uint32_t sub_mat_offset = off.local_submaterial;
local_features.clear();
for(uint32_t blockX = 0; blockX < d->x_block_count; blockX ++)
for(uint32_t blockY = 0; blockY < d->x_block_count; blockY ++)
{
// region X coord (48x48 tiles)
uint16_t region_x_local = ( (blockX / 3) + d->regionX ) / 16;
// region Y coord (48x48 tiles)
uint64_t region_y_local = ( (blockY / 3) + d->regionY ) / 16;
// this is just a few pointers to arrays of 16B (4 DWORD) structs
uint32_t array_elem = p->readDWord(base + (region_x_local / 16) * 4);
// 16B structs, second DWORD of the struct is a pointer
uint32_t wtf = p->readDWord(array_elem + ( sizeof_elem * ( (uint32_t)region_y_local/16)) + offset_elem);
if(wtf)
{
// wtf + sizeof(vector<ptr>) * crap;
uint32_t feat_vector = wtf + sizeof_vec * (16 * (region_x_local % 16) + (region_y_local % 16));
DfVector<uint32_t> p_features(p, feat_vector);
uint32_t size = p_features.size();
DFCoord pc(blockX,blockY);
std::vector<t_feature *> tempvec;
for(uint32_t i = 0; i < size; i++)
{
uint32_t cur_ptr = p_features[i];
map <uint32_t, 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
{
// create, add to store
t_feature tftemp;
tftemp.discovered = false; //= p->readDWord(cur_ptr + 4);
tftemp.origin = cur_ptr;
string name = p->readClassName(p->readDWord( cur_ptr ));
if(name == "feature_init_deep_special_tubest")
{
tftemp.main_material = p->readWord( cur_ptr + main_mat_offset );
tftemp.sub_material = p->readDWord( cur_ptr + sub_mat_offset );
tftemp.type = feature_Adamantine_Tube;
}
else if(name == "feature_init_deep_surface_portalst")
{
tftemp.main_material = p->readWord( cur_ptr + main_mat_offset );
tftemp.sub_material = p->readDWord( cur_ptr + sub_mat_offset );
tftemp.type = feature_Hell_Temple;
}
else
{
tftemp.main_material = -1;
tftemp.sub_material = -1;
tftemp.type = feature_Other;
}
d->local_feature_store[cur_ptr] = tftemp;
// push pointer
tempvec.push_back(&(d->local_feature_store[cur_ptr]));
}
}
local_features[pc] = tempvec;
}
}
return true;
}
bool Maps::ReadGlobalFeatures( std::vector <t_feature> & features)
{
MAPS_GUARD
if(!d->hasFeatures) return false;
// can't be used without a map!
if(!d->block)
return false;
Process * p = d->owner;
Private::t_offsets &off = d->offsets;
uint32_t global_feature_vector;
if(d->usesWorldDataPtr)
if(!d->FeaturesStarted)
StartFeatures();
if(d->FeaturesStarted)
{
global_feature_vector = p->readDWord(off.world_data) + off.global_vector;
}
else
{
global_feature_vector = off.global_vector;
}
// deref pointer to the humongo-structure
const uint32_t global_feature_funcptr = off.global_funcptr;
const uint32_t main_mat_offset = off.global_material;
const uint32_t sub_mat_offset = off.global_submaterial;
DfVector<uint32_t> p_features (p,global_feature_vector);
features.clear();
uint32_t size = p_features.size();
features.reserve(size);
for(uint32_t i = 0; i < size; i++)
{
t_feature temp;
uint32_t feat_ptr = p->readDWord(p_features[i] + global_feature_funcptr );
temp.origin = feat_ptr;
//temp.discovered = p->readDWord( feat_ptr + 4 ); // maybe, placeholder
temp.discovered = false;
// FIXME: use the memory_info cache mechanisms
string name = p->readClassName(p->readDWord( feat_ptr));
if(name == "feature_init_underworld_from_layerst")
{
temp.main_material = p->readWord( feat_ptr + main_mat_offset );
temp.sub_material = p->readDWord( feat_ptr + sub_mat_offset );
temp.type = feature_Underworld;
}
else
{
temp.main_material = -1;
temp.sub_material = -1;
temp.type = feature_Other;
}
features.push_back(temp);
}
features = d->v_global_feature;
return true;
}
return false;
}
bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<t_tree>* plants)

@ -335,7 +335,7 @@ int Maps_WriteLocalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->WriteLocalFeature(x, y, z, local);
return ((DFHack::Maps*)maps)->SetBlockLocalFeature(x, y, z, local);
}
return -1;
@ -345,7 +345,7 @@ int Maps_WriteEmptyLocalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->WriteLocalFeature(x, y, z, -1);
return ((DFHack::Maps*)maps)->SetBlockLocalFeature(x, y, z, -1);
}
return -1;
@ -355,7 +355,7 @@ int Maps_WriteGlobalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->WriteGlobalFeature(x, y, z, local);
return ((DFHack::Maps*)maps)->SetBlockGlobalFeature(x, y, z, local);
}
return -1;
@ -365,7 +365,7 @@ int Maps_WriteEmptyGlobalFeature(DFHackObject* maps, uint32_t x, uint32_t y, uin
{
if(maps != NULL)
{
return ((DFHack::Maps*)maps)->WriteGlobalFeature(x, y, z, -1);
return ((DFHack::Maps*)maps)->SetBlockGlobalFeature(x, y, z, -1);
}
return -1;

@ -74,6 +74,9 @@ DFHACK_TOOL(dfdoffsets dumpoffsets.cpp)
# change the weather
DFHACK_TOOL(dfweather weather.cpp)
# refill adamantine veins
DFHACK_TOOL(dftubefill dftubefill.cpp)
# deramp
# Author: zilpin
# seeks entire map for 'remove ramp' designation, makes a floor, removes designation.