Replace df_plant with df::plant - this leaves the Vegetation module a bit empty, but I'll leave it in case we decide to add something new there

develop
Quietust 2012-01-21 17:54:57 -06:00
parent d2c78646ea
commit ccf22bed10
7 changed files with 143 additions and 195 deletions

@ -321,7 +321,7 @@ extern DFHACK_EXPORT bool SortBlockEvents(uint32_t x, uint32_t y, uint32_t z,
extern DFHACK_EXPORT bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square_event * which );
/// read all plants in this block
extern DFHACK_EXPORT bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_plant *>*& plants);
extern DFHACK_EXPORT bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df::plant *>*& plants);
}
}

@ -34,48 +34,13 @@ distribution.
#include "Module.h"
#include "Types.h"
#include "DataDefs.h"
#include "df/language_name.h"
#include "df/plant.h"
namespace DFHack
{
/**
* \ingroup grp_vegetation
*/
const uint32_t sapling_to_tree_threshold = 0x1D880;
/**
* \ingroup grp_vegetation
*/
#pragma pack(push, 2)
struct df_plant
{
df::language_name name;
union
{
uint16_t type;
struct
{
bool watery : 1;
bool is_shrub : 1;
};
};
uint16_t material; // +0x3E
uint16_t x; // +0x40
uint16_t y; // +0x42
uint16_t z; // +0x44
uint16_t padding; // +0x46
uint32_t grow_counter; // +0x48
uint16_t temperature_1; // +0x4C
uint16_t temperature_2; // +0x4E - maybe fraction?
uint32_t is_burning; // 0x50: yes, just one flag
uint32_t hitpoints; // 0x54
/**
* 0x58 - the updates are staggered into 9? groups. this seems to be what differentiates the plants.
*/
uint16_t update_order;
uint16_t padding2;
// a vector is here
// some more temperature stuff after that
};
#pragma pack(pop)
/**
* The Vegetation module
* \ingroup grp_vegetation
@ -87,7 +52,6 @@ namespace DFHack
Vegetation();
~Vegetation();
bool Finish(){return true;};
std::vector <df_plant *> *all_plants;
};
}
#endif

@ -592,12 +592,12 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
return true;
}
bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_plant *>*& plants)
bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df::plant *>*& plants)
{
df::map_block *block = getBlock(x,y,z);
if (!block)
return false;
plants = (vector<DFHack::df_plant *> *)&block->plants;
plants = &block->plants;
return true;
}

@ -46,16 +46,6 @@ Module* DFHack::createVegetation()
Vegetation::Vegetation()
{
Core & c = Core::getInstance();
try
{
OffsetGroup * OG_Veg = c.vinfo->getGroup("Vegetation");
all_plants = (vector<df_plant *> *) OG_Veg->getAddress ("vector");
}
catch(exception &)
{
all_plants = 0;
}
}
Vegetation::~Vegetation()

@ -1,4 +1,4 @@
// Designate all matching plants for gathering/cutting
// (un)designate matching plants for gathering/cutting
#include "Core.h"
#include "Console.h"
@ -19,137 +19,144 @@ using std::string;
using std::vector;
using std::set;
using namespace DFHack;
using namespace df::enums;
using df::global::world;
DFhackCExport command_result df_getplants (Core * c, vector <string> & parameters)
{
string plantMatStr = "";
set<int> plantIDs;
set<string> plantNames;
bool deselect = false, exclude = false, treesonly = false, shrubsonly = false;
string plantMatStr = "";
set<int> plantIDs;
set<string> plantNames;
bool deselect = false, exclude = false, treesonly = false, shrubsonly = false;
int count = 0;
for (size_t i = 0; i < parameters.size(); i++)
{
if(parameters[i] == "help" || parameters[i] == "?")
{
c->con.print("Specify the types of trees to cut down and/or shrubs to gather by their plant names, separated by spaces.\n"
"Options:\n"
"\t-t - Select trees only (exclude shrubs)\n"
"\t-s - Select shrubs only (exclude trees)\n"
"\t-c - Clear designations instead of setting them\n"
"\t-x - Apply selected action to all plants except those specified\n"
"Specifying both -t and -s will have no effect.\n"
"If no plant IDs are specified, all valid plant IDs will be listed.\n"
);
return CR_OK;
}
else if(parameters[i] == "-t")
treesonly = true;
else if(parameters[i] == "-s")
shrubsonly = true;
else if(parameters[i] == "-c")
deselect = true;
else if(parameters[i] == "-x")
exclude = true;
else plantNames.insert(parameters[i]);
}
int count = 0;
for (size_t i = 0; i < parameters.size(); i++)
{
if(parameters[i] == "help" || parameters[i] == "?")
{
c->con.print("Specify the types of trees to cut down and/or shrubs to gather by their plant IDs, separated by spaces.\n"
"Options:\n"
"\t-t - Select trees only (exclude shrubs)\n"
"\t-s - Select shrubs only (exclude trees)\n"
"\t-c - Clear designations instead of setting them\n"
"\t-x - Apply selected action to all plants except those specified\n"
"Specifying both -t and -s will have no effect.\n"
"If no plant IDs are specified, all valid plant IDs will be listed.\n"
);
return CR_WRONG_USAGE;
}
else if(parameters[i] == "-t")
treesonly = true;
else if(parameters[i] == "-s")
shrubsonly = true;
else if(parameters[i] == "-c")
deselect = true;
else if(parameters[i] == "-x")
exclude = true;
else
plantNames.insert(parameters[i]);
}
if (treesonly && shrubsonly)
{
c->con.printerr("Cannot specify both -t and -s at the same time!\n");
return CR_WRONG_USAGE;
}
CoreSuspender suspend(c);
CoreSuspender suspend(c);
for (int i = 0; i < world->raws.plants.all.size(); i++)
{
df::plant_raw *plant = world->raws.plants.all[i];
if (plantNames.find(plant->id) != plantNames.end())
{
plantNames.erase(plant->id);
plantIDs.insert(i);
}
}
if (plantNames.size() > 0)
{
c->con.printerr("Invalid plant ID(s):");
for (set<string>::const_iterator it = plantNames.begin(); it != plantNames.end(); it++)
c->con.printerr(" %s", it->c_str());
c->con.printerr("\n");
return CR_FAILURE;
}
for (int i = 0; i < world->raws.plants.all.size(); i++)
{
df::plant_raw *plant = world->raws.plants.all[i];
if (plantNames.find(plant->id) != plantNames.end())
{
plantNames.erase(plant->id);
plantIDs.insert(i);
}
}
if (plantNames.size() > 0)
{
c->con.printerr("Invalid plant ID(s):");
for (set<string>::const_iterator it = plantNames.begin(); it != plantNames.end(); it++)
c->con.printerr(" %s", it->c_str());
c->con.printerr("\n");
return CR_FAILURE;
}
if (plantIDs.size() == 0)
{
c->con.print("Valid plant IDs:\n");
for (int i = 0; i < world->raws.plants.all.size(); i++)
{
df::plant_raw *plant = world->raws.plants.all[i];
if (plant->flags.is_set(df::plant_raw_flags::GRASS))
continue;
c->con.print("* (%s) %s - %s\n", plant->flags.is_set(df::plant_raw_flags::TREE) ? "tree" : "shrub", plant->id.c_str(), plant->name.c_str());
}
return CR_OK;
}
if (plantIDs.size() == 0)
{
c->con.print("Valid plant IDs:\n");
for (int i = 0; i < world->raws.plants.all.size(); i++)
{
df::plant_raw *plant = world->raws.plants.all[i];
if (plant->flags.is_set(plant_raw_flags::GRASS))
continue;
c->con.print("* (%s) %s - %s\n", plant->flags.is_set(plant_raw_flags::TREE) ? "tree" : "shrub", plant->id.c_str(), plant->name.c_str());
}
return CR_OK;
}
count = 0;
for (int i = 0; i < world->map.map_blocks.size(); i++)
{
df::map_block *cur = world->map.map_blocks[i];
bool dirty = false;
for (int j = 0; j < cur->plants.size(); j++)
{
const df_plant *plant = (df_plant *)cur->plants[i];
int x = plant->x % 16;
int y = plant->y % 16;
if (plantIDs.find(plant->material) != plantIDs.end())
{
if (exclude)
continue;
}
else
{
if (!exclude)
continue;
}
TileShape shape = tileShape(cur->tiletype[x][y]);
if (plant->is_shrub && (treesonly || shape != SHRUB_OK))
continue;
if (!plant->is_shrub && (shrubsonly || (shape != TREE_OK && shape != TREE_DEAD)))
continue;
if (cur->designation[x][y].bits.hidden)
continue;
if (deselect && cur->designation[x][y].bits.dig != df::tile_dig_designation::No)
{
cur->designation[x][y].bits.dig = df::tile_dig_designation::No;
dirty = true;
++count;
}
if (!deselect && cur->designation[x][y].bits.dig != df::tile_dig_designation::Default)
{
cur->designation[x][y].bits.dig = df::tile_dig_designation::Default;
dirty = true;
++count;
}
}
if (dirty)
cur->flags.set(df::block_flags::Designated);
}
if (count)
c->con.print("Updated %d plant designations.\n", count);
return CR_OK;
count = 0;
for (int i = 0; i < world->map.map_blocks.size(); i++)
{
df::map_block *cur = world->map.map_blocks[i];
bool dirty = false;
for (int j = 0; j < cur->plants.size(); j++)
{
const df::plant *plant = cur->plants[i];
int x = plant->pos.x % 16;
int y = plant->pos.y % 16;
if (plantIDs.find(plant->material) != plantIDs.end())
{
if (exclude)
continue;
}
else
{
if (!exclude)
continue;
}
TileShape shape = tileShape(cur->tiletype[x][y]);
if (plant->flags.bits.is_shrub && (treesonly || shape != SHRUB_OK))
continue;
if (!plant->flags.bits.is_shrub && (shrubsonly || (shape != TREE_OK && shape != TREE_DEAD)))
continue;
if (cur->designation[x][y].bits.hidden)
continue;
if (deselect && cur->designation[x][y].bits.dig == tile_dig_designation::Default)
{
cur->designation[x][y].bits.dig = tile_dig_designation::No;
dirty = true;
++count;
}
if (!deselect && cur->designation[x][y].bits.dig == tile_dig_designation::No)
{
cur->designation[x][y].bits.dig = tile_dig_designation::Default;
dirty = true;
++count;
}
}
if (dirty)
cur->flags.set(block_flags::Designated);
}
if (count)
c->con.print("Updated %d plant designations.\n", count);
return CR_OK;
}
DFhackCExport const char * plugin_name ( void )
{
return "getplants";
return "getplants";
}
DFhackCExport command_result plugin_init ( Core * c, vector <PluginCommand> &commands)
{
commands.clear();
commands.push_back(PluginCommand("getplants", "Cut down all of the specified trees or gather all of the specified shrubs", df_getplants));
return CR_OK;
commands.clear();
commands.push_back(PluginCommand("getplants", "Cut down all of the specified trees or gather all of the specified shrubs", df_getplants));
return CR_OK;
}
DFhackCExport command_result plugin_shutdown ( Core * c )
{
return CR_OK;
}
return CR_OK;
}

@ -19,6 +19,8 @@ using std::vector;
using std::string;
using namespace DFHack;
using df::global::world;
DFhackCExport command_result df_grow (Core * c, vector <string> & parameters);
DFhackCExport command_result df_immolate (Core * c, vector <string> & parameters);
DFhackCExport command_result df_extirpate (Core * c, vector <string> & parameters);
@ -109,19 +111,13 @@ static command_result immolations (Core * c, do_what what, bool shrubs, bool tre
uint32_t x_max, y_max, z_max;
Maps::getSize(x_max, y_max, z_max);
MapExtras::MapCache map;
DFHack::Vegetation *veg = c->getVegetation();
if (!veg->all_plants)
{
std::cerr << "Unable to read vegetation!" << std::endl;
return CR_FAILURE;
}
if(shrubs || trees)
{
int destroyed = 0;
for(size_t i = 0 ; i < veg->all_plants->size(); i++)
for(size_t i = 0 ; i < world->plants.all.size(); i++)
{
DFHack::df_plant *p = veg->all_plants->at(i);
if(shrubs && p->is_shrub || trees && !p->is_shrub)
df::plant *p = world->plants.all[i];
if(shrubs && p->flags.bits.is_shrub || trees && !p->flags.bits.is_shrub)
{
if (what == do_immolate)
p->is_burning = true;
@ -136,14 +132,14 @@ static command_result immolations (Core * c, do_what what, bool shrubs, bool tre
int32_t x,y,z;
if(Gui->getCursorCoords(x,y,z))
{
vector<DFHack::df_plant *> * alltrees;
vector<df::plant *> * alltrees;
if(Maps::ReadVegetation(x/16,y/16,z,alltrees))
{
bool didit = false;
for(size_t i = 0 ; i < alltrees->size(); i++)
{
DFHack::df_plant * tree = alltrees->at(i);
if(tree->x == x && tree->y == y && tree->z == z)
df::plant * tree = alltrees->at(i);
if(tree->pos.x == x && tree->pos.y == y && tree->pos.z == z)
{
if(what == do_immolate)
tree->is_burning = true;
@ -166,7 +162,6 @@ static command_result immolations (Core * c, do_what what, bool shrubs, bool tre
}
}
// Cleanup
veg->Finish();
c->Resume();
return CR_OK;
}
@ -218,24 +213,17 @@ DFhackCExport command_result df_grow (Core * c, vector <string> & parameters)
return CR_FAILURE;
}
MapExtras::MapCache map;
DFHack::Vegetation *veg = c->getVegetation();
if (!veg->all_plants)
{
con.printerr("Unable to read vegetation!\n");
c->Resume();
return CR_FAILURE;
}
DFHack::Gui *Gui = c->getGui();
int32_t x,y,z;
if(Gui->getCursorCoords(x,y,z))
{
vector<DFHack::df_plant *> * alltrees;
vector<df::plant *> * alltrees;
if(Maps::ReadVegetation(x/16,y/16,z,alltrees))
{
for(size_t i = 0 ; i < alltrees->size(); i++)
{
DFHack::df_plant * tree = alltrees->at(i);
if(tree->x == x && tree->y == y && tree->z == z)
df::plant * tree = alltrees->at(i);
if(tree->pos.x == x && tree->pos.y == y && tree->pos.z == z)
{
if(DFHack::tileShape(map.tiletypeAt(DFHack::DFCoord(x,y,z))) == DFHack::SAPLING_OK)
{
@ -249,11 +237,11 @@ DFhackCExport command_result df_grow (Core * c, vector <string> & parameters)
else
{
int grown = 0;
for(size_t i = 0 ; i < veg->all_plants->size(); i++)
for(size_t i = 0 ; i < world->plants.all.size(); i++)
{
DFHack::df_plant *p = veg->all_plants->at(i);
uint16_t ttype = map.tiletypeAt(DFHack::DFCoord(p->x,p->y,p->z));
if(!p->is_shrub && DFHack::tileShape(ttype) == DFHack::SAPLING_OK)
df::plant *p = world->plants.all[i];
uint16_t ttype = map.tiletypeAt(df::coord(p->pos.x,p->pos.y,p->pos.z));
if(!p->flags.bits.is_shrub && DFHack::tileShape(ttype) == DFHack::SAPLING_OK)
{
p->grow_counter = DFHack::sapling_to_tree_threshold;
}
@ -261,7 +249,6 @@ DFhackCExport command_result df_grow (Core * c, vector <string> & parameters)
}
// Cleanup
veg->Finish();
c->Resume();
return CR_OK;
}

@ -69,7 +69,7 @@ bool operator>(const matdata & q1, const matdata & q2)
typedef std::map<int16_t, matdata> MatMap;
typedef std::vector< pair<int16_t, matdata> > MatSorter;
typedef std::vector<DFHack::df_plant *> PlantList;
typedef std::vector<df::plant *> PlantList;
#define TO_PTR_VEC(obj_vec, ptr_vec) \
ptr_vec.clear(); \
@ -403,12 +403,12 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
{
for (PlantList::const_iterator it = plants->begin(); it != plants->end(); it++)
{
const DFHack::df_plant & plant = *(*it);
df::coord2d loc(plant.x, plant.y);
const df::plant & plant = *(*it);
df::coord2d loc(plant.pos.x, plant.pos.y);
loc = loc % 16;
if (showHidden || !b->DesignationAt(loc).bits.hidden)
{
if(plant.is_shrub)
if(plant.flags.bits.is_shrub)
plantMats[plant.material].add(global_z);
else
treeMats[plant.material].add(global_z);