|
|
|
@ -70,8 +70,6 @@ struct Maps::Private
|
|
|
|
|
|
|
|
|
|
DFContextShared *d;
|
|
|
|
|
Process * owner;
|
|
|
|
|
OffsetGroup *OG_local_features;
|
|
|
|
|
OffsetGroup *OG_global_features;
|
|
|
|
|
OffsetGroup *OG_vector;
|
|
|
|
|
bool Inited;
|
|
|
|
|
bool Started;
|
|
|
|
@ -79,6 +77,8 @@ struct Maps::Private
|
|
|
|
|
bool hasFeatures;
|
|
|
|
|
bool hasVeggies;
|
|
|
|
|
|
|
|
|
|
bool usesWorldDataPtr;
|
|
|
|
|
|
|
|
|
|
set <uint32_t> unknown_veins;
|
|
|
|
|
|
|
|
|
|
// map between feature address and the read object
|
|
|
|
@ -94,6 +94,7 @@ Maps::Maps(DFContextShared* _d)
|
|
|
|
|
Process *p = d->owner = _d->p;
|
|
|
|
|
d->Inited = d->Started = false;
|
|
|
|
|
d->block = NULL;
|
|
|
|
|
d->usesWorldDataPtr = false;
|
|
|
|
|
|
|
|
|
|
DFHack::VersionInfo * mem = p->getDescriptor();
|
|
|
|
|
Server::Maps::maps_offsets &off = d->offsets;
|
|
|
|
@ -101,6 +102,13 @@ Maps::Maps(DFContextShared* _d)
|
|
|
|
|
|
|
|
|
|
// get the offsets once here
|
|
|
|
|
OffsetGroup *OG_Maps = mem->getGroup("Maps");
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
off.world_data = OG_Maps->getAddress("world_data");
|
|
|
|
|
d->usesWorldDataPtr = true;
|
|
|
|
|
cout << "uses world ptr" << endl;
|
|
|
|
|
}catch(Error::AllMemdef &){}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
off.map_offset = OG_Maps->getAddress ("map_data");
|
|
|
|
|
off.x_count_offset = OG_Maps->getAddress ("x_count_block");
|
|
|
|
@ -109,8 +117,16 @@ Maps::Maps(DFContextShared* _d)
|
|
|
|
|
off.region_x_offset = OG_Maps->getAddress ("region_x");
|
|
|
|
|
off.region_y_offset = OG_Maps->getAddress ("region_y");
|
|
|
|
|
off.region_z_offset = OG_Maps->getAddress ("region_z");
|
|
|
|
|
off.world_size_x = OG_Maps->getAddress ("world_size_x");
|
|
|
|
|
off.world_size_y = OG_Maps->getAddress ("world_size_y");
|
|
|
|
|
if(d->usesWorldDataPtr)
|
|
|
|
|
{
|
|
|
|
|
off.world_size_x = OG_Maps->getOffset ("world_size_x_from_wdata");
|
|
|
|
|
off.world_size_y = OG_Maps->getOffset ("world_size_y_from_wdata");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
off.world_size_x = OG_Maps->getAddress ("world_size_x");
|
|
|
|
|
off.world_size_y = OG_Maps->getAddress ("world_size_y");
|
|
|
|
|
}
|
|
|
|
|
OffsetGroup *OG_MapBlock = OG_Maps->getGroup("block");
|
|
|
|
|
{
|
|
|
|
|
off.tile_type_offset = OG_MapBlock->getOffset ("type");
|
|
|
|
@ -123,31 +139,55 @@ Maps::Maps(DFContextShared* _d)
|
|
|
|
|
off.temperature1_offset = OG_MapBlock->getOffset ("temperature1");
|
|
|
|
|
off.temperature2_offset = OG_MapBlock->getOffset ("temperature2");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
OffsetGroup *OG_Geology = OG_Maps->getGroup("geology");
|
|
|
|
|
if(d->usesWorldDataPtr)
|
|
|
|
|
{
|
|
|
|
|
off.world_regions = OG_Geology->getOffset ("ptr2_region_array_from_wdata");
|
|
|
|
|
off.world_geoblocks_vector = OG_Geology->getOffset ("geoblock_vector_from_wdata");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
off.world_regions = OG_Geology->getAddress ("ptr2_region_array");
|
|
|
|
|
off.region_size = OG_Geology->getHexValue ("region_size");
|
|
|
|
|
off.region_geo_index_offset = OG_Geology->getOffset ("region_geo_index_off");
|
|
|
|
|
off.geolayer_geoblock_offset = OG_Geology->getOffset ("geolayer_geoblock_offset");
|
|
|
|
|
off.world_geoblocks_vector = OG_Geology->getAddress ("geoblock_vector");
|
|
|
|
|
off.type_inside_geolayer = OG_Geology->getOffset ("type_inside_geolayer");
|
|
|
|
|
}
|
|
|
|
|
off.region_size = OG_Geology->getHexValue ("region_size");
|
|
|
|
|
off.region_geo_index_offset = OG_Geology->getOffset ("region_geo_index_off");
|
|
|
|
|
off.geolayer_geoblock_offset = OG_Geology->getOffset ("geolayer_geoblock_offset");
|
|
|
|
|
off.type_inside_geolayer = OG_Geology->getOffset ("type_inside_geolayer");
|
|
|
|
|
}
|
|
|
|
|
catch(Error::AllMemdef &)
|
|
|
|
|
{
|
|
|
|
|
d->hasGeology = false;
|
|
|
|
|
}
|
|
|
|
|
OffsetGroup *OG_global_features = OG_Maps->getGroup("features")->getGroup("global");
|
|
|
|
|
OffsetGroup *OG_local_features = OG_Maps->getGroup("features")->getGroup("local");
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
d->OG_global_features = OG_Maps->getGroup("features")->getGroup("global");
|
|
|
|
|
d->OG_local_features = OG_Maps->getGroup("features")->getGroup("local");
|
|
|
|
|
if(d->usesWorldDataPtr)
|
|
|
|
|
{
|
|
|
|
|
off.local_f_start = OG_local_features->getOffset("start_ptr_from_wdata");
|
|
|
|
|
off.global_vector = OG_global_features->getOffset("vector_from_wdata");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
off.local_f_start = OG_local_features->getAddress("start_ptr");
|
|
|
|
|
off.global_vector = OG_global_features->getAddress("vector");
|
|
|
|
|
}
|
|
|
|
|
off.local_material = OG_local_features->getOffset("material");
|
|
|
|
|
off.local_submaterial = OG_local_features->getOffset("submaterial");
|
|
|
|
|
|
|
|
|
|
off.global_funcptr = OG_global_features->getOffset("funcptr");
|
|
|
|
|
off.global_material = OG_global_features->getOffset("material");
|
|
|
|
|
off.global_submaterial = OG_global_features->getOffset("submaterial");
|
|
|
|
|
}
|
|
|
|
|
catch(Error::AllMemdef &)
|
|
|
|
|
{
|
|
|
|
|
d->hasFeatures = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
OffsetGroup * OG_Veg = d->d->offset_descriptor->getGroup("Vegetation");
|
|
|
|
@ -739,16 +779,28 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
|
|
|
|
|
Process *p = d->owner;
|
|
|
|
|
// get needed addresses and offsets. Now this is what I call crazy.
|
|
|
|
|
uint16_t worldSizeX, worldSizeY;
|
|
|
|
|
uint32_t regions, geoblocks_vector_addr;
|
|
|
|
|
Server::Maps::maps_offsets &off = d->offsets;
|
|
|
|
|
// get world size
|
|
|
|
|
p->readWord (off.world_size_x, worldSizeX);
|
|
|
|
|
p->readWord (off.world_size_y, worldSizeY);
|
|
|
|
|
|
|
|
|
|
// get pointer to first part of 2d array of regions
|
|
|
|
|
uint32_t regions = p->readDWord (off.world_regions);
|
|
|
|
|
if(d->usesWorldDataPtr)
|
|
|
|
|
{
|
|
|
|
|
uint32_t world = p->readDWord(off.world_data);
|
|
|
|
|
p->readWord (world + off.world_size_x, worldSizeX);
|
|
|
|
|
p->readWord (world + off.world_size_y, worldSizeY);
|
|
|
|
|
regions = p->readDWord ( world + off.world_regions); // ptr2_region_array
|
|
|
|
|
geoblocks_vector_addr = world + off.world_geoblocks_vector;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
p->readWord (off.world_size_x, worldSizeX);
|
|
|
|
|
p->readWord (off.world_size_y, worldSizeY);
|
|
|
|
|
// get pointer to first part of 2d array of regions
|
|
|
|
|
regions = p->readDWord (off.world_regions); // ptr2_region_array
|
|
|
|
|
geoblocks_vector_addr = off.world_geoblocks_vector;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// read the geoblock vector
|
|
|
|
|
DfVector <uint32_t> geoblocks (d->d->p, off.world_geoblocks_vector);
|
|
|
|
|
DfVector <uint32_t> geoblocks (d->d->p, geoblocks_vector_addr);
|
|
|
|
|
|
|
|
|
|
// iterate over 8 surrounding regions + local region
|
|
|
|
|
for (int i = eNorthWest; i < eBiomeCount; i++)
|
|
|
|
@ -811,15 +863,26 @@ bool Maps::ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > &
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
Process * p = d->owner;
|
|
|
|
|
Server::Maps::maps_offsets &off = d->offsets;
|
|
|
|
|
uint32_t base = 0;
|
|
|
|
|
if(d->usesWorldDataPtr)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
// deref pointer to the humongo-structure
|
|
|
|
|
uint32_t base = p->readDWord(d->OG_local_features->getAddress("start_ptr"));
|
|
|
|
|
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 = d->OG_local_features->getOffset("material"); // 0x30
|
|
|
|
|
const uint32_t sub_mat_offset = d->OG_local_features->getOffset("submaterial"); // 0x34
|
|
|
|
|
const uint32_t main_mat_offset = off.local_material;
|
|
|
|
|
const uint32_t sub_mat_offset = off.local_submaterial;
|
|
|
|
|
|
|
|
|
|
local_features.clear();
|
|
|
|
|
|
|
|
|
@ -904,11 +967,20 @@ bool Maps::ReadGlobalFeatures( std::vector <t_feature> & features)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
Process * p = d->owner;
|
|
|
|
|
|
|
|
|
|
const uint32_t global_feature_vector = d->OG_global_features->getAddress("vector");
|
|
|
|
|
const uint32_t global_feature_funcptr = d->OG_global_features->getOffset("funcptr");
|
|
|
|
|
const uint32_t main_mat_offset = d->OG_global_features->getOffset("material"); // 0x34
|
|
|
|
|
const uint32_t sub_mat_offset = d->OG_global_features->getOffset("submaterial"); // 0x38
|
|
|
|
|
Server::Maps::maps_offsets &off = d->offsets;
|
|
|
|
|
uint32_t global_feature_vector;
|
|
|
|
|
if(d->usesWorldDataPtr)
|
|
|
|
|
{
|
|
|
|
|
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();
|
|
|
|
|