dfhack/tools/playground/itemdesignator.cpp

149 lines
3.9 KiB
C++

2011-04-16 15:57:04 -06:00
// Item designator
2010-01-18 19:05:25 -07:00
#include <iostream>
#include <iomanip>
#include <sstream>
#include <climits>
#include <vector>
using namespace std;
2011-04-16 15:57:04 -06:00
#include <DFHack.h>
#include <dfhack/DFVector.h>
using namespace DFHack;
2010-01-18 19:05:25 -07:00
int main ()
{
2011-04-16 15:57:04 -06:00
DFHack::ContextManager CM ("Memory.xml");
DFHack::Context * DF;
DFHack::VersionInfo *mem;
DFHack::Gui * Gui;
DFHack::Materials * Mats;
DFHack::Items * Items;
cout << "This utility lets you mass-designate items by type and material." << 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;
try
2010-01-18 19:05:25 -07:00
{
2011-04-16 15:57:04 -06:00
DF = CM.getSingleContext();
DF->Attach();
mem = DF->getMemoryInfo();
Gui = DF->getGui();
Mats = DF->getMaterials();
Mats->ReadAllMaterials();
Items = DF->getItems();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
2010-01-18 19:05:25 -07:00
return 1;
}
2011-04-16 15:57:04 -06:00
DFHack::Process * p = DF->getProcess();
DFHack::OffsetGroup* itemGroup = mem->getGroup("Items");
unsigned vector_addr = itemGroup->getAddress("items_vector");
DFHack::DfVector <uint32_t> p_items (p, vector_addr);
uint32_t numItems = p_items.size();
2010-01-18 19:05:25 -07:00
2011-04-16 15:57:04 -06:00
map< string, map<string,vector< dfh_item > > > itemmap;
map< string, map< string, vector< dfh_item > > >::iterator it1;
2010-01-18 19:05:25 -07:00
int failedItems = 0;
2010-02-10 17:25:47 -07:00
map <string, int > bad_mat_items;
2010-01-18 19:05:25 -07:00
for(uint32_t i=0; i< numItems; i++)
{
2011-04-16 15:57:04 -06:00
DFHack::dfh_item temp;
Items->readItem(p_items[i],temp);
string typestr = Items->getItemClass(temp);
string material = Mats->getDescription(temp.matdesc);
itemmap[typestr][material].push_back(temp);
2010-02-10 17:25:47 -07:00
}
2011-04-16 15:57:04 -06:00
2010-01-18 19:05:25 -07:00
int i =0;
2011-04-16 15:57:04 -06:00
for( it1 = itemmap.begin(); it1!=itemmap.end();it1++)
2010-02-10 16:49:55 -07:00
{
2010-01-18 19:05:25 -07:00
cout << i << ": " << it1->first << "\n";
i++;
}
2010-02-10 16:49:55 -07:00
if(i == 0)
{
cout << "No items found" << endl;
2011-04-16 15:57:04 -06:00
DF->Detach();
2010-02-10 16:49:55 -07:00
return 0;
}
cout << endl << "Select an item type from the list:";
2010-01-18 19:05:25 -07:00
int number;
string in;
stringstream ss;
getline(cin, in);
ss.str(in);
ss >> number;
int j = 0;
2011-04-16 15:57:04 -06:00
it1 = itemmap.begin();
while(j < number && it1!=itemmap.end())
2010-02-10 16:49:55 -07:00
{
2010-01-18 19:05:25 -07:00
it1++;
j++;
}
cout << it1->first << "\n";
2011-04-16 15:57:04 -06:00
map<string,vector<dfh_item> >::iterator it2;
2010-01-18 19:05:25 -07:00
i=0;
for(it2 = it1->second.begin();it2!=it1->second.end();it2++){
cout << i << ":\t" << it2->first << " [" << it2->second.size() << "]" << endl;
i++;
}
2010-02-10 16:49:55 -07:00
cout << endl << "Select a material type: ";
2010-01-18 19:05:25 -07:00
int number2;
ss.clear();
getline(cin, in);
ss.str(in);
ss >> number2;
2011-04-16 15:57:04 -06:00
2010-02-10 16:49:55 -07:00
decideAgain:
cout << "Select a designation - (d)ump, (f)orbid, (m)melt, set on fi(r)e :" << flush;
2010-01-18 19:05:25 -07:00
string designationType;
getline(cin,designationType);
DFHack::t_itemflags changeFlag = {0};
2010-02-10 16:49:55 -07:00
if(designationType == "d" || designationType == "dump")
{
2011-04-16 15:57:04 -06:00
changeFlag.dump = 1;
2010-01-18 19:05:25 -07:00
}
2010-02-10 16:49:55 -07:00
else if(designationType == "f" || designationType == "forbid")
{
2011-04-16 15:57:04 -06:00
changeFlag.forbid = 1;
2010-01-18 19:05:25 -07:00
}
2010-02-10 16:49:55 -07:00
else if(designationType == "m" || designationType == "melt")
{
2011-04-16 15:57:04 -06:00
changeFlag.melt = 1;
2010-01-18 19:05:25 -07:00
}
else if(designationType == "r" || designationType == "fire")
2010-02-10 16:49:55 -07:00
{
2011-04-16 15:57:04 -06:00
changeFlag.on_fire = 1;
2010-02-10 16:49:55 -07:00
}
else
{
goto decideAgain;
2010-01-18 19:05:25 -07:00
}
j=0;
it2= it1->second.begin();
2010-02-10 16:49:55 -07:00
while(j < number2 && it2!=it1->second.end())
{
2010-01-18 19:05:25 -07:00
it2++;
j++;
}
2010-02-10 16:49:55 -07:00
for(uint32_t k = 0;k< it2->second.size();k++)
{
2011-04-16 15:57:04 -06:00
DFHack::dfh_item & t = it2->second[k];
t.base.flags.whole |= changeFlag.whole;
Items->writeItem(t);
2010-01-18 19:05:25 -07:00
}
2011-04-16 15:57:04 -06:00
DF->Detach();
2010-01-18 19:05:25 -07:00
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}