private WallCuts RotateCuts(WorldRotation rot, WallCuts input, short x, short y)
        {
            int rotN = (int)rot;
            var output = new WallCuts();
            switch (rotN)
            {
                case 0:
                    return input;
                case 1:
                    output.TRCut = input.TLCut;
                    if (y + 1 < blueprint.Height) output.TLCut = Cuts[(y + 1) * blueprint.Width + x].TRCut;

                    if (output.TLCut == WallCut.DownLeftUpRight) output.TLCut = WallCut.DownRightUpLeft; //flip cut
                    else if (output.TLCut == WallCut.DownRightUpLeft) output.TLCut = WallCut.DownLeftUpRight;

                    return output;
                case 2:
                    output.TRCut = input.TLCut;
                    if (y + 1 < blueprint.Height) output.TRCut = Cuts[(y + 1) * blueprint.Width + x].TRCut;
                    if (x + 1 < blueprint.Width) output.TLCut = Cuts[y * blueprint.Width + x + 1].TLCut;

                    if (output.TLCut == WallCut.DownLeftUpRight) output.TLCut = WallCut.DownRightUpLeft; //flip cuts
                    else if (output.TLCut == WallCut.DownRightUpLeft) output.TLCut = WallCut.DownLeftUpRight;
                    if (output.TRCut == WallCut.DownLeftUpRight) output.TRCut = WallCut.DownRightUpLeft;
                    else if (output.TRCut == WallCut.DownRightUpLeft) output.TRCut = WallCut.DownLeftUpRight;

                    return output;
                case 3:
                    output.TLCut = input.TRCut;
                    if (x + 1 < blueprint.Width) output.TRCut = Cuts[y * blueprint.Width + x+1].TLCut;

                    if (output.TRCut == WallCut.DownLeftUpRight) output.TRCut = WallCut.DownRightUpLeft; //flip cut
                    else if (output.TRCut == WallCut.DownRightUpLeft) output.TRCut = WallCut.DownLeftUpRight;

                    return output;
            }
            return output;
        }
        private void GenerateWallData(WallTile[] walls, List<int> wallsAt, bool notTop)
        {
            var width = blueprint.Width;
            var height = blueprint.Height;
            Cuts = new WallCuts[width * height];
            DownJunctions = new JunctionFlags[width * height];
            UpJunctions = new JunctionFlags[width * height];

            foreach (var off in wallsAt)
            {
                var wall = walls[off];
                var x = off % width;
                var y = off / width;
                var result = new WallCuts();
                if (notTop && WallsDownAt(x, y))
                {
                    var cuts = GetCutEdges(off % width, off / width);

                    if (wall.TopLeftThick && wall.TopLeftStyle != 255)
                    {
                        if (cuts != 0)
                        {
                            if ((cuts & CutawayEdges.NegativeX) == CutawayEdges.NegativeX) result.TLCut = WallCut.Up; //if we are on the very edge of the cut we're up
                            else if ((cuts & CutawayEdges.PositiveY) == CutawayEdges.PositiveY) {
                                if ((cuts & CutawayEdges.NegativeY) == CutawayEdges.NegativeY)
                                {
                                    result.TLCut = WallCut.Down; //special case, cuts at both sides... just put wall down
                                }
                                else
                                {
                                    result.TLCut = WallCut.DownRightUpLeft;
                                }
                            }
                            else if ((cuts & CutawayEdges.NegativeY) == CutawayEdges.NegativeY)
                            {
                                result.TLCut = WallCut.DownLeftUpRight;
                            }
                            else result.TLCut = WallCut.Down;
                        }
                        else
                        {
                            result.TLCut = WallCut.Down;
                        }

                    }

                    if (wall.TopRightStyle == 1) //NOTE: top right style also includes diagonals!
                    {
                        if (wall.Segments == WallSegments.HorizontalDiag) {
                            if (cuts != 0)
                            {
                                var cutOnLeft = (cuts & (CutawayEdges.PositiveY | CutawayEdges.NegativeX)) > 0;
                                var cutOnRight = (cuts & (CutawayEdges.NegativeY | CutawayEdges.PositiveX)) > 0;
                                if (cutOnLeft && cutOnRight) result.TRCut = WallCut.Down;
                                else if (cutOnLeft) result.TRCut = WallCut.DownRightUpLeft;
                                else if (cutOnRight) result.TRCut = WallCut.DownLeftUpRight;
                                else result.TRCut = WallCut.Down;
                            }
                            else
                            {
                                result.TRCut = WallCut.Down;
                            }
                        }
                        else if (wall.Segments == WallSegments.VerticalDiag)
                        {
                            if (cuts != 0) //this info is not useful for front rotation, but is useful for sides.
                            {
                                var cutOnLeft = (cuts & (CutawayEdges.PositiveY | CutawayEdges.PositiveX)) > 0;
                                var cutOnRight = (cuts & (CutawayEdges.NegativeY | CutawayEdges.NegativeX)) > 0;
                                if (cutOnLeft && cutOnRight) result.TRCut = WallCut.Down;
                                else if (cutOnLeft) result.TRCut = WallCut.DownRightUpLeft;
                                else if (cutOnRight) result.TRCut = WallCut.DownLeftUpRight;
                                else result.TRCut = WallCut.Down;
                            }
                            else
                            {
                                result.TRCut = WallCut.Down;
                            }
                        }
                        else
                        {
                            if (cuts != 0)
                            {
                                if ((cuts & CutawayEdges.NegativeY) == CutawayEdges.NegativeY) result.TRCut = WallCut.Up; //if we are on the very edge of the cut we're up
                                else if ((cuts & CutawayEdges.PositiveX) == CutawayEdges.PositiveX)
                                {
                                    if ((cuts & CutawayEdges.NegativeX) == CutawayEdges.NegativeX)
                                    { //special case, cuts at both sides... just put wall down
                                        result.TRCut = WallCut.Down;
                                    }
                                    else
                                    {
                                        result.TRCut = WallCut.DownLeftUpRight;
                                    }
                                }
                                else if ((cuts & CutawayEdges.NegativeX) == CutawayEdges.NegativeX)
                                {
                                    result.TRCut = WallCut.DownRightUpLeft;
                                }
                                else result.TRCut = WallCut.Down;
                            }
                            else
                            {
                                result.TRCut = WallCut.Down;
                            }
                        }
                    }
                }
                //add to relevant junctions
                if ((wall.Segments & WallSegments.TopLeft) > 0 && !(wall.TopLeftDoor && result.TLCut > 0) && wall.TopLeftThick)
                {
                    if (result.TLCut > 0)
                    {
                        DownJunctions[off] |= JunctionFlags.BottomLeft;
                        if (y < height) DownJunctions[off + width] |= JunctionFlags.TopRight;
                    }
                    else
                    {
                        UpJunctions[off] |= JunctionFlags.BottomLeft;
                        if (y < height) UpJunctions[off + width] |= JunctionFlags.TopRight;
                    }
                }

                if ((wall.Segments & WallSegments.TopRight) > 0 && !(wall.TopRightDoor && result.TRCut > 0) && wall.TopRightThick)
                {
                    if (result.TRCut > 0)
                    {
                        DownJunctions[off] |= JunctionFlags.BottomRight;
                        if (x < width) DownJunctions[off + 1] |= JunctionFlags.TopLeft;
                    }
                    else
                    {
                        UpJunctions[off] |= JunctionFlags.BottomRight;
                        if (x < width) UpJunctions[off + 1] |= JunctionFlags.TopLeft;
                    }
                }

                if (wall.Segments == WallSegments.VerticalDiag && (wall.TopRightStyle == 1 || wall.TopRightStyle == 255))
                {
                    if (result.TRCut > 0)
                    {
                        DownJunctions[off] |= JunctionFlags.DiagBottom;
                        if (x < width && y < height) DownJunctions[off + 1 + width] |= JunctionFlags.DiagTop;
                    }
                    else
                    {
                        UpJunctions[off] |= JunctionFlags.DiagBottom;
                        if (x < width && y < height) UpJunctions[off + 1 + width] |= JunctionFlags.DiagTop;
                    }
                }
                else if (wall.Segments == WallSegments.HorizontalDiag && (wall.TopRightStyle == 1 || wall.TopRightStyle == 255))
                {
                    if (result.TRCut > 0)
                    {
                        if (x < width) DownJunctions[off + 1] |= JunctionFlags.DiagLeft;
                        if (y < height) DownJunctions[off + width] |= JunctionFlags.DiagRight;
                    }
                    else
                    {
                        if (x < width) UpJunctions[off + 1] |= JunctionFlags.DiagLeft;
                        if (y < height) UpJunctions[off + width] |= JunctionFlags.DiagRight;
                    }
                }
                Cuts[off] = result;
            }
        }