Esempio n. 1
0
int main ()
{

    DFHack::ContextManager 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
         << "Some unusual combinations might be untested and cause the program to crash..."<< endl
         << "so, watch your step and backup your fort" << endl;
    try
    {
        DF.Attach();
    }
    catch (exception& e)
    {
        cerr << e.what() << endl;
        #ifndef LINUX_BUILD
            cin.ignore();
        #endif
        return 1;
    }
    DFHack::memory_info *mem = DF.getMemoryInfo();
    DF.Suspend();
    DF.InitViewAndCursor();
    matGlosses mat;
    DF.ReadPlantMatgloss(mat.plantMat);
    DF.ReadWoodMatgloss(mat.woodMat);
    DF.ReadStoneMatgloss(mat.stoneMat);
    DF.ReadMetalMatgloss(mat.metalMat);
    DF.ReadCreatureMatgloss(mat.creatureMat);

//    vector <string> objecttypes;
//    DF.getClassIDMapping(objecttypes);
    uint32_t numItems;
    DF.InitReadItems(numItems);
    map< string, map<string,vector<uint32_t> > > count;
    int failedItems = 0;
    map <string, int > bad_mat_items;
    for(uint32_t i=0; i< numItems; i++)
    {
        DFHack::t_item temp;
        DF.ReadItem(i,temp);
        if(temp.type != -1) // this should be the case pretty much always
        {
            string typestr;
            mem->resolveClassIDToClassname(temp.type,typestr);
            string material = getMaterialType(temp,typestr,mat);
            if (material != "Invalid")
            {
                count[typestr][material].push_back(i);
            }
            else
            {
                if(bad_mat_items.count(typestr))
                {
                    int tmp = bad_mat_items[typestr];
                    tmp ++;
                    bad_mat_items[typestr] = tmp;
                }
                else
                {
                    bad_mat_items[typestr] = 1;
                }
            }
        }
    }
    
    map< string, int >::iterator it_bad;
    if(! bad_mat_items.empty())
    {
        cout << "Items with badly assigned materials:" << endl;
        for(it_bad = bad_mat_items.begin(); it_bad!=bad_mat_items.end();it_bad++)
        {
            cout << it_bad->first << " : " << it_bad->second << endl;
        }
    }
    map< string, map<string,vector<uint32_t> > >::iterator it1;
    int i =0;
    for(it1 = count.begin(); it1!=count.end();it1++)
    {
        cout << i << ": " << it1->first << "\n";
        i++;
    }
    if(i == 0)
    {
        cout << "No items found" << endl;
        DF.FinishReadBuildings();
        DF.Detach();
        return 0;
    }
    cout << endl << "Select an item type from the list:";
    int number;
    string in;
    stringstream ss;
    getline(cin, in);
    ss.str(in);
    ss >> number;
    int j = 0;
    it1 = count.begin();
    while(j < number && it1!=count.end())
    {
        it1++;
        j++;
    }
    cout << it1->first << "\n";
    map<string,vector<uint32_t> >::iterator it2;
    i=0;
    for(it2 = it1->second.begin();it2!=it1->second.end();it2++){
          cout << i << ":\t" << it2->first << " [" << it2->second.size() << "]" << endl;
            i++;
    }
    cout << endl << "Select a material type: ";
    int number2;
    ss.clear();
    getline(cin, in);
    ss.str(in);
    ss >> number2;
    
    decideAgain:
    cout << "Select a designation - (d)ump, (f)orbid, (m)melt, set on fi(r)e :" << flush;
    string designationType;
    getline(cin,designationType);
    DFHack::t_itemflags changeFlag = {0};
    if(designationType == "d" || designationType == "dump")
    {
        changeFlag.bits.dump = 1;
    }
    else if(designationType == "f" || designationType == "forbid")
    {
        changeFlag.bits.forbid = 1;
    }
    else if(designationType == "m" || designationType == "melt")
    {
        changeFlag.bits.melt = 1;
    }
    else if(designationType == "r" || designationType == "fire")
    {
        changeFlag.bits.on_fire = 1;
    }
    else
    {
        goto decideAgain;
    }
    j=0;
    it2= it1->second.begin();
    while(j < number2 && it2!=it1->second.end())
    {
        it2++;
        j++;
    }
    for(uint32_t k = 0;k< it2->second.size();k++)
    {
        DFHack::t_item temp;
        DF.ReadItem(it2->second[k],temp);
        temp.flags.whole |= changeFlag.whole;
        DF.WriteRaw(temp.origin+12,sizeof(uint32_t),(uint8_t *)&temp.flags.whole);
    }

    DF.FinishReadItems();
    DF.Detach();
#ifndef LINUX_BUILD
    cout << "Done. Press any key to continue" << endl;
    cin.ignore();
#endif
    return 0;
}
Esempio n. 2
0
int main ()
{
    DFHack::Process *proc;
    DFHack::memory_info *meminfo;
    DFHack::DfVector *items_vector;
    DFHack::t_item_df40d item_40d;
    DFHack::t_matglossPair item_40d_material;
    vector<DFHack::t_matgloss> stoneMat;
    uint32_t item_material_offset;
    uint32_t temp;
    int32_t type;
    int items;
    int found = 0, converted = 0;

    DFHack::API DF("Memory.xml");
    try
    {
        DF.Attach();
    }
    catch (exception& e)
    {
        cerr << e.what() << endl;
        #ifndef LINUX_BUILD
            cin.ignore();
        #endif
        return 1;
    }
    
    // Find out which material is bauxite
    if(!DF.ReadStoneMatgloss(stoneMat))
    {
        cout << "Materials not supported for this version of DF, exiting." << endl;
        #ifndef LINUX_BUILD
            cin.ignore();
        #endif
        DF.Detach();
        return EXIT_FAILURE;
    }
    int bauxiteIndex = -1;
    for (int i = 0; i < stoneMat.size();i++)
    {
        if(strcmp(stoneMat[i].id, "BAUXITE") == 0)
        {
            bauxiteIndex = i;
            break;
        }
    }
    if(bauxiteIndex == -1)
    {
        cout << "Cannot locate bauxite in the DF raws, exiting" << endl;
        #ifndef LINUX_BUILD
            cin.ignore();
        #endif
        DF.Detach();
        return EXIT_FAILURE;
    }
    
    // Get some basics needed for full access
    proc = DF.getProcess();
    meminfo = proc->getDescriptor();
    
    // Get the object name/ID mapping
    //FIXME: work on the 'supported features' system required

    // Check availability of required addresses and offsets (doing custom stuff here)

    items = meminfo->getAddress("items");
    item_material_offset = meminfo->getOffset("item_materials");
    if( !items || ! item_material_offset)
    {
        cout << "Items not supported for this DF version, exiting" << endl;
        #ifndef LINUX_BUILD
            cin.ignore();
        #endif
        DF.Detach();
        return EXIT_FAILURE;
    }
    
    items_vector = new DFHack::DfVector (proc->readVector (items, 4));
    for(uint32_t i = 0; i < items_vector->getSize(); i++)
    {
        // get pointer to object
        temp = * (uint32_t *) items_vector->at (i);
        // read object
        proc->read (temp, sizeof (DFHack::t_item_df40d), (uint8_t *) &item_40d);

        // resolve object type
        type = -1;
        
        // skip things we can't identify
        if(!meminfo->resolveObjectToClassID (temp, type))
            continue;
        string classname;
        if(!meminfo->resolveClassIDToClassname (type, classname))
            continue;
       
        if(classname == "item_trapparts")
        {
            proc->read (temp + item_material_offset, sizeof (DFHack::t_matglossPair), (uint8_t *) &item_40d_material);

            cout << dec << "Mechanism at x:" << item_40d.x << " y:" << item_40d.y << " z:" << item_40d.z << " ID:" << item_40d.ID << endl;
            
            if (item_40d_material.index != bauxiteIndex)
            {
                item_40d_material.index = bauxiteIndex;
                proc->write (temp + item_material_offset, sizeof (DFHack::t_matglossPair), (uint8_t *) &item_40d_material);
                converted++;
            }

            found++;
        }
    }


    if (found == 0)
    {
        cout << "No mechanisms to convert" << endl;
    } else {
        cout << found << " mechanisms found" << endl;
        cout << converted << " mechanisms converted" << endl;
    }

    DF.Resume();
    DF.Detach();

    delete items_vector;

#ifndef LINUX_BUILD
    cout << "Done. Press any key to continue" << endl;
    cin.ignore();
#endif

    return 0;
}