Ejemplo n.º 1
0
void read_segment( void *arg)
{
    if(!Maps::IsValid()) {
        return;
    }
    static bool firstLoad = 1;
    ssConfig.threadstarted = 1;
    WorldSegment* segment = NULL;
	{
		CoreSuspender suspend;

		//read cursor
		if (ssConfig.follow_DFcursor) {
			Gui::getCursorCoords(ssState.dfCursor.x, ssState.dfCursor.y, ssState.dfCursor.z);
			ssState.dfSelection.x = df::global::selection_rect->start_x;
			ssState.dfSelection.y = df::global::selection_rect->start_y;
			ssState.dfSelection.z = df::global::selection_rect->start_z;
		}

        if (firstLoad || ssConfig.track_mode != GameConfiguration::TRACKING_NONE) {
            firstLoad = 0;
            if (ssConfig.track_mode == GameConfiguration::TRACKING_CENTER) {
                followCurrentDFCenter();
            } else if (ssConfig.track_mode == GameConfiguration::TRACKING_WINDOW) {
                followCurrentDFWindow();
            } else if (ssConfig.track_mode == GameConfiguration::TRACKING_FOCUS) {
                followCurrentDFFocus();
				ssConfig.follow_DFcursor = true;
            }
        }
        segment = map_segment.getRead();
        readMapSegment(segment, ssState);
        ssConfig.threadstarted = 0;
    }

    if(segment) {
        beautifySegment(segment);

        //putting these here to increase responsiveness of the UI and to make megashots work
        //segment->segState.Position = ssState.Position;
        //segment->segState.dfCursor = ssState.dfCursor;

        segment->AssembleAllTiles();

        //only need to lock the drawing segment because the reading segment is already locked
        map_segment.lockDraw();
        map_segment.swap();
        map_segment.unlockDraw();
    }
}
Ejemplo n.º 2
0
void read_segment( void *arg)
{
    if(!Maps::IsValid()) {
        return;
    }
    static bool firstLoad = 1;
    ssConfig.threadstarted = 1;
    WorldSegment* segment = NULL;
    {
        CoreSuspender suspend;
        if (firstLoad || ssConfig.follow_DFscreen) {
            firstLoad = 0;
            if (ssConfig.track_center) {
                FollowCurrentDFCenter();
            } else {
                FollowCurrentDFWindow();
            }
        }
        segment = map_segment.getRead();
        readMapSegment(segment, parms.x, parms.y, parms.z,parms.sizex, parms.sizey, parms.sizez);
        ssConfig.threadstarted = 0;
    }

    if(segment) {
        beautifySegment(segment);

        //putting these here to increase responsiveness of the UI and to make megashots work
        segment->segState.DisplayedSegment = ssState.DisplayedSegment;

        segment->AssembleAllTiles();

        //only need to lock the drawing segment because the reading segment is already locked
        map_segment.lockDraw();
        map_segment.swap();
        map_segment.unlockDraw();
    }
}
Ejemplo n.º 3
0
/**
* reads one 16x16 block pulled over RPC into stonesense tiles
*/
void readRemoteBlockToSegment(RemoteFortressReader::MapBlock &block, WorldSegment& segment)
{
    for (int xx = 0; xx < BLOCKEDGESIZE; xx++)
    for (int yy = 0; yy < BLOCKEDGESIZE; yy++)
    {
        int32_t x = xx + block.map_x();
        int32_t y = yy + block.map_y();
        int32_t z = block.map_z();

        int32_t index = xx + (yy * BLOCKEDGESIZE);

        Tile * t = segment.getTile(x, y, z);
        if (!t)
            continue;
        t->tileType = (tiletype::tiletype)block.tiles(index);
        t->material.index = block.materials(index).mat_index();
        t->material.type = block.materials(index).mat_type();
    }
}
Ejemplo n.º 4
0
/**
* reads one 16x16 map block into stonesense tiles
* attempts to only read as much information as is necessary to do the tile optimization
*/
void readBlockToSegment(DFHack::Core& DF, WorldSegment& segment, 
    int BlockX, int BlockY, int BlockZ,
    uint32_t BoundrySX, uint32_t BoundrySY,
    uint32_t BoundryEX, uint32_t BoundryEY,
    vector< vector <int16_t> >* allLayers)
{
    if(ssConfig.skipMaps) {
        return;
    }
    //boundry check
    int blockDimX, blockDimY, blockDimZ;
    Maps::getSize((unsigned int &)blockDimX, (unsigned int &)blockDimY, (unsigned int &)blockDimZ);
    if( BlockX < 0 || BlockX >= blockDimX ||
        BlockY < 0 || BlockY >= blockDimY ||
        BlockZ < 0 || BlockZ >= blockDimZ ) {
            return;
    }

    //make boundries local
    BoundrySX -= BlockX * BLOCKEDGESIZE;
    BoundryEX -= BlockX * BLOCKEDGESIZE;
    BoundrySY -= BlockY * BLOCKEDGESIZE;
    BoundryEY -= BlockY * BLOCKEDGESIZE;

    //read block data
    df::map_block *trueBlock;
    trueBlock = Maps::getBlock(BlockX, BlockY, BlockZ);
    if(!trueBlock) {
        return;
    }        
    //read the map features
    t_feature local, global;
    Maps::ReadFeatures(BlockX,BlockY,BlockZ,&local,&global);
    //read local vein data
    vector <df::block_square_event_mineralst * > veins;
    vector <df::block_square_event_frozen_liquidst * > ices;
    vector <df::block_square_event_material_spatterst * > splatter;
    vector <df::block_square_event_grassst * > grass;
    vector <df::block_square_event_world_constructionst * > worldconstructions;
    Maps::SortBlockEvents(
        trueBlock,
        &veins,
        &ices,
        &splatter,
        &grass,
        &worldconstructions);    
    //parse block
    for(uint32_t ly = BoundrySY; ly <= BoundryEY; ly++) {
        for(uint32_t lx = BoundrySX; lx <= BoundryEX; lx++) {
            uint32_t gx = lx + (BlockX * BLOCKEDGESIZE);
            uint32_t gy = ly + (BlockY * BLOCKEDGESIZE);
            if( !segment.CoordinateInsideSegment( gx, gy, BlockZ) ) {
                continue;
            }

            bool shouldBeIncluded = true;

            //open terrain needs to be included to make blackboxes if 
            // we are shading but not showing hidden tiles
            if(isOpenTerrain(trueBlock->tiletype[lx][ly]) 
                && trueBlock->tiletype[lx][ly] != tiletype::RampTop) {
                    if(!ssConfig.show_hidden_tiles 
                        && ssConfig.shade_hidden_tiles 
                        && trueBlock->designation[lx][ly].bits.hidden) {
                            shouldBeIncluded = true;
                    } else {
                        shouldBeIncluded = false;
                    }
                    //all other terrain needs including, except for hidden tiles
                    // when we are neither showing nor shading hidden tiles
            } else if(!ssConfig.show_hidden_tiles
                && !ssConfig.shade_hidden_tiles
                && trueBlock->designation[lx][ly].bits.hidden) {
                    shouldBeIncluded = false;
            }

            //add back in any liquid tiles, in case they can be seen from above
            // as well as any hanging buildings
            if(trueBlock->designation[lx][ly].bits.flow_size
                || trueBlock->occupancy[lx][ly].bits.building) {
                    shouldBeIncluded = true;
            }

			//add back in any tiles that are constructions or designations
			if( ssConfig.show_designations
				&& containsDesignations(
					trueBlock->designation[lx][ly], 
					trueBlock->occupancy[lx][ly] ) ) {
				shouldBeIncluded = true;
			}

            if(!shouldBeIncluded){
                continue;
            }

            Tile * b = segment.ResetTile(gx, gy, BlockZ, trueBlock->tiletype[lx][ly]);
			
			b->occ.bits.unit = false;//this will be set manually when we read the creatures vector
            b->occ = trueBlock->occupancy[lx][ly];
			b->designation = trueBlock->designation[lx][ly];

			//if the tile has designations, read them and nothing else
			if( ssConfig.show_designations 
				&& readDesignationsToTile( 
					b, trueBlock->designation[lx][ly], 
					trueBlock->occupancy[lx][ly] ) ) {
						continue;
			}
			
			//set whether the tile is hidden
			b->fog_of_war = !b->designation.bits.pile;

            //don't read detailed information for blackbox tiles
            if(!ssConfig.show_hidden_tiles
                && ssConfig.shade_hidden_tiles
                && b->designation.bits.hidden
                && !b->designation.bits.flow_size) {
                    continue;
            }

            //read the grasses
            b->grasslevel = 0;
            b->grassmat = -1;
            //b->grasslevels.clear();
            //b->grassmats.clear();
            for(int i = 0; i < grass.size(); i++) {
                if(grass[i]->amount[lx][ly] > 0 && b->grasslevel == 0) { //b->grasslevel)
                    b->grasslevel = grass[i]->amount[lx][ly];
                    b->grassmat = grass[i]->plant_index;
                    //b->grasslevels.push_back(grass[i].intensity[lx][ly]);
                    //b->grassmats.push_back(grass[i].material);
                }
            }

			//read the water flows and direction.
			b->flow_direction = trueBlock->liquid_flow[lx][ly].bits.perm_flow_dir;

            //read the tile spatter
            readSpatterToTile(b, lx, ly, splatter); 

            //read the tile material
            readMaterialToTile(b, lx, ly, trueBlock, local, global, veins, allLayers);
        }
    }

    //add trees and other vegetation
    for(auto iter = trueBlock->plants.begin(); iter != trueBlock->plants.end(); iter++) {
        df::plant * wheat = *iter;
        assert(wheat != NULL);
        Tile* b = segment.getTile( wheat->pos.x, wheat->pos.y, wheat->pos.z);
        if(!b) {
            b = segment.ResetTile(wheat->pos.x, wheat->pos.y, wheat->pos.z, tiletype::OpenSpace);
            if(!b) {
                continue;
            }
        }
        if( b->tileShape() == tiletype_shape::TREE ||
            b->tileShape() == tiletype_shape::SAPLING ||
            b->tileShape() == tiletype_shape::SHRUB) {
                b->tree.type = wheat->flags.whole;
                b->tree.index = wheat->material;
        }
    }

    //add items
    for(auto iter = trueBlock->items.begin(); iter != trueBlock->items.end(); iter++) {
		int32_t item_index = *iter;
		df::item * found_item = df::item::find(item_index);
		if(!found_item) {
			continue;
		}
		Tile* b = segment.getTile( found_item->pos.x, found_item->pos.y, found_item->pos.z);
		if(!b) {
			b = segment.ResetTile(found_item->pos.x, found_item->pos.y, found_item->pos.z, tiletype::OpenSpace);
			if(!b) {
				continue;
			}
		}
		b->Item = ConvertItem(found_item, segment);
	}


    //add effects
    for(auto iter = trueBlock->flows.begin(); iter != trueBlock->flows.end(); iter++) {
        df::flow_info * eff = *iter;
        if(eff == NULL || eff->density <= 0) {
            continue;
        }
        Tile* b = segment.getTile( eff->pos.x, eff->pos.y, eff->pos.z);
        if(segment.CoordinateInsideSegment(eff->pos.x, eff->pos.y, eff->pos.z)) {
            if(!b) {
                b = segment.ResetTile(eff->pos.x, eff->pos.y, eff->pos.z, tiletype::OpenSpace);
                if(!b) {
                    continue;
                }
            }
            if(eff->density > b->tileeffect.density 
                || b->tileeffect.type == (df::flow_type) INVALID_INDEX) {
                    b->tileeffect.type = eff->type;
                    b->tileeffect.density = eff->density;
                    b->tileeffect.matt.index = eff->mat_index;
                    b->tileeffect.matt.type = eff->mat_type;
            }
        } 
    }
}
Ejemplo n.º 5
0
void readBlockColumnToSegment(DFHack::Core& DF, WorldSegment& segment,
    int BlockX, int BlockY)
{
    if (ssConfig.skipMaps) {
        return;
    }
    //boundry check
    int blockDimX, blockDimY, blockDimZ;
    Maps::getSize((unsigned int &)blockDimX, (unsigned int &)blockDimY, (unsigned int &)blockDimZ);
    if (BlockX < 0 || BlockX >= blockDimX ||
        BlockY < 0 || BlockY >= blockDimY) {
        return;
    }

    //read block data
    df::map_block_column *trueColumn;
    trueColumn = Maps::getBlockColumn(BlockX, BlockY);
    if (!trueColumn) {
        return;
    }

    for (int i = 0; i < trueColumn->plants.size(); i++)
    {
        df::plant * pp = trueColumn->plants[i];
        // A plant without tree_info is single tile
        if (!pp->tree_info)
        {
            if (!segment.CoordinateInsideSegment(pp->pos.x, pp->pos.y, pp->pos.z))
                continue;
            Tile * t = segment.getTile(pp->pos.x, pp->pos.y, pp->pos.z);
            if (!t)
                t = segment.ResetTile(pp->pos.x, pp->pos.y, pp->pos.z);
            if (!t)
                continue;
            t->tree.type = pp->flags.whole;
            t->tree.index = pp->material;
            continue;
        }

        // tree_info contains vertical slices of the tree. This ensures there's a slice for our Z-level.
        df::plant_tree_info * info = pp->tree_info;
        if (!segment.RangeInsideSegment(
            pp->pos.x - (pp->tree_info->dim_x / 2),
            pp->pos.y - (pp->tree_info->dim_y / 2),
            pp->pos.z - (pp->tree_info->roots_depth),
            pp->pos.x + (pp->tree_info->dim_x / 2),
            pp->pos.y + (pp->tree_info->dim_y / 2),
            pp->pos.z + pp->tree_info->body_height - 1))
            continue;

        auto raw = df::plant_raw::find(pp->material);


        for (int zz = 0; zz < info->body_height; zz++)
        {
            // Parse through a single horizontal slice of the tree.
            for (int xx = 0; xx < info->dim_x; xx++)
            for (int yy = 0; yy < info->dim_y; yy++)
            {
                // Any non-zero value here other than blocked means there's some sort of branch here.
                // If the block is at or above the plant's base level, we use the body array
                // otherwise we use the roots.
                // TODO: verify that the tree bounds intersect the block.
                df::plant_tree_tile tile = info->body[zz][xx + (yy*info->dim_x)];
                if (tile.whole && !(tile.bits.blocked))
                {
                    df::coord pos = pp->pos;
                    pos.x = pos.x - (info->dim_x / 2) + xx;
                    pos.y = pos.y - (info->dim_y / 2) + yy;
                    pos.z = pos.z + zz;
                    if (!segment.CoordinateInsideSegment(pos.x, pos.y, pos.z))
                        continue;
                    Tile * t = segment.getTile(pos.x, pos.y, pos.z);
                    if (!t)
                        t = segment.ResetTile(pos.x, pos.y, pos.z);
                    if (!t)
                        continue;
                    t->tree.type = pp->flags.whole;
                    t->tree.index = pp->material;
                    t->tree_tile = tile;
                    if (raw)
                    {
                        t->material.type = raw->material_defs.type_basic_mat;
                        t->material.index = raw->material_defs.idx_basic_mat;
                    }
                }
            }
        }
        for (int zz = 0; zz < info->roots_depth; zz++)
        {
            // Parse through a single horizontal slice of the tree.
            for (int xx = 0; xx < info->dim_x; xx++)
            for (int yy = 0; yy < info->dim_y; yy++)
            {
                // Any non-zero value here other than blocked means there's some sort of branch here.
                // If the block is at or above the plant's base level, we use the body array
                // otherwise we use the roots.
                // TODO: verify that the tree bounds intersect the block.
                df::plant_tree_tile tile = info->roots[zz][xx + (yy*info->dim_x)];
                if (tile.whole && !(tile.bits.blocked))
                {
                    df::coord pos = pp->pos;
                    pos.x = pos.x - (info->dim_x / 2) + xx;
                    pos.y = pos.y - (info->dim_y / 2) + yy;
                    pos.z = pos.z - 1 - zz;
                    if (!segment.CoordinateInsideSegment(pos.x, pos.y, pos.z))
                        continue;
                    Tile * t = segment.getTile(pos.x, pos.y, pos.z);
                    if (!t)
                        t = segment.ResetTile(pos.x, pos.y, pos.z);
                    if (!t)
                        continue;
                    t->tree.type = pp->flags.whole;
                    t->tree.index = pp->material;
                }
            }
        }
    }

}