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(); }