Esempio n. 1
0
DFhackCExport command_result df_flows (Core * c, vector <string> & parameters)
{
    uint32_t x_max,y_max,z_max;
    DFHack::designations40d designations;
    DFHack::Maps *Maps;

    c->Suspend();
    Maps = c->getMaps();
    // init the map
    if(!Maps->Start())
    {
        c->con.printerr("Can't init map.\n");
        c->Resume();
        return CR_FAILURE;
    }
    DFHack::t_blockflags bflags;
    Maps->getSize(x_max,y_max,z_max);
    // walk the map, count flowing tiles, magma, water
    uint32_t flow1=0, flow2=0, flowboth=0, water=0, magma=0;
    c->con.print("Counting flows and liquids ...\n");
    for(uint32_t x = 0; x< x_max;x++)
    {
        for(uint32_t y = 0; y< y_max;y++)
        {
            for(uint32_t z = 0; z< z_max;z++)
            {
                if(Maps->getBlock(x,y,z))
                {
                    Maps->ReadBlockFlags(x, y, z, bflags);
                    Maps->ReadDesignations(x, y, z, &designations);
                    if (bflags.bits.liquid_1)
                        flow1++;
                    if (bflags.bits.liquid_2)
                        flow2++;
                    if (bflags.bits.liquid_1 && bflags.bits.liquid_2)
                        flowboth++;
                    for (uint32_t i = 0; i < 16;i++) for (uint32_t j = 0; j < 16;j++)
                    {
                        if (designations[i][j].bits.liquid_type == DFHack::liquid_magma)
                            magma++;
                        if (designations[i][j].bits.liquid_type == DFHack::liquid_water)
                            water++;
                    }
                }
            }
        }
    }
    c->con.print("Blocks with liquid_1=true: %d\n"
                 "Blocks with liquid_2=true: %d\n"
                 "Blocks with both:          %d\n"
                 "Water tiles:               %d\n"
                 "Magma tiles:               %d\n"
                 ,flow1, flow2, flowboth, water, magma
                );
    c->Resume();
    return CR_OK;
}
Esempio n. 2
0
DFhackCExport command_result cleanmap (Core * c, vector <string> & parameters)
{
    const uint32_t water_idx = 6;
    const uint32_t mud_idx = 12;

    bool snow = false;
    bool mud = false;
    bool help = false;
    for(int i = 0; i < parameters.size();i++)
    {
        if(parameters[i] == "snow")
            snow = true;
        else if(parameters[i] == "mud")
            mud = true;
        else if(parameters[i] == "help" ||parameters[i] == "?")
        {
            help = true;
        }
    }
    if(help)
    {
        c->con.print("This command cleans the coverings from the map. Snow and mud are ignored by default.\n"
                     "Options:\n"
                     "snow   - also remove snow\n"
                     "mud    - also remove mud\n"
                    );
        return CR_OK;
    }
    c->Suspend();
    vector<DFHack::t_spattervein *> splatter;
    DFHack::Maps *Mapz = c->getMaps();

    // init the map
    if(!Mapz->Start())
    {
        c->con << "Can't init map." << std::endl;
        c->Resume();
        return CR_FAILURE;
    }

    uint32_t x_max,y_max,z_max;
    Mapz->getSize(x_max,y_max,z_max);

    // walk the map
    for(uint32_t x = 0; x< x_max;x++)
    {
        for(uint32_t y = 0; y< y_max;y++)
        {
            for(uint32_t z = 0; z< z_max;z++)
            {
                df_block * block = Mapz->getBlock(x,y,z);
                if(block)
                {
                    Mapz->SortBlockEvents(x,y,z,0,0,&splatter);
                    for(int i = 0; i < 16; i++)
                        for(int j = 0; j < 16; j++)
                        {
                            block->occupancy[i][j].bits.arrow_color = 0;
                            block->occupancy[i][j].bits.broken_arrows_variant = 0;
                        }
                    for(uint32_t i = 0; i < splatter.size(); i++)
                    {
                        DFHack::t_spattervein * vein = splatter[i];
                        // filter snow
                        if(!snow && vein->mat1 == water_idx && vein->matter_state == DFHack::state_powder)
                            continue;
                        // filter mud
                        if(!mud && vein->mat1 == mud_idx && vein->matter_state == DFHack::state_solid)
                            continue;
                        Mapz->RemoveBlockEvent(x,y,z,(t_virtual *) vein);
                    }
                }
            }
        }
    }
    c->Resume();
    return CR_OK;
}
Esempio n. 3
0
static command_result autodump_main(Core * c, vector <string> & parameters)
{
    // Command line options
    bool destroy = false;
    bool here = false;
    if(parameters.size() > 0)
    {
        string & p = parameters[0];
        if(p == "destroy")
            destroy = true;
        else if (p == "destroy-here")
            destroy = here = true;
        else if(p == "?" || p == "help")
        {
            c->con.print(
                "This utility lets you quickly move all items designated to be dumped.\n"
                "Items are instantly moved to the cursor position, the dump flag is unset,\n"
                "and the forbid flag is set, as if it had been dumped normally.\n"
                "Be aware that any active dump item tasks still point at the item.\n\n"
                "Options:\n"
                "destroy       - instead of dumping, destroy the items instantly.\n"
                "destroy-here  - only affect the tile under cursor.\n"
                        );
            return CR_OK;
        }
    }
    c->Suspend();
    DFHack::VersionInfo *mem = c->vinfo;
    DFHack::Gui * Gui = c->getGui();
    DFHack::Items * Items = c->getItems();
    DFHack::Maps *Maps = c->getMaps();

    vector <df_item*> p_items;
    if(!Items->readItemVector(p_items))
    {
        c->con.printerr("Can't access the item vector.\n");
        return CR_FAILURE;
    }
    std::size_t numItems = p_items.size();

    // init the map
    if(!Maps->Start())
    {
        c->con.printerr("Can't initialize map.\n");
        return CR_FAILURE;
    }
    MapCache MC (Maps);
    int i = 0;
    int dumped_total = 0;

    int cx, cy, cz;
    DFCoord pos_cursor;
    if(!destroy || here)
    {
        if (!Gui->getCursorCoords(cx,cy,cz))
        {
            c->con.printerr("Cursor position not found. Please enabled the cursor.\n");
            return CR_FAILURE;
        }
        pos_cursor = DFCoord(cx,cy,cz);
    }
    if (!destroy)
    {
        {
            Block * b = MC.BlockAt(pos_cursor / 16);
            if(!b)
            {
                c->con.printerr("Cursor is in an invalid/uninitialized area. Place it over a floor.\n");
                return CR_FAILURE;
            }
            uint16_t ttype = MC.tiletypeAt(pos_cursor);
            if(!DFHack::isFloorTerrain(ttype))
            {
                c->con.printerr("Cursor should be placed over a floor.\n");
                return CR_FAILURE;
            }
        }
    }
    coordmap counts;
    // proceed with the dumpification operation
    for(std::size_t i=0; i< numItems; i++)
    {
        df_item * itm = p_items[i];
        DFCoord pos_item(itm->x, itm->y, itm->z);

        // keep track how many items are at places. all items.
        coordmap::iterator it = counts.find(pos_item);
        if(it == counts.end())
        {
            std::pair< coordmap::iterator, bool > inserted = counts.insert(std::make_pair(pos_item,1));
            it = inserted.first;
        }
        else
        {
            it->second ++;
        }
        // iterator is valid here, we use it later to decrement the pile counter if the item is moved

        // only dump the stuff marked for dumping and laying on the ground
        if (   !itm->flags.dump
            || !itm->flags.on_ground
            ||  itm->flags.construction
            ||  itm->flags.hidden
            ||  itm->flags.in_building
            ||  itm->flags.in_chest
            ||  itm->flags.in_inventory
            ||  itm->flags.artifact1
        )
            continue;

        if(!destroy) // move to cursor
        {
            // Change flags to indicate the dump was completed, as if by super-dwarfs
            itm->flags.dump = false;
            itm->flags.forbid = true;

            // Don't move items if they're already at the cursor
            if (pos_cursor == pos_item)
                continue;

            // Do we need to fix block-local item ID vector?
            if(pos_item/16 != pos_cursor/16)
            {
                // yes...
                cerr << "Moving from block to block!" << endl;
                df_block * bl_src = Maps->getBlock(itm->x /16, itm->y/16, itm->z);
                df_block * bl_tgt = Maps->getBlock(cx /16, cy/16, cz);
                if(bl_src)
                {
                    std::remove(bl_src->items.begin(), bl_src->items.end(),itm->id);
                }
                else
                {
                    cerr << "No source block" << endl;
                }
                if(bl_tgt)
                {
                    bl_tgt->items.push_back(itm->id);
                }
                else
                {
                    cerr << "No target block" << endl;
                }
            }

            // Move the item
            itm->x = pos_cursor.x;
            itm->y = pos_cursor.y;
            itm->z = pos_cursor.z;
        }
        else // destroy
        {
            if (here && pos_item != pos_cursor)
                continue;

            itm->flags.garbage_colect = true;

            // Cosmetic changes: make them disappear from view instantly
            itm->flags.forbid = true;
            itm->flags.hidden = true;
        }
        // keeping track of item pile sizes ;)
        it->second --;
        dumped_total++;
    }
    if(!destroy) // TODO: do we have to do any of this when destroying items?
    {
        // for each item pile, see if it reached zero. if so, unset item flag on the tile it's on
        coordmap::iterator it = counts.begin();
        coordmap::iterator end = counts.end();
        while(it != end)
        {
            if(it->second == 0)
            {
                t_occupancy occ = MC.occupancyAt(it->first);
                occ.bits.item = false;
                MC.setOccupancyAt(it->first, occ);
            }
            it++;
        }
        // Set "item here" flag on target tile, if we moved any items to the target tile.
        if (dumped_total > 0)
        {
            // assume there is a possibility the cursor points at some weird location with missing block data
            Block * b = MC.BlockAt(pos_cursor / 16);
            if(b)
            {
                t_occupancy occ = MC.occupancyAt(pos_cursor);
                occ.bits.item = 1;
                MC.setOccupancyAt(pos_cursor,occ);
            }
        }
        // write map changes back to DF.
        MC.WriteAll();
        // Is this necessary?  Is "forbid" a dirtyable attribute like "dig" is?
        Maps->WriteDirtyBit(cx/16, cy/16, cz, true);
    }
    c->con.print("Done. %d items %s.\n", dumped_total, destroy ? "marked for desctruction" : "quickdumped");
    return CR_OK;
}