Vegetation module becomes rather skeletal.

develop
Petr Mrázek 2011-06-13 21:11:02 +02:00
parent 511f459182
commit 0a428b509e
8 changed files with 105 additions and 185 deletions

@ -1,3 +0,0 @@
[Project]
Manager=KDevCMakeManager
Name=dfhack

@ -19,16 +19,16 @@ SET(PROJECT_HDRS_INTERNAL
SET(PROJECT_HDRS
include/DFHack.h
include/dfhack/Context.h
include/dfhack/DFError.h
include/dfhack/DFExport.h
include/dfhack/DFIntegers.h
include/dfhack/DFMiscUtils.h
include/dfhack/DFModule.h
include/dfhack/DFPragma.h
include/dfhack/Error.h
include/dfhack/Export.h
include/dfhack/Integers.h
include/dfhack/MiscUtils.h
include/dfhack/Module.h
include/dfhack/Pragma.h
include/dfhack/Process.h
include/dfhack/TileTypes.h
include/dfhack/DFTypes.h
include/dfhack/DFVector.h
include/dfhack/Types.h
include/dfhack/Vector.h
include/dfhack/VersionInfoFactory.h
include/dfhack/VersionInfo.h
include/dfhack/extra/MapExtras.h

@ -40,6 +40,7 @@ distribution.
#include "DFHack.h"
#include "dfhack/VersionInfoFactory.h"
#include "dfhack/Context.h"
#include "dfhack/modules/Vegetation.h"
#include <iostream>
@ -51,6 +52,8 @@ DFHack::VersionInfoFactory * vif = 0;
DFHack::Process * p = 0;
DFHack::Context * c = 0;
DFHack::Gui * gui = 0;
DFHack::Maps * maps = 0;
DFHack::Vegetation * veg = 0;
uint32_t OS_getPID()
{
@ -75,14 +78,47 @@ void SHM_Init ( void )
c = new DFHack::Context(p);
gui = c->getGui();
gui->Start();
veg = c->getVegetation();
veg->Start();
maps = c->getMaps();
maps->Start();
inited = true;
}
int32_t x = 0,y = 0,z = 0;
int32_t xo = 0,yo = 0,zo = 0;
void print_tree( DFHack::df_plant & tree)
{
//DFHack::Materials * mat = DF->getMaterials();
printf("%d:%d = ",tree.type,tree.material);
if(tree.watery)
{
std::cout << "near-water ";
}
//std::cout << mat->organic[tree.material].id << " ";
if(!tree.is_shrub)
{
std::cout << "tree";
}
else
{
std::cout << "shrub";
}
std::cout << std::endl;
printf("Grow counter: 0x%08x\n", tree.grow_counter);
printf("temperature 1: %d\n", tree.temperature_1);
printf("temperature 2: %d\n", tree.temperature_2);
printf("On fire: %d\n", tree.is_burning);
printf("hitpoints: 0x%08x\n", tree.hitpoints);
printf("update order: %d\n", tree.update_order);
printf("Address: 0x%x\n", &tree);
//hexdump(DF,tree.address,13*16);
}
void SHM_Act()
{
maps->Start();
gui->getCursorCoords(x,y,z);
if(x != xo || y!= yo || z != zo)
{
@ -90,6 +126,23 @@ void SHM_Act()
yo = y;
zo = z;
std::cout << "Cursor: " << x << "/" << y << "/" << z << std::endl;
if(x != -30000)
{
std::vector <DFHack::df_plant *> * vec;
if(maps->ReadVegetation(x/16,y/16,z,vec))
{
for(size_t i = 0; i < vec->size();i++)
{
DFHack::df_plant * p = vec->at(i);
if(p->x == x && p->y == y && p->z == z)
{
print_tree(*p);
}
}
}
else
std::cout << "No veg vector..." << std::endl;
}
}
};

@ -49,6 +49,17 @@ struct junk_fill
uint8_t data[SIZE];
};
struct df_name
{
std::string first_name;
std::string nick_name;
int32_t words[7];
int16_t parts_of_speech[7];
int32_t language;
int16_t unknown;
int16_t has_name;
};
enum EFFECT_TYPE
{
EFF_MIASMA=0,

@ -653,7 +653,7 @@ namespace DFHack
std::vector<t_worldconstruction>* constructions = 0
);
/// read all plants in this block
bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<dfh_plant>* plants);
bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_plant *>*& plants);
private:
struct Private;
Private *d;

@ -19,9 +19,9 @@ namespace DFHack
* \ingroup grp_vegetation
*/
#pragma pack(push, 2)
struct t_plant
struct df_plant
{
// +0x3C
df_name name;
union
{
uint16_t type;
@ -50,19 +50,6 @@ namespace DFHack
// some more temperature stuff after that
};
#pragma pack(pop)
/**
* Plant object read from the game
* \ingroup grp_vegetation
*/
struct dfh_plant
{
/// name of the plant
t_name name;
/// data with static size/address
t_plant sdata;
/// address where the plant was read from
uint32_t address;
};
class DFContextShared;
/**
* The Vegetation module
@ -74,14 +61,8 @@ namespace DFHack
public:
Vegetation(DFContextShared * d);
~Vegetation();
bool Start(uint32_t & numTrees);
bool Read (const uint32_t index, dfh_plant & shrubbery);
bool Write (dfh_plant & shrubbery);
bool Finish();
private:
struct Private;
Private *d;
bool Finish(){return true;};
std::vector <df_plant *> *all_plants;
};
}
#endif

@ -142,8 +142,6 @@ struct Maps::Private
bool hasFeatures;
bool hasVeggies;
bool usesWorldDataPtr;
set <uint32_t> unknown_veins;
// map between feature address and the read object
@ -161,7 +159,6 @@ Maps::Maps(DFContextShared* _d)
Process *p = d->owner = _d->p;
d->Inited = d->FeaturesStarted = d->Started = false;
d->block = NULL;
d->usesWorldDataPtr = false;
DFHack::VersionInfo * mem = p->getDescriptor();
Private::t_offsets &off = d->offsets;
@ -169,12 +166,7 @@ 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.world_data = OG_Maps->getAddress("world_data");
{
off.map_offset = OG_Maps->getAddress ("map_data");
@ -184,16 +176,8 @@ 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");
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");
}
off.world_size_x = OG_Maps->getOffset ("world_size_x_from_wdata");
off.world_size_y = OG_Maps->getOffset ("world_size_y_from_wdata");
OffsetGroup *OG_MapBlock = OG_Maps->getGroup("block");
{
off.tile_type_offset = OG_MapBlock->getOffset ("type");
@ -217,16 +201,8 @@ Maps::Maps(DFContextShared* _d)
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.world_geoblocks_vector = OG_Geology->getAddress ("geoblock_vector");
}
off.world_regions = OG_Geology->getOffset ("ptr2_region_array_from_wdata");
off.world_geoblocks_vector = OG_Geology->getOffset ("geoblock_vector_from_wdata");
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");
@ -240,16 +216,8 @@ Maps::Maps(DFContextShared* _d)
OffsetGroup *OG_local_features = OG_Maps->getGroup("features")->getGroup("local");
try
{
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_f_start = OG_local_features->getOffset("start_ptr_from_wdata");
off.global_vector = OG_global_features->getOffset("vector_from_wdata");
off.local_material = OG_local_features->getOffset("material");
off.local_submaterial = OG_local_features->getOffset("submaterial");
@ -287,7 +255,6 @@ Maps::Maps(DFContextShared* _d)
mem->resolveClassnameToVPtr("block_square_event_grassst",off.vein_grass_vptr);
off.vein_worldconstruction_vptr = 0;
mem->resolveClassnameToVPtr("block_square_event_world_constructionst",off.vein_worldconstruction_vptr);
d->Inited = true;
}
@ -658,18 +625,10 @@ bool Maps::StartFeatures()
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;
}
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;
// deref pointer to the humongo-structure
if(!base)
@ -1111,22 +1070,11 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
uint32_t regions, geoblocks_vector_addr;
Private::t_offsets &off = d->offsets;
// get world size
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;
}
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;
// read the geoblock vector
DfVector <uint32_t> geoblocks (geoblocks_vector_addr);
@ -1198,7 +1146,7 @@ bool Maps::ReadLocalFeatures( std::map <DFCoord, std::vector<t_feature *> > & lo
return false;
}
bool Maps::ReadGlobalFeatures( std::vector <t_feature> & features)
bool Maps::ReadGlobalFeatures( std::vector <t_feature> & features )
{
StopFeatures();
StartFeatures();
@ -1210,26 +1158,14 @@ bool Maps::ReadGlobalFeatures( std::vector <t_feature> & features)
return false;
}
bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<dfh_plant>* plants)
bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_plant *>*& plants)
{
if(!d->hasVeggies || !d->Started)
return false;
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if(!addr)
return false;
dfh_plant shrubbery;
plants->clear();
Private::t_offsets &off = d->offsets;
DfVector<uint32_t> vegptrs(addr + off.vegvector);
for(size_t i = 0; i < vegptrs.size(); i++)
{
d->d->readName(shrubbery.name,vegptrs[i]);
d->owner->read (vegptrs[i] + off.tree_desc_offset, sizeof (t_plant), (uint8_t *) &shrubbery.sdata);
shrubbery.address = vegptrs[i];
plants->push_back(shrubbery);
}
if(plants->empty()) return false;
plants = (std::vector<df_plant *>*) (addr + off.vegvector);
return true;
}

@ -45,79 +45,21 @@ Module* DFHack::createVegetation(DFContextShared * d)
return new Vegetation(d);
}
struct Vegetation::Private
{
uint32_t vegetation_vector;
uint32_t tree_desc_offset;
// translation
DfVector <uint32_t> * p_veg;
DFContextShared *d;
Process * owner;
bool Inited;
bool Started;
};
Vegetation::Vegetation(DFContextShared * d_)
{
d = new Private;
d->owner = d_->p;
d->d = d_;
d->Inited = d->Started = false;
OffsetGroup * OG_Veg = d->d->offset_descriptor->getGroup("Vegetation");
d->vegetation_vector = OG_Veg->getAddress ("vector");
d->tree_desc_offset = OG_Veg->getOffset ("tree_desc_offset");
d->Inited = true;
try
{
OffsetGroup * OG_Veg = d_->offset_descriptor->getGroup("Vegetation");
all_plants = (vector<df_plant *> *) OG_Veg->getAddress ("vector");
}
catch(exception &)
{
all_plants = 0;
}
}
Vegetation::~Vegetation()
{
if(d->Started)
Finish();
delete d;
}
bool Vegetation::Start(uint32_t & numplants)
{
if(!d->Inited)
return false;
d->p_veg = new DfVector <uint32_t> (d->vegetation_vector);
numplants = d->p_veg->size();
d->Started = true;
return true;
}
bool Vegetation::Read (const uint32_t index, dfh_plant & shrubbery)
{
if(!d->Started)
return false;
// read pointer from vector at position
uint32_t temp = d->p_veg->at (index);
// read from memory
d->d->readName(shrubbery.name,temp);
d->owner->read (temp + d->tree_desc_offset, sizeof (t_plant), (uint8_t *) &shrubbery.sdata);
shrubbery.address = temp;
return true;
}
bool Vegetation::Write (dfh_plant & shrubbery)
{
if(!d->Started)
return false;
d->owner->write (shrubbery.address + d->tree_desc_offset, sizeof (t_plant), (uint8_t *) &shrubbery.sdata);
return true;
}
bool Vegetation::Finish()
{
if(d->p_veg)
{
delete d->p_veg;
d->p_veg = 0;
}
d->Started = false;
return true;
}