Ejemplo n.º 1
0
 void InitializeCells()
 {
     _cells = new LXFMLCell[_count];
     for (int i = 0; i < _count; ++i)
     {
         _cells[i] = new LXFMLCell(new Vector2(i % _width, (int)i / _width));
     }
 }
Ejemplo n.º 2
0
    public void AddBrick(BrickData brick)
    {
        _bricks[brick.id]           = brick;
        _bricksCellsCache[brick.id] = new LXFMLCell[brick.design.width * brick.design.height];

        var brickOrigin = GetNormalizedBrickOrigin(brick);

        var normalizedOrigin = new Vector2(brickOrigin.x, brickOrigin.y);

        if (brick.isFlipped)
        {
            normalizedOrigin.x = normalizedOrigin.x - (brick.design.width - 1);
        }

        LXFMLCell     originCell = _grid.GetCellAt(brickOrigin);
        LXFMLCell     cell;
        LXFMLCellData cellData;

        int cellCount = 0;

        for (int y = 0; y < brick.design.height; ++y)
        {
            for (int x = 0; x < brick.design.width; ++x)
            {
                cellData = new LXFMLCellData();

                cell = _grid.GetCellAt(normalizedOrigin.x + x, normalizedOrigin.y + y);

                if (normalizedOrigin.x + x >= LXFMLHelper.kGridSize || normalizedOrigin.y + y >= LXFMLHelper.kGridSize)
                {
                    Debug.LogWarning("Invalid position");
                }

                _bricksCellsCache[brick.id][cellCount++] = cell;

                if (!cell.IsEmpty)
                {
                    //Debug.LogWarningFormat("Overriting cell at {0}.", cell.Coordinates);
                }

                cellData.Brick = brick;

                //TODO: Is it necessary?
                cellData.IsFull = true;

                cell.Data        = cellData;
                cell.BrickOrigin = originCell;
            }
        }

        SetConnectedBricks(brick, brickOrigin);

        originCell.Data.IsOrigin = true;

        CommitChange(ConstructionChangesetOperation.Addition, originCell.Data.Brick, originCell.Coordinates);

        _lastBrickId++;
    }
Ejemplo n.º 3
0
    public int SortByXAscending(LXFMLCell cell1, LXFMLCell cell2)
    {
        int returnVal = cell1.Coordinates.x.CompareTo(cell2.Coordinates.x);

        if (returnVal == 0)
        {
            return(cell1.Coordinates.y.CompareTo(cell2.Coordinates.y));
        }
        return(returnVal);
    }
Ejemplo n.º 4
0
    public void CheckSelectedBrick()
    {
        if (!_isTweening)
        {
#if UNITY_EDITOR
            Vector2 mousePos = Input.mousePosition;
#else
            Vector2 mousePos = Input.touchCount > 0 ? Input.GetTouch(0).position : Vector2.zero;
#endif
            Vector2 gridPos = screenPointToGridPosition(mousePos);

            LXFMLCell cell = _builder.construction.Grid.GetCellAt(gridPos);
            if (cell != null && cell.Data != null)
            {
                selectedPart       = draggingScenePart = _bricks[cell.Data.Brick.id];
                _startDragPosition = selectedPart.transform.position;
                _startDragCell     = gridPos;
                UpdateAvailableParts(selectedPart);
                UpdateAvailableColors(selectedPart);

                _dragCellData = cell.Data;

                _originalPos = selectedPart.transform.position;

                Vector2 blockOrigin = _builder.construction.GetBrickCell(selectedPart.id).Coordinates;
                if (cell.Data.Brick.isFlipped)
                {
                    blockOrigin.x -= cell.Data.Brick.design.width - 1;
                }
                _cellOffset.x = gridPos.x - blockOrigin.x;
                _cellOffset.y = gridPos.y - blockOrigin.y;

                _builder.construction.RemoveBrick(cell.Data.Brick.id);
            }
            else
            {
                _modelUI.UpdateColorsList(new int[0], 0);
                selectedPart = null;
                UpdateAvailableParts(null);
                UpdateAvailableColors(null);
            }
        }
    }
Ejemplo n.º 5
0
    public bool CellHasUpperStudConnection(LXFMLCell cell, int brickId)
    {
        bool      hasStud     = true;
        BrickData brickData   = _bricks[brickId];
        int       brickHeight = LXFMLHelper.GetBrickHeight(brickData.design.id);
        Vector2   brickOrigin = GetBrickOrigin(brickId);

        if (brickHeight == 1)
        {
            if (LXFMLHelper.IsSlopeDown(brickData.design.id))
            {
                if (!MathUtils.NearEqual(brickOrigin, cell.Coordinates))
                {
                    hasStud = false;
                }
            }
        }
        else
        {
            float upperY = cell.Coordinates.y + brickHeight - 1;
            if (!MathUtils.NearEqual(upperY, cell.Coordinates.y))
            {
                hasStud = false;
            }
            else
            {
                if (LXFMLHelper.IsSlopeDown(brickData.design.id))
                {
                    if (!MathUtils.NearEqual(cell.Coordinates.x, cell.Coordinates.x))
                    {
                        hasStud = false;
                    }
                }
            }
        }

        return(hasStud);
    }
Ejemplo n.º 6
0
    void TestValidPosition(Vector2 gridPos)
    {
        int width  = LXFMLHelper.GetBrickWidth(draggingScenePart.designId);
        int heigth = LXFMLHelper.GetBrickHeight(draggingScenePart.designId);

        int xStartTest = Mathf.RoundToInt(gridPos.x - _cellOffset.x);
        int xEndTest   = Mathf.RoundToInt(gridPos.x - _cellOffset.x + width);

        int yStartTest = Mathf.RoundToInt(gridPos.y - _cellOffset.y);
        int yEndTest   = Mathf.RoundToInt(gridPos.y - _cellOffset.y + heigth);

        _validPosition = true;

        //TEST GRID LIMITS
        if (xStartTest < 0 || xEndTest > LXFMLHelper.kGridSize || yStartTest < 0 || yEndTest > LXFMLHelper.kGridSize)
        {
            _validPosition = false;
        }

        //TEST OCCUPIED CELLS
        if (_validPosition)
        {
            for (int i = xStartTest; i < xEndTest; i++)
            {
                for (int j = yStartTest; j < yEndTest; j++)
                {
                    LXFMLCell cell = _builder.construction.Grid.GetCellAt(i, j);
                    if (cell != null && cell.Data != null)
                    {
                        _validPosition = false;
                        break;
                    }
                }
            }
        }

        //TEST FLOATING BRICK
        if (_validPosition)
        {
            int numContacts = 0;
            for (int i = xStartTest; i < xEndTest; i++)
            {
                LXFMLCell cellBottom = _builder.construction.Grid.GetCellAt(i, yStartTest - 1);
                if (cellBottom != null && cellBottom.Data != null)
                {
                    if (cellBottom.Data.Brick.design.type == BrickType.Normal || cellBottom.Data.Brick.design.type == BrickType.SlopeUp || cellBottom.Data.Brick.design.type == BrickType.CurveIn)
                    {
                        numContacts++;
                    }
                    else
                    {
                        if (cellBottom.Data.IsOrigin)
                        {
                            numContacts++;
                        }
                        else
                        {
                            if (i == _builder.construction.GetBrickOrigin(cellBottom.Data.Brick.id).x)
                            {
                                numContacts++;
                            }
                        }
                    }
                }
                LXFMLCell cellTop = _builder.construction.Grid.GetCellAt(i, yEndTest);

                if (cellTop != null && cellTop.Data != null)
                {
                    if (cellTop.Data.Brick.design.type == BrickType.Normal || cellTop.Data.Brick.design.type == BrickType.SlopeDown || cellTop.Data.Brick.design.type == BrickType.CurveOut)
                    {
                        numContacts++;
                    }
                    else
                    {
                        if (cellTop.Data.IsOrigin)
                        {
                            numContacts++;
                        }
                    }
                }
            }
            _validPosition = numContacts != 0;
        }
    }
Ejemplo n.º 7
0
    private void SetConnectedBricks(BrickData brick, Vector2 brickOrigin)
    {
        int numUpperSlots = LXFMLHelper.UpperSlots(brick.design.id);
        int numLowerSlots = LXFMLHelper.LowerSlots(brick.design.id);

        int inc = 0;
        int i   = Mathf.RoundToInt(brickOrigin.x);


        while (inc < numUpperSlots)
        {
            LXFMLCell upperCell = _grid.GetCellAt(i, (int)brickOrigin.y + brick.design.height);
            if (upperCell != null && !upperCell.IsEmpty)
            {
                if (upperCell.Data.Brick.design.type == BrickType.Normal || upperCell.Data.Brick.design.type == BrickType.SlopeDown || upperCell.Data.Brick.design.type == BrickType.CurveOut)
                {
                    ConnectBricks(brick, upperCell.Data.Brick);
                }
                else
                {
                    if (upperCell.Data.IsOrigin)
                    {
                        ConnectBricks(brick, upperCell.Data.Brick);
                    }
                }
            }
            i += brick.Orientation;
            inc++;
        }

        inc = 0;
        i   = Mathf.RoundToInt(brickOrigin.x);

        while (inc < numLowerSlots)
        {
            LXFMLCell lowerCell = _grid.GetCellAt(i, (int)brickOrigin.y - 1);
            if (lowerCell != null && !lowerCell.IsEmpty)
            {
                if (lowerCell.Data.Brick.design.type == BrickType.Normal || lowerCell.Data.Brick.design.type == BrickType.SlopeUp || lowerCell.Data.Brick.design.type == BrickType.CurveIn)
                {
                    ConnectBricks(brick, lowerCell.Data.Brick);
                }
                else
                {
                    if (lowerCell.Data.IsOrigin)
                    {
                        ConnectBricks(brick, lowerCell.Data.Brick);
                    }
                    else
                    {
                        if (i == GetBrickOrigin(lowerCell.Data.Brick.id).x)
                        {
                            ConnectBricks(brick, lowerCell.Data.Brick);
                        }
                    }
                }
            }
            i += brick.Orientation;
            inc++;
        }

        var leftCell  = _grid.GetCellAt(brickOrigin.x - 1f, brickOrigin.y);
        var rightCell = _grid.GetCellAt(brickOrigin.x + brick.design.width, brickOrigin.y);

        if (brick.Orientation < 0)
        {
            leftCell  = _grid.GetCellAt(brickOrigin.x - brick.design.width, brickOrigin.y);
            rightCell = _grid.GetCellAt(brickOrigin.x + 1, brickOrigin.y);
        }

        if (leftCell != null && !leftCell.IsEmpty)
        {
            brick.NeighbourBricks.Add(leftCell.Data.Brick);
            leftCell.Data.Brick.NeighbourBricks.Add(brick);
        }

        if (rightCell != null && !rightCell.IsEmpty)
        {
            brick.NeighbourBricks.Add(rightCell.Data.Brick);
            rightCell.Data.Brick.NeighbourBricks.Add(brick);
        }
    }
Ejemplo n.º 8
0
    void AddLasers(List <BrickData> bricksList, int direction)
    {
        for (int i = 0; i < bricksList.Count; i++)
        {
            if (LXFMLHelper.IsPowerBrick(bricksList[i].design.id, bricksList[i].materialId))
            {
                //Check upper and lower bricks
                int     numUpperSlots = LXFMLHelper.UpperSlots(bricksList[i].design.id);
                int     numLowerSlots = LXFMLHelper.LowerSlots(bricksList[i].design.id);
                Vector2 brickOrigin   = GetBrickOrigin(bricksList[i].id);

                int inc            = 0;
                int j              = Mathf.RoundToInt(brickOrigin.x);
                int numUpperBricks = 0;


                while (inc < numUpperSlots)
                {
                    LXFMLCell upperCell = _grid.GetCellAt(j, (int)brickOrigin.y + bricksList[i].design.height);
                    if (upperCell != null && !upperCell.IsEmpty)
                    {
                        if (upperCell.Data.Brick.design.type == BrickType.Normal || upperCell.Data.Brick.design.type == BrickType.SlopeDown || upperCell.Data.Brick.design.type == BrickType.CurveOut)
                        {
                            numUpperBricks++;
                        }
                        else
                        {
                            if (upperCell.Data.IsOrigin)
                            {
                                numUpperBricks++;
                            }
                        }
                    }
                    j += bricksList[i].Orientation;
                    inc++;
                }

                inc = 0;
                j   = Mathf.RoundToInt(brickOrigin.x);
                int numLowerBricks = 0;

                while (inc < numLowerSlots)
                {
                    LXFMLCell lowerCell = _grid.GetCellAt(j, (int)brickOrigin.y - 1);
                    if (lowerCell != null && !lowerCell.IsEmpty)
                    {
                        if (lowerCell.Data.Brick.design.type == BrickType.Normal || lowerCell.Data.Brick.design.type == BrickType.SlopeUp || lowerCell.Data.Brick.design.type == BrickType.CurveIn)
                        {
                            numLowerBricks++;
                        }
                        else
                        {
                            if (lowerCell.Data.IsOrigin)
                            {
                                numLowerBricks++;
                            }
                            else
                            {
                                if (j == GetBrickOrigin(lowerCell.Data.Brick.id).x)
                                {
                                    numLowerBricks++;
                                }
                            }
                        }
                    }
                    j += bricksList[i].Orientation;
                    inc++;
                }

                if (numLowerBricks == numLowerSlots && numUpperBricks == numUpperSlots)
                {
                    CreateLaser(bricksList[i], direction);
                }
            }
        }
    }
Ejemplo n.º 9
0
    private void SetRoof()
    {
        var roofContainer = new GameObject("roofContainer").transform;

        roofContainer.localScale = new Vector3(1f, 1f, 1f);


        var topEdgeBricks = construction.GetTopEdgeBricks();

        var wallBricks = new List <BrickData>();
        var roofBricks = new List <BrickData>();
        var roofCells  = new List <LXFMLCell>();

        wallBricks.AddRange(construction.GetLeftEdgeBricks());
        wallBricks.AddRange(construction.GetRightEdgeBricks());

        for (int i = 0; i < topEdgeBricks.Count; i++)
        {
            List <LXFMLCell> brickCells = construction.GetBrickCells(topEdgeBricks[i].id);
            for (int j = 0; j < brickCells.Count; j++)
            {
                bool      hasStud   = true;
                LXFMLCell upperCell = construction.Grid.GetCellAt(brickCells[j].Coordinates.x, brickCells[j].Coordinates.y + 1f);
                if (upperCell != null && upperCell.Data != null && upperCell.Data.Brick != null)
                {
                    hasStud = false;
                }

                if (construction.CellHasUpperStudConnection(brickCells[j], topEdgeBricks[i].id) && hasStud)
                {
                    roofCells.Add(brickCells[j]);
                }
            }
            if (!wallBricks.Contains(topEdgeBricks[i]))
            {
                roofBricks.Add(topEdgeBricks[i]);
            }
        }

        roofCells.Sort(SortByXAscending);

        float lastX = float.MinValue;
        float lastY = float.MinValue;

        int inc = 0;

        //Dictionary<Cell for deco position, maxWidth for deco>
        Dictionary <LXFMLCell, int> decoFootprints = new Dictionary <LXFMLCell, int>();

        LXFMLCell currentCell = roofCells[0];

        for (int i = 0; i < roofCells.Count; i++)
        {
            if ((MathUtils.NearEqual(lastX, roofCells[i].Coordinates.x - 1f) && MathUtils.NearEqual(roofCells[i].Coordinates.y, lastY)) || i == 0)
            {
                inc++;
            }
            else
            {
                //min roof deco width is 2
                if (inc >= 2)
                {
                    decoFootprints.Add(currentCell, inc);
                }
                currentCell = roofCells[i];
                inc         = 1;
            }
            lastX = roofCells[i].Coordinates.x;
            lastY = roofCells[i].Coordinates.y;
        }

        currentCell = null;
        int maxY = int.MinValue;

        foreach (KeyValuePair <LXFMLCell, int> kvp in decoFootprints)
        {
            int coordY = (int)kvp.Key.Coordinates.y;
            if (coordY > maxY)
            {
                maxY        = coordY;
                currentCell = kvp.Key;
            }
        }

        if (currentCell != null)
        {
            //found a spot for roof deco
            GameObject deco = ConstructionController.Instance.resourcesProvider.GetDecorationForWidth(decoFootprints[currentCell], LXFMLDecoration.DecoPosition.Roof);
            if (deco != null)
            {
                int maxDecoWidth = decoFootprints[currentCell];
                var decoWidth    = deco.GetComponent <LXFMLDecoration>().width;
                var decoHeight   = deco.GetComponent <LXFMLDecoration>().height;

                GameObject decoInstance = Instantiate(deco);
                decoInstance.transform.SetParent(roofContainer);

                //construction starting position
                Vector3 pivotPoint  = new Vector3(float.MaxValue, float.MaxValue, float.MinValue);
                int     offsetIndex = int.MaxValue;

                for (int i = 0; i < _bricks.Count; i++)
                {
                    pivotPoint.x = Mathf.Min(pivotPoint.x, _bricks[i].localPosition.x);
                    pivotPoint.y = Mathf.Min(pivotPoint.y, _bricks[i].localPosition.y);
                    pivotPoint.z = Mathf.Max(pivotPoint.z, _bricks[i].localPosition.z);
                    offsetIndex  = Mathf.Min(offsetIndex, (int)_bricks[i].GetComponent <LegoBrickId>().coords.x);
                }

                var pos = pivotPoint;
                pos.x += ((currentCell.Coordinates.x - (float)offsetIndex + ((maxDecoWidth - decoWidth) / 2f)) * LXFMLHelper.kBrickSize.x);
                pos.y += ((currentCell.Coordinates.y + 1f) * LXFMLHelper.kBrickSize.y);
                pos.z += (((_extrusionSize - 2f) / 2f) + 2f) * LXFMLHelper.kBrickSize.x;

                decoInstance.transform.localPosition = pos;

                buildingDecorations.Add(decoInstance);
            }
        }

        for (int i = 0; i < roofBricks.Count; i++)
        {
            float     posZ   = LXFMLHelper.kBrickSize.x;
            Transform brickT = _bricksLookup[roofBricks[i].id];
            for (int j = 0; j < _extrusionSize; j++)
            {
                GameObject copy = Instantiate(brickT.gameObject);
                copy.transform.localPosition = brickT.localPosition;
                copy.transform.localRotation = brickT.localRotation;
                copy.transform.SetParent(roofContainer, false);
                copy.transform.Translate(0f, 0f, posZ, Space.World);
                posZ += LXFMLHelper.kBrickSize.x;
                extrudedBricksBySize[j].Add(copy);

                /*
                 * for(int j = 0 ; j < _extrusionSize ; j++){
                 *                      if((j < start || j > end) || (gridPos.y >= cellForDeco.Coordinates.y || gridPos.y < cellForDeco.Coordinates.y - (decoHeight))){
                 *                              GameObject copy = Instantiate (brickT.gameObject);
                 *                              copy.transform.localPosition = brickT.localPosition;
                 *                              copy.transform.localRotation = brickT.localRotation;
                 *                              copy.transform.SetParent(container, false);
                 *                              copy.transform.Translate(0f,0f,posZ, Space.World);
                 *                              extrudedBricksBySize[j].Add(copy);
                 *                      }
                 *                      posZ += LXFMLHelper.kBrickSize.x;
                 *              }
                 *
                 */
            }
        }
        roofContainer.SetParent(transform, false);
    }
Ejemplo n.º 10
0
    private void SetWall(string containerName, List <BrickData> edgeBricks, WallPosition position)
    {
        //Create transform to hold the bricks
        var container = new GameObject(containerName).transform;

        container.localScale = new Vector3(1f, 1f, 1f);

        List <LXFMLCell> cellsForDeco = new List <LXFMLCell>();

        //FILTER ALL EDGE BRICKS TO RETRIEVE ELIGIBLE CELLS FOR DECO HOOK ON LOWER PART
        for (int i = 0; i < edgeBricks.Count - 1; i++)
        {
            Vector2 brickOrigin = construction.GetBrickOrigin(edgeBricks[i].id);

            if (LXFMLHelper.IsBrickFlipped(edgeBricks[i]))
            {
                for (int j = (int)brickOrigin.x - LXFMLHelper.GetBrickWidth(edgeBricks[i].design.id) + 1; j < (int)brickOrigin.x; j++)
                {
//					Debug.Log (j);
                    if (!LXFMLHelper.IsSlopeUp(edgeBricks[i].design.id) || j == (int)brickOrigin.x)
                    {
                        cellsForDeco.Add(construction.Grid.GetCellAt((float)j, brickOrigin.y));
                    }
                }
            }
            else
            {
                for (int j = (int)brickOrigin.x; j < (int)brickOrigin.x + LXFMLHelper.GetBrickWidth(edgeBricks[i].design.id); j++)
                {
//					Debug.Log (j);
                    if (!LXFMLHelper.IsSlopeUp(edgeBricks[i].design.id) || j == (int)brickOrigin.x)
                    {
                        cellsForDeco.Add(construction.Grid.GetCellAt((float)j, brickOrigin.y));
                    }
                }
            }
        }

        //FOR EACH ELIGIBLE CELL, FIND BOTTOM CELLS TO EXCLUDE FROM EXTRUSION

        Dictionary <LXFMLCell, List <LXFMLCell> > bricksToRemove       = new Dictionary <LXFMLCell, List <LXFMLCell> >();
        Dictionary <LXFMLCell, List <int> >       availableDecoHeights = new Dictionary <LXFMLCell, List <int> >();

        for (int i = 0; i < cellsForDeco.Count; i++)
        {
//			Debug.Log ("Testing " + cellsForDeco[i].Coordinates.ToString());
            int indexX = (int)cellsForDeco[i].Coordinates.x;
            int indexY = (int)cellsForDeco[i].Coordinates.y;

            bricksToRemove.Add(cellsForDeco[i], new List <LXFMLCell>());
            availableDecoHeights.Add(cellsForDeco[i], new List <int>());

            //if cell is first row, discard
            if (indexY == 0)
            {
                break;
            }

            //Stop lookup at index 1 or maxSize
            int endIndex = indexY - _decoMaxHeight < 0 ? 0 : indexY - _decoMaxHeight;

            int j = indexY - 1;

            for (j = indexY - 1; j >= endIndex; j--)
            {
                LXFMLCell cell = construction.Grid.GetCellAt(indexX, j);
                bricksToRemove[cellsForDeco[i]].Add(cell);
            }

            for (j = 0; j < bricksToRemove[cellsForDeco[i]].Count; j++)
            {
                LXFMLCell currentCell = bricksToRemove[cellsForDeco[i]][j];
                if (j > _decoMinHeight - 1)
                {
                    //DISCARD IF CELL HAS NO STUD TO HOOK THE DECO
                    if (currentCell.Data != null && currentCell.Data.Brick != null && edgeBricks.Contains(currentCell.Data.Brick))
                    {
                        BrickData currentBrick = currentCell.Data.Brick;
                        int       h            = LXFMLHelper.GetBrickHeight(currentBrick.design.id);
                        if (construction.CellHasUpperStudConnection(currentCell, currentBrick.id))
                        {
                            availableDecoHeights[cellsForDeco[i]].Add(j);
                        }
                    }
                }
            }
        }

        Dictionary <int, int> xIndexComparer = new Dictionary <int, int>();

        //RETRIEVE LEFT/RIGHT MOST AVAILABLE CELL FOR DECO
        foreach (KeyValuePair <LXFMLCell, List <int> > kvp in availableDecoHeights)
        {
            if (kvp.Value.Count == 0)
            {
                bricksToRemove.Remove(kvp.Key);
            }
            else
            {
                if (kvp.Key.Data != null && kvp.Key.Data.Brick != null)
                {
                    int id = kvp.Key.Data.Brick.id;
                    if (!xIndexComparer.ContainsKey(id))
                    {
                        if (position == WallPosition.Left)
                        {
                            xIndexComparer.Add(id, int.MaxValue);
                        }
                        else
                        {
                            xIndexComparer.Add(id, int.MinValue);
                        }
                    }
                    int minY = -1;
                    if (position == WallPosition.Left)
                    {
                        minY = Mathf.Min(xIndexComparer[id], (int)kvp.Key.Coordinates.x);
                    }
                    else
                    {
                        minY = Mathf.Max(xIndexComparer[id], (int)kvp.Key.Coordinates.x);
                    }
                    xIndexComparer[id] = minY;

                    for (int k = 0; k < kvp.Value.Count; k++)
                    {
                        Debug.Log("Cell " + kvp.Key.Coordinates.ToString() + " can have " + kvp.Value[k].ToString() + " height deco");
                    }
                }
            }
        }

        Dictionary <LXFMLCell, List <LXFMLCell> > toKeep = new Dictionary <LXFMLCell, List <LXFMLCell> >();

        //TRIM CELLS WHEN NOT LEFTMOST OF BRICK
        foreach (KeyValuePair <LXFMLCell, List <LXFMLCell> > kvp in bricksToRemove)
        {
            if (kvp.Key.Data != null && kvp.Key.Data.Brick != null)
            {
                int comparer = kvp.Key.Data.Brick.id;
                foreach (KeyValuePair <int, int> xIndices in xIndexComparer)
                {
                    if (comparer == xIndices.Key)
                    {
                        if (xIndices.Value == (int)kvp.Key.Coordinates.x)
                        {
                            toKeep.Add(kvp.Key, kvp.Value);
                        }
                    }
                }
            }
        }


        //PICK BEST MATCH FOR DECO
        if (toKeep.Count > 0)
        {
            Debug.Log("Deco avail " + toKeep.Count.ToString());
            //ONLY SUPPORT 1 DECO PER WALL, NEED TO SUPPORT MORE H & V
            int midIndex;
            if (toKeep.Count == 1)
            {
                midIndex = 0;
            }
            else
            {
                midIndex = Mathf.RoundToInt((float)toKeep.Count / 2f) - 1;
            }

            int brickId = 0;

            LXFMLCell cellForDeco = null;

            int index = 0;

            foreach (KeyValuePair <LXFMLCell, List <LXFMLCell> > kvp in toKeep)
            {
                if (index == midIndex)
                {
                    brickId     = kvp.Key.Data.Brick.id;
                    cellForDeco = kvp.Key;
                }
                index++;
            }

            if (cellForDeco != null)
            {
                GameObject deco = ConstructionController.Instance.resourcesProvider.GetDecorationForHeight(availableDecoHeights[cellForDeco], LXFMLDecoration.DecoPosition.Wall);

                if (deco != null)
                {
                    var decoWidth  = deco.GetComponent <LXFMLDecoration>().width;
                    var decoHeight = deco.GetComponent <LXFMLDecoration>().height;
                    int start      = ((_extrusionSize - (int)decoWidth) / 2);
                    int end        = start + (int)decoWidth - 1;

                    for (int i = 0; i < edgeBricks.Count; i++)
                    {
                        float     posZ    = +LXFMLHelper.kBrickSize.x;
                        Transform brickT  = _bricksLookup[edgeBricks[i].id];
                        Vector2   gridPos = construction.GetBrickOrigin(edgeBricks[i].id);
                        for (int j = 0; j < _extrusionSize; j++)
                        {
                            if ((j < start || j > end) || (gridPos.y >= cellForDeco.Coordinates.y || gridPos.y < cellForDeco.Coordinates.y - (decoHeight)))
                            {
                                GameObject copy = Instantiate(brickT.gameObject);
                                copy.transform.localPosition = brickT.localPosition;
                                copy.transform.localRotation = brickT.localRotation;
                                copy.transform.SetParent(container, false);
                                copy.transform.Translate(0f, 0f, posZ, Space.World);
                                extrudedBricksBySize[j].Add(copy);
                            }
                            posZ += LXFMLHelper.kBrickSize.x;
                        }
                    }
                    //construction starting position
                    Vector3 pivotPoint  = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
                    int     offsetIndex = int.MaxValue;

                    for (int i = 0; i < _bricks.Count; i++)
                    {
                        pivotPoint.x = Mathf.Min(pivotPoint.x, _bricks[i].localPosition.x);
                        pivotPoint.y = Mathf.Min(pivotPoint.y, _bricks[i].localPosition.y);
                        pivotPoint.z = Mathf.Min(pivotPoint.z, _bricks[i].localPosition.z);
                        offsetIndex  = Mathf.Min(offsetIndex, (int)_bricks[i].GetComponent <LegoBrickId>().coords.x);
                    }


                    GameObject decoInstance = Instantiate(deco);
                    decoInstance.transform.SetParent(container);

                    var pos = pivotPoint;
                    pos.x += ((cellForDeco.Coordinates.x - (float)offsetIndex) * LXFMLHelper.kBrickSize.x);
                    pos.y += (cellForDeco.Coordinates.y * LXFMLHelper.kBrickSize.y) - (decoHeight * LXFMLHelper.kBrickSize.y);
                    pos.z  = position == WallPosition.Right ? ((float)start + 1f) * LXFMLHelper.kBrickSize.x : ((float)start + decoWidth) * LXFMLHelper.kBrickSize.x;
                    pos.z += pivotPoint.z;


                    decoInstance.transform.localPosition = pos;
                    float rotY = position == WallPosition.Left ? 90f : 270f;
                    decoInstance.transform.Rotate(Vector3.up, rotY);

                    buildingDecorations.Add(decoInstance);
                }
                else
                {
                    ExtrudeNoDeco(edgeBricks, container);
                }
            }
        }
        else
        {
            ExtrudeNoDeco(edgeBricks, container);
        }
        container.SetParent(transform, false);
    }