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
allModules.clear();
memset(&(s_mods), 0, sizeof(s_mods));
namesInited = false;
namesFailed = false;
}
DFContextShared::~DFContextShared()
@ -31,18 +33,35 @@ DFContextShared::~DFContextShared()
bool DFContextShared::InitReadNames()
{
OffsetGroup * OG = offset_descriptor->getGroup("name");
name_firstname_offset = OG->getOffset("first");
name_nickname_offset = OG->getOffset("nick");
name_words_offset = OG->getOffset("second_words");
name_parts_offset = OG->getOffset("parts_of_speech");
name_language_offset = OG->getOffset("language");
name_set_offset = OG->getOffset("has_name");
try
{
OffsetGroup * OG = offset_descriptor->getGroup("name");
name_firstname_offset = OG->getOffset("first");
name_nickname_offset = OG->getOffset("nick");
name_words_offset = OG->getOffset("second_words");
name_parts_offset = OG->getOffset("parts_of_speech");
name_language_offset = OG->getOffset("language");
name_set_offset = OG->getOffset("has_name");
}
catch(exception & e)
{
namesFailed = true;
return false;
}
namesInited = true;
return true;
}
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_nickname_offset , name.nickname, 128);
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_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;
@ -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(Hotkey, t_hotkey**, alloc_hotkey_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(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_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);
@ -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 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));

@ -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 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
}

@ -36,7 +36,7 @@ extern "C" {
DFHACK_EXPORT int Vegetation_Start(DFHackObject* veg, uint32_t* numTrees);
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
}

@ -638,7 +638,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<t_tree>* plants);
bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<dfh_plant>* plants);
private:
struct Private;
Private *d;

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

@ -1210,7 +1210,7 @@ bool Maps::ReadGlobalFeatures( std::vector <t_feature> & features)
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)
return false;
@ -1218,14 +1218,15 @@ bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<t_tree
if(!addr)
return false;
t_tree shrubbery;
dfh_plant shrubbery;
plants->clear();
Private::t_offsets &off = d->offsets;
DfVector<uint32_t> vegptrs(d->owner, addr + off.vegvector);
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];
plants->push_back(shrubbery);
}

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

@ -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)
return false;
// read pointer from vector at position
uint32_t temp = d->p_veg->at (index);
// 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;
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)

@ -57,14 +57,14 @@ int Vegetation_Finish(DFHackObject* veg)
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)
{
return ((DFHack::Vegetation*)veg)->Read(index, *shrubbery);
}
if(veg != NULL)
{
return ((DFHack::Vegetation*)veg)->Read(index, *shrubbery);
}
return -1;
return -1;
}
#ifdef __cplusplus

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

@ -26,31 +26,31 @@ using namespace std;
// a vector is here
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();
printf("%d:%d = ",tree.type,tree.material);
if(tree.type == 1 || tree.type == 3)
DFHack::t_plant & tdata = tree.sdata;
printf("%d:%d = ",tdata.type,tdata.material);
if(tdata.watery)
{
cout << "near-water ";
}
cout << mat->organic[tree.material].id << " ";
if(tree.type == 0 || tree.type == 1)
cout << mat->organic[tdata.material].id << " ";
if(!tdata.is_shrub)
{
cout << "tree";
}
if(tree.type == 2 || tree.type == 3)
else
{
cout << "shrub";
}
cout << endl;
printf("unknown_1: 0x%08x\n", tree.unknown_1);
printf("temperature_1: %d\n", tree.temperature_1);
printf("temperature_2: %d\n", tree.temperature_2);
printf("mystery_flag: %d\n", tree.mystery_flag);
printf("unknown_2: 0x%08x\n", tree.unknown_2);
printf("unknown_3: 0x%08x\n", tree.unknown_3);
printf("unknown_1: 0x%08x\n", tdata.unknown_1);
printf("temperature_1: %d\n", tdata.temperature_1);
printf("temperature_2: %d\n", tdata.temperature_2);
printf("On fire: %d\n", tdata.is_burning);
printf("hitpoints: 0x%08x\n", tdata.hitpoints);
printf("unknown_3: 0x%08x\n", tdata.unknown_3);
printf("Address: 0x%x\n", tree.address);
hexdump(DF,tree.address,13*16);
}
@ -97,9 +97,9 @@ int main (int numargs, const char ** args)
cout << "----==== Trees ====----" << endl;
for(uint32_t i =0; i < numVegs; i++)
{
DFHack::t_tree tree;
DFHack::dfh_plant 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
@ -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
if(mps->Start())
{
vector<DFHack::t_tree> alltrees;
vector<DFHack::dfh_plant> alltrees;
if(mps->ReadVegetation(x/16,y/16,z,&alltrees))
{
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
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;
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
for(uint32_t i =0; i < numVegs; i++)
{
DFHack::t_tree tree;
DFHack::dfh_plant 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;
print_tree(DF, tree);

@ -19,6 +19,9 @@ ENDIF()
# a creature mood dump hack. has hardcoded offsets
DFHACK_TOOL(dfmoodump moodump.cpp)
# burn trees to ashes
DFHACK_TOOL(dfimmolate immolate.cpp)
# bauxite - turn all mechanisms into bauxite mechanisms
# Author: Alex Legg
# 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*> FeatureListPointer;
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 &showSlade, bool &showTemple)
@ -316,15 +316,15 @@ int main(int argc, char *argv[])
{
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);
loc = loc % 16;
if (showHidden || !b->DesignationAt(loc).bits.hidden)
{
if(plant.is_shrub)
plantMats[it->material]++;
plantMats[plant.material]++;
else
treeMats[it->material]++;
treeMats[plant.material]++;
}
}
}