예제 #1
0
파일: Maps.cpp 프로젝트: sizeak/dfhack
Maps::Maps(DFContextShared* _d)
{
    d = new Private;
    d->d = _d;
    Process *p = d->owner = _d->p;
    d->Inited = d->Started = false;

    DFHack::memory_info * mem = p->getDescriptor();
    Server::Maps::maps_offsets &off = d->offsets;

    // get the offsets once here
    off.map_offset = mem->getAddress ("map_data");
    off.x_count_offset = mem->getAddress ("x_count_block");
    off.y_count_offset = mem->getAddress ("y_count_block");
    off.z_count_offset = mem->getAddress ("z_count_block");
    off.tile_type_offset = mem->getOffset ("map_data_type");
    off.designation_offset = mem->getOffset ("map_data_designation");
    off.occupancy_offset = mem->getOffset("map_data_occupancy");
    off.biome_stuffs = mem->getOffset ("map_data_biome_stuffs");
    off.veinvector = mem->getOffset ("map_data_vein_vector");
    off.local_feature_offset = mem->getOffset ("map_data_feature_local");
    off.global_feature_offset = mem->getOffset ("map_data_feature_global");

    off.temperature1_offset = mem->getOffset ("map_data_temperature1_offset");
    off.temperature2_offset = mem->getOffset ("map_data_temperature2_offset");
    off.region_x_offset = mem->getAddress ("region_x");
    off.region_y_offset = mem->getAddress ("region_y");
    off.region_z_offset =  mem->getAddress ("region_z");

    off.world_regions =  mem->getAddress ("ptr2_region_array");
    off.region_size =  mem->getHexValue ("region_size");
    off.region_geo_index_offset =  mem->getOffset ("region_geo_index_off");
    off.geolayer_geoblock_offset = mem->getOffset ("geolayer_geoblock_offset");
    off.world_geoblocks_vector =  mem->getAddress ("geoblock_vector");
    off.type_inside_geolayer = mem->getOffset ("type_inside_geolayer");

    off.world_size_x = mem->getAddress ("world_size_x");
    off.world_size_y = mem->getAddress ("world_size_y");

    // these can fail and will be found when looking at the actual veins later
    // basically a cache
    off.vein_ice_vptr = 0;
    mem->resolveClassnameToVPtr("block_square_event_frozen_liquid", off.vein_ice_vptr);
    off.vein_mineral_vptr = 0;
    mem->resolveClassnameToVPtr("block_square_event_mineral",off.vein_mineral_vptr);

    // upload offsets to SHM server if possible
    d->maps_module = 0;
    if(p->getModuleIndex("Maps2010",1,d->maps_module))
    {
        // supply the module with offsets so it can work with them
        Server::Maps::maps_offsets *off2 = SHMDATA(Server::Maps::maps_offsets);
        memcpy(off2, &(d->offsets), sizeof(Server::Maps::maps_offsets));
        full_barrier
        const uint32_t cmd = Server::Maps::MAP_INIT + (d->maps_module << 16);
        p->SetAndWait(cmd);
    }
    d->Inited = true;
}
예제 #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;
}