Esempio n. 1
0
void colorTile(const df::tiletype_material& tileMat,MapExtras::MapCache& cache,const DFCoord& pos,screenTile& trg,bool isUndug=false)
{
    t_matpair mat;

    switch(tileMat)
    {
    case df::tiletype_material::ASHES:
        trg.fg=COLOR_GREY;
        trg.bold=false;
        break;
    case df::tiletype_material::CAMPFIRE:
        trg.fg=COLOR_YELLOW;
        trg.bold=true;
        break;
    case df::tiletype_material::SOIL:
        mat=cache.baseMaterialAt(pos);
        {
            df::material* m=lookupMaterial(mat,trg);
            if(m && isUndug)
            {
                trg.tile=m->tile;
            }
            break;
        }
    case df::tiletype_material::STONE:
    case df::tiletype_material::LAVA_STONE:
        mat=cache.baseMaterialAt(pos);
        lookupMaterial(mat,trg);
        break;
    case df::tiletype_material::CONSTRUCTION:
        mat=cache.staticMaterialAt(pos);
        lookupMaterial(mat,trg,true);
        break;
    case df::tiletype_material::MINERAL:
        mat.mat_index=cache.veinMaterialAt(pos);
        mat.mat_type=0;//inorganic
        {
            df::material* m=lookupMaterial(mat,trg);
            if(m && isUndug)
            {
                trg.tile=m->tile;
            }
        }


        break;

    case df::tiletype_material::FROZEN_LIQUID:
        trg.fg=COLOR_CYAN;
        trg.bold=true;
        break;
    case df::tiletype_material::PLANT:
    case df::tiletype_material::GRASS_LIGHT: //MORE INFO IN MAP BLOCK EVENTS
        trg.fg=COLOR_GREEN;
        trg.bold=true;
        break;
    case df::tiletype_material::GRASS_DARK:
        trg.fg=COLOR_GREEN;
        trg.bold=false;
        break; 
    case df::tiletype_material::GRASS_DRY:
        trg.fg=COLOR_YELLOW;
        trg.bold=true;
        break;
    case df::tiletype_material::GRASS_DEAD:
        trg.fg=COLOR_BROWN;
        trg.bold=false;
        break;

    case df::tiletype_material::DRIFTWOOD:
        trg.fg=COLOR_WHITE;
        trg.bold=true;
        break;
    case df::tiletype_material::MAGMA:
        trg.fg=COLOR_RED;
        trg.bold=true;
        break;
    case df::tiletype_material::POOL:    
    case df::tiletype_material::RIVER:
    case df::tiletype_material::BROOK:
        trg.fg=COLOR_BROWN;
        trg.bold=false;
        break;
    }

}
Esempio n. 2
0
command_result df_probe (color_ostream &out, vector <string> & parameters)
{
    //bool showBlock, showDesig, showOccup, showTile, showMisc;

    /*
    if (!parseOptions(parameters, showBlock, showDesig, showOccup,
                      showTile, showMisc))
    {
        out.printerr("Unknown parameters!\n");
        return CR_FAILURE;
    }
    */

    CoreSuspender suspend;

    DFHack::Materials *Materials = Core::getInstance().getMaterials();

    std::vector<t_matglossInorganic> inorganic;
    bool hasmats = Materials->CopyInorganicMaterials(inorganic);

    if (!Maps::IsValid())
    {
        out.printerr("Map is not available!\n");
        return CR_FAILURE;
    }
    MapExtras::MapCache mc;

    int32_t regionX, regionY, regionZ;
    Maps::getPosition(regionX,regionY,regionZ);

    int32_t cursorX, cursorY, cursorZ;
    Gui::getCursorCoords(cursorX,cursorY,cursorZ);
    if(cursorX == -30000)
    {
        out.printerr("No cursor; place cursor over tile to probe.\n");
        return CR_FAILURE;
    }
    DFCoord cursor (cursorX,cursorY,cursorZ);

    uint32_t blockX = cursorX / 16;
    uint32_t tileX = cursorX % 16;
    uint32_t blockY = cursorY / 16;
    uint32_t tileY = cursorY % 16;

    MapExtras::Block * b = mc.BlockAt(cursor/16);
    if(!b || !b->is_valid())
    {
        out.printerr("No data.\n");
        return CR_OK;
    }

    auto &block = *b->getRaw();
    out.print("block addr: 0x%x\n\n", &block);
/*
    if (showBlock)
    {
        out.print("block flags:\n");
        print_bits<uint32_t>(block.blockflags.whole,out);
        out.print("\n\n");
    }
*/
    df::tiletype tiletype = mc.tiletypeAt(cursor);
    df::tile_designation &des = block.designation[tileX][tileY];
    df::tile_occupancy &occ = block.occupancy[tileX][tileY];
/*
    if(showDesig)
    {
        out.print("designation\n");
        print_bits<uint32_t>(block.designation[tileX][tileY].whole,
                                out);
        out.print("\n\n");
    }

    if(showOccup)
    {
        out.print("occupancy\n");
        print_bits<uint32_t>(block.occupancy[tileX][tileY].whole,
                                out);
        out.print("\n\n");
    }
*/

    // tiletype
    out.print("tiletype: ");
    describeTile(out, tiletype);
    out.print("static: ");
    describeTile(out, mc.staticTiletypeAt(cursor));
    out.print("base: ");
    describeTile(out, mc.baseTiletypeAt(cursor));

    out.print("temperature1: %d U\n",mc.temperature1At(cursor));
    out.print("temperature2: %d U\n",mc.temperature2At(cursor));

    int offset = block.region_offset[des.bits.biome];
    int bx = clip_range(block.region_pos.x + (offset % 3) - 1, 0, world->world_data->world_width-1);
    int by = clip_range(block.region_pos.y + (offset / 3) - 1, 0, world->world_data->world_height-1);

    auto biome = &world->world_data->region_map[bx][by];

    int sav = biome->savagery;
    int evi = biome->evilness;
    int sindex = sav > 65 ? 2 : sav < 33 ? 0 : 1;
    int eindex = evi > 65 ? 2 : evi < 33 ? 0 : 1;
    int surr = sindex + eindex * 3;

    const char* surroundings[] = { "Serene", "Mirthful", "Joyous Wilds", "Calm", "Wilderness", "Untamed Wilds", "Sinister", "Haunted", "Terrifying" };

    // biome, geolayer
    out << "biome: " << des.bits.biome << " (" << 
        "region id=" << biome->region_id << ", " <<
        surroundings[surr] << ", " <<
        "savagery " << biome->savagery << ", " <<
        "evilness " << biome->evilness << ")" << std::endl;
    out << "geolayer: " << des.bits.geolayer_index
        << std::endl;
    int16_t base_rock = mc.layerMaterialAt(cursor);
    if(base_rock != -1)
    {
        out << "Layer material: " << dec << base_rock;
        if(hasmats)
            out << " / " << inorganic[base_rock].id
                << " / "
                << inorganic[base_rock].name
                << endl;
        else
            out << endl;
    }
    int16_t vein_rock = mc.veinMaterialAt(cursor);
    if(vein_rock != -1)
    {
        out << "Vein material (final): " << dec << vein_rock;
        if(hasmats)
            out << " / " << inorganic[vein_rock].id
                << " / "
                << inorganic[vein_rock].name
                << endl;
        else
            out << endl;
    }
    MaterialInfo minfo(mc.baseMaterialAt(cursor));
    if (minfo.isValid())
        out << "Base material: " << minfo.getToken() << " / " << minfo.toString() << endl;
    minfo.decode(mc.staticMaterialAt(cursor));
    if (minfo.isValid())
        out << "Static material: " << minfo.getToken() << " / " << minfo.toString() << endl;
    // liquids
    if(des.bits.flow_size)
    {
        if(des.bits.liquid_type == tile_liquid::Magma)
            out <<"magma: ";
        else out <<"water: ";
        out << des.bits.flow_size << std::endl;
    }
    if(des.bits.flow_forbid)
        out << "flow forbid" << std::endl;
    if(des.bits.pile)
        out << "stockpile?" << std::endl;
    if(des.bits.rained)
        out << "rained?" << std::endl;
    if(des.bits.smooth)
        out << "smooth?" << std::endl;
    if(des.bits.water_salt)
        out << "salty" << endl;
    if(des.bits.water_stagnant)
        out << "stagnant" << endl;

    #define PRINT_FLAG( FIELD, BIT )  out.print("%-16s= %c\n", #BIT , ( FIELD.bits.BIT ? 'Y' : ' ' ) )
    PRINT_FLAG( des, hidden );
    PRINT_FLAG( des, light );
    PRINT_FLAG( des, outside );
    PRINT_FLAG( des, subterranean );
    PRINT_FLAG( des, water_table );
    PRINT_FLAG( des, rained );
    PRINT_FLAG( occ, monster_lair);

    df::coord2d pc(blockX, blockY);

    t_feature local;
    t_feature global;
    Maps::ReadFeatures(&block,&local,&global);
    PRINT_FLAG( des, feature_local );
    if(local.type != -1)
    {
        out.print("%-16s", "");
        out.print("  %4d", block.local_feature);
        out.print(" (%2d)", local.type);
        out.print(" addr 0x%X ", local.origin);
        out.print(" %s\n", sa_feature(local.type));
    }
    PRINT_FLAG( des, feature_global );
    if(global.type != -1)
    {
        out.print("%-16s", "");
        out.print("  %4d", block.global_feature);
        out.print(" (%2d)", global.type);
        out.print(" %s\n", sa_feature(global.type));
    }
    #undef PRINT_FLAG
    out << "local feature idx: " << block.local_feature
        << endl;
    out << "global feature idx: " << block.global_feature
        << endl;
    out << std::endl;

    if(block.occupancy[tileX][tileY].bits.no_grow)
        out << "no grow" << endl;

    for(size_t e=0; e<block.block_events.size(); e++)
    {            
        df::block_square_event * blev = block.block_events[e];
        df::block_square_event_type blevtype = blev->getType();
        switch(blevtype)
        {
        case df::block_square_event_type::grass:
            {
                df::block_square_event_grassst * gr_ev = (df::block_square_event_grassst *)blev;
                if(gr_ev->amount[tileX][tileY] > 0)
                {
                    out << "amount of grass: " << (int)gr_ev->amount[tileX][tileY] << endl;
                }
                break;
            }
        case df::block_square_event_type::world_construction:
            {
                df::block_square_event_world_constructionst * co_ev = (df::block_square_event_world_constructionst*)blev;
                uint16_t bits = co_ev->tile_bitmask[tileY];
                out << "construction bits: " << bits << endl;
                break;
            }
        default:
            //out << "unhandled block event type!" << endl;
            break;
        }
    }


    return CR_OK;
}
Esempio n. 3
0
void Offscreen::drawBuffer( rect2d window,int z,std::vector<screenTile>& buffer )
{
    if(!df::global::world)
        return;

    //TODO static array of images for each tiletype
    MapExtras::MapCache cache;
    int w=window.second.x-window.first.x;
    int h=window.second.y-window.first.y;
    rect2d localWindow=mkrect_wh(0,0,w+1,h+1);
    if(buffer.size()!=w*h)
        buffer.resize(w*h);
    //basic tiletype stuff here
    for(int x=window.first.x;x<window.second.x;x++) //todo, make it by block, minimal improvement over cache prob though
        for(int y=window.first.y;y<window.second.y;y++)
        {
            DFCoord coord(x,y,z);
            df::tiletype tt=cache.tiletypeAt(coord);
            df::tiletype_shape shape = ENUM_ATTR(tiletype,shape,tt);
            df::tiletype_shape_basic basic_shape = ENUM_ATTR(tiletype_shape, basic_shape, shape);
            t_matpair mat=cache.staticMaterialAt(coord);
            df::tiletype_material tileMat= ENUM_ATTR(tiletype,material,tt);
            df::tile_designation d=cache.designationAt(coord);
            df::tile_occupancy o=cache.occupancyAt(coord);
            df::tiletype_special sp=ENUM_ATTR(tiletype,special,tt);

            int wx=x-window.first.x;
            int wy=y-window.first.y;
            screenTile& curTile=buffer[wx*h+wy];
            if(d.bits.hidden)
            {
                curTile.tile=0;
                continue;
            }
            if(shape==df::tiletype_shape::EMPTY || shape==df::tiletype_shape::RAMP_TOP)
            {
                //empty,liquids and '.' for other stuff...
                DFCoord coord2(x,y,z-1);
                df::tiletype tt2=cache.tiletypeAt(coord2);
                df::tiletype_shape shape2 = ENUM_ATTR(tiletype,shape,tt);
                df::tiletype_material tileMat2= ENUM_ATTR(tiletype,material,tt2);
                df::tile_designation d2=cache.designationAt(coord2);
                df::tiletype_special sp2=ENUM_ATTR(tiletype,special,tt2);
                bool unDug2= (sp2!=df::tiletype_special::SMOOTH && shape2==df::tiletype_shape::WALL);
                
                if (d2.bits.flow_size>0)
                {
                    if(shape!=df::tiletype_shape::RAMP_TOP) //don't show liquid amount on ramp tops
                        curTile.tile='0'+d2.bits.flow_size; //TODO lookup setting for this
                    else
                        curTile.tile=tilePics[tt];
                    curTile.fg=(d2.bits.liquid_type)?(COLOR_RED):(COLOR_BLUE);
                    continue;
                }
                else if(shape2==df::tiletype_shape::EMPTY)
                {
                    curTile.tile=178; //look up settings
                    curTile.fg=COLOR_CYAN; 
                    continue;
                }
                else
                {
                    if(shape==df::tiletype_shape::RAMP_TOP)
                        curTile.tile=tilePics[tt];
                    else
                        curTile.tile='.';
                    colorTile(tileMat2,cache,coord2,curTile,unDug2);
                    continue;
                }
            }
            bool inliquid=false;
            bool unDug= (sp!=df::tiletype_special::SMOOTH && shape==df::tiletype_shape::WALL);
            if (d.bits.flow_size>0)
            {
                curTile.tile='0'+d.bits.flow_size;
                curTile.fg=(d.bits.liquid_type)?(COLOR_RED):(COLOR_BLUE);
                curTile.bold=true;
                inliquid=true;
            }    
            if(!inliquid && shape!=df::tiletype_shape::RAMP_TOP)
            {
                curTile.tile=tilePics[tt];
                colorTile(tileMat,cache,coord,curTile,unDug);
                if(!unDug)
                {
                    curTile.bg=0;
                }
            }
            else
            {
                if(shape==df::tiletype_shape::RAMP || shape==df::tiletype_shape::BROOK_BED || shape==df::tiletype_shape::RAMP_TOP)
                    curTile.tile=tilePics[tt];
                if(!inliquid)
                    colorTile(tileMat,cache,coord,curTile,true);
            }

        }
        //plants
        for(int bx=window.first.x/16;bx<=window.second.x/16;bx++) //blocks have items by id. So yeah each item a search would be slow
            for(int by=window.first.y/16;by<=window.second.y/16;by++)
            {
                MapExtras::Block* b=cache.BlockAt(DFCoord(bx,by,z));
                if(!b || !b->getRaw())
                    continue;
                std::vector<df::plant*>& plants=b->getRaw()->plants;
                for(int i=0;i<plants.size();i++)
                {
                    df::plant* p=plants[i];
                    if(p->pos.z==z && isInRect(df::coord2d(p->pos.x,p->pos.y),window))
                    {
                        int wx=p->pos.x-window.first.x;
                        int wy=p->pos.y-window.first.y;
                        screenTile& curTile=buffer[wx*h+wy];
                        drawPlant(p,curTile);
                    }
                }
                std::vector<df::block_square_event*>& events=b->getRaw()->block_events;
                for(size_t i=0;i<events.size();i++)//maybe aggregate all the events to one array and move to a function.
                {
                    df::block_square_event* e=events[i];
                    switch(e->getType())
                    {
                    case df::block_square_event_type::grass:
                        {
                            df::block_square_event_grassst* grass=static_cast<df::block_square_event_grassst*>(e);
                            MaterialInfo mat(419, grass->plant_index);
                            if(mat.isPlant())
                            {
                                df::plant_raw* p=mat.plant;
                                for(int x=0;x<16;x++)
                                for(int y=0;y<16;y++)
                                {
                                    int wx=x+bx*16-window.first.x;
                                    int wy=y+by*16-window.first.y;
                                    if(isInRect(df::coord2d(wx,wy),localWindow) && grass->amount[x][y]>0)
                                    {
                                        screenTile& curTile=buffer[wx*h+wy];
                                        /*
                                        df::tiletype tt=b->tiletypeAt(df::coord2d(x,y));
                                        df::tiletype_special sp=ENUM_ATTR(tiletype,special,tt);
                                        df::tiletype_special::DEAD;
                                        df::tiletype_special::WET;
                                        df::tiletype_special::NORMAL;
                                        +variants
                                        */

                                        curTile.tile=p->tiles.grass_tiles[0];
                                        curTile.fg=p->colors.grass_colors_0[0];
                                        curTile.bg=p->colors.grass_colors_1[0];
                                        curTile.bold=p->colors.grass_colors_2[0];
                                    }
                                    
                                    
                                }
                                
                                
                                
                                //TODO alt-tiles
                            }
                            
                            break;
                        }
                    case df::block_square_event_type::material_spatter:
                        {
                            //liquid:
                            //0 nothing 
                            //1->49 color 
                            //50->99 wave
                            //100->255 two waves
                            //color only, if small
                            //draw waves, if pool
                            df::block_square_event_material_spatterst* spatter=static_cast<df::block_square_event_material_spatterst*>(e);
                            MaterialInfo mat(spatter);
                            if(mat.material)
                            {

                            for(int x=0;x<16;x++)
                                for(int y=0;y<16;y++)
                                {
                                    int wx=x+bx*16-window.first.x;
                                    int wy=y+by*16-window.first.y;
                                    uint8_t amount=spatter->amount[x][y];
                                    if(isInRect(df::coord2d(wx,wy),localWindow) && amount>0)
                                    {
                                        screenTile& curTile=buffer[wx*h+wy];
                                        
                                        curTile.fg=mat.material->tile_color[0];
                                        curTile.bold=mat.material->tile_color[2];
                                        if(spatter->mat_state==df::matter_state::Liquid && amount>49)
                                        {
                                            if(amount>99)
                                                curTile.tile=247;
                                            else
                                                curTile.tile=126;
                                        }
                                    }
                                }
                            }
                            break;
                        }
                    default:;
                    }
                }
                std::vector<df::flow_info*>& flows=b->getRaw()->flows;
                for(size_t i=0;i<flows.size();i++)
                {
                    df::flow_info* f=flows[i];
                    int wx=f->pos.x-window.first.x;
                    int wy=f->pos.y-window.first.y;
                    if(f->density>0 && isInRect(df::coord2d(wx,wy),localWindow))
                    {
                        screenTile& curTile=buffer[wx*h+wy];
                        drawFlow(f,curTile);
                    }
                }
            }
            //in df items blink between stuff, but i don't have time for that
            //also move up, before flows
            std::vector<df::item*>& items=df::global::world->items.other[df::items_other_id::IN_PLAY];
            for(int i=0;i<items.size();i++)
            {
                df::item* it=items[i];
                if(it->flags.bits.on_ground && it->pos.z==z && isInRect(df::coord2d(it->pos.x,it->pos.y),window))
                {
                    int wx=it->pos.x-window.first.x;
                    int wy=it->pos.y-window.first.y;
                    screenTile& curTile=buffer[wx*h+wy];
                    drawItem(it,curTile);
                }
            }
            //buildings
            std::vector<df::building*>& buildings=df::global::world->buildings.all;
            for(int i=0;i<buildings.size();i++)
            {
                df::building* build=buildings[i];


                if(z!=build->z)
                    continue;
                if(!build->isVisibleInUI())
                    continue;
                if(isInRect(df::coord2d(build->x1,build->y1),window)||isInRect(df::coord2d(build->x2,build->y2),window))
                {
                    df::building_drawbuffer drawBuffer;
                    build->getDrawExtents(&drawBuffer);
                    int bw=drawBuffer.x2-drawBuffer.x1;
                    int bh=drawBuffer.y2-drawBuffer.y1;
                    build->drawBuilding(&drawBuffer,0); //might be viewscreen dependant
                    int wx=build->x1-window.first.x;
                    int wy=build->y1-window.first.y;

                    for(int x=0;x<=bw;x++)
                        for(int y=0;y<=bh;y++)
                        {
                            df::coord2d p(x+wx,y+wy);
                            if(isInRect(p,localWindow))
                            {
                                screenTile& curTile=buffer[p.x*h+p.y];
                                if(drawBuffer.tile[x][y]!=32)
                                {
                                    curTile.tile=drawBuffer.tile[x][y];
                                    curTile.fg=drawBuffer.fore[x][y];
                                    curTile.bg=drawBuffer.back[x][y];
                                    curTile.bold=drawBuffer.bright[x][y];
                                }
                            }
                        }
                }
            }
            //units. TODO No multi tile units yet.
            std::vector<df::unit*>& units=df::global::world->units.active;
            for(int i=0;i<units.size();i++)
            {
                df::unit* u=units[i];
                if(!u->flags1.bits.dead && u->pos.z==z && isInRect(df::coord2d(u->pos.x,u->pos.y),window))
                {
                    int wx=u->pos.x-window.first.x;
                    int wy=u->pos.y-window.first.y;
                    screenTile& curTile=buffer[wx*h+wy];
                    drawUnit(u,curTile);
                }
            }
            
}