Added ability to set trees on fire.

develop
Petr Mrázek 2011-05-15 00:26:44 +02:00
parent 9995207833
commit 43fc15476a
15 changed files with 128 additions and 81 deletions

@ -17,6 +17,8 @@ DFContextShared::DFContextShared()
// init modules // init modules
allModules.clear(); allModules.clear();
memset(&(s_mods), 0, sizeof(s_mods)); memset(&(s_mods), 0, sizeof(s_mods));
namesInited = false;
namesFailed = false;
} }
DFContextShared::~DFContextShared() DFContextShared::~DFContextShared()
@ -30,6 +32,8 @@ DFContextShared::~DFContextShared()
} }
bool DFContextShared::InitReadNames() bool DFContextShared::InitReadNames()
{
try
{ {
OffsetGroup * OG = offset_descriptor->getGroup("name"); OffsetGroup * OG = offset_descriptor->getGroup("name");
name_firstname_offset = OG->getOffset("first"); name_firstname_offset = OG->getOffset("first");
@ -38,11 +42,26 @@ bool DFContextShared::InitReadNames()
name_parts_offset = OG->getOffset("parts_of_speech"); name_parts_offset = OG->getOffset("parts_of_speech");
name_language_offset = OG->getOffset("language"); name_language_offset = OG->getOffset("language");
name_set_offset = OG->getOffset("has_name"); name_set_offset = OG->getOffset("has_name");
}
catch(exception & e)
{
namesFailed = true;
return false;
}
namesInited = true;
return true; return true;
} }
void DFContextShared::readName(t_name & name, uint32_t address) void DFContextShared::readName(t_name & name, uint32_t address)
{ {
if(namesFailed)
{
return;
}
if(!namesInited)
{
if(!InitReadNames()) return;
}
p->readSTLString(address + name_firstname_offset , name.first_name, 128); p->readSTLString(address + name_firstname_offset , name.first_name, 128);
p->readSTLString(address + name_nickname_offset , name.nickname, 128); p->readSTLString(address + name_nickname_offset , name.nickname, 128);
p->read(address + name_words_offset, 7*4, (uint8_t *)name.words); p->read(address + name_words_offset, 7*4, (uint8_t *)name.words);

@ -84,7 +84,7 @@ int (*alloc_feature_buffer_callback)(t_feature**, uint32_t) = NULL;
int (*alloc_hotkey_buffer_callback)(t_hotkey**, uint32_t) = NULL; int (*alloc_hotkey_buffer_callback)(t_hotkey**, uint32_t) = NULL;
int (*alloc_screen_buffer_callback)(t_screen**, uint32_t) = NULL; int (*alloc_screen_buffer_callback)(t_screen**, uint32_t) = NULL;
int (*alloc_tree_buffer_callback)(t_tree**, uint32_t) = NULL; int (*alloc_tree_buffer_callback)(dfh_plant**, uint32_t) = NULL;
int (*alloc_memrange_buffer_callback)(t_memrange**, uint32_t*, uint32_t) = NULL; int (*alloc_memrange_buffer_callback)(t_memrange**, uint32_t*, uint32_t) = NULL;
@ -115,7 +115,7 @@ REG_MACRO(MatglossOther, t_matglossOther**, alloc_matgloss_other_buffer_callback
REG_MACRO(Feature, t_feature**, alloc_feature_buffer_callback) REG_MACRO(Feature, t_feature**, alloc_feature_buffer_callback)
REG_MACRO(Hotkey, t_hotkey**, alloc_hotkey_buffer_callback) REG_MACRO(Hotkey, t_hotkey**, alloc_hotkey_buffer_callback)
REG_MACRO(Screen, t_screen**, alloc_screen_buffer_callback) REG_MACRO(Screen, t_screen**, alloc_screen_buffer_callback)
REG_MACRO(Tree, t_tree**, alloc_tree_buffer_callback) REG_MACRO(Tree, dfh_plant**, alloc_tree_buffer_callback)
REG_MACRO(CustomWorkshop, t_customWorkshop**, alloc_customWorkshop_buffer_callback) REG_MACRO(CustomWorkshop, t_customWorkshop**, alloc_customWorkshop_buffer_callback)
REG_MACRO(Material, t_material**, alloc_material_buffer_callback) REG_MACRO(Material, t_material**, alloc_material_buffer_callback)

@ -59,7 +59,7 @@ DFHACK_EXPORT extern int (*alloc_feature_buffer_callback)(t_feature**, uint32_t)
DFHACK_EXPORT extern int (*alloc_hotkey_buffer_callback)(t_hotkey**, uint32_t); DFHACK_EXPORT extern int (*alloc_hotkey_buffer_callback)(t_hotkey**, uint32_t);
DFHACK_EXPORT extern int (*alloc_screen_buffer_callback)(t_screen**, uint32_t); DFHACK_EXPORT extern int (*alloc_screen_buffer_callback)(t_screen**, uint32_t);
DFHACK_EXPORT extern int (*alloc_tree_buffer_callback)(t_tree**, uint32_t); DFHACK_EXPORT extern int (*alloc_tree_buffer_callback)(dfh_plant**, uint32_t);
DFHACK_EXPORT extern int (*alloc_memrange_buffer_callback)(t_memrange**, uint32_t*, uint32_t); DFHACK_EXPORT extern int (*alloc_memrange_buffer_callback)(t_memrange**, uint32_t*, uint32_t);
@ -81,7 +81,7 @@ DFHACK_EXPORT void RegisterFeatureBufferCallback(int (*funcptr)(t_feature**, uin
DFHACK_EXPORT void RegisterHotkeyBufferCallback(int (*funcptr)(t_hotkey**, uint32_t)); DFHACK_EXPORT void RegisterHotkeyBufferCallback(int (*funcptr)(t_hotkey**, uint32_t));
DFHACK_EXPORT void RegisterScreenBufferCallback(int (*funcptr)(t_screen**, uint32_t)); DFHACK_EXPORT void RegisterScreenBufferCallback(int (*funcptr)(t_screen**, uint32_t));
DFHACK_EXPORT void RegisterTreeBufferCallback(int (*funcptr)(t_tree**, uint32_t)); DFHACK_EXPORT void RegisterTreeBufferCallback(int (*funcptr)(dfh_plant**, uint32_t));
DFHACK_EXPORT void RegisterMemRangeBufferCallback(int (*funcptr)(t_memrange**, uint32_t*, uint32_t)); DFHACK_EXPORT void RegisterMemRangeBufferCallback(int (*funcptr)(t_memrange**, uint32_t*, uint32_t));

@ -93,7 +93,7 @@ typedef struct
DFHACK_EXPORT int Maps_ReadAllVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, c_allveins* vein_struct); DFHACK_EXPORT int Maps_ReadAllVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, c_allveins* vein_struct);
DFHACK_EXPORT t_tree* Maps_ReadVegetation(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z); DFHACK_EXPORT dfh_plant* Maps_ReadVegetation(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z);
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -36,7 +36,7 @@ extern "C" {
DFHACK_EXPORT int Vegetation_Start(DFHackObject* veg, uint32_t* numTrees); DFHACK_EXPORT int Vegetation_Start(DFHackObject* veg, uint32_t* numTrees);
DFHACK_EXPORT int Vegetation_Finish(DFHackObject* veg); DFHACK_EXPORT int Vegetation_Finish(DFHackObject* veg);
DFHACK_EXPORT int Vegetation_Read(DFHackObject* veg, const uint32_t index, t_tree* shrubbery); DFHACK_EXPORT int Vegetation_Read(DFHackObject* veg, const uint32_t index, dfh_plant* shrubbery);
#ifdef __cplusplus #ifdef __cplusplus
} }

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

@ -8,12 +8,13 @@
#include "dfhack/DFExport.h" #include "dfhack/DFExport.h"
#include "dfhack/DFModule.h" #include "dfhack/DFModule.h"
#include "dfhack/DFTypes.h"
namespace DFHack namespace DFHack
{ {
/** /**
* \ingroup grp_vegetation * \ingroup grp_vegetation
*/ */
struct t_tree struct t_plant
{ {
// +0x3C // +0x3C
#pragma pack(push, 1) #pragma pack(push, 1)
@ -36,13 +37,24 @@ namespace DFHack
uint32_t unknown_1; // +0x48 uint32_t unknown_1; // +0x48
uint16_t temperature_1; // +0x4C uint16_t temperature_1; // +0x4C
uint16_t temperature_2; // +0x4E - maybe fraction? uint16_t temperature_2; // +0x4E - maybe fraction?
uint32_t mystery_flag; // 0x50: yes, just one uint32_t is_burning; // 0x50: yes, just one flag
uint32_t unknown_2; // 0x54 uint32_t hitpoints; // 0x54
uint32_t unknown_3; // 0x58 uint32_t unknown_3; // 0x58
// a vector is here // a vector is here
};
/**
* 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; uint32_t address;
}; };
class DFContextShared; class DFContextShared;
/** /**
* The Vegetation module * The Vegetation module
@ -55,7 +67,8 @@ namespace DFHack
Vegetation(DFContextShared * d); Vegetation(DFContextShared * d);
~Vegetation(); ~Vegetation();
bool Start(uint32_t & numTrees); bool Start(uint32_t & numTrees);
bool Read (const uint32_t index, t_tree & shrubbery); bool Read (const uint32_t index, dfh_plant & shrubbery);
bool Write (dfh_plant & shrubbery);
bool Finish(); bool Finish();
private: private:

@ -1210,7 +1210,7 @@ bool Maps::ReadGlobalFeatures( std::vector <t_feature> & features)
return false; return false;
} }
bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<t_tree>* plants) bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<dfh_plant>* plants)
{ {
if(!d->hasVeggies || !d->Started) if(!d->hasVeggies || !d->Started)
return false; return false;
@ -1218,14 +1218,15 @@ bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<t_tree
if(!addr) if(!addr)
return false; return false;
t_tree shrubbery; dfh_plant shrubbery;
plants->clear(); plants->clear();
Private::t_offsets &off = d->offsets; Private::t_offsets &off = d->offsets;
DfVector<uint32_t> vegptrs(d->owner, addr + off.vegvector); DfVector<uint32_t> vegptrs(d->owner, addr + off.vegvector);
for(size_t i = 0; i < vegptrs.size(); i++) for(size_t i = 0; i < vegptrs.size(); i++)
{ {
d->owner->read (vegptrs[i] + off.tree_desc_offset, sizeof (t_tree), (uint8_t *) &shrubbery); 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]; shrubbery.address = vegptrs[i];
plants->push_back(shrubbery); plants->push_back(shrubbery);
} }

@ -31,6 +31,7 @@ using namespace std;
#include "dfhack-c/DFTypes_C.h" #include "dfhack-c/DFTypes_C.h"
#include "dfhack-c/modules/Maps_C.h" #include "dfhack-c/modules/Maps_C.h"
#include <string.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -672,27 +673,26 @@ int Maps_ReadAllVeins(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z, c_
return -1; return -1;
} }
t_tree* Maps_ReadVegetation(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z) //FIXME: doesn't copy out the address and name variables!
dfh_plant* Maps_ReadVegetation(DFHackObject* maps, uint32_t x, uint32_t y, uint32_t z)
{ {
if(maps == NULL) if(maps == NULL)
return NULL; return NULL;
else else
{ {
std::vector<t_tree> plants; std::vector<dfh_plant> plants;
dfh_plant* buf = NULL;
bool result = ((DFHack::Maps*)maps)->ReadVegetation(x, y, z, &plants); bool result = ((DFHack::Maps*)maps)->ReadVegetation(x, y, z, &plants);
t_tree* buf = NULL;
if(!result || plants.size() <= 0) if(!result || plants.size() <= 0)
{
return NULL; return NULL;
}
else else
{ {
((*alloc_tree_buffer_callback)(&buf, plants.size())); ((*alloc_tree_buffer_callback)(&buf, plants.size()));
if(buf == NULL) if(buf == NULL)
return NULL; return NULL;
copy(plants.begin(), plants.end(), buf); copy(plants.begin(), plants.end(), buf);
return buf; return buf;
} }
} }

@ -88,18 +88,28 @@ bool Vegetation::Start(uint32_t & numplants)
} }
bool Vegetation::Read (const uint32_t index, t_tree & shrubbery) bool Vegetation::Read (const uint32_t index, dfh_plant & shrubbery)
{ {
if(!d->Started) if(!d->Started)
return false; return false;
// read pointer from vector at position // read pointer from vector at position
uint32_t temp = d->p_veg->at (index); uint32_t temp = d->p_veg->at (index);
// read from memory // read from memory
d->owner->read (temp + d->tree_desc_offset, sizeof (t_tree), (uint8_t *) &shrubbery); d->d->readName(shrubbery.name,temp);
d->owner->read (temp + d->tree_desc_offset, sizeof (t_plant), (uint8_t *) &shrubbery.sdata);
shrubbery.address = temp; shrubbery.address = temp;
return true; 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() bool Vegetation::Finish()
{ {
if(d->p_veg) if(d->p_veg)

@ -57,7 +57,7 @@ int Vegetation_Finish(DFHackObject* veg)
return -1; return -1;
} }
int Vegetation_Read(DFHackObject* veg, const uint32_t index, t_tree* shrubbery) int Vegetation_Read(DFHackObject* veg, const uint32_t index, dfh_plant* shrubbery)
{ {
if(veg != NULL) if(veg != NULL)
{ {

@ -66,6 +66,7 @@ namespace DFHack
uint32_t name_language_offset; uint32_t name_language_offset;
uint32_t name_set_offset; uint32_t name_set_offset;
bool namesInited; bool namesInited;
bool namesFailed;
ProcessEnumerator* pm; ProcessEnumerator* pm;
Process* p; Process* p;

@ -26,31 +26,31 @@ using namespace std;
// a vector is here // a vector is here
uint32_t address; uint32_t address;
*/ */
void print_tree( DFHack::Context * DF , DFHack::t_tree & tree) void print_tree( DFHack::Context * DF , DFHack::dfh_plant & tree)
{ {
DFHack::Materials * mat = DF->getMaterials(); DFHack::Materials * mat = DF->getMaterials();
DFHack::t_plant & tdata = tree.sdata;
printf("%d:%d = ",tree.type,tree.material); printf("%d:%d = ",tdata.type,tdata.material);
if(tree.type == 1 || tree.type == 3) if(tdata.watery)
{ {
cout << "near-water "; cout << "near-water ";
} }
cout << mat->organic[tree.material].id << " "; cout << mat->organic[tdata.material].id << " ";
if(tree.type == 0 || tree.type == 1) if(!tdata.is_shrub)
{ {
cout << "tree"; cout << "tree";
} }
if(tree.type == 2 || tree.type == 3) else
{ {
cout << "shrub"; cout << "shrub";
} }
cout << endl; cout << endl;
printf("unknown_1: 0x%08x\n", tree.unknown_1); printf("unknown_1: 0x%08x\n", tdata.unknown_1);
printf("temperature_1: %d\n", tree.temperature_1); printf("temperature_1: %d\n", tdata.temperature_1);
printf("temperature_2: %d\n", tree.temperature_2); printf("temperature_2: %d\n", tdata.temperature_2);
printf("mystery_flag: %d\n", tree.mystery_flag); printf("On fire: %d\n", tdata.is_burning);
printf("unknown_2: 0x%08x\n", tree.unknown_2); printf("hitpoints: 0x%08x\n", tdata.hitpoints);
printf("unknown_3: 0x%08x\n", tree.unknown_3); printf("unknown_3: 0x%08x\n", tdata.unknown_3);
printf("Address: 0x%x\n", tree.address); printf("Address: 0x%x\n", tree.address);
hexdump(DF,tree.address,13*16); hexdump(DF,tree.address,13*16);
} }
@ -97,9 +97,9 @@ int main (int numargs, const char ** args)
cout << "----==== Trees ====----" << endl; cout << "----==== Trees ====----" << endl;
for(uint32_t i =0; i < numVegs; i++) for(uint32_t i =0; i < numVegs; i++)
{ {
DFHack::t_tree tree; DFHack::dfh_plant tree;
v->Read(i,tree); v->Read(i,tree);
printf("%d/%d/%d, %d:%d\n",tree.x,tree.y,tree.z,tree.type,tree.material); printf("%d/%d/%d, %d:%d\n",tree.sdata.x,tree.sdata.y,tree.sdata.z,tree.sdata.type,tree.sdata.material);
} }
} }
else else
@ -107,14 +107,14 @@ int main (int numargs, const char ** args)
// new method, gets the vector of trees in a block. can show farm plants // new method, gets the vector of trees in a block. can show farm plants
if(mps->Start()) if(mps->Start())
{ {
vector<DFHack::t_tree> alltrees; vector<DFHack::dfh_plant> alltrees;
if(mps->ReadVegetation(x/16,y/16,z,&alltrees)) if(mps->ReadVegetation(x/16,y/16,z,&alltrees))
{ {
for(int i = 0 ; i < alltrees.size(); i++) for(int i = 0 ; i < alltrees.size(); i++)
{ {
DFHack::t_tree & tree = alltrees[i]; DFHack::dfh_plant & tree = alltrees[i];
// you could take the tree coords from the struct and % them with 16 for use in loops over the whole block // you could take the tree coords from the struct and % them with 16 for use in loops over the whole block
if(tree.x == x && tree.y == y && tree.z == z) if(tree.sdata.x == x && tree.sdata.y == y && tree.sdata.z == z)
{ {
cout << "----==== Tree at "<< x << "/" << y << "/" << z << " ====----" << endl; cout << "----==== Tree at "<< x << "/" << y << "/" << z << " ====----" << endl;
print_tree(DF, tree); print_tree(DF, tree);
@ -126,9 +126,9 @@ int main (int numargs, const char ** args)
// old method, gets the tree from the global vegetation vector. can't show farm plants // old method, gets the tree from the global vegetation vector. can't show farm plants
for(uint32_t i =0; i < numVegs; i++) for(uint32_t i =0; i < numVegs; i++)
{ {
DFHack::t_tree tree; DFHack::dfh_plant tree;
v->Read(i,tree); v->Read(i,tree);
if(tree.x == x && tree.y == y && tree.z == z) if(tree.sdata.x == x && tree.sdata.y == y && tree.sdata.z == z)
{ {
cout << "----==== Tree at "<< dec << x << "/" << y << "/" << z << " ====----" << endl; cout << "----==== Tree at "<< dec << x << "/" << y << "/" << z << " ====----" << endl;
print_tree(DF, tree); print_tree(DF, tree);

@ -19,6 +19,9 @@ ENDIF()
# a creature mood dump hack. has hardcoded offsets # a creature mood dump hack. has hardcoded offsets
DFHACK_TOOL(dfmoodump moodump.cpp) DFHACK_TOOL(dfmoodump moodump.cpp)
# burn trees to ashes
DFHACK_TOOL(dfimmolate immolate.cpp)
# bauxite - turn all mechanisms into bauxite mechanisms # bauxite - turn all mechanisms into bauxite mechanisms
# Author: Alex Legg # Author: Alex Legg
# FIXME: turned off. there is no reliable Items module. # FIXME: turned off. there is no reliable Items module.

@ -23,7 +23,7 @@ typedef std::vector< pair<int16_t, unsigned int> > MatSorter;
typedef std::vector<DFHack::t_feature> FeatureList; typedef std::vector<DFHack::t_feature> FeatureList;
typedef std::vector<DFHack::t_feature*> FeatureListPointer; typedef std::vector<DFHack::t_feature*> FeatureListPointer;
typedef std::map<DFHack::DFCoord, FeatureListPointer> FeatureMap; typedef std::map<DFHack::DFCoord, FeatureListPointer> FeatureMap;
typedef std::vector<DFHack::t_tree> PlantList; typedef std::vector<DFHack::dfh_plant> PlantList;
bool parseOptions(int argc, char **argv, bool &showHidden, bool &showPlants, bool parseOptions(int argc, char **argv, bool &showHidden, bool &showPlants,
bool &showSlade, bool &showTemple) bool &showSlade, bool &showTemple)
@ -316,15 +316,15 @@ int main(int argc, char *argv[])
{ {
for (PlantList::const_iterator it = plants.begin(); it != plants.end(); it++) for (PlantList::const_iterator it = plants.begin(); it != plants.end(); it++)
{ {
DFHack::t_tree plant = *it; const DFHack::t_plant & plant = (*it).sdata;
DFHack::DFCoord loc(plant.x, plant.y); DFHack::DFCoord loc(plant.x, plant.y);
loc = loc % 16; loc = loc % 16;
if (showHidden || !b->DesignationAt(loc).bits.hidden) if (showHidden || !b->DesignationAt(loc).bits.hidden)
{ {
if(plant.is_shrub) if(plant.is_shrub)
plantMats[it->material]++; plantMats[plant.material]++;
else else
treeMats[it->material]++; treeMats[plant.material]++;
} }
} }
} }