Example #1
0
int main (int argc, char* argv[])
{
    // Command line options
    bool updown = false;
    if(argc > 1 && strcmp(argv[1],"-x") == 0)
        updown = true;

    DFHack::ContextManager DFMgr("Memory.xml");
    DFHack::Context * DF;
    try
    {
        DF = DFMgr.getSingleContext();
        DF->Attach();
    }
    catch (exception& e)
    {
        cerr << e.what() << endl;
        #ifndef LINUX_BUILD
            cin.ignore();
        #endif
        return 1;
    }

    uint32_t x_max,y_max,z_max;
    DFHack::Maps * Maps = DF->getMaps();
    DFHack::Gui * Gui = DF->getGui();

    // init the map
    if(!Maps->Start())
    {
        cerr << "Can't init map. Make sure you have a map loaded in DF." << endl;
        DF->Detach();
        #ifndef LINUX_BUILD
            cin.ignore();
        #endif
        return 1;
    }

    int32_t cx, cy, cz;
    Maps->getSize(x_max,y_max,z_max);
    uint32_t tx_max = x_max * 16;
    uint32_t ty_max = y_max * 16;

    Gui->getCursorCoords(cx,cy,cz);
    while(cx == -30000)
    {
        cerr << "Cursor is not active. Point the cursor at a vein." << endl;
        DF->Resume();
        cin.ignore();
        DF->Suspend();
        Gui->getCursorCoords(cx,cy,cz);
    }
    DFHack::DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz);
    if(xy.x == 0 || xy.x == tx_max - 1 || xy.y == 0 || xy.y == ty_max - 1)
    {
        cerr << "I won't dig the borders. That would be cheating!" << endl;
        DF->Detach();
        #ifndef LINUX_BUILD
            cin.ignore();
        #endif
        return 1;
    }
    MapCache * MCache = new MapCache(Maps);

    DFHack::t_designation des = MCache->designationAt(xy);
    int16_t tt = MCache->tiletypeAt(xy);
    int16_t veinmat = MCache->veinMaterialAt(xy);

    if( veinmat == -1 )
    {
        cerr << "This tile is non-vein. Bye :)" << endl;
        delete MCache;
        DF->Detach();
        #ifndef LINUX_BUILD
            cin.ignore();
        #endif
        return 1;
    }
    printf("%d/%d/%d tiletype: %d, veinmat: %d, designation: 0x%x ... DIGGING!\n", cx,cy,cz, tt, veinmat, des.whole);
    stack <DFHack::DFCoord> flood;
    flood.push(xy);


    while( !flood.empty() )
    {
        DFHack::DFCoord current = flood.top();
        flood.pop();
        int16_t vmat2 = MCache->veinMaterialAt(current);
        tt = MCache->tiletypeAt(current);
        if(!DFHack::isWallTerrain(tt))
            continue;
        if(vmat2!=veinmat)
            continue;

        // found a good tile, dig+unset material
        DFHack::t_designation des = MCache->designationAt(current);
        DFHack::t_designation des_minus;
        DFHack::t_designation des_plus;
        des_plus.whole = des_minus.whole = 0;
        int16_t vmat_minus = -1;
        int16_t vmat_plus = -1;
        bool below = 0;
        bool above = 0;
        if(updown)
        {
            if(MCache->testCoord(current-1))
            {
                below = 1;
                des_minus = MCache->designationAt(current-1);
                vmat_minus = MCache->veinMaterialAt(current-1);
            }

            if(MCache->testCoord(current+1))
            {
                above = 1;
                des_plus = MCache->designationAt(current+1);
                vmat_plus = MCache->veinMaterialAt(current+1);
            }
        }
        if(MCache->testCoord(current))
        {
            MCache->clearMaterialAt(current);
            if(current.x < tx_max - 2)
            {
                flood.push(DFHack::DFCoord(current.x + 1, current.y, current.z));
                if(current.y < ty_max - 2)
                {
                    flood.push(DFHack::DFCoord(current.x + 1, current.y + 1,current.z));
                    flood.push(DFHack::DFCoord(current.x, current.y + 1,current.z));
                }
                if(current.y > 1)
                {
                    flood.push(DFHack::DFCoord(current.x + 1, current.y - 1,current.z));
                    flood.push(DFHack::DFCoord(current.x, current.y - 1,current.z));
                }
            }
            if(current.x > 1)
            {
                flood.push(DFHack::DFCoord(current.x - 1, current.y,current.z));
                if(current.y < ty_max - 2)
                {
                    flood.push(DFHack::DFCoord(current.x - 1, current.y + 1,current.z));
                    flood.push(DFHack::DFCoord(current.x, current.y + 1,current.z));
                }
                if(current.y > 1)
                {
                    flood.push(DFHack::DFCoord(current.x - 1, current.y - 1,current.z));
                    flood.push(DFHack::DFCoord(current.x, current.y - 1,current.z));
                }
            }
            if(updown)
            {
                if(current.z > 0 && below && vmat_minus == vmat2)
                {
                    flood.push(current-1);

                    if(des_minus.bits.dig == DFHack::designation_d_stair)
                        des_minus.bits.dig = DFHack::designation_ud_stair;
                    else
                        des_minus.bits.dig = DFHack::designation_u_stair;
                    MCache->setDesignationAt(current-1,des_minus);

                    des.bits.dig = DFHack::designation_d_stair;
                }
                if(current.z < z_max - 1 && above && vmat_plus == vmat2)
                {
                    flood.push(current+ 1);

                    if(des_plus.bits.dig == DFHack::designation_u_stair)
                        des_plus.bits.dig = DFHack::designation_ud_stair;
                    else
                        des_plus.bits.dig = DFHack::designation_d_stair;
                    MCache->setDesignationAt(current+1,des_plus);

                    if(des.bits.dig == DFHack::designation_d_stair)
                        des.bits.dig = DFHack::designation_ud_stair;
                    else
                        des.bits.dig = DFHack::designation_u_stair;
                }
            }
            if(des.bits.dig == DFHack::designation_no)
                des.bits.dig = DFHack::designation_default;
            MCache->setDesignationAt(current,des);
        }
    }
    MCache->WriteAll();
    delete MCache;
    DF->Detach();
    #ifndef LINUX_BUILD
        cout << "Done. Press any key to continue" << endl;
        cin.ignore();
    #endif
    return 0;
}
Example #2
0
command_result df_liquids_execute(color_ostream &out)
{
    // create brush type depending on old parameters
    Brush * brush;

    if (brushname == "point")
    {
        brush = new RectangleBrush(1,1,1,0,0,0);
        //width = 1;
        //height = 1;
        //z_levels = 1;
    }
    else if (brushname == "range")
    {
        brush = new RectangleBrush(width,height,z_levels,0,0,0);
    }
    else if(brushname == "block")
    {
        brush = new BlockBrush();
    }
    else if(brushname == "column")
    {
        brush = new ColumnBrush();
    }
    else if(brushname == "flood")
    {
        brush = new FloodBrush(&Core::getInstance());
    }
    else
    {
        // this should never happen!
        out << "Old brushtype is invalid! Resetting to point brush.\n";
        brushname = "point";
        width = 1;
        height = 1;
        z_levels = 1;
        brush = new RectangleBrush(width,height,z_levels,0,0,0);
    }

    CoreSuspender suspend;

    do
    {
        if (!Maps::IsValid())
        {
            out << "Can't see any DF map loaded." << endl;
            break;;
        }
        int32_t x,y,z;
        if(!Gui::getCursorCoords(x,y,z))
        {
            out << "Can't get cursor coords! Make sure you have a cursor active in DF." << endl;
            break;
        }
        out << "cursor coords: " << x << "/" << y << "/" << z << endl;
        MapCache mcache;
        DFHack::DFCoord cursor(x,y,z);
        coord_vec all_tiles = brush->points(mcache,cursor);
        out << "working..." << endl;

        // Force the game to recompute its walkability cache
        df::global::world->reindex_pathfinding = true;

        if(mode == "obsidian")
        {
            coord_vec::iterator iter = all_tiles.begin();
            while (iter != all_tiles.end())
            {
                mcache.setTiletypeAt(*iter, tiletype::LavaWall);
                mcache.setTemp1At(*iter,10015);
                mcache.setTemp2At(*iter,10015);
                df::tile_designation des = mcache.designationAt(*iter);
                des.bits.flow_size = 0;
                des.bits.flow_forbid = false;
                mcache.setDesignationAt(*iter, des);
                iter ++;
            }
        }
        if(mode == "obsidian_floor")
        {
            coord_vec::iterator iter = all_tiles.begin();
            while (iter != all_tiles.end())
            {
                mcache.setTiletypeAt(*iter, findRandomVariant(tiletype::LavaFloor1));
                iter ++;
            }
        }
        else if(mode == "riversource")
        {
            coord_vec::iterator iter = all_tiles.begin();
            while (iter != all_tiles.end())
            {
                mcache.setTiletypeAt(*iter, tiletype::RiverSource);

                df::tile_designation a = mcache.designationAt(*iter);
                a.bits.liquid_type = tile_liquid::Water;
                a.bits.liquid_static = false;
                a.bits.flow_size = 7;
                mcache.setTemp1At(*iter,10015);
                mcache.setTemp2At(*iter,10015);
                mcache.setDesignationAt(*iter,a);

                Block * b = mcache.BlockAt((*iter)/16);
                DFHack::t_blockflags bf = b->BlockFlags();
                bf.bits.update_liquid = true;
                bf.bits.update_liquid_twice = true;
                b->setBlockFlags(bf);

                iter++;
            }
        }
        else if(mode=="wclean")
        {
            coord_vec::iterator iter = all_tiles.begin();
            while (iter != all_tiles.end())
            {
                DFHack::DFCoord current = *iter;
                df::tile_designation des = mcache.designationAt(current);
                des.bits.water_salt = false;
                des.bits.water_stagnant = false;
                mcache.setDesignationAt(current,des);
                iter++;
            }
        }
        else if(mode== "magma" || mode== "water" || mode == "flowbits")
        {
            set <Block *> seen_blocks;
            coord_vec::iterator iter = all_tiles.begin();
            while (iter != all_tiles.end())
            {
                DFHack::DFCoord current = *iter; // current tile coord
                DFHack::DFCoord curblock = current /16; // current block coord
                // check if the block is actually there
                if(!mcache.BlockAt(curblock))
                {
                    iter ++;
                    continue;
                }
                df::tile_designation des = mcache.designationAt(current);
                df::tiletype tt = mcache.tiletypeAt(current);
                // don't put liquids into places where they don't belong...
                if(!DFHack::FlowPassable(tt))
                {
                    iter++;
                    continue;
                }
                if(mode != "flowbits")
                {
                    if(setmode == "s.")
                    {
                        des.bits.flow_size = amount;
                    }
                    else if(setmode == "s+")
                    {
                        if(des.bits.flow_size < amount)
                            des.bits.flow_size = amount;
                    }
                    else if(setmode == "s-")
                    {
                        if (des.bits.flow_size > amount)
                            des.bits.flow_size = amount;
                    }
                    if(amount != 0 && mode == "magma")
                    {
                        des.bits.liquid_type =  tile_liquid::Magma;
                        mcache.setTemp1At(current,12000);
                        mcache.setTemp2At(current,12000);
                    }
                    else if(amount != 0 && mode == "water")
                    {
                        des.bits.liquid_type =  tile_liquid::Water;
                        mcache.setTemp1At(current,10015);
                        mcache.setTemp2At(current,10015);
                    }
                    else if(amount == 0 && (mode == "water" || mode == "magma"))
                    {
                        // reset temperature to sane default
                        mcache.setTemp1At(current,10015);
                        mcache.setTemp2At(current,10015);
                    }
                    // mark the tile passable or impassable like the game does
                    des.bits.flow_forbid = des.bits.flow_size &&
                        (des.bits.liquid_type == tile_liquid::Magma || des.bits.flow_size > 3);
                    mcache.setDesignationAt(current,des);
                }
                seen_blocks.insert(mcache.BlockAt(current / 16));
                iter++;
            }
            set <Block *>::iterator biter = seen_blocks.begin();
            while (biter != seen_blocks.end())
            {
                DFHack::t_blockflags bflags = (*biter)->BlockFlags();
                if(flowmode == "f+")
                {
                    bflags.bits.update_liquid = true;
                    bflags.bits.update_liquid_twice = true;
                    (*biter)->setBlockFlags(bflags);
                }
                else if(flowmode == "f-")
                {
                    bflags.bits.update_liquid = false;
                    bflags.bits.update_liquid_twice = false;
                    (*biter)->setBlockFlags(bflags);
                }
                else
                {
                    out << "flow bit 1 = " << bflags.bits.update_liquid << endl; 
                    out << "flow bit 2 = " << bflags.bits.update_liquid_twice << endl;
                }
                biter ++;
            }
        }
        if(mcache.WriteAll())
            out << "OK" << endl;
        else
            out << "Something failed horribly! RUN!" << endl;
    } while (0);

    // cleanup
    delete brush;
    return CR_OK;
}
Example #3
0
command_result revflood(color_ostream &out, vector<string> & params)
{
    for(size_t i = 0; i < params.size();i++)
    {
        if(params[i] == "help" || params[i] == "?")
            return CR_WRONG_USAGE;
    }
    CoreSuspender suspend;
    uint32_t x_max,y_max,z_max;
    if (!Maps::IsValid())
    {
        out.printerr("Map is not available!\n");
        return CR_FAILURE;
    }
    if(revealed != NOT_REVEALED)
    {
        out.printerr("This is only safe to use with non-revealed map.\n");
        return CR_FAILURE;
    }
    t_gamemodes gm;
    World::ReadGameMode(gm);
    if(!World::isFortressMode(gm.g_type) || gm.g_mode != game_mode::DWARF )
    {
        out.printerr("Only in proper dwarf mode.\n");
        return CR_FAILURE;
    }
    int32_t cx, cy, cz;
    Maps::getSize(x_max,y_max,z_max);
    uint32_t tx_max = x_max * 16;
    uint32_t ty_max = y_max * 16;

    Gui::getCursorCoords(cx,cy,cz);
    if(cx == -30000)
    {
        out.printerr("Cursor is not active. Point the cursor at some empty space you want to be unhidden.\n");
        return CR_FAILURE;
    }
    DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz);
    MapCache * MCache = new MapCache;
    df::tiletype tt = MCache->tiletypeAt(xy);
    if(isWallTerrain(tt))
    {
        out.printerr("Point the cursor at some empty space you want to be unhidden.\n");
        delete MCache;
        return CR_FAILURE;
    }
    // hide all tiles, flush cache
    Maps::getSize(x_max,y_max,z_max);

    for(size_t i = 0; i < world->map.map_blocks.size(); i++)
    {
        df::map_block * b = world->map.map_blocks[i];
        // change the hidden flag to 0
        for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
        {
            b->designation[x][y].bits.hidden = 1;
        }
    }
    MCache->trash();

    typedef std::pair <DFCoord, bool> foo;
    std::stack < foo > flood;
    flood.push( foo(xy,false) );

    while( !flood.empty() )
    {
        foo tile = flood.top();
        DFCoord & current = tile.first;
        bool & from_below = tile.second;
        flood.pop();

        if(!MCache->testCoord(current))
            continue;
        df::tiletype tt = MCache->baseTiletypeAt(current);
        df::tile_designation des = MCache->designationAt(current);
        if(!des.bits.hidden)
        {
            continue;
        }
        bool below = 0;
        bool above = 0;
        bool sides = 0;
        bool unhide = 1;
        // by tile shape, determine behavior and action
        switch (tileShape(tt))
        {
        // walls:
        case tiletype_shape::WALL:
            if(from_below)
                unhide = 0;
            break;
        // air/free space
        case tiletype_shape::EMPTY:
        case tiletype_shape::RAMP_TOP:
        case tiletype_shape::STAIR_UPDOWN:
        case tiletype_shape::STAIR_DOWN:
        case tiletype_shape::BROOK_TOP:
            above = below = sides = true;
            break;
        // has floor
        case tiletype_shape::FORTIFICATION:
        case tiletype_shape::STAIR_UP:
        case tiletype_shape::RAMP:
        case tiletype_shape::FLOOR:
        case tiletype_shape::BRANCH:
        case tiletype_shape::TRUNK_BRANCH:
        case tiletype_shape::TWIG:
        case tiletype_shape::SAPLING:
        case tiletype_shape::SHRUB:
        case tiletype_shape::BOULDER:
        case tiletype_shape::PEBBLES:
        case tiletype_shape::BROOK_BED:
        case tiletype_shape::ENDLESS_PIT:
            if(from_below)
                unhide = 0;
            above = sides = true;
            break;
        }
        if (tileMaterial(tt) == tiletype_material::PLANT || tileMaterial(tt) == tiletype_material::MUSHROOM)
        {
            if(from_below)
                unhide = 0;
            above = sides = true;
        }
        if(unhide)
        {
            des.bits.hidden = false;
            MCache->setDesignationAt(current,des);
        }
        if(sides)
        {
            flood.push(foo(DFCoord(current.x + 1, current.y ,current.z),false));
            flood.push(foo(DFCoord(current.x + 1, current.y + 1 ,current.z),false));
            flood.push(foo(DFCoord(current.x, current.y + 1 ,current.z),false));
            flood.push(foo(DFCoord(current.x - 1, current.y + 1 ,current.z),false));
            flood.push(foo(DFCoord(current.x - 1, current.y ,current.z),false));
            flood.push(foo(DFCoord(current.x - 1, current.y - 1 ,current.z),false));
            flood.push(foo(DFCoord(current.x, current.y - 1 ,current.z),false));
            flood.push(foo(DFCoord(current.x + 1, current.y - 1 ,current.z),false));
        }
        if(above)
        {
            flood.push(foo(DFCoord(current.x, current.y ,current.z + 1),true));
        }
        if(below)
        {
            flood.push(foo(DFCoord(current.x, current.y ,current.z - 1),false));
        }
    }
    MCache->WriteAll();
    delete MCache;
    return CR_OK;
}
Example #4
0
command_result df_liquids_execute(color_ostream &out, OperationMode &cur_mode, df::coord cursor)
{
    // create brush type depending on old parameters
    Brush *brush;

    switch (cur_mode.brush)
    {
    case B_POINT:
        brush = new RectangleBrush(1,1,1,0,0,0);
        break;
    case B_RANGE:
        brush = new RectangleBrush(cur_mode.size.x,cur_mode.size.y,cur_mode.size.z,0,0,0);
        break;
    case B_BLOCK:
        brush = new BlockBrush();
        break;
    case B_COLUMN:
        brush = new ColumnBrush();
        break;
    case B_FLOOD:
        brush = new FloodBrush(&Core::getInstance());
        break;
    default:
        // this should never happen!
        out << "Old brushtype is invalid! Resetting to point brush.\n";
        cur_mode.brush = B_POINT;
        brush = new RectangleBrush(1,1,1,0,0,0);
    }

    std::auto_ptr<Brush> brush_ref(brush);

    if (!Maps::IsValid())
    {
        out << "Can't see any DF map loaded." << endl;
        return CR_FAILURE;
    }

    MapCache mcache;
    coord_vec all_tiles = brush->points(mcache,cursor);

    // Force the game to recompute its walkability cache
    df::global::world->reindex_pathfinding = true;

    switch (cur_mode.paint)
    {
    case P_OBSIDIAN:
        {
            coord_vec::iterator iter = all_tiles.begin();
            while (iter != all_tiles.end())
            {
                mcache.setTiletypeAt(*iter, tiletype::LavaWall);
                mcache.setTemp1At(*iter,10015);
                mcache.setTemp2At(*iter,10015);
                df::tile_designation des = mcache.designationAt(*iter);
                des.bits.flow_size = 0;
                des.bits.flow_forbid = false;
                mcache.setDesignationAt(*iter, des);
                iter ++;
            }
            break;
        }
    case P_OBSIDIAN_FLOOR:
        {
            coord_vec::iterator iter = all_tiles.begin();
            while (iter != all_tiles.end())
            {
                mcache.setTiletypeAt(*iter, findRandomVariant(tiletype::LavaFloor1));
                iter ++;
            }
            break;
        }
    case P_RIVER_SOURCE:
        {
            coord_vec::iterator iter = all_tiles.begin();
            while (iter != all_tiles.end())
            {
                mcache.setTiletypeAt(*iter, tiletype::RiverSource);

                df::tile_designation a = mcache.designationAt(*iter);
                a.bits.liquid_type = tile_liquid::Water;
                a.bits.liquid_static = false;
                a.bits.flow_size = 7;
                mcache.setTemp1At(*iter,10015);
                mcache.setTemp2At(*iter,10015);
                mcache.setDesignationAt(*iter,a);

                Block * b = mcache.BlockAt((*iter)/16);
                b->enableBlockUpdates(true);

                iter++;
            }
            break;
        }
    case P_WCLEAN:
        {
            coord_vec::iterator iter = all_tiles.begin();
            while (iter != all_tiles.end())
            {
                DFHack::DFCoord current = *iter;
                df::tile_designation des = mcache.designationAt(current);
                des.bits.water_salt = false;
                des.bits.water_stagnant = false;
                mcache.setDesignationAt(current,des);
                iter++;
            }
            break;
        }
    case P_MAGMA:
    case P_WATER:
    case P_FLOW_BITS:
        {
            set <Block *> seen_blocks;
            coord_vec::iterator iter = all_tiles.begin();
            while (iter != all_tiles.end())
            {
                DFHack::DFCoord current = *iter; // current tile coord
                DFHack::DFCoord curblock = current /16; // current block coord
                // check if the block is actually there
                auto block = mcache.BlockAt(curblock);
                if(!block)
                {
                    iter ++;
                    continue;
                }
                auto raw_block = block->getRaw();
                df::tile_designation des = mcache.designationAt(current);
                df::tiletype tt = mcache.tiletypeAt(current);
                // don't put liquids into places where they don't belong...
                if(!DFHack::FlowPassable(tt))
                {
                    iter++;
                    continue;
                }
                if(cur_mode.paint != P_FLOW_BITS)
                {
                    unsigned old_amount = des.bits.flow_size;
                    unsigned new_amount = old_amount;
                    df::tile_liquid old_liquid = des.bits.liquid_type;
                    df::tile_liquid new_liquid = old_liquid;
                    // Compute new liquid type and amount
                    switch (cur_mode.setmode)
                    {
                    case M_KEEP:
                        new_amount = cur_mode.amount;
                        break;
                    case M_INC:
                        if(old_amount < cur_mode.amount)
                            new_amount = cur_mode.amount;
                        break;
                    case M_DEC:
                        if (old_amount > cur_mode.amount)
                            new_amount = cur_mode.amount;
                    }
                    if (cur_mode.paint == P_MAGMA)
                        new_liquid = tile_liquid::Magma;
                    else if (cur_mode.paint == P_WATER)
                        new_liquid = tile_liquid::Water;
                    // Store new amount and type
                    des.bits.flow_size = new_amount;
                    des.bits.liquid_type = new_liquid;
                    // Compute temperature
                    if (!old_amount)
                        old_liquid = tile_liquid::Water;
                    if (!new_amount)
                        new_liquid = tile_liquid::Water;
                    if (old_liquid != new_liquid)
                    {
                        if (new_liquid == tile_liquid::Water)
                        {
                            mcache.setTemp1At(current,10015);
                            mcache.setTemp2At(current,10015);
                        }
                        else
                        {
                            mcache.setTemp1At(current,12000);
                            mcache.setTemp2At(current,12000);
                        }
                    }
                    // mark the tile passable or impassable like the game does
                    des.bits.flow_forbid = (new_liquid == tile_liquid::Magma || new_amount > 3);
                    mcache.setDesignationAt(current,des);
                    // request flow engine updates
                    block->enableBlockUpdates(new_amount != old_amount, new_liquid != old_liquid);
                }
                if (cur_mode.permaflow != PF_KEEP && raw_block)
                {
                    auto &flow = raw_block->liquid_flow[current.x&15][current.y&15];
                    flow.bits.perm_flow_dir = permaflow_id[cur_mode.permaflow];
                    flow.bits.temp_flow_timer = 0;
                }
                seen_blocks.insert(block);
                iter++;
            }
            set <Block *>::iterator biter = seen_blocks.begin();
            while (biter != seen_blocks.end())
            {
                switch (cur_mode.flowmode)
                {
                case M_INC:
                    (*biter)->enableBlockUpdates(true);
                    break;
                case M_DEC:
                    if (auto block = (*biter)->getRaw())
                    {
                        block->flags.clear(block_flags::update_liquid);
                        block->flags.clear(block_flags::update_liquid_twice);
                    }
                    break;
                case M_KEEP:
                    {
                        auto block = (*biter)->getRaw();
                        out << "flow bit 1 = " << block->flags.is_set(block_flags::update_liquid) << endl; 
                        out << "flow bit 2 = " << block->flags.is_set(block_flags::update_liquid_twice) << endl;
                    }
                }
                biter ++;
            }
            break;
        }
    }

    if(!mcache.WriteAll())
    {
        out << "Something failed horribly! RUN!" << endl;
        return CR_FAILURE;
    }

    return CR_OK;
}
Example #5
0
int main (int argc, const char* argv[])
{
    // Command line options
    bool updown = false;
    bool quiet = true;
    // let's be more useful when double-clicked on windows
    #ifndef LINUX_BUILD
    quiet = false;
    #endif
    int dig_up_n = 5;
    int dig_down_n = 5;

    for(int i = 1; i < argc; i++)
    {
        string arg_cur = argv[i];
        string arg_next = "";
	int arg_next_int = -99999;
	/* Check if argv[i+1] is a number >= 0 */
	if (i < argc-1) {
	    arg_next = argv[i+1];
	    arg_next_int = strtoint(arg_next);
	    if (arg_next != "0" && arg_next_int == 0) {
		arg_next_int = -99999;
	    }
	}
	if (arg_cur == "-x")
	{
	    updown = true;
	}
	else if (arg_cur == "-q")
	{
	    quiet = true;
	}
	else if(arg_cur == "-u" && i < argc-1)
	{
	    if (arg_next_int < 0 || arg_next_int >= 99999) {
		usage(argc, argv);
		return 1;
	    }
	    dig_up_n = arg_next_int;
	    i++;
	}
	else if(arg_cur == "-d" && i < argc-1)
	{
	    if (arg_next_int < 0 || arg_next_int >= 99999) {
		usage(argc, argv);
		return 1;
	    }
	    dig_down_n = arg_next_int;
	    i++;
	}
	else
	{
	    usage(argc, argv);
	    return 1;
	}
    }

    DFHack::ContextManager DFMgr("Memory.xml");
    DFHack::Context * DF;
    try
    {
        DF = DFMgr.getSingleContext();
        DF->Attach();
    }
    catch (exception& e)
    {
        cerr << "Error getting context: " << e.what() << endl;
        if (!quiet)
            cin.ignore();

        return 1;
    }

    uint32_t x_max,y_max,z_max;
    DFHack::Maps * Maps = DF->getMaps();
    DFHack::Gui * Gui = DF->getGui();

    // init the map
    if(!Maps->Start())
    {
        cerr << "Can't init map. Make sure you have a map loaded in DF." << endl;
        DF->Detach();
        if (!quiet)
            cin.ignore();

        return 1;
    }

    int32_t cx, cy, cz;
    Maps->getSize(x_max,y_max,z_max);
    uint32_t tx_max = x_max * 16;
    uint32_t ty_max = y_max * 16;

    Gui->getCursorCoords(cx,cy,cz);
    if (cx == -30000)
    {
        cerr << "Cursor is not active. Point the cursor at the position to dig at." << endl;
        DF->Detach();
        if (!quiet)
	{
            cin.ignore();
	}
	return 1;
    }

    DFHack::DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz);
    if(xy.x == 0 || xy.x == tx_max - 1 || xy.y == 0 || xy.y == ty_max - 1)
    {
        cerr << "I won't dig the borders. That would be cheating!" << endl;
        DF->Detach();
        if (!quiet)
	{
            cin.ignore();
	}
        return 1;
    }
    MapCache * MCache = new MapCache(Maps);

    DFHack::t_designation des = MCache->designationAt(xy);
    int16_t tt = MCache->tiletypeAt(xy);
    int16_t veinmat = MCache->veinMaterialAt(xy);

    /*
    if( veinmat == -1 )
    {
        cerr << "This tile is non-vein. Bye :)" << endl;
        delete MCache;
        DF->Detach();
        if (!quiet) {
            cin.ignore();
	}
        return 1;
    }
    */
    printf("Digging at (%d/%d/%d), tiletype: %d, veinmat: %d, designation: 0x%x ... DIGGING!\n", cx,cy,cz, tt, veinmat, des.whole);

    // 1 < xy.x < tx_max - 1
    // 1 < xy.y < ty_max - 1
    // xy.z

    // X____
    // X_XXX
    // XXXXX
    // __XXX
    // __XXX
    // _____
    pos map[] = 
    {
	  { 0,0 }
	, { 0,1 }
	, { 0,2 }         , { 2,2 }, { 3,2 }, { 4,2 }
	, { 0,3 }, { 1,3 }, { 2,3 }, { 3,3 }, { 4,3 }
	                  , { 2,4 }, { 3,4 }, { 4,4 }
    // this is mirrored, goes left instead of right
	                  , {-2,2 }, {-3,2 }, {-4,2 }
	         , {-1,3 }, {-2,3 }, {-3,3 }, {-4,3 }
	                  , {-2,4 }, {-3,4 }, {-4,4 }
    };

    DFHack::DFCoord npos = xy;

    if (dig_up_n > 0)
    {
	for (int j = 0; j < dig_up_n; j++)
	{
	    for (int i = 0; i < sizeof(map)/sizeof(map[0]); i++) 
	    {
		npos=xy;
		npos.x += map[i].x;
		npos.y -= 4*j + map[i].y;
		printf("Digging at (%d/%d/%d)\n", npos.x, npos.y, npos.z);
		digat(MCache, npos);
	    }
	}
    }
    if (dig_down_n > 0)
    {
	for (int j = 0; j < dig_down_n; j++)
	{
	    for (int i = 0; i < sizeof(map)/sizeof(map[0]); i++) 
	    {
		npos=xy;
		npos.x += map[i].x;
		npos.y += 4*j + map[i].y;
		printf("Digging at (%d/%d/%d)\n", npos.x, npos.y, npos.z);
		digat(MCache, npos);
	    }
	}
    }

    MCache->WriteAll();
    delete MCache;
    DF->Detach();
    if (!quiet) {
        cout << "Done. Press any key to continue" << endl;
        cin.ignore();
    }
    return 0;
}