// Path: src/main/java/org/terasology/cities/BlockType.java
// public interface BlockType {
//     // empty marker
// }
// 
// Path: src/main/java/org/terasology/cities/DefaultBlockType.java
// public enum DefaultBlockType implements BlockType {
// 
//     /**
//      * Air
//      */
//     AIR,
// 
//     /**
//      * Windows
//      */
//     WINDOW_GLASS,
// 
//     /**
//      * A single-block door element
//      */
//     SIMPLE_DOOR,
// 
//     /**
//      * A two-folded wing door
//      */
//     WING_DOOR,
// 
//     /**
//      * Fill material under the surface of a road
//      */
//     ROAD_FILL,
// 
//     /**
//      * Surface of a road (asphalt)
//      */
//     ROAD_SURFACE,
// 
//     /**
//      * Empty space in a lot
//      */
//     LOT_EMPTY,
// 
//     /**
//      * A simple building's floor
//      */
//     BUILDING_FLOOR,
// 
//     /**
//      * A simple building's foundation
//      */
//     BUILDING_FOUNDATION,
// 
//     /**
//      * A simple building wall
//      */
//     BUILDING_WALL,
// 
//     /**
//      * Flat roof
//      */
//     ROOF_FLAT,
// 
//     /**
//      * Hip roof
//      */
//     ROOF_HIP,
// 
//     /**
//      * Dome roof
//      */
//     ROOF_DOME,
// 
//     /**
//      * The roof gable for saddle roofs
//      */
//     ROOF_GABLE,
// 
//     /**
//      * Saddle roof
//      */
//     ROOF_SADDLE,
// 
//     /**
//      * Tower stone
//      */
//     TOWER_WALL,
// 
//     /**
//      * Fence
//      */
//     FENCE,
// 
//     /**
//      * Fence gate
//      */
//     FENCE_GATE,
// 
//     /**
//      * Tower staircase
//      */
//     TOWER_STAIRS,
// 
//     /**
//      * A barrel
//      */
//     BARREL,
// 
//     /**
//      * A torch
//      */
//     TORCH,
// 
//     /**
//      * Pillar material
//      */
//     PILLAR_TOP,
// 
//     /**
//      * Pillar material
//      */
//     PILLAR_MIDDLE,
// 
//     /**
//      * Pillar material
//      */
//     PILLAR_BASE,
// 
//     /**
//      * A ladder element
//      */
//     LADDER
// }
// 
// Path: src/main/java/org/terasology/cities/raster/RasterTarget.java
// public interface RasterTarget {
// 
//     /**
//      * @param x x in world coords
//      * @param y y in world coords
//      * @param z z in world coords
//      * @param type the block type
//      */
//     void setBlock(int x, int y, int z, BlockType type);
// 
//     /**
//      * @param pos the position in world coords
//      * @param type the block type
//      */
//     default void setBlock(Vector3ic pos, BlockType type) {
//         setBlock(pos.x(), pos.y(), pos.z(), type);
//     }
// 
//     /**
//      * @param x x in world coords
//      * @param y y in world coords
//      * @param z z in world coords
//      * @param type the block type
//      * @param side the sides (used to find the correct block from the family)
//      */
//     void setBlock(int x, int y, int z, BlockType type, Set<Side> side);
// 
//     /**
//      * @param pos the position in world coords
//      * @param type the block type
//      * @param sides the sides (used to find the correct block from the family)
//      */
//     default void setBlock(Vector3ic pos, BlockType type, Set<Side> sides) {
//         setBlock(pos.x(), pos.y(), pos.z(), type, sides);
//     }
// 
//     /**
//      * @return the maximum drawing height
//      */
//     default int getMaxHeight() {
//         return getAffectedRegion().maxY();
//     }
// 
//     /**
//      * @return the maximum drawing height
//      */
//     default int getMinHeight() {
//         return getAffectedRegion().minY();
//     }
// 
//     /**
//      * @return the XZ area that is drawn by this raster target
//      */
//     BlockAreac getAffectedArea();
// 
//     /**
//      * @return the region that is drawn by this raster target
//      */
//     BlockRegionc getAffectedRegion();
// }


import java.util.Set;
import org.terasology.cities.BlockType;
import org.terasology.cities.DefaultBlockType;
import org.terasology.cities.raster.RasterTarget;
import org.terasology.engine.math.Side;
import org.terasology.engine.world.block.BlockArea;
import org.terasology.engine.world.block.BlockAreac;
import org.terasology.engine.world.block.BlockRegion;
import org.terasology.engine.world.chunks.Chunks;
import org.terasology.engine.world.chunks.blockdata.TeraArray;
import org.terasology.engine.world.chunks.blockdata.TeraDenseArray16Bit;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;

    @Override
    public void setBlock(int x, int y, int z, BlockType type) {
        int index = mapping.indexOf(type);
        if (index == -1) {
            index = mapping.size();
            mapping.add(type);
        }
        data.set(x, y - region.minY(), z, index);
    }

    @Override
    public void setBlock(int x, int y, int z, BlockType type, Set<Side> side) {
        setBlock(x, y, z, type); // ignore side flags
    }

    @Override
    public BlockAreac getAffectedArea() {
        return area;
    }

    @Override
    public BlockRegion getAffectedRegion() {
        return region;
    }

    public List<BlockType> getColumn(int x, int z) {
        return new AbstractList<BlockType>() {

            @Override
// Path: src/main/java/org/terasology/cities/BlockType.java
// public interface BlockType {
//     // empty marker
// }
// 
// Path: src/main/java/org/terasology/cities/DefaultBlockType.java
// public enum DefaultBlockType implements BlockType {
// 
//     /**
//      * Air
//      */
//     AIR,
// 
//     /**
//      * Windows
//      */
//     WINDOW_GLASS,
// 
//     /**
//      * A single-block door element
//      */
//     SIMPLE_DOOR,
// 
//     /**
//      * A two-folded wing door
//      */
//     WING_DOOR,
// 
//     /**
//      * Fill material under the surface of a road
//      */
//     ROAD_FILL,
// 
//     /**
//      * Surface of a road (asphalt)
//      */
//     ROAD_SURFACE,
// 
//     /**
//      * Empty space in a lot
//      */
//     LOT_EMPTY,
// 
//     /**
//      * A simple building's floor
//      */
//     BUILDING_FLOOR,
// 
//     /**
//      * A simple building's foundation
//      */
//     BUILDING_FOUNDATION,
// 
//     /**
//      * A simple building wall
//      */
//     BUILDING_WALL,
// 
//     /**
//      * Flat roof
//      */
//     ROOF_FLAT,
// 
//     /**
//      * Hip roof
//      */
//     ROOF_HIP,
// 
//     /**
//      * Dome roof
//      */
//     ROOF_DOME,
// 
//     /**
//      * The roof gable for saddle roofs
//      */
//     ROOF_GABLE,
// 
//     /**
//      * Saddle roof
//      */
//     ROOF_SADDLE,
// 
//     /**
//      * Tower stone
//      */
//     TOWER_WALL,
// 
//     /**
//      * Fence
//      */
//     FENCE,
// 
//     /**
//      * Fence gate
//      */
//     FENCE_GATE,
// 
//     /**
//      * Tower staircase
//      */
//     TOWER_STAIRS,
// 
//     /**
//      * A barrel
//      */
//     BARREL,
// 
//     /**
//      * A torch
//      */
//     TORCH,
// 
//     /**
//      * Pillar material
//      */
//     PILLAR_TOP,
// 
//     /**
//      * Pillar material
//      */
//     PILLAR_MIDDLE,
// 
//     /**
//      * Pillar material
//      */
//     PILLAR_BASE,
// 
//     /**
//      * A ladder element
//      */
//     LADDER
// }
// 
// Path: src/main/java/org/terasology/cities/raster/RasterTarget.java
// public interface RasterTarget {
// 
//     /**
//      * @param x x in world coords
//      * @param y y in world coords
//      * @param z z in world coords
//      * @param type the block type
//      */
//     void setBlock(int x, int y, int z, BlockType type);
// 
//     /**
//      * @param pos the position in world coords
//      * @param type the block type
//      */
//     default void setBlock(Vector3ic pos, BlockType type) {
//         setBlock(pos.x(), pos.y(), pos.z(), type);
//     }
// 
//     /**
//      * @param x x in world coords
//      * @param y y in world coords
//      * @param z z in world coords
//      * @param type the block type
//      * @param side the sides (used to find the correct block from the family)
//      */
//     void setBlock(int x, int y, int z, BlockType type, Set<Side> side);
// 
//     /**
//      * @param pos the position in world coords
//      * @param type the block type
//      * @param sides the sides (used to find the correct block from the family)
//      */
//     default void setBlock(Vector3ic pos, BlockType type, Set<Side> sides) {
//         setBlock(pos.x(), pos.y(), pos.z(), type, sides);
//     }
// 
//     /**
//      * @return the maximum drawing height
//      */
//     default int getMaxHeight() {
//         return getAffectedRegion().maxY();
//     }
// 
//     /**
//      * @return the maximum drawing height
//      */
//     default int getMinHeight() {
//         return getAffectedRegion().minY();
//     }
// 
//     /**
//      * @return the XZ area that is drawn by this raster target
//      */
//     BlockAreac getAffectedArea();
// 
//     /**
//      * @return the region that is drawn by this raster target
//      */
//     BlockRegionc getAffectedRegion();
// }


// Path: src/test/java/org/terasology/cities/bldg/DebugRasterTarget.java
import java.util.Set;
import org.terasology.cities.BlockType;
import org.terasology.cities.DefaultBlockType;
import org.terasology.cities.raster.RasterTarget;
import org.terasology.engine.math.Side;
import org.terasology.engine.world.block.BlockArea;
import org.terasology.engine.world.block.BlockAreac;
import org.terasology.engine.world.block.BlockRegion;
import org.terasology.engine.world.chunks.Chunks;
import org.terasology.engine.world.chunks.blockdata.TeraArray;
import org.terasology.engine.world.chunks.blockdata.TeraDenseArray16Bit;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;


    @Override
    public void setBlock(int x, int y, int z, BlockType type) {
        int index = mapping.indexOf(type);
        if (index == -1) {
            index = mapping.size();
            mapping.add(type);
        }
        data.set(x, y - region.minY(), z, index);
    }

    @Override
    public void setBlock(int x, int y, int z, BlockType type, Set<Side> side) {
        setBlock(x, y, z, type); // ignore side flags
    }

    @Override
    public BlockAreac getAffectedArea() {
        return area;
    }

    @Override
    public BlockRegion getAffectedRegion() {
        return region;
    }

    public List<BlockType> getColumn(int x, int z) {
        return new AbstractList<BlockType>() {

            @Override
            public BlockType get(int index) {