API changes: InitRead* methods made safer - they now return false on error

develop
Petr Mrázek 2010-02-11 21:08:39 +00:00
parent ae8eada92e
commit 63f82cd580
10 changed files with 212 additions and 169 deletions

@ -639,14 +639,21 @@ bool API::ReadGeology (vector < vector <uint16_t> >& assign)
// returns number of buildings, expects v_buildingtypes that will later map t_building.type to its name // returns number of buildings, expects v_buildingtypes that will later map t_building.type to its name
uint32_t API::InitReadBuildings (vector <string> &v_buildingtypes) bool API::InitReadBuildings ( uint32_t& numbuildings )
{ {
d->buildingsInited = true;
int buildings = d->offset_descriptor->getAddress ("buildings"); int buildings = d->offset_descriptor->getAddress ("buildings");
assert (buildings); if(buildings)
d->p_bld = new DfVector (d->dm->readVector (buildings, 4)); {
d->offset_descriptor->copyBuildings (v_buildingtypes); d->buildingsInited = true;
return d->p_bld->getSize(); d->p_bld = new DfVector (d->dm->readVector (buildings, 4));
return true;
}
else
{
d->buildingsInited = false;
numbuildings = 0;
return false;
}
} }
@ -691,14 +698,22 @@ void API::FinishReadBuildings()
//TODO: maybe do construction reading differently - this could go slow with many of them. //TODO: maybe do construction reading differently - this could go slow with many of them.
// returns number of constructions, prepares a vector, returns total number of constructions // returns number of constructions, prepares a vector, returns total number of constructions
uint32_t API::InitReadConstructions() bool API::InitReadConstructions(uint32_t & numconstructions)
{ {
d->constructionsInited = true;
int constructions = d->offset_descriptor->getAddress ("constructions"); int constructions = d->offset_descriptor->getAddress ("constructions");
assert (constructions); if(constructions)
{
d->p_cons = new DfVector (d->dm->readVector (constructions, 4)); d->p_cons = new DfVector (d->dm->readVector (constructions, 4));
return d->p_cons->getSize(); d->constructionsInited = true;
numconstructions = d->p_cons->getSize();
return true;
}
else
{
d->constructionsInited = false;
numconstructions = 0;
return false;
}
} }
@ -731,14 +746,23 @@ void API::FinishReadConstructions()
} }
uint32_t API::InitReadVegetation() bool API::InitReadVegetation(uint32_t & numplants)
{ {
d->vegetationInited = true;
int vegetation = d->offset_descriptor->getAddress ("vegetation"); int vegetation = d->offset_descriptor->getAddress ("vegetation");
d->tree_offset = d->offset_descriptor->getOffset ("tree_desc_offset"); d->tree_offset = d->offset_descriptor->getOffset ("tree_desc_offset");
assert (vegetation && d->tree_offset); if(vegetation && d->tree_offset)
d->p_veg = new DfVector (d->dm->readVector (vegetation, 4)); {
return d->p_veg->getSize(); d->vegetationInited = true;
d->p_veg = new DfVector (d->dm->readVector (vegetation, 4));
numplants = d->p_veg->getSize();
return true;
}
else
{
d->vegetationInited = false;
numplants = 0;
return false;
}
} }
@ -764,7 +788,7 @@ void API::FinishReadVegetation()
} }
uint32_t API::InitReadCreatures() bool API::InitReadCreatures( uint32_t numcreatures )
{ {
memory_info * minfo = d->offset_descriptor; memory_info * minfo = d->offset_descriptor;
int creatures = d->offset_descriptor->getAddress ("creatures"); int creatures = d->offset_descriptor->getAddress ("creatures");
@ -818,18 +842,14 @@ uint32_t API::InitReadCreatures()
{ {
d->p_cre = new DfVector (d->dm->readVector (creatures, 4)); d->p_cre = new DfVector (d->dm->readVector (creatures, 4));
//InitReadNameTables(); //InitReadNameTables();
//if(d->InitReadNameTables())
//{
d->creaturesInited = true; d->creaturesInited = true;
return d->p_cre->getSize(); numcreatures = d->p_cre->getSize();
//} return false;
//else
//{
// return false;
//}
} }
else else
{ {
d->creaturesInited = false;
numcreatures = 0;
return false; return false;
} }
} }
@ -968,35 +988,44 @@ void API::WriteLabors(const uint32_t &index, uint8_t labors[NUM_CREATURE_LABORS]
WriteRaw(temp + d->creature_labors_offset, NUM_CREATURE_LABORS, labors); WriteRaw(temp + d->creature_labors_offset, NUM_CREATURE_LABORS, labors);
} }
void API::InitReadNameTables (map< string, vector<string> > & nameTable) bool API::InitReadNameTables (map< string, vector<string> > & nameTable)
{ {
int genericAddress = d->offset_descriptor->getAddress ("language_vector"); int genericAddress = d->offset_descriptor->getAddress ("language_vector");
int transAddress = d->offset_descriptor->getAddress ("translation_vector"); int transAddress = d->offset_descriptor->getAddress ("translation_vector");
int word_table_offset = d->offset_descriptor->getOffset ("word_table"); int word_table_offset = d->offset_descriptor->getOffset ("word_table");
DfVector genericVec (d->dm->readVector (genericAddress, 4)); if(genericAddress && transAddress && word_table_offset)
DfVector transVec (d->dm->readVector (transAddress, 4));
for (uint32_t i = 0;i < genericVec.getSize();i++)
{ {
uint32_t genericNamePtr = * (uint32_t *) genericVec.at (i); DfVector genericVec (d->dm->readVector (genericAddress, 4));
string genericName = d->dm->readSTLString (genericNamePtr); DfVector transVec (d->dm->readVector (transAddress, 4));
nameTable["GENERIC"].push_back (genericName);
}
for (uint32_t i = 0; i < transVec.getSize();i++) for (uint32_t i = 0;i < genericVec.getSize();i++)
{
uint32_t transPtr = * (uint32_t *) transVec.at (i);
string transName = d->dm->readSTLString (transPtr);
DfVector trans_names_vec (d->dm->readVector (transPtr + word_table_offset, 4));
for (uint32_t j = 0;j < trans_names_vec.getSize();j++)
{ {
uint32_t transNamePtr = * (uint32_t *) trans_names_vec.at (j); uint32_t genericNamePtr = * (uint32_t *) genericVec.at (i);
string name = d->dm->readSTLString (transNamePtr); string genericName = d->dm->readSTLString (genericNamePtr);
nameTable[transName].push_back (name); nameTable["GENERIC"].push_back (genericName);
} }
for (uint32_t i = 0; i < transVec.getSize();i++)
{
uint32_t transPtr = * (uint32_t *) transVec.at (i);
string transName = d->dm->readSTLString (transPtr);
DfVector trans_names_vec (d->dm->readVector (transPtr + word_table_offset, 4));
for (uint32_t j = 0;j < trans_names_vec.getSize();j++)
{
uint32_t transNamePtr = * (uint32_t *) trans_names_vec.at (j);
string name = d->dm->readSTLString (transNamePtr);
nameTable[transName].push_back (name);
}
}
d->nameTablesInited = true;
return true;
}
else
{
d->nameTablesInited = false;
return false;
} }
d->nameTablesInited = true;
} }
string API::TranslateName (const t_lastname & last, const map<string, vector<string> > & nameTable, const string & language) string API::TranslateName (const t_lastname & last, const map<string, vector<string> > & nameTable, const string & language)
@ -1230,6 +1259,16 @@ bool API::getWindowSize (int32_t &width, int32_t &height)
return true; return true;
} }
bool API::getClassIDMapping (vector <string>& objecttypes)
{
if(isAttached())
{
d->offset_descriptor->getClassIDMapping(objecttypes);
return true;
}
return false;
}
memory_info API::getMemoryInfo() memory_info API::getMemoryInfo()
{ {
return *d->offset_descriptor; return *d->offset_descriptor;
@ -1244,19 +1283,24 @@ DFWindow * API::getWindow()
return d->p->getWindow(); return d->p->getWindow();
} }
uint32_t API::InitReadItems() bool API::InitReadItems(uint32_t & numitems)
{ {
int items = d->offset_descriptor->getAddress ("items"); int items = d->offset_descriptor->getAddress ("items");
assert (items);
//cerr << hex << items;
d->item_material_offset = d->offset_descriptor->getOffset ("item_materials"); d->item_material_offset = d->offset_descriptor->getOffset ("item_materials");
assert (d->item_material_offset);
d->p_itm = new DfVector (d->dm->readVector (items, 4)); if(items && d->item_material_offset)
d->itemsInited = true; {
return d->p_itm->getSize(); d->p_itm = new DfVector (d->dm->readVector (items, 4));
d->itemsInited = true;
numitems = d->p_itm->getSize();
return true;
}
else
{
d->itemsInited = false;
numitems = 0;
return false;
}
} }
bool API::ReadItem (const uint32_t &index, t_item & item) bool API::ReadItem (const uint32_t &index, t_item & item)
{ {

@ -147,19 +147,19 @@ namespace DFHack
/** /**
* Buildings, constructions, plants, all pretty straighforward. InitReadBuildings returns all the building types as a mapping between a numeric values and strings * Buildings, constructions, plants, all pretty straighforward. InitReadBuildings returns all the building types as a mapping between a numeric values and strings
*/ */
uint32_t InitReadConstructions(); bool InitReadConstructions( uint32_t & numconstructions );
bool ReadConstruction(const int32_t &index, t_construction & construction); bool ReadConstruction(const int32_t &index, t_construction & construction);
void FinishReadConstructions(); void FinishReadConstructions();
uint32_t InitReadBuildings(vector <string> &v_buildingtypes); bool InitReadBuildings ( uint32_t& numbuildings );
bool ReadBuilding(const int32_t &index, t_building & building); bool ReadBuilding(const int32_t &index, t_building & building);
void FinishReadBuildings(); void FinishReadBuildings();
uint32_t InitReadVegetation(); bool InitReadVegetation( uint32_t & numplants );
bool ReadVegetation(const int32_t &index, t_tree_desc & shrubbery); bool ReadVegetation(const int32_t &index, t_tree_desc & shrubbery);
void FinishReadVegetation(); void FinishReadVegetation();
uint32_t InitReadCreatures(); bool InitReadCreatures( uint32_t numcreatures );
/// returns index of creature actually read or -1 if no creature can be found /// returns index of creature actually read or -1 if no creature can be found
int32_t ReadCreatureInBox(int32_t index, t_creature & furball, int32_t ReadCreatureInBox(int32_t index, t_creature & furball,
const uint16_t &x1, const uint16_t &y1,const uint16_t &z1, const uint16_t &x1, const uint16_t &y1,const uint16_t &z1,
@ -198,7 +198,7 @@ namespace DFHack
vector<t_trait> getTraits(const uint32_t &index); vector<t_trait> getTraits(const uint32_t &index);
vector<t_labor> getLabors(const uint32_t &index); vector<t_labor> getLabors(const uint32_t &index);
*/ */
void InitReadNameTables(map< string, vector< string > > & nameTable); bool InitReadNameTables (map< string, vector<string> > & nameTable);
void FinishReadNameTables(); void FinishReadNameTables();
string TranslateName(const t_lastname & last, const map< string, vector< string > > &nameTable,const string & language="GENERIC"); string TranslateName(const t_lastname & last, const map< string, vector< string > > &nameTable,const string & language="GENERIC");
@ -206,10 +206,13 @@ namespace DFHack
void WriteLabors(const uint32_t &index, uint8_t labors[NUM_CREATURE_LABORS]); void WriteLabors(const uint32_t &index, uint8_t labors[NUM_CREATURE_LABORS]);
uint32_t InitReadItems(); bool InitReadItems(uint32_t & numitems);
bool ReadItem(const uint32_t &index, t_item & item); bool ReadItem(const uint32_t &index, t_item & item);
void FinishReadItems(); void FinishReadItems();
// wrapper for meminfo method of the same name
bool getClassIDMapping (vector <string>& objecttypes);
memory_info getMemoryInfo(); memory_info getMemoryInfo();
Process * getProcess(); Process * getProcess();
DFWindow * getWindow(); DFWindow * getWindow();

@ -329,11 +329,11 @@ bool memory_info::resolveClassId(uint32_t address, int32_t & classid)
} }
// Flatten vtables into a index<->name mapping // Flatten vtables into a index<->name mapping
void memory_info::copyBuildings(vector<string> & v_buildingtypes) void memory_info::getClassIDMapping(vector<string> & v_ClassID2ObjName)
{ {
for(uint32_t i = 0;i< classes.size();i++) for(uint32_t i = 0;i< classes.size();i++)
{ {
v_buildingtypes.push_back(classes[i].classname); v_ClassID2ObjName.push_back(classes[i].classname);
if(!classes[i].is_multiclass) if(!classes[i].is_multiclass)
{ {
continue; continue;
@ -341,7 +341,7 @@ void memory_info::copyBuildings(vector<string> & v_buildingtypes)
vector <t_type>& vec = classsubtypes[classes[i].multi_index]; vector <t_type>& vec = classsubtypes[classes[i].multi_index];
for (uint32_t k = 0; k < vec.size();k++) for (uint32_t k = 0; k < vec.size();k++)
{ {
v_buildingtypes.push_back(vec[k].classname); v_ClassID2ObjName.push_back(vec[k].classname);
} }
} }
} }

@ -117,7 +117,7 @@ namespace DFHack
// ALERT: uses memory reading directly // ALERT: uses memory reading directly
bool resolveClassId(const uint32_t address, int32_t & classid); bool resolveClassId(const uint32_t address, int32_t & classid);
void copyBuildings(vector<string> & v_buildingtypes); void getClassIDMapping(vector<string> & v_ClassID2ObjName);
void flush(); void flush();

@ -136,30 +136,43 @@ int main (int argc,const char* argv[])
return 1; return 1;
} }
vector <string> buildingtypes; /*
uint32_t numBuildings = DF.InitReadBuildings(buildingtypes); * Get the object name/ID mapping
vector < uint32_t > addresses; */
for(uint32_t i = 0; i < numBuildings; i++) vector <string> objecttypes;
DF.getClassIDMapping (objecttypes);
uint32_t numBuildings;
if(DF.InitReadBuildings(numBuildings))
{ {
DFHack::t_building temp; vector < uint32_t > addresses;
DF.ReadBuilding(i, temp); for(uint32_t i = 0; i < numBuildings; i++)
if(temp.type != 0xFFFFFFFF) // check if type isn't invalid
{ {
if(buildingtypes[temp.type] == argv[1]) DFHack::t_building temp;
DF.ReadBuilding(i, temp);
if(temp.type != 0xFFFFFFFF) // check if type isn't invalid
{ {
//cout << buildingtypes[temp.type] << " 0x" << hex << temp.origin << endl; if(objecttypes[temp.type] == argv[1])
//hexdump(DF, temp.origin, 16); {
addresses.push_back(temp.origin); //cout << buildingtypes[temp.type] << " 0x" << hex << temp.origin << endl;
//hexdump(DF, temp.origin, 16);
addresses.push_back(temp.origin);
}
}
else
{
// couldn't translate type, print out the vtable
cout << "unknown vtable: " << temp.vtable << endl;
} }
} }
else interleave_hex(DF,addresses,lines / 4);
{ DF.FinishReadBuildings();
// couldn't translate type, print out the vtable
cout << "unknown vtable: " << temp.vtable << endl;
}
} }
interleave_hex(DF,addresses,lines / 4); else
DF.FinishReadBuildings(); {
cerr << "buildings not supported for this DF version" << endl;
}
DF.Detach(); DF.Detach();
#ifndef LINUX_BUILD #ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl; cout << "Done. Press any key to continue" << endl;

@ -144,19 +144,16 @@ likeType printLike(DFHack::t_like like, const matGlosses & mat,const vector< vec
int main (void) int main (void)
{ {
vector<DFHack::t_matgloss> creaturestypes; vector<DFHack::t_matgloss> creaturestypes;
// t_matglossPlant test;
DFHack::API DF("Memory.xml"); DFHack::API DF("Memory.xml");
if(!DF.Attach()) if(!DF.Attach())
{ {
cerr << "DF not found" << endl; cerr << "DF not found" << endl;
return 1; return 1;
} }
vector <string> buildingtypes;
uint32_t numBuildings = DF.InitReadBuildings(buildingtypes);
//vector< vector <string> > all;
vector< vector <DFHack::t_itemType> > itemTypes; vector< vector <DFHack::t_itemType> > itemTypes;
DF.ReadItemTypes(itemTypes); DF.ReadItemTypes(itemTypes);
//DF.ReadAllMatgloss(all);
matGlosses mat; matGlosses mat;
DF.ReadPlantMatgloss(mat.plantMat); DF.ReadPlantMatgloss(mat.plantMat);
DF.ReadWoodMatgloss(mat.woodMat); DF.ReadWoodMatgloss(mat.woodMat);
@ -173,8 +170,17 @@ int main (void)
} }
map<string, vector<string> > names; map<string, vector<string> > names;
DF.InitReadNameTables(names); if(!DF.InitReadNameTables(names))
uint32_t numCreatures = DF.InitReadCreatures(); {
cerr << "Can't get name tables" << endl;
return 1;
}
uint32_t numCreatures;
if(!DF.InitReadCreatures(numCreatures))
{
cerr << "Can't get creatures" << endl;
return 1;
}
for(uint32_t i = 0; i < numCreatures; i++) for(uint32_t i = 0; i < numCreatures; i++)
{ {
DFHack::t_creature temp; DFHack::t_creature temp;

@ -21,7 +21,7 @@ void print_bits ( T val, std::ostream& out )
val >>= 1; val >>= 1;
} }
} }
vector <string> buildingtypes; vector <string> objecttypes;
map<string, vector<string> > names; map<string, vector<string> > names;
uint32_t numCreatures; uint32_t numCreatures;
vector<DFHack::t_matgloss> creaturestypes; vector<DFHack::t_matgloss> creaturestypes;
@ -176,7 +176,7 @@ bool waitTillScreenState(DFHack::API &DF, string screenState,bool EqualTo=true)
DF.Suspend(); DF.Suspend();
DF.ReadViewScreen(current); DF.ReadViewScreen(current);
int tryCount = 0; int tryCount = 0;
while(((EqualTo && buildingtypes[current.type] != screenState) || (!EqualTo && buildingtypes[current.type] == screenState)) && tryCount < 50) while(((EqualTo && objecttypes[current.type] != screenState) || (!EqualTo && objecttypes[current.type] == screenState)) && tryCount < 50)
{ {
DF.Resume(); DF.Resume();
w->TypeSpecial(DFHack::WAIT,1,100); w->TypeSpecial(DFHack::WAIT,1,100);
@ -185,7 +185,7 @@ bool waitTillScreenState(DFHack::API &DF, string screenState,bool EqualTo=true)
tryCount++; tryCount++;
} }
if(tryCount >= 50){ if(tryCount >= 50){
cerr << "Something went wrong, DF at " << buildingtypes[current.type] << endl; cerr << "Something went wrong, DF at " << objecttypes[current.type] << endl;
return false; return false;
} }
DF.Resume(); DF.Resume();
@ -242,12 +242,12 @@ bool moveToBaseWindow(DFHack::API &DF)
DFHack::DFWindow * w = DF.getWindow(); DFHack::DFWindow * w = DF.getWindow();
DFHack::t_viewscreen current; DFHack::t_viewscreen current;
DF.ReadViewScreen(current); DF.ReadViewScreen(current);
while(buildingtypes[current.type] != string("viewscreen_dwarfmode")) while(objecttypes[current.type] != string("viewscreen_dwarfmode"))
{ {
w->TypeSpecial(DFHack::F9); // cancel out of text input in names w->TypeSpecial(DFHack::F9); // cancel out of text input in names
// DF.TypeSpecial(DFHack::ENTER); // cancel out of text input in hotkeys // DF.TypeSpecial(DFHack::ENTER); // cancel out of text input in hotkeys
w->TypeSpecial(DFHack::SPACE); // should move up a level w->TypeSpecial(DFHack::SPACE); // should move up a level
if(!waitTillScreenState(DF,buildingtypes[current.type],false)) return false; // wait until screen changes from current if(!waitTillScreenState(DF,objecttypes[current.type],false)) return false; // wait until screen changes from current
DF.ReadViewScreen(current); DF.ReadViewScreen(current);
} }
if(DF.ReadMenuState() != 0){// if menu state != 0 then there is a menu, so escape it if(DF.ReadMenuState() != 0){// if menu state != 0 then there is a menu, so escape it
@ -287,18 +287,22 @@ int main (void)
return 1; return 1;
} }
DF.Suspend(); DF.Suspend();
//Need buildingtypes for the viewscreen vtables, this really should not be just buildings, as viewscreen and items both use the same interface if(!DF.getClassIDMapping(objecttypes))
uint32_t numBuildings = DF.InitReadBuildings(buildingtypes); {
cerr << "Can't get type info" << endl;
return 1;
}
DFHack::memory_info mem = DF.getMemoryInfo(); DFHack::memory_info mem = DF.getMemoryInfo();
// get stone matgloss mapping
if(!DF.ReadCreatureMatgloss(creaturestypes)) if(!DF.ReadCreatureMatgloss(creaturestypes))
{ {
cerr << "Can't get the creature types." << endl; cerr << "Can't get the creature types." << endl;
return 1; return 1;
} }
DF.InitReadNameTables(names); DF.InitReadNameTables(names);
numCreatures = DF.InitReadCreatures(); DF.InitReadCreatures(numCreatures);
DF.InitViewAndCursor(); DF.InitViewAndCursor();
printDwarves(DF); printDwarves(DF);
DFHack::t_creature toChange; DFHack::t_creature toChange;

@ -63,18 +63,18 @@ int main ()
return EXIT_FAILURE; return EXIT_FAILURE;
} }
//FIXME: very counter-intuitive, fix the API. This returns a mapping from the internal ID to the object name
// internal IDs can be obtained by using resolveClassId
//FIXME: Proper error reporting/exceptions support is sorely needed
/* /*
* Get the object name/ID mapping * Get some basics needed for full access
*/ */
vector <string> buildingtypes;
uint32_t numBuildings = DF.InitReadBuildings(buildingtypes);
proc = DF.getProcess(); proc = DF.getProcess();
meminfo = proc->getDescriptor(); meminfo = proc->getDescriptor();
/*
* Get the object name/ID mapping
*/
vector <string> objecttypes;
DF.getClassIDMapping (objecttypes);
//FIXME: work on the 'supported features' system required //FIXME: work on the 'supported features' system required
/* /*
* Check availability of required addresses and offsets (doing custom stuff here) * Check availability of required addresses and offsets (doing custom stuff here)
@ -106,7 +106,7 @@ int main ()
if(!meminfo->resolveClassId (temp, type)) if(!meminfo->resolveClassId (temp, type))
continue; continue;
if(buildingtypes[type] == "item_trapparts") if(objecttypes[type] == "item_trapparts")
{ {
proc->read (temp + item_material_offset, sizeof (DFHack::t_matglossPair), (uint8_t *) &item_40d_material); proc->read (temp + item_material_offset, sizeof (DFHack::t_matglossPair), (uint8_t *) &item_40d_material);

@ -94,20 +94,13 @@ int main ()
DF.ReadCreatureMatgloss(mat.creatureMat); DF.ReadCreatureMatgloss(mat.creatureMat);
DF.ForceResume(); DF.ForceResume();
vector <string> buildingtypes; vector <string> objecttypes;
DF.InitReadBuildings(buildingtypes); DF.getClassIDMapping(objecttypes);
uint32_t numItems = DF.InitReadItems();
/*
map< string, map<string,vector<uint32_t> > > count;
for(uint32_t i=0; i< numItems; i++){
DFHack::t_item temp;
DF.ReadItem(i,temp);
// cout << int(temp.type) << endl;
count[buildingtypes[temp.type]][getMaterialType(temp,buildingtypes,mat)].push_back(i);
}
*/
uint32_t numItems;
DF.InitReadItems(numItems);
DF.InitViewAndCursor(); DF.InitViewAndCursor();
cout << "q to quit, anything else to look up items at that location\n"; cout << "q to quit, anything else to look up items at that location\n";
while(1) while(1)
{ {
@ -115,37 +108,14 @@ int main ()
DF.ForceResume(); DF.ForceResume();
getline (cin, input); getline (cin, input);
DF.Suspend(); DF.Suspend();
uint32_t numItems = DF.InitReadItems(); //FIXME: why twice?
uint32_t numItems;
DF.InitReadItems(numItems);
if(input == "q") if(input == "q")
{ {
break; break;
} }
// else if(next == 'c'){
// cerr << "clearing similarity" << endl;
// similarity.clear();
// continue;
// }
// else if(next == 'p'){
// vector<bool> same(similarity[0].size(),true);
// for(int k =0; k < similarity.size(); k++){
// for(int j =0; j < similarity.size(); j++){
// if(k != j){
// for(int l =0; l < similarity[k].size(); l++){
// if(similarity[k][l] != similarity[j][l]){
// same[l] = false;
// }
// }
// }
// }
// }
// for(int itr =0; itr < same.size(); itr++){
// if(same[itr] == true && similarity[0][itr] != 0){
// cout << hex << itr << " " << hex << (int)similarity[0][itr] << endl;
// }
// }
// continue;
// }
int32_t x,y,z; int32_t x,y,z;
DF.getCursorCoords(x,y,z); DF.getCursorCoords(x,y,z);
vector <DFHack::t_item> foundItems; vector <DFHack::t_item> foundItems;
@ -162,15 +132,16 @@ int main ()
if(foundItems.size() == 0){ if(foundItems.size() == 0){
cerr << "No Items at x:" << x << " y:" << y << " z:" << z << endl; cerr << "No Items at x:" << x << " y:" << y << " z:" << z << endl;
} }
else if(foundItems.size() == 1){ else if(foundItems.size() == 1)
printItem(foundItems[0], buildingtypes,mat); {
// similarity.push_back(foundItems[0].bytes); printItem(foundItems[0], objecttypes ,mat);
} }
else{ else
{
cerr << "Please Select which item you want to display\n"; cerr << "Please Select which item you want to display\n";
for(uint32_t j = 0; j < foundItems.size(); ++j) for(uint32_t j = 0; j < foundItems.size(); ++j)
{ {
cerr << j << " " << buildingtypes[foundItems[j].type] << endl; cerr << j << " " << objecttypes[foundItems[j].type] << endl;
} }
uint32_t value; uint32_t value;
string input2; string input2;
@ -178,7 +149,8 @@ int main ()
getline(cin, input2); getline(cin, input2);
ss.str(input2); ss.str(input2);
ss >> value; ss >> value;
while(value >= foundItems.size()){ while(value >= foundItems.size())
{
cerr << "invalid choice, please try again" << endl; cerr << "invalid choice, please try again" << endl;
input2.clear(); input2.clear();
ss.clear(); ss.clear();
@ -186,8 +158,7 @@ int main ()
ss.str(input2); ss.str(input2);
ss >> value; ss >> value;
} }
printItem(foundItems[value], buildingtypes,mat); printItem(foundItems[value], objecttypes ,mat);
// similarity.push_back(foundItems[value].bytes);
} }
DF.FinishReadItems(); DF.FinishReadItems();
} }

@ -141,8 +141,10 @@ int main ()
{ {
DFHack::API DF ("Memory.xml"); DFHack::API DF ("Memory.xml");
cout << "This utility lets you mass-designate items by type and material." << endl <<"Like set on fire all MICROCLINE item_stone..." << endl cout << "This utility lets you mass-designate items by type and material." << endl
<< "Some unusual combinations might be untested and cause the program to crash..."<< endl << "so, watch your step and backup your fort" << endl; << "Like set on fire all MICROCLINE item_stone..." << endl
<< "Some unusual combinations might be untested and cause the program to crash..."<< endl
<< "so, watch your step and backup your fort" << endl;
if(!DF.Attach()) if(!DF.Attach())
{ {
cerr << "DF not found" << endl; cerr << "DF not found" << endl;
@ -156,11 +158,11 @@ int main ()
DF.ReadStoneMatgloss(mat.stoneMat); DF.ReadStoneMatgloss(mat.stoneMat);
DF.ReadMetalMatgloss(mat.metalMat); DF.ReadMetalMatgloss(mat.metalMat);
DF.ReadCreatureMatgloss(mat.creatureMat); DF.ReadCreatureMatgloss(mat.creatureMat);
//DF.ForceResume();
vector <string> buildingtypes; vector <string> objecttypes;
DF.InitReadBuildings(buildingtypes); DF.getClassIDMapping(objecttypes);
uint32_t numItems = DF.InitReadItems(); uint32_t numItems;
DF.InitReadItems(numItems);
map< string, map<string,vector<uint32_t> > > count; map< string, map<string,vector<uint32_t> > > count;
int failedItems = 0; int failedItems = 0;
map <string, int > bad_mat_items; map <string, int > bad_mat_items;
@ -170,22 +172,22 @@ int main ()
DF.ReadItem(i,temp); DF.ReadItem(i,temp);
if(temp.type != -1) if(temp.type != -1)
{ {
string material = getMaterialType(temp,buildingtypes,mat); string material = getMaterialType(temp,objecttypes,mat);
if (material != "Invalid") if (material != "Invalid")
{ {
count[buildingtypes[temp.type]][material].push_back(i); count[objecttypes[temp.type]][material].push_back(i);
} }
else else
{ {
if(bad_mat_items.count(buildingtypes[temp.type])) if(bad_mat_items.count(objecttypes[temp.type]))
{ {
int tmp = bad_mat_items[buildingtypes[temp.type]]; int tmp = bad_mat_items[objecttypes[temp.type]];
tmp ++; tmp ++;
bad_mat_items[buildingtypes[temp.type]] = tmp; bad_mat_items[objecttypes[temp.type]] = tmp;
} }
else else
{ {
bad_mat_items[buildingtypes[temp.type]] = 1; bad_mat_items[objecttypes[temp.type]] = 1;
} }
} }
} }
@ -243,7 +245,7 @@ int main ()
ss >> number2; ss >> number2;
decideAgain: decideAgain:
cout << "Select a designation - (d)ump, (f)orbid, (m)melt, on fi(r)e :" << flush; cout << "Select a designation - (d)ump, (f)orbid, (m)melt, set on fi(r)e :" << flush;
string designationType; string designationType;
getline(cin,designationType); getline(cin,designationType);
DFHack::t_itemflags changeFlag = {0}; DFHack::t_itemflags changeFlag = {0};
@ -259,7 +261,7 @@ int main ()
{ {
changeFlag.bits.melt = 1; changeFlag.bits.melt = 1;
} }
else if(designationType == "r" || designationType == "flame") else if(designationType == "r" || designationType == "fire")
{ {
changeFlag.bits.on_fire = 1; changeFlag.bits.on_fire = 1;
} }