public void buildOnWorld()

in Minecraft/src/main/java/com/microsoft/Malmo/MissionHandlers/ClassroomDecoratorImplementation.java [102:219]


    public void buildOnWorld(MissionInit missionInit, World world) throws DecoratorException {
        this.drawContext = new BlockDrawingHelper();
        if(this.buildingWidth == 0){
            // We are using complexity so these need to be sampled from the Gaussian
            this.buildingWidth = Math.max((int)(rand.nextGaussian()*2 + this.buildingComplexity*MAX_BUILDING_SIZE + MIN_ROOM_SIZE), MIN_ROOM_SIZE);
            this.buildingLength = Math.max((int)(rand.nextGaussian()*2 + this.buildingComplexity*MAX_BUILDING_SIZE + MIN_ROOM_SIZE), MIN_ROOM_SIZE);
            this.buildingHeight = Math.max(Math.max(this.buildingWidth, this.buildingLength) * ROOM_HEIGHT / MIN_ROOM_SIZE, ROOM_HEIGHT);
        }
        
        // create the room grid
        ArrayList<Room> rooms = this.createRooms();
        
        // randomize the indices used to query different divisions.  This has the effect of making
        // the path to the goal random each time.
        this.shuffleIndices();
        
        // determine how long the path to the goal should be
        if(this.pathLength == 0){
            this.pathLength = (int)((1 - 0.25 * this.pathComplexity)*rooms.size()) - 1;
        }else{
            this.pathLength = Math.min(this.pathLength, rooms.size() - 1);
        }
        
        // find a path to the goal
        ArrayList<Divider> path = new ArrayList<Divider>();        
        Room startRoom, goalRoom;
        if(this.pathLength > 0){                    
            for(Room room : rooms){
                for(Room markRoom : rooms){
                	markRoom.mark = false;
                }
                
                if(findPath(path, room, this.pathLength)){
                    break;
                }               
            }
            
            if(path.size() < this.pathLength){
                // error
                throw new DecoratorException("Unable to find path to goal");
            }
            
            startRoom = path.get(0).getIn();
            goalRoom = path.get(path.size() - 1).getOut();
            
            for(Divider divider : path){
            	divider.setHint(this.rand.nextDouble() < this.hintLikelihood);
            }
        
            // create all of the obstacles along the path
            createObstacles(path);
        }else{
            startRoom = goalRoom = rooms.get(0);
            startRoom.isComplete = true;
        }

        // find orphan rooms
        for(Room room : rooms){
            if(room.isComplete){
                continue;
            }
            
            for(Room markRoom : rooms){
                markRoom.mark = false;
            }    
            
            path.clear();
            
            if(findPath(path, room, rooms.size())){
                // reverse the directions (the algorithm finds a path from the start room
                // to the end room, so we will reverse it so it goes from the completed
                // portion of the building back to the orphan room.
                for(Divider obstacle : path){
                    obstacle.reverse();
                }
                
                // create all of the obstacles along the path
                createObstacles(path);
            }else{
                throw new DecoratorException("Unable to join orphan room to goal path");
            }
        }

        // carve out the building
        this.drawContext.beginDrawing(world);
        for(int x=START_X; x<START_X + this.buildingWidth; x++){
            for(int y=START_Y; y<START_Y + this.buildingHeight; y++){
                for(int z=START_Z; z<START_Z + this.buildingLength; z++){
                    world.setBlockToAir(new BlockPos(x, y, z));
                }
            }
        }
        
        // this should clear all of the torches and levers left over from last time.  It doesn't.
        drawContext.clearEntities(world, START_X - 1, START_Y - 1, START_Z - 1, START_X + this.buildingWidth, START_Y + this.buildingHeight, START_Z + this.buildingLength);
        
        // draw the rooms
        for(Room room : rooms){
            room.draw(world, this.rand, this.palette);
        }
        
        // place goal
        setBlockState(world, new BlockPos(goalRoom.x+this.rand.nextInt(goalRoom.width-4) + 2, goalRoom.y, goalRoom.z + goalRoom.length - 2), this.palette.goal);
        this.drawContext.endDrawing(world);
        // set the agent positions
        PosAndDirection p2 = new PosAndDirection();
        p2.setX(new BigDecimal(startRoom.x + this.rand.nextInt(goalRoom.width-2) + 0.5));
        p2.setY(new BigDecimal(1 + startRoom.y));
        p2.setZ(new BigDecimal(startRoom.z + 0.5));

        // TODO - for the moment, force all players to being at the maze start point - but this needs to be optional.
        for (AgentSection as : missionInit.getMission().getAgentSection())
        {
            p2.setPitch(as.getAgentStart().getPlacement().getPitch());
            p2.setYaw(as.getAgentStart().getPlacement().getYaw());
            as.getAgentStart().setPlacement(p2);
        }
    }