FSO.LotView.Components.WallComponent.Draw C# (CSharp) Method

Draw() public method

public Draw ( GraphicsDevice device, WorldState world ) : void
device GraphicsDevice
world WorldState
return void
        public override void Draw(GraphicsDevice device, WorldState world)
        {
            var timer = new System.Diagnostics.Stopwatch();
            timer.Start();

            if (WallZBuffers == null) WallZBuffers = TextureGenerator.GetWallZBuffer(device);

            var pxOffset = world.WorldSpace.GetScreenOffset();
            var wallContent = Content.Content.Get().WorldWalls;
            var floorContent = Content.Content.Get().WorldFloors;

            //draw walls
            for (sbyte level = 1; level <= world.Level; level++)
            {
                int off = 0;
                bool canCut = !(level < world.Level);
                GenerateWallData(blueprint.Walls[level-1], blueprint.WallsAt[level-1], canCut);
                var rMap = blueprint.RoomMap[level - 1];
                for (short y = 0; y < blueprint.Height; y++)
                { //ill decide on a reasonable system for components when it's finished ok pls :(
                    for (short x = 0; x < blueprint.Height; x++)
                    {
                        TileRoom = (rMap == null)?1:rMap[x + y * blueprint.Width];
                        var comp = blueprint.GetWall(x, y, level);
                        if (comp.Segments != 0)
                        {
                            comp = RotateWall(world.Rotation, comp, x, y, level);
                            var tilePosition = new Vector3(x, y, (level-1) * 2.95f);
                            world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition));
                            world._2D.OffsetTile(tilePosition);
                            var myCuts = Cuts[off];
                            var cDown = canCut && WallsDownAt(x, y);

                            if ((byte)comp.Segments < 16) myCuts = RotateCuts(world.Rotation, myCuts, x, y);
                            else if ((int)world.Rotation > 1) //for diagonals, just flip cuts on two furthest rotations
                            {
                                if (myCuts.TLCut == WallCut.DownRightUpLeft) myCuts.TLCut = WallCut.DownLeftUpRight;
                                else if (myCuts.TLCut == WallCut.DownLeftUpRight) myCuts.TLCut = WallCut.DownRightUpLeft;
                                if (myCuts.TRCut == WallCut.DownRightUpLeft) myCuts.TRCut = WallCut.DownLeftUpRight;
                                else if (myCuts.TRCut == WallCut.DownLeftUpRight) myCuts.TRCut = WallCut.DownRightUpLeft;
                            }

                            if ((comp.Segments & WallSegments.TopLeft) == WallSegments.TopLeft && !(myCuts.TLCut > 0 && comp.TopLeftDoor))
                            {
                                //draw top left and top right relative to this rotation
                                var tlPattern = GetPattern(comp.TopLeftPattern);

                                ushort styleID = 1;
                                ushort overlayID = 0;
                                bool down = false;

                                switch (myCuts.TLCut)
                                {
                                    case WallCut.Down:
                                        styleID = comp.TopLeftStyle;
                                        down = true; break;
                                    case WallCut.DownLeftUpRight:
                                        styleID = 7;
                                        overlayID = 252; break;
                                    case WallCut.DownRightUpLeft:
                                        styleID = 8;
                                        overlayID = 253; break;
                                    default:
                                        if (comp.TopLeftStyle != 1) styleID = comp.TopLeftStyle;
                                        else if (comp.ObjSetTLStyle != 0) styleID = comp.ObjSetTLStyle; //use custom style set by object if no cut
                                        else styleID = 1;
                                        break;
                                }

                                var tlStyle = GetStyle(styleID);

                                var _Sprite = GetWallSprite(tlPattern, tlStyle, 0, down, world);
                                if (_Sprite.Pixel != null)
                                {
                                    world._2D.Draw(_Sprite);

                                    //draw overlay if exists

                                    if (overlayID != 0) world._2D.Draw(GetWallSprite(GetPattern(overlayID), null, 0, down, world));

                                    var contOff = tilePosition + RotateOffset(world.Rotation, new Vector3(0, -1, 0));

                                    if (comp.TopLeftThick)
                                    {
                                        //check far side of wall for continuation. if there is none, round this part off
                                        if (!comp.TopRightThick && OffsetValid(contOff, blueprint))
                                        {
                                            var comp2 = RotateWall(world.Rotation, blueprint.GetWall((short)(contOff.X), (short)(contOff.Y), level), (short)(contOff.X), (short)(contOff.Y), level);
                                            if (!comp2.TopLeftThick)
                                            {
                                                _Sprite = CopySprite(world, _Sprite);
                                                tlStyle = GetStyle(comp.TopLeftStyle); //return to normal if cutaway
                                                var tilePosition2 = contOff;

                                                world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition2));
                                                world._2D.OffsetTile(tilePosition2);
                                                int newWidth = 0;
                                                bool downAtCont = canCut && WallsDownAt((short)(contOff.X), (short)(contOff.Y));

                                                SPR mask = null;
                                                switch (world.Zoom)
                                                {
                                                    case WorldZoom.Far:
                                                        newWidth = 3;
                                                        mask = downAtCont ? tlStyle.WallsDownFar : tlStyle.WallsUpFar;
                                                        break;
                                                    case WorldZoom.Medium:
                                                        newWidth = 6;
                                                        mask = downAtCont ? tlStyle.WallsDownMedium : tlStyle.WallsUpMedium;
                                                        break;
                                                    case WorldZoom.Near:
                                                        newWidth = 12;
                                                        mask = downAtCont ? tlStyle.WallsDownNear : tlStyle.WallsUpNear;
                                                        break;
                                                }
                                                if (mask != null) _Sprite.Mask = world._2D.GetTexture(mask.Frames[0]);
                                                if (x > 0 && (blueprint.GetWall((short)(x - 1), (short)(y - 1), level).Segments & WallSegments.VerticalDiag) == WallSegments.VerticalDiag) newWidth = (newWidth * 2) / 3;
                                                //if there is a diagonal behind the extension, make it a bit shorter.
                                                _Sprite.SrcRect.Width = newWidth;
                                                _Sprite.DestRect.Width = newWidth;
                                                world._2D.Draw(_Sprite);
                                            }
                                        }

                                        //check close side of wall for continuation
                                        contOff = tilePosition + RotateOffset(world.Rotation, new Vector3(0, 1, 0)); //so we can check the most things with the least impact
                                        var contOff2 = tilePosition + RotateOffset(world.Rotation, new Vector3(-1, 1, 0)); //last check, unfortunately required
                                        if (OffsetValid(contOff, blueprint) && OffsetValid(contOff2, blueprint))
                                        {
                                            var comp2 = RotateWall(world.Rotation, blueprint.GetWall((short)(contOff.X), (short)(contOff.Y), level), (short)(contOff.X), (short)(contOff.Y), level);
                                            if (!comp2.TopLeftThick && !comp2.TopRightThick)
                                            {
                                                var comp3 = RotateWall(world.Rotation, blueprint.GetWall((short)(contOff2.X), (short)(contOff2.Y), level), (short)(contOff2.X), (short)(contOff2.Y), level);
                                                if (!comp3.TopRightThick)
                                                {
                                                    _Sprite = GetWallSprite(tlPattern, tlStyle, 1, down, world);
                                                    var tilePosition2 = tilePosition + RotateOffset(world.Rotation, new Vector3(-1, 1, 0));
                                                    bool downAtCont = canCut && WallsDownAt((int)tilePosition.X, (int)tilePosition.Y) && styleID != 8;
                                                    tlStyle = GetStyle(comp.TopLeftStyle);

                                                    world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition2));
                                                    world._2D.OffsetTile(tilePosition2);
                                                    int newWidth = 0;

                                                    SPR mask = null;
                                                    switch (world.Zoom)
                                                    {
                                                        case WorldZoom.Far:
                                                            newWidth = 3;
                                                            mask = downAtCont ? tlStyle.WallsDownFar : tlStyle.WallsUpFar;
                                                            break;
                                                        case WorldZoom.Medium:
                                                            newWidth = 6;
                                                            mask = downAtCont ? tlStyle.WallsDownMedium : tlStyle.WallsUpMedium;
                                                            break;
                                                        case WorldZoom.Near:
                                                            newWidth = 12;
                                                            mask = downAtCont ? tlStyle.WallsDownNear : tlStyle.WallsUpNear;
                                                            break;
                                                    }
                                                    if (mask != null) _Sprite.Mask = world._2D.GetTexture(mask.Frames[1]);
                                                    _Sprite.SrcRect.X += _Sprite.SrcRect.Width - newWidth;
                                                    _Sprite.DestRect.X += _Sprite.DestRect.Width - newWidth;
                                                    _Sprite.SrcRect.Width = newWidth;
                                                    _Sprite.DestRect.Width = newWidth;
                                                    world._2D.Draw(_Sprite);
                                                }
                                            }
                                        }
                                        world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition));
                                        world._2D.OffsetTile(tilePosition);
                                    }
                                }
                            }
                            //top right

                            if ((comp.Segments & WallSegments.TopRight) == WallSegments.TopRight && !(myCuts.TRCut > 0 && comp.TopRightDoor))
                            {

                                var trPattern = GetPattern(comp.TopRightPattern);

                                ushort styleID = 1;
                                ushort overlayID = 0;
                                bool down = false;

                                switch (myCuts.TRCut)
                                {
                                    case WallCut.Down:
                                        styleID = comp.TopRightStyle;
                                        down = true; break;
                                    case WallCut.DownLeftUpRight:
                                        styleID = 7;
                                        overlayID = 252; break;
                                    case WallCut.DownRightUpLeft:
                                        styleID = 8;
                                        overlayID = 253; break;
                                    default:
                                        if (comp.TopRightStyle != 1) styleID = comp.TopRightStyle;
                                        else if (comp.ObjSetTRStyle != 0) styleID = comp.ObjSetTRStyle; //use custom style set by object if no cut
                                        else styleID = 1;
                                        break;
                                }

                                var trStyle = GetStyle(styleID);

                                var _Sprite = GetWallSprite(trPattern, trStyle, 1, down, world);
                                if (_Sprite.Pixel != null)
                                {
                                    world._2D.Draw(_Sprite);

                                    if (overlayID != 0) world._2D.Draw(GetWallSprite(GetPattern(overlayID), null, 1, down, world));
                                    var contOff = tilePosition + RotateOffset(world.Rotation, new Vector3(-1, 0, 0));
                                    if (comp.TopRightThick)
                                    {
                                        //check far side of wall for continuation. if there is none, round this part off
                                        if (!comp.TopLeftThick && OffsetValid(contOff, blueprint))
                                        {
                                            var comp2 = RotateWall(world.Rotation, blueprint.GetWall((short)(contOff.X), (short)(contOff.Y), level), (short)(contOff.X), (short)(contOff.Y), level);
                                            if (!comp2.TopRightThick)
                                            {
                                                _Sprite = CopySprite(world, _Sprite);
                                                trStyle = GetStyle(comp.TopRightStyle); //return to normal if cutaway

                                                var tilePosition2 = contOff;
                                                world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition2));
                                                world._2D.OffsetTile(tilePosition2);
                                                int newWidth = 0;
                                                bool downAtCont = canCut && WallsDownAt((short)(contOff.X), (short)(contOff.Y));

                                                SPR mask = null;
                                                switch (world.Zoom)
                                                {
                                                    case WorldZoom.Far:
                                                        newWidth = 3;
                                                        mask = downAtCont ? trStyle.WallsDownFar : trStyle.WallsUpFar;
                                                        break;
                                                    case WorldZoom.Medium:
                                                        newWidth = 6;
                                                        mask = downAtCont ? trStyle.WallsDownMedium : trStyle.WallsUpMedium;
                                                        break;
                                                    case WorldZoom.Near:
                                                        newWidth = 12;
                                                        mask = downAtCont ? trStyle.WallsDownNear : trStyle.WallsUpNear;
                                                        break;
                                                }
                                                if (mask != null) _Sprite.Mask = world._2D.GetTexture(mask.Frames[1]);
                                                if (y > 0 && (blueprint.GetWall((short)(x - 1), (short)(y - 1), level).Segments & WallSegments.VerticalDiag) == WallSegments.VerticalDiag) newWidth = (newWidth * 2) / 3;
                                                //if there is a diagonal behind the extension, make it a bit shorter.
                                                _Sprite.SrcRect.X += _Sprite.SrcRect.Width - newWidth;
                                                _Sprite.DestRect.X += _Sprite.DestRect.Width - newWidth;
                                                _Sprite.SrcRect.Width = newWidth;
                                                _Sprite.DestRect.Width = newWidth;
                                                world._2D.Draw(_Sprite);
                                            }
                                        }

                                        //check close side of wall for continuation
                                        contOff = tilePosition + RotateOffset(world.Rotation, new Vector3(1, 0, 0)); //so we can check the most things with the least impact
                                        var contOff2 = tilePosition + RotateOffset(world.Rotation, new Vector3(1, -1, 0)); //last check, unfortunately required
                                        if (OffsetValid(contOff, blueprint) && OffsetValid(contOff2, blueprint))
                                        {
                                            var comp2 = RotateWall(world.Rotation, blueprint.GetWall((short)(contOff.X), (short)(contOff.Y), level), (short)(contOff.X), (short)(contOff.Y), level);
                                            if (!comp2.TopLeftThick && !comp2.TopRightThick)
                                            {
                                                var comp3 = RotateWall(world.Rotation, blueprint.GetWall((short)(contOff2.X), (short)(contOff2.Y), level), (short)(contOff2.X), (short)(contOff2.Y), level);
                                                if (!comp3.TopLeftThick)
                                                {
                                                    _Sprite = GetWallSprite(trPattern, trStyle, 0, down, world);
                                                    var tilePosition2 = tilePosition + RotateOffset(world.Rotation, new Vector3(1, -1, 0));
                                                    bool downAtCont = canCut && WallsDownAt((int)tilePosition.X, (int)tilePosition.Y) && styleID != 8;
                                                    trStyle = GetStyle(comp.TopRightStyle);

                                                    world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition2));
                                                    world._2D.OffsetTile(tilePosition2);
                                                    int newWidth = 0;

                                                    SPR mask = null;
                                                    switch (world.Zoom)
                                                    {
                                                        case WorldZoom.Far:
                                                            newWidth = 3;
                                                            mask = downAtCont ? trStyle.WallsDownFar : trStyle.WallsUpFar;
                                                            break;
                                                        case WorldZoom.Medium:
                                                            newWidth = 6;
                                                            mask = downAtCont ? trStyle.WallsDownMedium : trStyle.WallsUpMedium;
                                                            break;
                                                        case WorldZoom.Near:
                                                            newWidth = 12;
                                                            mask = downAtCont ? trStyle.WallsDownNear : trStyle.WallsUpNear;
                                                            break;
                                                    }
                                                    if (mask != null) _Sprite.Mask = world._2D.GetTexture(mask.Frames[0]);
                                                    _Sprite.SrcRect.Width = newWidth;
                                                    _Sprite.DestRect.Width = newWidth;
                                                    world._2D.Draw(_Sprite);
                                                }
                                            }
                                        }
                                        world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition));
                                        world._2D.OffsetTile(tilePosition);
                                    }
                                }
                            }

                            //horizontal diag

                            if (comp.Segments == WallSegments.HorizontalDiag)
                            {

                                var trPattern = GetPattern(comp.BottomRightPattern); //bottom left is facing other way.

                                ushort styleID = 1;
                                ushort overlayID = 0;
                                bool down = false;

                                switch (myCuts.TRCut)
                                {
                                    case WallCut.Down:
                                        styleID = comp.TopRightStyle;
                                        down = true; break;
                                    case WallCut.DownLeftUpRight:
                                        styleID = 7;
                                        overlayID = 252; break;
                                    case WallCut.DownRightUpLeft:
                                        styleID = 8;
                                        overlayID = 253; break;
                                    default:
                                        if (comp.TopRightStyle != 1) styleID = comp.TopRightStyle;
                                        else if (comp.ObjSetTRStyle != 0) styleID = comp.ObjSetTRStyle; //use custom style set by object if no cut
                                        else styleID = 1;
                                        break;
                                }

                                var trStyle = GetStyle(styleID);

                                int roomSide = 16-((((int)world.Rotation+1)/2)%2) * 16;
                                var _Sprite = GetWallSprite(trPattern, trStyle, 2, down, world);

                                _Sprite.Room = (ushort)(TileRoom>>roomSide);
                                if (_Sprite.Pixel != null)
                                {
                                    world._2D.Draw(_Sprite);

                                    if (overlayID != 0) world._2D.Draw(GetWallSprite(GetPattern(overlayID), null, 2, down, world));

                                    //draw diagonally cut floors
                                    if (comp.TopLeftPattern != 0)
                                    {
                                        var floor = GetFloorSprite(floorContent.Get(comp.TopLeftPattern), 0, world, 3);
                                        floor.Room = (ushort)(TileRoom >> roomSide);
                                        if (floor.Pixel != null) world._2D.Draw(floor);
                                    }
                                    if (comp.TopLeftStyle != 0)
                                    {
                                        var floor = GetFloorSprite(floorContent.Get(comp.TopLeftStyle), 0, world, 2);
                                        floor.Room = (ushort)(TileRoom >> (16-roomSide));
                                        if (floor.Pixel != null) world._2D.Draw(floor);
                                    }
                                }
                            }

                            if (comp.Segments == WallSegments.VerticalDiag)
                            {

                                var trPattern = GetPattern(comp.BottomRightPattern); //choose right one here, not sure which is chosen in real game

                                ushort styleID = 1;
                                ushort overlayID = 0;
                                bool down = false;

                                switch (myCuts.TRCut)
                                {
                                    case WallCut.Down:
                                        styleID = comp.TopRightStyle;
                                        down = true; break;
                                    case WallCut.DownLeftUpRight:
                                        styleID = 7;
                                        overlayID = 252; break;
                                    case WallCut.DownRightUpLeft:
                                        styleID = 8;
                                        overlayID = 253; break;
                                    default:
                                        if (comp.TopRightStyle != 1) styleID = comp.TopRightStyle;
                                        else if (comp.ObjSetTRStyle != 0) styleID = comp.ObjSetTRStyle; //use custom style set by object if no cut
                                        else styleID = 1;
                                        break;
                                }

                                var trStyle = GetStyle(styleID);

                                int roomSide = ((int)world.Rotation / 2) * 16;
                                var _Sprite = GetWallSprite(trPattern, trStyle, 3, down, world);
                                _Sprite.Room = (ushort)(TileRoom>>roomSide);
                                if (_Sprite.Pixel != null)
                                {
                                    world._2D.Draw(_Sprite);

                                    if (overlayID != 0) world._2D.Draw(GetWallSprite(GetPattern(overlayID), null, 3, down, world));

                                    //draw diagonally cut floors
                                    if (comp.TopLeftPattern != 0)
                                    {
                                        var floor = GetFloorSprite(floorContent.Get(comp.TopLeftPattern), 0, world, 1);
                                        floor.Room = (ushort)(TileRoom >> roomSide);
                                        if (floor.Pixel != null) world._2D.Draw(floor);
                                    }
                                    if (comp.TopLeftStyle != 0)
                                    {
                                        var floor = GetFloorSprite(floorContent.Get(comp.TopLeftStyle), 0, world, 0);
                                        floor.Room = (ushort)(TileRoom >> (16-roomSide));
                                        if (floor.Pixel != null) world._2D.Draw(floor);
                                    }
                                }
                            }
                        }

                        //draw junctions (part of this iteration to simplify things)

                        JunctionFlags flags;

                        float yOff;
                        if (UpJunctions[off] == 0)
                        {
                            flags = DownJunctions[off];
                            yOff = 0.3f + (level - 1) * 2.95f; ;
                        }
                        else
                        {
                            flags = UpJunctions[off];
                            yOff = level * 2.95f;
                        }

                        if (flags > 0 && JunctionMap.ContainsKey(flags)) //there is a junction here! if the junction map contains the unrotated junction, it will contain the rotated junction.
                        {
                            flags = RotateJunction(world.Rotation, flags);
                            var tilePosition = new Vector3(x - 0.5f, y - 0.5f, yOff); //2.95 for walls up, 0.3 for walls down
                            world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition));
                            world._2D.OffsetTile(tilePosition);

                            var _Sprite = world._2D.NewSprite(_2DBatchRenderMode.Z_BUFFER);

                            var Junctions = wallContent.Junctions;

                            SPR sprite = null;
                            switch (world.Zoom)
                            {
                                case WorldZoom.Far:
                                    sprite = Junctions.Far;
                                    _Sprite.DestRect = JUNCDEST_FAR;
                                    _Sprite.Depth = WallZBuffers[20];
                                    break;
                                case WorldZoom.Medium:
                                    sprite = Junctions.Medium;
                                    _Sprite.DestRect = JUNCDEST_MED;
                                    _Sprite.Depth = WallZBuffers[19];
                                    break;
                                case WorldZoom.Near:
                                    sprite = Junctions.Near;
                                    _Sprite.DestRect = JUNCDEST_NEAR;
                                    _Sprite.Depth = WallZBuffers[18];
                                    break;
                            }
                            _Sprite.Pixel = world._2D.GetTexture(sprite.Frames[JunctionMap[flags]]);
                            _Sprite.SrcRect = new Microsoft.Xna.Framework.Rectangle(0, 0, _Sprite.Pixel.Width, _Sprite.Pixel.Height);
                            _Sprite.Room = 1;
                            world._2D.Draw(_Sprite);
                        }

                        off++;
                    }
                }
            }
            timer.Stop();
            //System.Diagnostics.Debug.WriteLine("Drawing walls took " + timer.ElapsedMilliseconds.ToString() + " ms");
        }