Ejemplo n.º 1
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;
                }
            }
        }
    }

}