diff --git a/dfhack/APIPrivate.cpp b/dfhack/APIPrivate.cpp index 2f132b8cc..453cbac7e 100644 --- a/dfhack/APIPrivate.cpp +++ b/dfhack/APIPrivate.cpp @@ -12,6 +12,7 @@ #include "modules/Materials.h" #include "modules/Position.h" #include "modules/Translation.h" +#include "modules/Vegetation.h" #include "modules/Gui.h" using namespace DFHack; @@ -25,6 +26,7 @@ APIPrivate::APIPrivate() gui = 0; materials = 0; translation = 0; + vegetation = 0; } APIPrivate::~APIPrivate() @@ -35,6 +37,7 @@ APIPrivate::~APIPrivate() if(gui) delete gui; if(materials) delete materials; if(translation) delete translation; + if(vegetation) delete vegetation; } bool APIPrivate::InitReadNames() diff --git a/dfhack/CMakeLists.txt b/dfhack/CMakeLists.txt index b15aa71b4..5f5df470d 100644 --- a/dfhack/CMakeLists.txt +++ b/dfhack/CMakeLists.txt @@ -38,6 +38,7 @@ modules/Maps.cpp modules/Materials.cpp modules/Position.cpp modules/Translation.cpp +modules/Vegetation.cpp ) SET(PROJECT_HDRS_LINUX diff --git a/dfhack/DFHackAPI.cpp b/dfhack/DFHackAPI.cpp index d47189f6b..6b65cf811 100644 --- a/dfhack/DFHackAPI.cpp +++ b/dfhack/DFHackAPI.cpp @@ -41,6 +41,7 @@ distribution. #include "modules/Gui.h" #include "modules/Creatures.h" #include "modules/Translation.h" +#include "modules/Vegetation.h" using namespace DFHack; @@ -209,6 +210,13 @@ Translation * API::getTranslation() return d->translation; } +Vegetation * API::getVegetation() +{ + if(!d->vegetation) + d->vegetation = new Vegetation(d); + return d->vegetation; +} + /* // returns number of buildings, expects v_buildingtypes that will later map t_building.type to its name bool API::InitReadBuildings ( uint32_t& numbuildings ) @@ -379,51 +387,6 @@ void API::FinishReadConstructions() d->constructionsInited = false; } - -bool API::InitReadVegetation(uint32_t & numplants) -{ - try - { - int vegetation = d->offset_descriptor->getAddress ("vegetation"); - d->tree_offset = d->offset_descriptor->getOffset ("tree_desc_offset"); - - d->vegetationInited = true; - d->p_veg = new DfVector (d->p, vegetation, 4); - numplants = d->p_veg->getSize(); - return true; - } - catch (Error::MissingMemoryDefinition&) - { - d->vegetationInited = false; - numplants = 0; - throw; - } -} - - -bool API::ReadVegetation (const int32_t index, t_tree_desc & shrubbery) -{ - if(!d->vegetationInited) - return false; - // read pointer from vector at position - uint32_t temp = * (uint32_t *) d->p_veg->at (index); - //read construction from memory - g_pProcess->read (temp + d->tree_offset, sizeof (t_tree_desc), (uint8_t *) &shrubbery); - // FIXME: this is completely wrong. type isn't just tree/shrub but also different kinds of trees. stuff that grows around ponds has its own type ID - if (shrubbery.material.type == 3) shrubbery.material.type = 2; - return true; -} - - -void API::FinishReadVegetation() -{ - if(d->p_veg) - { - delete d->p_veg; - d->p_veg = 0; - } - d->vegetationInited = false; -} */ /* bool API::InitReadNotes( uint32_t &numnotes ) diff --git a/dfhack/include/DFHackAPI.h b/dfhack/include/DFHackAPI.h index 352caeb1b..5a6ee82f8 100644 --- a/dfhack/include/DFHackAPI.h +++ b/dfhack/include/DFHackAPI.h @@ -49,6 +49,7 @@ namespace DFHack class Gui; class Materials; class Translation; + class Vegetation; class DFHACK_EXPORT API { @@ -92,6 +93,7 @@ namespace DFHack Position * getPosition(); Materials * getMaterials(); Translation * getTranslation(); + Vegetation * getVegetation(); /* * Constructions (costructed walls, floors, ramps, etc...) diff --git a/dfhack/include/DFTypes.h b/dfhack/include/DFTypes.h index c47932911..f9d19c0dc 100644 --- a/dfhack/include/DFTypes.h +++ b/dfhack/include/DFTypes.h @@ -180,14 +180,6 @@ struct t_building // FIXME: not complete, we need building presence bitmaps for stuff like farm plots and stockpiles, orientation (N,E,S,W) and state (open/closed) }; -struct t_tree_desc -{ - t_matglossPair material; - uint16_t x; - uint16_t y; - uint16_t z; -}; - /* case 10: ret += "leather"; diff --git a/dfhack/include/modules/Vegetation.h b/dfhack/include/modules/Vegetation.h new file mode 100644 index 000000000..f5c21a564 --- /dev/null +++ b/dfhack/include/modules/Vegetation.h @@ -0,0 +1,45 @@ +#ifndef CL_MOD_VEGETATION +#define CL_MOD_VEGETATION +/* +* DF vegetation - stuff that grows and gets cut down or trampled by dwarves +*/ +#include "Export.h" +namespace DFHack +{ + /* + types + 0: sapling?, dead sapling?, grown maple tree + 1: willow sapling? + 2: shrub + 3: shrub near water! + */ + struct t_tree + { + uint16_t type; // +0x6C + uint16_t material; // +0x6E + uint16_t x; // +0x70 + uint16_t y; // +0x72 + uint16_t z; // +0x74 + /* + junk_fill<0xA> junk; + uint32_t flags; // +0x80 maybe? + */ + uint32_t address; + }; + + struct APIPrivate; + class DFHACK_EXPORT Vegetation + { + public: + Vegetation(APIPrivate * d); + ~Vegetation(); + bool Start(uint32_t & numTrees); + bool Read (const uint32_t index, t_tree & shrubbery); + bool Finish(); + + private: + struct Private; + Private *d; + }; +} +#endif diff --git a/dfhack/modules/Vegetation.cpp b/dfhack/modules/Vegetation.cpp new file mode 100644 index 000000000..721f6af1e --- /dev/null +++ b/dfhack/modules/Vegetation.cpp @@ -0,0 +1,96 @@ +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "DFCommonInternal.h" +#include "../private/APIPrivate.h" +#include "modules/Translation.h" +#include "DFMemInfo.h" +#include "DFProcess.h" +#include "DFVector.h" +#include "DFTypes.h" +#include "modules/Vegetation.h" + +using namespace DFHack; + +struct Vegetation::Private +{ + uint32_t vegetation_vector; + uint32_t tree_desc_offset; + // translation + DfVector * p_veg; + + APIPrivate *d; + bool Inited; + bool Started; +}; + +Vegetation::Vegetation(APIPrivate * d_) +{ + d = new Private; + d->d = d_; + d->Inited = d->Started = false; + memory_info * mem = d->d->offset_descriptor; + d->vegetation_vector = mem->getAddress ("vegetation_vector"); + d->tree_desc_offset = mem->getOffset ("tree_desc_offset"); + d->Inited = true; +} + +Vegetation::~Vegetation() +{ + if(d->Started) + Finish(); + delete d; +} + +bool Vegetation::Start(uint32_t & numplants) +{ + d->p_veg = new DfVector (g_pProcess, d->vegetation_vector, 4); + numplants = d->p_veg->getSize(); + d->Started = true; + return true; +} + + +bool Vegetation::Read (const uint32_t index, t_tree & shrubbery) +{ + if(!d->Started) + return false; + // read pointer from vector at position + uint32_t temp = * (uint32_t *) d->p_veg->at (index); + // read from memory + g_pProcess->read (temp + d->tree_desc_offset, sizeof (t_tree), (uint8_t *) &shrubbery); + shrubbery.address = temp; + return true; +} + +bool Vegetation::Finish() +{ + if(d->p_veg) + { + delete d->p_veg; + d->p_veg = 0; + } + d->Started = false; + return true; +} \ No newline at end of file diff --git a/dfhack/private/APIPrivate.h b/dfhack/private/APIPrivate.h index 85fce5f26..1131df91b 100644 --- a/dfhack/private/APIPrivate.h +++ b/dfhack/private/APIPrivate.h @@ -39,6 +39,7 @@ namespace DFHack class Translation; class ProcessEnumerator; class Process; + class Vegetation; class memory_info; struct t_name; class APIPrivate @@ -69,6 +70,7 @@ namespace DFHack Gui * gui; Materials * materials; Translation * translation; + Vegetation * vegetation; /* uint32_t item_material_offset; diff --git a/examples/veccheck.cpp b/examples/veccheck.cpp index e8cfbe086..74a746a8e 100644 --- a/examples/veccheck.cpp +++ b/examples/veccheck.cpp @@ -1,6 +1,7 @@ // Just show some position data #include +#include #include #include #include @@ -15,6 +16,9 @@ using namespace std; #include #include #include +#include +#include +#include void DumpObjStr0Vector (const char * name, DFHack::Process *p, uint32_t addr) { @@ -51,6 +55,37 @@ void DumpDWordVector (const char * name, DFHack::Process *p, uint32_t addr) cout << endl; } +/* +address = absolute address of dump start +length = length in lines. 1 line = 16 bytes +*/ +void hexdump (DFHack::API& DF, uint32_t address, uint32_t length) +{ + char *buf = new char[length * 16]; + + DF.ReadRaw(address, length * 16, (uint8_t *) buf); + for (int i = 0; i < length; i++) + { + // leading offset + cout << "0x" << hex << setw(4) << i*16 << " "; + // groups + for(int j = 0; j < 4; j++) + { + // bytes + for(int k = 0; k < 4; k++) + { + int idx = i * 16 + j * 4 + k; + + cout << hex << setw(2) << int(static_cast(buf[idx])) << " "; + } + cout << " "; + } + cout << endl; + } + delete buf; +} + + int main (int numargs, const char ** args) { uint32_t addr; @@ -99,6 +134,7 @@ int main (int numargs, const char ** args) /* DumpObjStr0Vector("Material templates",p, mem->getAddress("mat_templates")); */ + /* DumpObjStr0Vector("Inorganics",p, mem->getAddress("mat_inorganics")); cout << "----==== Inorganics ====----" << endl; @@ -109,7 +145,7 @@ int main (int numargs, const char ** args) cout << p->readSTLString(addr) << endl; } cout << endl; - + */ /* DumpObjStr0Vector("Organics - all",p, mem->getAddress("mat_organics_all")); @@ -133,6 +169,59 @@ int main (int numargs, const char ** args) DumpObjStr0Vector("Creature types",p, mem->getAddress("mat_creature_types")); */ + DFHack::Position * pos = DF.getPosition(); + DFHack::Vegetation * v = DF.getVegetation(); + DFHack::Materials * mat = DF.getMaterials(); + vector organics; + mat->ReadOrganicMaterials(organics); + + int32_t x,y,z; + pos->getCursorCoords(x,y,z); + + + uint32_t numVegs = 0; + v->Start(numVegs); + if(x == -30000) + { + cout << "----==== Trees ====----" << endl; + for(uint32_t i =0; i < numVegs; i++) + { + DFHack::t_tree tree; + v->Read(i,tree); + printf("%d/%d/%d, %d:%d\n",tree.x,tree.y,tree.z,tree.type,tree.material); + } + } + else + { + cout << "----==== Tree at "<< x << "/" << y << "/" << z << " ====----" << endl; + for(uint32_t i =0; i < numVegs; i++) + { + DFHack::t_tree tree; + v->Read(i,tree); + if(tree.x == x && tree.y == y && tree.z == z) + { + printf("%d:%d = ",tree.type,tree.material); + if(tree.type == 1 || tree.type == 3) + { + cout << "near-water "; + } + cout << organics[tree.material].id << " "; + if(tree.type == 0 || tree.type == 1) + { + cout << "tree"; + } + if(tree.type == 2 || tree.type == 3) + { + cout << "shrub"; + } + cout << endl; + printf("Address: 0x%x\n", tree.address); + hexdump(DF,tree.address,13); + break; + } + } + } + v->Finish(); #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; diff --git a/output/Memory.xml b/output/Memory.xml index 60f548fc4..d80209eab 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -3037,8 +3037,8 @@ map_data_1b60_offset 0x1B9c Vegetation ========== - - :( +
0x0167030C
belal: 0x017f6d98 ... what? + 0x6C Buildings ========= @@ -3073,7 +3073,6 @@ map_data_1b60_offset 0x1B9c settlement_current 0xffffffff settlements 0x016af4a4 translation_vector 0x016b0010 - vegetation 0x017f6da0 view_screen 0xffffffff window_dims 0x017f5abc window_x 0x00e32798