/// <summary>
        /// Renders the map using current settings and editing stuff.
        /// </summary>
        public void RenderTo(Graphics g, bool ToImage = false)
        {
            PointF nwCorner, neCorner, seCorner, swCorner, center;
            bool   DrawTextured  = EditorSettings.Default.Edit_PreviewMode;
            bool   DrawExtents3D = EditorSettings.Default.Draw_Extents_3D;
            bool   DrawText      = EditorSettings.Default.Draw_AllText;

            // enable transparency only in textured preview mode
            if (DrawTextured)
            {
                g.CompositingMode = CompositingMode.SourceOver;
            }
            else
            {
                g.CompositingMode = CompositingMode.SourceCopy;
            }
            // optimizations
            g.CompositingQuality = CompositingQuality.HighSpeed;
            g.PixelOffsetMode    = PixelOffsetMode.HighSpeed;
            g.InterpolationMode  = InterpolationMode.Low;
            g.SmoothingMode      = SmoothingMode.HighSpeed;
            proDefault           = (!mapView.picking && mapView.mapPanel.Cursor != Cursors.SizeAll && Form.ActiveForm == MainWindow.Instance);
            proHand = (!mapView.picking && !MapInterface.KeyHelper.ShiftKey && MapInterface.SelectedObjects.Items.Count > 1 && !mapView.contextMenuOpen);
            // expand clip rectangle a bit
            const int sqSize2 = squareSize * 2;

            Rectangle clip = new Rectangle((int)g.ClipBounds.X - sqSize2, (int)g.ClipBounds.Y - sqSize2, (int)g.ClipBounds.Width + sqSize2, (int)g.ClipBounds.Height + sqSize2);

            if (ToImage)
            {
                clip             = new Rectangle(0, 0, 5880, 5880);
                updCanvasObjects = true;
                updCanvasTiles   = true;
            }
            if (updCanvasObjects)
            {
                objectRenderer.UpdateCanvas(clip);
                updCanvasObjects = false;
            }
            if (updCanvasTiles)
            {
                floorRenderer.UpdateCanvas(clip);
                updCanvasTiles = false;
            }
            // Paint it black
            Size size = mapView.mapPanel.Size;

            g.Clear(ColorLayout.Background);
            Point mouseLocation = mapView.mouseLocation;
            Pen   pen;

            // Draw tiles and edges
            if (MapInterface.CurrentMode == EditMode.FLOOR_PLACE || EditorSettings.Default.Draw_FloorTiles || MapInterface.CurrentMode == EditMode.EDGE_PLACE)
            {
                floorRenderer.Render(g);
            }

            // Draw grid
            if (EditorSettings.Default.Draw_Grid)
            {
                using (pen = new Pen(Color.Gray, 1F))
                {
                    //draw the grid sloppily (an extra screen's worth of lines along either axis)
                    for (int x = -squareSize * (size.Width / squareSize) - 3 * squareSize / 2 % (2 * squareSize); x < 2 * size.Width; x += 2 * squareSize)
                    {
                        int y = -3 * squareSize / 2 % (2 * squareSize);
                        g.DrawLine(pen, new Point(x - 1, y), new Point(y, x - 1));
                        g.DrawLine(pen, new Point(x, y), new Point(size.Width + x, size.Width + y));
                    }
                }
            }

            if (MapInterface.CurrentMode >= EditMode.FLOOR_PLACE && MapInterface.CurrentMode <= EditMode.EDGE_PLACE)
            {
                // Draw the overlay to show tile location
                Point  pt          = new Point(mouseLocation.X, mouseLocation.Y);
                PointF tilePt      = (PointF)MapView.GetNearestTilePoint(pt);
                int    squareSize2 = squareSize;

                int bs = (int)MainWindow.Instance.mapView.TileMakeNewCtrl.BrushSize.Value;

                if ((MapInterface.CurrentMode == EditMode.FLOOR_BRUSH || MapInterface.CurrentMode == EditMode.FLOOR_PLACE) && !mapView.picking)
                {
                    squareSize2 *= bs;
                    if (bs > 1)
                    {
                        tilePt.X -= (float)(-0.5 + 0.5 * bs);
                        tilePt.Y -= (float)(1.5 + 0.5 * bs);
                        //tilePt.Y -= 1;
                        tilePt.Y -= ((bs - 1) + ((bs % 2 == 0) ? 1 : 0));
                        tilePt.Y += 2;
                    }
                }

                // Change overlay color depending on editor EditMode
                Color tileOverlayCol = Color.Yellow;
                if (MapInterface.CurrentMode == EditMode.EDGE_PLACE)
                {
                    tileOverlayCol = MainWindow.Instance.mapView.EdgeMakeNewCtrl.AutoEgeBox.Checked ? Color.Green : Color.Aqua;
                }
                if (MapInterface.CurrentMode == EditMode.FLOOR_BRUSH)
                {
                    tileOverlayCol = Color.LawnGreen;
                }

                if (mapView.picking)
                {
                    tileOverlayCol = Color.GhostWhite;
                }

                tilePt.X *= squareSize;
                tilePt.Y *= squareSize;

                center   = new PointF(tilePt.X + squareSize / 2f, tilePt.Y + (3 / 2f) * squareSize);
                nwCorner = new PointF(tilePt.X - squareSize2 / 2f, tilePt.Y + (3 / 2f) * squareSize2);
                neCorner = new PointF(nwCorner.X + squareSize2, nwCorner.Y - squareSize2);
                swCorner = new PointF(nwCorner.X + squareSize2, nwCorner.Y + squareSize2);
                seCorner = new PointF(neCorner.X + squareSize2, neCorner.Y + squareSize2);

                g.DrawPolygon(new Pen(tileOverlayCol, 2), new PointF[] { nwCorner, neCorner, seCorner, swCorner });
            }

            Pen destructablePen = new Pen(ColorLayout.WallsBreakable, 2);
            Pen windowPen       = new Pen(ColorLayout.WallsWindowed, 2);
            Pen secretPen       = new Pen(ColorLayout.WallsSecret, 2);
            Pen invisiblePen    = new Pen(Color.DarkGray, 2);
            Pen FakeWallPen     = new Pen(Color.LightGray, 2);
            Pen OpenPen         = new Pen(Color.FromArgb(255, 110, 170, 110), 2);
            Pen wallPen         = new Pen(ColorLayout.Walls, 2);

            // Draw [BELOW] objects
            objectRenderer.RenderBelow(g);

            // Draw walls
            if (EditorSettings.Default.Draw_Walls)
            {
                Map.Wall removing = mapView.GetWallUnderCursor();

                Point highlightUndoRedo = mapView.highlightUndoRedo;



                if (MapInterface.CurrentMode == EditMode.WALL_BRUSH && !mapView.picking)
                {
                    removing = null;
                }


                if (FakeWalls.Count > 0 && !EditorSettings.Default.Edit_PreviewMode)
                {
                    foreach (Map.Wall wall in FakeWalls.Values)
                    {
                        Point pt = wall.Location;
                        int   x = pt.X * squareSize, y = pt.Y * squareSize;
                        Point txtPoint = new Point(x, y);
                        pen    = invisiblePen;
                        center = new PointF(x + squareSize / 2f, y + squareSize / 2f);
                        Point nCorner = new Point(x, y);
                        Point sCorner = new Point(x + squareSize, y + squareSize);
                        Point wCorner = new Point(x + squareSize, y);
                        Point eCorner = new Point(x, y + squareSize);

                        Point  nCornerUp = new Point(x, y - 40);
                        Point  sCornerUp = new Point(x + squareSize, y + squareSize - 40);
                        Point  wCornerUp = new Point(x + squareSize, y - 40);
                        Point  eCornerUp = new Point(x, y + squareSize - 40);
                        PointF centerUp  = new PointF(x + squareSize / 2f, (y + squareSize / 2f) - 40);

                        switch (wall.Facing)
                        {
                        case Map.Wall.WallFacing.NORTH:
                            g.DrawLine(pen, wCorner, eCorner);
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, wCornerUp, eCornerUp);

                            g.DrawLine(pen, wCornerUp, wCorner);
                            g.DrawLine(pen, eCornerUp, eCorner);

                            break;

                        case Map.Wall.WallFacing.WEST:
                            g.DrawLine(pen, nCorner, sCorner);
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, nCornerUp, sCornerUp);

                            g.DrawLine(pen, nCorner, nCornerUp);
                            g.DrawLine(pen, sCorner, sCornerUp);
                            break;

                        case Map.Wall.WallFacing.CROSS:
                            g.DrawLine(pen, wCorner, eCorner);    //north wall
                            g.DrawLine(pen, nCorner, sCorner);    //south wall
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, wCornerUp, eCornerUp);    //north wall
                            g.DrawLine(pen, nCornerUp, sCornerUp);    //south wall

                            g.DrawLine(pen, wCorner, wCornerUp);
                            g.DrawLine(pen, nCorner, nCornerUp);
                            g.DrawLine(pen, sCorner, sCornerUp);
                            g.DrawLine(pen, eCorner, eCornerUp);

                            break;

                        case Map.Wall.WallFacing.NORTH_T:
                            g.DrawLine(pen, wCorner, eCorner);   //north wall
                            g.DrawLine(pen, center, sCorner);    //tail towards south
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, wCornerUp, eCornerUp);   //north wall
                            g.DrawLine(pen, centerUp, sCornerUp);    //tail towards south

                            g.DrawLine(pen, wCorner, wCornerUp);
                            g.DrawLine(pen, eCorner, eCornerUp);
                            g.DrawLine(pen, sCorner, sCornerUp);
                            g.DrawLine(pen, center, centerUp);

                            break;

                        case Map.Wall.WallFacing.SOUTH_T:
                            g.DrawLine(pen, wCorner, eCorner);   //north wall
                            g.DrawLine(pen, center, nCorner);    //tail towards north
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, wCornerUp, eCornerUp);   //north wall
                            g.DrawLine(pen, centerUp, nCornerUp);    //tail towards south

                            g.DrawLine(pen, wCorner, wCornerUp);
                            g.DrawLine(pen, eCorner, eCornerUp);
                            g.DrawLine(pen, nCorner, nCornerUp);
                            g.DrawLine(pen, center, centerUp);
                            break;

                        case Map.Wall.WallFacing.WEST_T:
                            g.DrawLine(pen, nCorner, sCorner);   //west wall
                            g.DrawLine(pen, center, eCorner);    //tail towards east
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, nCornerUp, sCornerUp);   //north wall
                            g.DrawLine(pen, centerUp, eCornerUp);    //tail towards south

                            g.DrawLine(pen, nCorner, nCornerUp);
                            g.DrawLine(pen, sCorner, sCornerUp);
                            g.DrawLine(pen, eCorner, eCornerUp);
                            g.DrawLine(pen, center, centerUp);
                            break;

                        case Map.Wall.WallFacing.EAST_T:
                            g.DrawLine(pen, nCorner, sCorner);   //west wall
                            g.DrawLine(pen, center, wCorner);    //tail towards west
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, nCornerUp, sCornerUp);   //north wall
                            g.DrawLine(pen, centerUp, wCornerUp);    //tail towards south

                            g.DrawLine(pen, wCorner, wCornerUp);
                            g.DrawLine(pen, nCorner, nCornerUp);
                            g.DrawLine(pen, sCorner, sCornerUp);
                            g.DrawLine(pen, center, centerUp);
                            break;

                        case Map.Wall.WallFacing.NE_CORNER:
                            g.DrawLine(pen, center, eCorner);
                            g.DrawLine(pen, center, sCorner);
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, centerUp, eCornerUp);
                            g.DrawLine(pen, centerUp, sCornerUp);

                            g.DrawLine(pen, centerUp, center);
                            g.DrawLine(pen, eCornerUp, eCorner);
                            g.DrawLine(pen, sCornerUp, sCorner);
                            break;

                        case Map.Wall.WallFacing.NW_CORNER:
                            g.DrawLine(pen, center, wCorner);
                            g.DrawLine(pen, center, sCorner);
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, centerUp, wCornerUp);
                            g.DrawLine(pen, centerUp, sCornerUp);

                            g.DrawLine(pen, centerUp, center);
                            g.DrawLine(pen, wCornerUp, wCorner);
                            g.DrawLine(pen, sCornerUp, sCorner);
                            break;

                        case Map.Wall.WallFacing.SW_CORNER:
                            g.DrawLine(pen, center, nCorner);
                            g.DrawLine(pen, center, wCorner);
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, centerUp, nCornerUp);
                            g.DrawLine(pen, centerUp, wCornerUp);

                            g.DrawLine(pen, centerUp, center);
                            g.DrawLine(pen, wCornerUp, wCorner);
                            g.DrawLine(pen, nCornerUp, nCorner);
                            break;

                        case Map.Wall.WallFacing.SE_CORNER:
                            g.DrawLine(pen, center, nCorner);
                            g.DrawLine(pen, center, eCorner);

                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, centerUp, nCornerUp);
                            g.DrawLine(pen, centerUp, eCornerUp);

                            g.DrawLine(pen, centerUp, center);
                            g.DrawLine(pen, eCornerUp, eCorner);
                            g.DrawLine(pen, nCornerUp, nCorner);
                            break;

                        default:
                            g.DrawRectangle(pen, x, y, squareSize, squareSize);
                            if (DrawText)
                            {
                                TextRenderer.DrawText(g, "?", drawFont, nCorner, Color.Red);
                            }
                            break;
                        }
                    }
                }

                foreach (Map.Wall wall in Map.Walls.Values)
                {
                    Point pt = wall.Location;
                    int   x = pt.X * squareSize, y = pt.Y * squareSize;
                    Point txtPoint = new Point(x, y);
                    if (clip.Contains(x, y))
                    {
                        if (DrawTextured && !wall.Material.Contains("Invisible"))
                        {
                            //DrawTexturedWall(g, wall, false, removing == wall);
                            continue;
                        }

                        continue;

                        //TODO: how to draw if a destructable window? is this even possible?

                        if (wall.Secret)
                        {
                            pen = wall.Secret_WallState == 4 ? OpenPen : secretPen;
                        }
                        else if (wall.Destructable)//if (wall.Destructable || MapInterface.GetLastWalls(wall))
                        {
                            pen = destructablePen;
                        }
                        else if (wall.Window)
                        {
                            pen = windowPen;
                        }
                        else if (wall.Material.Contains("Invisible"))
                        {
                            pen = invisiblePen;
                        }
                        else
                        {
                            pen = wallPen;
                        }

                        if (removing == wall)
                        {
                            if (mapView.picking)
                            {
                                pen = new Pen(Color.Aqua, 3);
                            }
                            else if (MapInterface.CurrentMode == EditMode.WALL_CHANGE)
                            {
                                pen = new Pen(Color.Purple, 3);
                            }
                        }
                        center = new PointF(x + squareSize / 2f, y + squareSize / 2f);
                        Point nCorner = new Point(x, y);
                        Point sCorner = new Point(x + squareSize, y + squareSize);
                        Point wCorner = new Point(x + squareSize, y);
                        Point eCorner = new Point(x, y + squareSize);

                        Point  nCornerUp = new Point(x, y - 40);
                        Point  sCornerUp = new Point(x + squareSize, y + squareSize - 40);
                        Point  wCornerUp = new Point(x + squareSize, y - 40);
                        Point  eCornerUp = new Point(x, y + squareSize - 40);
                        PointF centerUp  = new PointF(x + squareSize / 2f, (y + squareSize / 2f) - 40);

                        switch (wall.Facing)
                        {
                        case Map.Wall.WallFacing.NORTH:
                            g.DrawLine(pen, wCorner, eCorner);
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, wCornerUp, eCornerUp);

                            g.DrawLine(pen, wCornerUp, wCorner);
                            g.DrawLine(pen, eCornerUp, eCorner);

                            break;

                        case Map.Wall.WallFacing.WEST:
                            g.DrawLine(pen, nCorner, sCorner);
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, nCornerUp, sCornerUp);

                            g.DrawLine(pen, nCorner, nCornerUp);
                            g.DrawLine(pen, sCorner, sCornerUp);
                            break;

                        case Map.Wall.WallFacing.CROSS:
                            g.DrawLine(pen, wCorner, eCorner);    //north wall
                            g.DrawLine(pen, nCorner, sCorner);    //south wall
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, wCornerUp, eCornerUp);    //north wall
                            g.DrawLine(pen, nCornerUp, sCornerUp);    //south wall

                            g.DrawLine(pen, wCorner, wCornerUp);
                            g.DrawLine(pen, nCorner, nCornerUp);
                            g.DrawLine(pen, sCorner, sCornerUp);
                            g.DrawLine(pen, eCorner, eCornerUp);

                            break;

                        case Map.Wall.WallFacing.NORTH_T:
                            g.DrawLine(pen, wCorner, eCorner);   //north wall
                            g.DrawLine(pen, center, sCorner);    //tail towards south
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, wCornerUp, eCornerUp);   //north wall
                            g.DrawLine(pen, centerUp, sCornerUp);    //tail towards south

                            g.DrawLine(pen, wCorner, wCornerUp);
                            g.DrawLine(pen, eCorner, eCornerUp);
                            g.DrawLine(pen, sCorner, sCornerUp);
                            g.DrawLine(pen, center, centerUp);

                            break;

                        case Map.Wall.WallFacing.SOUTH_T:
                            g.DrawLine(pen, wCorner, eCorner);   //north wall
                            g.DrawLine(pen, center, nCorner);    //tail towards north
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, wCornerUp, eCornerUp);   //north wall
                            g.DrawLine(pen, centerUp, nCornerUp);    //tail towards south

                            g.DrawLine(pen, wCorner, wCornerUp);
                            g.DrawLine(pen, eCorner, eCornerUp);
                            g.DrawLine(pen, nCorner, nCornerUp);
                            g.DrawLine(pen, center, centerUp);
                            break;

                        case Map.Wall.WallFacing.WEST_T:
                            g.DrawLine(pen, nCorner, sCorner);   //west wall
                            g.DrawLine(pen, center, eCorner);    //tail towards east
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, nCornerUp, sCornerUp);   //north wall
                            g.DrawLine(pen, centerUp, eCornerUp);    //tail towards south

                            g.DrawLine(pen, nCorner, nCornerUp);
                            g.DrawLine(pen, sCorner, sCornerUp);
                            g.DrawLine(pen, eCorner, eCornerUp);
                            g.DrawLine(pen, center, centerUp);
                            break;

                        case Map.Wall.WallFacing.EAST_T:
                            g.DrawLine(pen, nCorner, sCorner);   //west wall
                            g.DrawLine(pen, center, wCorner);    //tail towards west
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, nCornerUp, sCornerUp);   //north wall
                            g.DrawLine(pen, centerUp, wCornerUp);    //tail towards south

                            g.DrawLine(pen, wCorner, wCornerUp);
                            g.DrawLine(pen, nCorner, nCornerUp);
                            g.DrawLine(pen, sCorner, sCornerUp);
                            g.DrawLine(pen, center, centerUp);
                            break;

                        case Map.Wall.WallFacing.NE_CORNER:
                            g.DrawLine(pen, center, eCorner);
                            g.DrawLine(pen, center, sCorner);
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, centerUp, eCornerUp);
                            g.DrawLine(pen, centerUp, sCornerUp);

                            g.DrawLine(pen, centerUp, center);
                            g.DrawLine(pen, eCornerUp, eCorner);
                            g.DrawLine(pen, sCornerUp, sCorner);
                            break;

                        case Map.Wall.WallFacing.NW_CORNER:
                            g.DrawLine(pen, center, wCorner);
                            g.DrawLine(pen, center, sCorner);
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, centerUp, wCornerUp);
                            g.DrawLine(pen, centerUp, sCornerUp);

                            g.DrawLine(pen, centerUp, center);
                            g.DrawLine(pen, wCornerUp, wCorner);
                            g.DrawLine(pen, sCornerUp, sCorner);
                            break;

                        case Map.Wall.WallFacing.SW_CORNER:
                            g.DrawLine(pen, center, nCorner);
                            g.DrawLine(pen, center, wCorner);
                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, centerUp, nCornerUp);
                            g.DrawLine(pen, centerUp, wCornerUp);

                            g.DrawLine(pen, centerUp, center);
                            g.DrawLine(pen, wCornerUp, wCorner);
                            g.DrawLine(pen, nCornerUp, nCorner);
                            break;

                        case Map.Wall.WallFacing.SE_CORNER:
                            g.DrawLine(pen, center, nCorner);
                            g.DrawLine(pen, center, eCorner);

                            if (!DrawExtents3D)
                            {
                                break;
                            }
                            g.DrawLine(pen, centerUp, nCornerUp);
                            g.DrawLine(pen, centerUp, eCornerUp);

                            g.DrawLine(pen, centerUp, center);
                            g.DrawLine(pen, eCornerUp, eCorner);
                            g.DrawLine(pen, nCornerUp, nCorner);
                            break;

                        default:
                            g.DrawRectangle(pen, x, y, squareSize, squareSize);
                            if (DrawText)
                            {
                                TextRenderer.DrawText(g, "?", drawFont, nCorner, Color.Red);
                            }
                            break;
                        }
                        if (DrawText)
                        {
                            TextRenderer.DrawText(g, wall.Minimap.ToString(), drawFont, txtPoint, Color.Red);
                        }
                    }
                }
            }

            RenderPostLineWalls(g);

            RenderPostWalls(g);
            RenderPostObjects(g);
            RenderPostSelRect(g);

            // Draw objects
            objectRenderer.RenderNormal(g);
            RenderHelpMark(g);
            // Draw polygons
            if (EditorSettings.Default.Draw_Polygons)
            {
                foreach (Map.Polygon poly in Map.Polygons)
                {
                    pen = Pens.PaleGreen;
                    // Highlight the polygon being edited
                    if (MapInterface.CurrentMode == EditMode.POLYGON_RESHAPE)
                    {
                        if (mapView.PolygonEditDlg.SelectedPolygon == poly || mapView.PolygonEditDlg.SuperPolygon == poly)
                        {
                            pen = Pens.PaleVioletRed;

                            foreach (PointF pt in poly.Points)
                            {
                                center = new PointF(pt.X - MapView.objectSelectionRadius, pt.Y - MapView.objectSelectionRadius);
                                Pen pen2 = MapInterface.SelectedPolyPoint == pt ? Pens.DodgerBlue : Pens.DeepPink;
                                g.DrawEllipse(pen2, new RectangleF(center, new Size(2 * MapView.objectSelectionRadius, 2 * MapView.objectSelectionRadius)));
                            }
                        }
                    }
                    if (poly.Points.Count > 2)
                    {
                        poly.Points.Add(poly.Points[0]);

                        if (MainWindow.Instance.mapView.PolygonEditDlg.ambientColors.Checked)
                        {
                            int        alphaa      = ((poly.AmbientLightColor.R + poly.AmbientLightColor.R + poly.AmbientLightColor.B + poly.AmbientLightColor.B + poly.AmbientLightColor.G + poly.AmbientLightColor.G) / 6);
                            FillMode   newFillMode = FillMode.Alternate;
                            Color      newColor    = Color.FromArgb(Math.Abs(255 - alphaa), poly.AmbientLightColor);
                            SolidBrush blueBrush   = new SolidBrush(newColor);
                            g.DrawPolygon(pen, poly.Points.ToArray());
                            g.FillPolygon(blueBrush, poly.Points.ToArray(), newFillMode);
                        }

                        if (mapView.PolygonEditDlg.SuperPolygon == poly && MapInterface.CurrentMode == EditMode.POLYGON_RESHAPE)
                        {
                            pen = new Pen(Color.PaleVioletRed, 2);
                        }
                        g.DrawLines(pen, poly.Points.ToArray());
                        poly.Points.RemoveAt(poly.Points.Count - 1);
                    }
                }
            }

            // Draw waypoints
            if (EditorSettings.Default.Draw_Waypoints)
            {
                foreach (Map.Waypoint wp in Map.Waypoints)
                {
                    // highlight selected waypoint
                    pen = wp.Flags == 1 ? ColorLayout.WaypointNorm : ColorLayout.WaypointDis;
                    pen = MapInterface.SelectedWaypoint == wp ? ColorLayout.WaypointSel : pen;
                    // draw waypoint and related pathes
                    center = new PointF(wp.Point.X - MapView.objectSelectionRadius, wp.Point.Y - MapView.objectSelectionRadius);
                    g.DrawEllipse(pen, new RectangleF(center, new Size(2 * MapView.objectSelectionRadius, 2 * MapView.objectSelectionRadius)));
                    pen = ColorLayout.WaypointDis;
                    // Draw paths (code/idea from UndeadZeus)
                    foreach (Map.Waypoint.WaypointConnection wpc in wp.connections)
                    {
                        g.DrawLine(pen, wp.Point.X, wp.Point.Y, wpc.wp.Point.X, wpc.wp.Point.Y);
                        foreach (Map.Waypoint.WaypointConnection wpwp in wpc.wp.connections)//Checks if the waypoint connection is connecting to wp
                        {
                            if (wpwp.wp.Equals(wp))
                            {
                                // if there is two way connection

                                /*
                                 * if (MapInterface.SelectedWaypoint != wp) pen = ColorLayout.WaypointTwoPath;
                                 * g.DrawLine(pen, wp.Point.X, wp.Point.Y, wpc.wp.Point.X, wpc.wp.Point.Y);
                                 * break;
                                 */

                                if (MapInterface.SelectedWaypoint != null && wp == MapInterface.SelectedWaypoint)
                                {
                                    g.DrawLine(ColorLayout.WaypointSel, wp.Point.X, wp.Point.Y, wpc.wp.Point.X, wpc.wp.Point.Y);
                                }
                                else
                                {
                                    g.DrawLine(ColorLayout.WaypointTwoPath, wp.Point.X, wp.Point.Y, wpc.wp.Point.X, wpc.wp.Point.Y);
                                }
                                break;
                            }
                        }
                    }
                    Point wayPoint = new Point(Convert.ToInt32(center.X), Convert.ToInt32(center.Y));
                    // text rendering is slow - as such don't label unseen waypoints
                    if (DrawText && clip.Contains(wayPoint))
                    {
                        if (wp.Name.Length > 0)
                        {
                            TextRenderer.DrawText(g, wp.Number + ":" + wp.ShortName, drawFont, wayPoint, Color.YellowGreen);
                        }
                        else
                        {
                            TextRenderer.DrawText(g, wp.Number + "", drawFont, wayPoint, Color.MediumPurple);
                        }
                    }
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Renders the map using current settings and editing stuff.
        /// </summary>
        public void RenderTo(Graphics g, bool ToImage = false)
        {
            PointF nwCorner, neCorner, seCorner, swCorner, center;
            bool   DrawTextured  = EditorSettings.Default.Edit_PreviewMode;
            bool   DrawExtents3D = EditorSettings.Default.Draw_Extents_3D;
            bool   DrawText      = EditorSettings.Default.Draw_AllText;

            // optimizations
            g.CompositingQuality = CompositingQuality.HighSpeed;
            g.PixelOffsetMode    = PixelOffsetMode.HighSpeed;
            g.InterpolationMode  = InterpolationMode.Low;
            g.SmoothingMode      = SmoothingMode.HighSpeed;

            proDefault = (!mapView.copyAreaMode && !mapView.pasteAreaMode &&
                          !mapView.wallBucket && !mapView.tileBucket && !mapView.picking &&
                          mapView.mapPanel.Cursor != Cursors.SizeAll && Form.ActiveForm == MainWindow.Instance);
            proHand = (!mapView.picking && !MapInterface.KeyHelper.ShiftKey &&
                       MapInterface.SelectedObjects.Items.Count > 1 && !mapView.contextMenuOpen);

            // expand clip rectangle a bit
            const int sqSize2 = squareSize * 2;

            Rectangle clip = new Rectangle((int)g.ClipBounds.X - sqSize2, (int)g.ClipBounds.Y - sqSize2, (int)g.ClipBounds.Width + sqSize2, (int)g.ClipBounds.Height + sqSize2);

            if (ToImage)
            {
                clip             = new Rectangle(0, 0, 5880, 5880);
                updCanvasObjects = true;
                updCanvasTiles   = true;
            }
            if (updCanvasObjects)
            {
                objectRenderer.UpdateCanvas(clip);
                updCanvasObjects = false;
            }
            if (teleCtrl)
            {
                objectRenderer.UpdateTele();
                teleCtrl = false;
            }
            if (updCanvasTiles)
            {
                floorRenderer.UpdateCanvas(clip);
                if (mapView.pasteAreaMode)
                {
                    floorRenderer.UpdateCanvasWithFakeTiles(clip);
                }

                updCanvasTiles = false;
            }
            // Paint it black
            Size size = mapView.mapPanel.Size;

            g.Clear(ColorLayout.Background);
            Point mouseLocation = mapView.mouseLocation;
            Pen   pen;

            // Draw tiles and edges
            if (MapInterface.CurrentMode == EditMode.FLOOR_PLACE || EditorSettings.Default.Draw_FloorTiles || MapInterface.CurrentMode == EditMode.EDGE_PLACE)
            {
                floorRenderer.Render(g);
            }

            // Draw grid
            if (EditorSettings.Default.Draw_Grid)
            {
                using (pen = new Pen(Color.Gray, 1F))
                {
                    //draw the grid sloppily (an extra screen's worth of lines along either axis)
                    for (int x = -squareSize * (size.Width / squareSize) - 3 * squareSize / 2 % (2 * squareSize); x < 2 * size.Width; x += 2 * squareSize)
                    {
                        int y = -3 * squareSize / 2 % (2 * squareSize);
                        g.DrawLine(pen, new Point(x - 1, y), new Point(y, x - 1));
                        g.DrawLine(pen, new Point(x, y), new Point(size.Width + x, size.Width + y));
                    }
                }
            }

            if (MapInterface.CurrentMode >= EditMode.FLOOR_PLACE && MapInterface.CurrentMode <= EditMode.EDGE_PLACE && !MainWindow.Instance.imgMode)
            {
                // Draw the overlay to show tile location
                Point  pt          = new Point(mouseLocation.X, mouseLocation.Y);
                PointF tilePt      = MapView.GetNearestTilePoint(pt);
                int    squareSize2 = squareSize;

                int bs = (int)MainWindow.Instance.mapView.TileMakeNewCtrl.BrushSize.Value;

                if ((MapInterface.CurrentMode == EditMode.FLOOR_BRUSH || MapInterface.CurrentMode == EditMode.FLOOR_PLACE) && !mapView.picking)
                {
                    squareSize2 *= bs;
                    if (bs > 1)
                    {
                        tilePt.X -= (float)(-0.5 + 0.5 * bs);
                        tilePt.Y -= (float)(1.5 + 0.5 * bs);
                        //tilePt.Y -= 1;
                        tilePt.Y -= ((bs - 1) + ((bs % 2 == 0) ? 1 : 0));
                        tilePt.Y += 2;
                    }
                }

                // Change overlay color depending on editor EditMode
                Color tileOverlayCol = Color.Yellow;
                if (MapInterface.CurrentMode == EditMode.EDGE_PLACE)
                {
                    tileOverlayCol = MainWindow.Instance.mapView.EdgeMakeNewCtrl.chkAutoEdge.Checked ? Color.Green : Color.Aqua;
                }
                if (MapInterface.CurrentMode == EditMode.FLOOR_BRUSH)
                {
                    tileOverlayCol = Color.LawnGreen;
                }

                if (mapView.picking)
                {
                    tileOverlayCol = Color.GhostWhite;
                }
                if (mapView.tileBucket)
                {
                    tileOverlayCol = Color.DeepSkyBlue;
                }

                tilePt.X *= squareSize;
                tilePt.Y *= squareSize;

                center   = new PointF(tilePt.X + squareSize / 2f, tilePt.Y + (3 / 2f) * squareSize);
                nwCorner = new PointF(tilePt.X - squareSize2 / 2f, tilePt.Y + (3 / 2f) * squareSize2);
                neCorner = new PointF(nwCorner.X + squareSize2, nwCorner.Y - squareSize2);
                swCorner = new PointF(nwCorner.X + squareSize2, nwCorner.Y + squareSize2);
                seCorner = new PointF(neCorner.X + squareSize2, neCorner.Y + squareSize2);

                g.DrawPolygon(new Pen(tileOverlayCol, 2), new PointF[] { nwCorner, neCorner, seCorner, swCorner });
            }

            // Draw [BELOW] objects
            objectRenderer.RenderBelow(g);

            // Draw walls
            Pen destructablePen = new Pen(ColorLayout.WallsBreakable, 2);
            Pen windowPen       = new Pen(ColorLayout.WallsWindowed, 2);
            Pen secretPen       = new Pen(ColorLayout.WallsSecret, 2);
            Pen invisiblePen    = new Pen(Color.DarkGray, 2);
            Pen fakeWallPen     = new Pen(Color.LightGray, 2);
            Pen openPen         = new Pen(Color.FromArgb(255, 110, 170, 110), 2);
            Pen wallPen         = new Pen(ColorLayout.Walls, 2);

            if (EditorSettings.Default.Draw_Walls)
            {
                Map.Wall removing          = mapView.GetWallUnderCursor();
                Point    highlightUndoRedo = mapView.highlightUndoRedo;

                if (MapInterface.CurrentMode == EditMode.WALL_BRUSH && !mapView.picking)
                {
                    removing = null;
                }

                // Render simple preview walls (Wall drawing modes)
                if (FakeWalls.Count > 0 && !EditorSettings.Default.Edit_PreviewMode)
                {
                    foreach (Map.Wall wall in FakeWalls.Values)
                    {
                        pen = invisiblePen;
                        DrawSimpleWall(g, wall, pen, false);
                    }
                }

                foreach (Map.Wall wall in Map.Walls.Values)
                {
                    Point pt = wall.Location;
                    int   x = pt.X * squareSize, y = pt.Y * squareSize;
                    Point txtPoint = new Point(x, y);
                    if (clip.Contains(x, y))
                    {
                        // Textured walls
                        if (DrawTextured && !wall.Material.Contains("Invisible"))
                        {
                            DrawTexturedWall(g, wall, false, removing == wall);
                            continue;
                        }

                        if (MainWindow.Instance.imgMode)
                        {
                            break;
                        }

                        // Simple walls
                        pen = wallPen;
                        if (EditorSettings.Default.Draw_ColorWalls || (MapInterface.CurrentMode == EditMode.WALL_CHANGE))
                        {
                            if (wall.Secret)
                            {
                                pen = wall.Secret_WallState == 4 ? openPen : secretPen;
                            }
                            else if (wall.Destructable)//if (wall.Destructable || MapInterface.GetLastWalls(wall))
                            {
                                pen = destructablePen;
                            }
                            else if (wall.Window)
                            {
                                pen = windowPen;
                            }
                            else if (wall.Material.Contains("Invisible"))
                            {
                                pen = invisiblePen;
                            }
                            else
                            {
                                pen = wallPen;
                            }
                        }

                        if (removing == wall)
                        {
                            if (mapView.picking)
                            {
                                pen = new Pen(Color.Aqua, 3);
                            }
                            else if (MapInterface.CurrentMode == EditMode.WALL_CHANGE)
                            {
                                pen = new Pen(Color.Purple, 3);
                            }
                        }

                        DrawSimpleWall(g, wall, pen, DrawText);
                    }
                }
            }

            if (!MainWindow.Instance.imgMode)
            {
                RenderPostLineWalls(g);
                RenderPostWalls(g);
                RenderPostObjects(g);
                RenderPostSelRect(g);
            }

            // Draw objects
            objectRenderer.RenderNormal(g);
            RenderHelpMark(g);
            // Draw polygons
            if (EditorSettings.Default.Draw_Polygons)
            {
                foreach (Map.Polygon poly in Map.Polygons)
                {
                    pen = Pens.PaleGreen;
                    // Highlight the polygon being edited
                    if (MapInterface.CurrentMode == EditMode.POLYGON_RESHAPE)
                    {
                        if (mapView.PolygonEditDlg.SelectedPolygon == poly || mapView.PolygonEditDlg.SuperPolygon == poly)
                        {
                            pen = Pens.PaleVioletRed;

                            foreach (PointF pt in poly.Points)
                            {
                                center = new PointF(pt.X - MapView.objectSelectionRadius, pt.Y - MapView.objectSelectionRadius);
                                Pen pen2 = MapInterface.SelectedPolyPoint == pt ? Pens.DodgerBlue : Pens.DeepPink;
                                g.DrawEllipse(pen2, new RectangleF(center, new Size(2 * MapView.objectSelectionRadius, 2 * MapView.objectSelectionRadius)));
                            }
                        }
                    }
                    if (poly.Points.Count > 2)
                    {
                        poly.Points.Add(poly.Points[0]);

                        if (MainWindow.Instance.mapView.PolygonEditDlg.ambientColors.Checked)
                        {
                            int        alphaa      = ((poly.AmbientLightColor.R + poly.AmbientLightColor.R + poly.AmbientLightColor.B + poly.AmbientLightColor.B + poly.AmbientLightColor.G + poly.AmbientLightColor.G) / 6);
                            FillMode   newFillMode = FillMode.Alternate;
                            Color      newColor    = Color.FromArgb(Math.Abs(255 - alphaa), poly.AmbientLightColor);
                            SolidBrush blueBrush   = new SolidBrush(newColor);
                            g.DrawPolygon(pen, poly.Points.ToArray());
                            g.FillPolygon(blueBrush, poly.Points.ToArray(), newFillMode);
                        }

                        if (mapView.PolygonEditDlg.SuperPolygon == poly && MapInterface.CurrentMode == EditMode.POLYGON_RESHAPE)
                        {
                            pen = new Pen(Color.PaleVioletRed, 2);
                        }
                        g.DrawLines(pen, poly.Points.ToArray());
                        poly.Points.RemoveAt(poly.Points.Count - 1);
                    }
                }
            }

            // Draw copied selection
            if (MainWindow.Instance.mapView.selectionPoly.Count > 2)
            {
                var pen1 = new Pen(Brushes.DeepSkyBlue, 4);
                pen1.DashStyle = DashStyle.Dash;

                g.DrawLines(pen1, MainWindow.Instance.mapView.selectionPoly.ToArray());
            }

            // Draw waypoints
            if (EditorSettings.Default.Draw_Waypoints)
            {
                foreach (Map.Waypoint wp in Map.Waypoints)
                {
                    // Highlight selected waypoint
                    pen = wp.Flags == 1 ? ColorLayout.WaypointNorm : ColorLayout.WaypointDis;
                    pen = ((MapInterface.SelectedWaypoint == wp) || (MapInterface.SelectedWaypoints.Contains(wp))) ? ColorLayout.WaypointSel : pen;
                    // Draw waypoint and related pathes
                    center = new PointF(wp.Point.X - MapView.objectSelectionRadius, wp.Point.Y - MapView.objectSelectionRadius);
                    g.DrawEllipse(pen, new RectangleF(center, new Size(2 * MapView.objectSelectionRadius, 2 * MapView.objectSelectionRadius)));
                    pen = ColorLayout.WaypointDis;
                    // Draw paths (code/idea from UndeadZeus)
                    foreach (Map.Waypoint.WaypointConnection wpc in wp.connections)
                    {
                        g.DrawLine(pen, wp.Point.X, wp.Point.Y, wpc.wp.Point.X, wpc.wp.Point.Y);
                        foreach (Map.Waypoint.WaypointConnection wpwp in wpc.wp.connections)//Checks if the waypoint connection is connecting to wp
                        {
                            if (wpwp.wp.Equals(wp))
                            {
                                // Draw connections
                                if ((MapInterface.SelectedWaypoint != null) && (wp == MapInterface.SelectedWaypoint))
                                {
                                    g.DrawLine(ColorLayout.WaypointSel, wp.Point.X, wp.Point.Y, wpc.wp.Point.X, wpc.wp.Point.Y);
                                }
                                else
                                {
                                    g.DrawLine(ColorLayout.WaypointTwoPath, wp.Point.X, wp.Point.Y, wpc.wp.Point.X, wpc.wp.Point.Y);
                                }
                                break;
                            }
                        }
                    }

                    // Draw text
                    if (DrawText && clip.Contains(center.ToPoint()))
                    {
                        if (wp.Name.Length > 0)
                        {
                            g.DrawString(wp.Number + ":" + wp.ShortName, drawFont, Brushes.YellowGreen, center);
                        }
                        else
                        {
                            g.DrawString(wp.Number.ToString(), drawFont, Brushes.MediumPurple, center);
                        }
                    }
                }
            }
        }