Ejemplo n.º 1
0
        protected override void OnMouseMove(MouseEventArgs e)
        {
            mouse.X = (e.Location.X - AutoScrollPosition.X);
            mouse.Y = (e.Location.Y - AutoScrollPosition.Y);
            base.OnMouseMove(e);

            if (doc == null)
            {
                return;
            }

            if (Mode != EditMode.Entrance)
            {
                entranceResizeIndex = -1;
                entranceMoveIndex   = -1;
            }

            if (Mode != EditMode.Way)
            {
                waySelectIndex     = -1;
                wayPointMoveIndex  = -1;
                wayPointHoverIndex = -1;
            }

            switch (mode)
            {
            case EditMode.Tile:
                if (e.Button == MouseButtons.Left && Tile != null && tilePainting)
                {
                    Point pt = e.Location;
                    pt.X = (pt.X - AutoScrollPosition.X) / doc.TileSize;
                    pt.Y = (pt.Y - AutoScrollPosition.Y) / doc.TileSize;

                    if (pt.X >= 0 && pt.Y >= 0 && pt.X < doc.Size.Width && pt.Y < doc.Size.Height)
                    {
                        if (doc.GetTile(pt.X, pt.Y) != Tile)
                        {
                            doc.SetTile(pt.X, pt.Y, Tile);
                        }
                    }
                }
                break;

            case EditMode.Entrance:
                if (!entranceMoving && !entranceResizing)
                {
                    Cursor cursor = Cursors.Arrow;

                    entranceResizeCorner = ResizeCorner.None;
                    entranceResizeIndex  = -1;
                    entranceMoveIndex    = -1;

                    for (int i = 0; i < doc.EntranceCount && entranceResizeIndex == -1; i++)
                    {
                        Entrance en = doc.GetEntrance(i);

                        Rectangle rc = en.Rect;
                        rc.Inflate(2, 2);

                        if (rc.Contains(mouse))
                        {
                            rc.Inflate(-4, -4);
                            if (!rc.Contains(mouse))
                            {
                                entranceResizeCorner |= (mouse.X <= rc.Left) ? ResizeCorner.Left : ResizeCorner.None;
                                entranceResizeCorner |= (mouse.X >= rc.Right) ? ResizeCorner.Right : ResizeCorner.None;
                                entranceResizeCorner |= (mouse.Y <= rc.Top) ? ResizeCorner.Top : ResizeCorner.None;
                                entranceResizeCorner |= (mouse.Y >= rc.Bottom) ? ResizeCorner.Bottom : ResizeCorner.None;

                                entranceResizeIndex = i;

                                switch (entranceResizeCorner)
                                {
                                case ResizeCorner.Left:
                                case ResizeCorner.Right:
                                    cursor = Cursors.SizeWE;
                                    break;

                                case ResizeCorner.Top:
                                case ResizeCorner.Bottom:
                                    cursor = Cursors.SizeNS;
                                    break;

                                case ResizeCorner.TopRight:
                                case ResizeCorner.BottomLeft:
                                    cursor = Cursors.SizeNESW;
                                    break;

                                case ResizeCorner.TopLeft:
                                case ResizeCorner.BottomRight:
                                    cursor = Cursors.SizeNWSE;
                                    break;

                                default:
                                    entranceResizeIndex  = -1;
                                    entranceResizeCorner = ResizeCorner.None;
                                    break;
                                }
                            }
                            else
                            {
                                cursor            = Cursors.SizeAll;
                                entranceMoveIndex = i;
                            }
                        }
                    }

                    Cursor = cursor;
                }
                if (entranceResizing)
                {
                    Entrance en = doc.GetEntrance(entranceResizeIndex);

                    if ((entranceResizeCorner & ResizeCorner.Left) != ResizeCorner.None)
                    {
                        int change = (en.Rect.X - mouse.X) + en.Rect.Width;
                        if (change < 6)
                        {
                            change = 6;
                        }
                        en.Rect.X     = en.Rect.Right - change;
                        en.Rect.Width = change;
                    }
                    if ((entranceResizeCorner & ResizeCorner.Right) != ResizeCorner.None)
                    {
                        en.Rect.Width = (mouse.X - en.Rect.X);
                        if (en.Rect.Width < 6)
                        {
                            en.Rect.Width = 6;
                        }
                    }
                    if ((entranceResizeCorner & ResizeCorner.Top) != ResizeCorner.None)
                    {
                        int change = (en.Rect.Y - mouse.Y) + en.Rect.Height;
                        if (change < 6)
                        {
                            change = 6;
                        }
                        en.Rect.Y      = en.Rect.Bottom - change;
                        en.Rect.Height = change;
                    }
                    if ((entranceResizeCorner & ResizeCorner.Bottom) != ResizeCorner.None)
                    {
                        en.Rect.Height = (mouse.Y - en.Rect.Y);
                        if (en.Rect.Height < 6)
                        {
                            en.Rect.Height = 6;
                        }
                    }

                    doc.SetEntrance(entranceResizeIndex, en);
                }

                if (entranceMoving)
                {
                    Entrance en = doc.GetEntrance(entranceMoveIndex);

                    if (en.Rect.X != mouse.X + entranceMoveOffset.X &&
                        en.Rect.Y != mouse.Y + entranceMoveOffset.Y)
                    {
                        en.Rect.X = mouse.X + entranceMoveOffset.X;
                        en.Rect.Y = mouse.Y + entranceMoveOffset.Y;

                        doc.SetEntrance(entranceMoveIndex, en);
                    }
                }
                break;

            case EditMode.Way:
                entranceMoveIndex = -1;

                for (int i = 0; i < doc.EntranceCount; i++)
                {
                    Entrance en = doc.GetEntrance(i);

                    Rectangle rc = en.Rect;
                    rc.Inflate(2, 2);

                    if (rc.Contains(mouse))
                    {
                        entranceMoveIndex = i;
                    }
                }

                wayHoverIndex = -1;
                if (entranceMoveIndex == -1 && entranceResizeIndex == -1)
                {
                    for (int j = 0; j < doc.WayCount; j++)
                    {
                        Way way = doc.GetWay(j);

                        Rectangle rc0 = doc.GetEntrance(way.Entrance[0]).Rect;
                        Rectangle rc1 = doc.GetEntrance(way.Entrance[1]).Rect;

                        Rectangle area = Rectangle.Union(rc0, rc1);
                        if (area.Contains(mouse))
                        {
                            PointF start = new PointF(rc0.Left + rc0.Width / 2, rc0.Top + rc0.Height / 2);
                            PointF end   = new PointF(rc1.Left + rc1.Width / 2, rc1.Top + rc1.Height / 2);
                            PointF dir   = new PointF(end.X - start.X, end.Y - start.Y);
                            float  len   = (float)Math.Sqrt(dir.X * dir.X + dir.Y * dir.Y);
                            dir.X /= len;
                            dir.Y /= len;

                            float  lambda = (mouse.X - start.X) * dir.X + (mouse.Y - start.Y) * dir.Y;
                            PointF d      = new PointF();
                            d.X = start.X + lambda * dir.X;
                            d.Y = start.Y + lambda * dir.Y;

                            float dist = (float)Math.Sqrt((d.X - mouse.X) * (d.X - mouse.X) + (d.Y - mouse.Y) * (d.Y - mouse.Y));
                            if (dist < 8)
                            {
                                wayHoverIndex = j;
                            }
                        }
                    }
                }

                wayPointHoverIndex = -1;
                if (entranceMoveIndex == -1 && entranceResizeIndex == -1)
                {
                    for (int j = 0; j < doc.WayCount; j++)
                    {
                        Way way = doc.GetWay(j);

                        for (int k = 0; k < doc.Ways[j].Points.Count; k++)
                        {
                            Rectangle rect = new Rectangle(way.Points[k].X - 2, way.Points[k].Y - 2, 5, 5);
                            rect.Inflate(3, 3);
                            if (rect.Contains(mouse))
                            {
                                wayPointHoverIndex = k;
                                wayHoverIndex      = j;
                            }
                        }
                    }
                }

                if (wayPointMoving)
                {
                    Point pt = doc.Ways[wayMoveIndex].Points[wayPointMoveIndex];
                    if (pt.X != mouse.X + wayPointMoveOffset.X &&
                        pt.Y != mouse.Y + wayPointMoveOffset.Y)
                    {
                        pt.X = mouse.X + wayPointMoveOffset.X;
                        pt.Y = mouse.Y + wayPointMoveOffset.Y;
                        doc.Ways[wayMoveIndex].Points[wayPointMoveIndex] = pt;
                        doc.Saved = false;
                    }
                }
                break;

            case EditMode.Walkable:
                if (walkablePainting)
                {
                    Point pt = e.Location;
                    pt.X = (pt.X - AutoScrollPosition.X) / doc.TileSize;
                    pt.Y = (pt.Y - AutoScrollPosition.Y) / doc.TileSize;

                    if (pt.X >= 0 && pt.Y >= 0 && pt.X < doc.Size.Width && pt.Y < doc.Size.Height)
                    {
                        Tile tile = doc.GetTile(pt.X, pt.Y);
                        if (tile != null)
                        {
                            Point sub = e.Location;
                            sub.X = (sub.X - AutoScrollPosition.X) / (doc.TileSize / 4);
                            sub.Y = (sub.Y - AutoScrollPosition.Y) / (doc.TileSize / 4);

                            sub.X -= pt.X * 4;
                            sub.Y -= pt.Y * 4;

                            tile.Mask[sub.X + sub.Y * 4] = (e.Button == MouseButtons.Left);
                            TileManager.Change(tile);
                        }
                    }
                }
                break;
            }

            Invalidate();
        }