Пример #1
0
 public static LuaLinedef NearestLinedefRange(LuaVector2D pos, float range)
 {
     Linedef l = MapSet.NearestLinedefRange(General.Map.Map.Linedefs, pos.vec, range);
     if (l == null)
     {
         return null;
     }
     return new LuaLinedef(l);
 }
Пример #2
0
        // Mouse moves
        public override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            // Not holding any buttons?
            if (e.Button == MouseButtons.None)
            {
                // Find the nearest linedef within highlight range
                Linedef l = MapSet.NearestLinedefRange(validlinedefs, mousemappos, BuilderPlug.Me.HighlightRange / renderer.Scale);

                // Highlight if not the same
                if (l != highlighted)
                {
                    Highlight(l);
                }
            }
        }
        // This moves the selected geometry relatively
        // Returns true when geometry has actually moved
        private bool MoveGeometryRelative(Vector2D offset, bool snapgrid, bool snapnearest)
        {
            Vector2D oldpos = dragitem.Position;
            Vector2D anchorpos = dragitemposition + offset;
            Vector2D tl, br;

            // don't move if the offset contains invalid data
            if (!offset.IsFinite())
            {
                return(false);
            }

            // Find the outmost vertices
            tl = br = oldpositions[0];
            for (int i = 0; i < oldpositions.Count; i++)
            {
                if (oldpositions[i].x < tl.x)
                {
                    tl.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].x > br.x)
                {
                    br.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].y > tl.y)
                {
                    tl.y = (int)oldpositions[i].y;
                }
                if (oldpositions[i].y < br.y)
                {
                    br.y = (int)oldpositions[i].y;
                }
            }

            // Snap to nearest?
            if (snapnearest)
            {
                // Find nearest unselected vertex within range
                Vertex nv = MapSet.NearestVertexSquareRange(unselectedverts, anchorpos, BuilderPlug.Me.StitchRange / renderer.Scale);
                if (nv != null)
                {
                    // Move the dragged item
                    dragitem.Move(nv.Position);

                    // Adjust the offset
                    offset = nv.Position - dragitemposition;

                    // Do not snap to grid!
                    snapgrid = false;
                }
                else
                {
                    // Find the nearest unselected line within range
                    Linedef nl = MapSet.NearestLinedefRange(snaptolines, anchorpos, BuilderPlug.Me.StitchRange / renderer.Scale);
                    if (nl != null)
                    {
                        // Snap to grid?
                        if (snaptogrid)
                        {
                            // Get grid intersection coordinates
                            List <Vector2D> coords = nl.GetGridIntersections();

                            // Find nearest grid intersection
                            float    found_distance = float.MaxValue;
                            Vector2D found_coord    = new Vector2D();
                            foreach (Vector2D v in coords)
                            {
                                Vector2D delta = anchorpos - v;
                                if (delta.GetLengthSq() < found_distance)
                                {
                                    found_distance = delta.GetLengthSq();
                                    found_coord    = v;
                                }
                            }

                            // Move the dragged item
                            dragitem.Move(found_coord);

                            // Align to line here
                            offset = found_coord - dragitemposition;

                            // Do not snap to grid anymore
                            snapgrid = false;
                        }
                        else
                        {
                            // Move the dragged item
                            dragitem.Move(nl.NearestOnLine(anchorpos));

                            // Align to line here
                            offset = nl.NearestOnLine(anchorpos) - dragitemposition;
                        }
                    }
                }
            }

            // Snap to grid?
            if (snapgrid)
            {
                // Move the dragged item
                dragitem.Move(anchorpos);

                // Snap item to grid
                dragitem.SnapToGrid();

                // Adjust the offset
                offset += dragitem.Position - anchorpos;
            }

            // Make sure the offset is inside the map boundaries
            if (offset.x + tl.x < General.Map.FormatInterface.LeftBoundary)
            {
                offset.x = General.Map.FormatInterface.LeftBoundary - tl.x;
            }
            if (offset.x + br.x > General.Map.FormatInterface.RightBoundary)
            {
                offset.x = General.Map.FormatInterface.RightBoundary - br.x;
            }
            if (offset.y + tl.y > General.Map.FormatInterface.TopBoundary)
            {
                offset.y = General.Map.FormatInterface.TopBoundary - tl.y;
            }
            if (offset.y + br.y < General.Map.FormatInterface.BottomBoundary)
            {
                offset.y = General.Map.FormatInterface.BottomBoundary - br.y;
            }

            // Drag item moved?
            if (!snapgrid || (dragitem.Position != oldpos))
            {
                int i = 0;

                // Move selected geometry
                foreach (Vertex v in selectedverts)
                {
                    // Move vertex from old position relative to the
                    // mouse position change since drag start
                    v.Move(oldpositions[i] + offset);

                    // Next
                    i++;
                }

                // Update labels
                int index = 0;
                foreach (Linedef l in unstablelines)
                {
                    labels[index++].Move(l.Start.Position, l.End.Position);
                }

                // Moved
                return(true);
            }
            else
            {
                // No changes
                return(false);
            }
        }
Пример #4
0
        // This updates the selection
        private void Update()
        {
            // Not in any modifying mode?
            if (mode == ModifyMode.None)
            {
                Vector2D prevdragoffset = alignoffset;
                alignoffset     = new Vector2D(float.MinValue, float.MinValue);
                showalignoffset = false;

                // Check what grip the mouse is over
                // and change cursor accordingly
                Grip mousegrip = CheckMouseGrip();
                switch (mousegrip)
                {
                case Grip.Main:
                    int   closestcorner = -1;
                    float cornerdist    = float.MaxValue;
                    for (int i = 0; i < 4; i++)
                    {
                        Vector2D delta = corners[i] - mousemappos;
                        float    d     = delta.GetLengthSq();
                        if (d < cornerdist)
                        {
                            closestcorner = i;
                            cornerdist    = d;
                        }
                    }
                    switch (closestcorner)
                    {
                    // TODO:
                    case 0: alignoffset = new Vector2D(0f, 0f); break;

                    case 1: alignoffset = new Vector2D(texture.ScaledWidth, 0f); break;

                    case 2: alignoffset = new Vector2D(texture.ScaledWidth, -texture.ScaledHeight); break;

                    case 3: alignoffset = new Vector2D(0f, -texture.ScaledHeight); break;
                    }
                    showalignoffset = true;
                    General.Interface.SetCursor(Cursors.Hand);
                    break;

                case Grip.RotateLB:
                case Grip.RotateRT:
                    alignoffset     = new Vector2D(0f, 0f);
                    showalignoffset = true;
                    General.Interface.SetCursor(Cursors.Cross);
                    break;

                case Grip.SizeH:
                case Grip.SizeV:
                    alignoffset     = new Vector2D(0f, 0f);
                    showalignoffset = true;
                    // Pick the best matching cursor depending on rotation and side
                    float resizeangle = -(rotation + sectorinfo[0].rotation);
                    if (mousegrip == Grip.SizeH)
                    {
                        resizeangle += Angle2D.PIHALF;
                    }
                    resizeangle = Angle2D.Normalized(resizeangle);
                    if (resizeangle > Angle2D.PI)
                    {
                        resizeangle -= Angle2D.PI;
                    }
                    resizeangle = Math.Abs(resizeangle + Angle2D.PI / 8.000001f);
                    int cursorindex = (int)Math.Floor((resizeangle / Angle2D.PI) * 4.0f) % 4;
                    General.Interface.SetCursor(RESIZE_CURSORS[cursorindex]);
                    break;

                default:
                    General.Interface.SetCursor(Cursors.Default);
                    break;
                }

                if (prevdragoffset != alignoffset)
                {
                    General.Interface.RedrawDisplay();
                }
            }
            else
            {
                Vector2D snappedmappos = mousemappos;
                bool     dosnaptogrid  = snaptogrid;

                // Options
                snaptogrid    = General.Interface.ShiftState ^ General.Interface.SnapToGrid;
                snaptonearest = General.Interface.CtrlState ^ General.Interface.AutoMerge;

                // Change to crosshair cursor so we can clearly see around the mouse cursor
                General.Interface.SetCursor(Cursors.Cross);

                // Check what modifying mode we are in
                switch (mode)
                {
                case ModifyMode.Dragging:

                    offset = -mousemappos - dragoffset;
                    Vector2D transformedpos = TexToWorld(alignoffset);

                    // Snap to nearest vertex?
                    if (snaptonearest)
                    {
                        float vrange = BuilderPlug.Me.StitchRange / renderer.Scale;

                        // Try the nearest vertex
                        Vertex nv = MapSet.NearestVertexSquareRange(General.Map.Map.Vertices, transformedpos, vrange);
                        if (nv != null)
                        {
                            // Change offset to snap to target
                            offset      -= nv.Position - transformedpos;
                            dosnaptogrid = false;
                        }
                        else
                        {
                            // Find the nearest line within range
                            Linedef nl = MapSet.NearestLinedefRange(General.Map.Map.Linedefs, transformedpos, vrange);
                            if (nl != null)
                            {
                                // Snap to grid?
                                if (dosnaptogrid)
                                {
                                    // Get grid intersection coordinates
                                    List <Vector2D> coords = nl.GetGridIntersections();

                                    // Find nearest grid intersection
                                    float    found_distance = float.MaxValue;
                                    Vector2D found_pos      = new Vector2D(float.NaN, float.NaN);
                                    foreach (Vector2D v in coords)
                                    {
                                        Vector2D dist = transformedpos - v;
                                        if (dist.GetLengthSq() < found_distance)
                                        {
                                            // Found a better match
                                            found_distance = dist.GetLengthSq();
                                            found_pos      = v;

                                            // Do not snap to grid anymore
                                            dosnaptogrid = false;
                                        }
                                    }

                                    // Found something?
                                    if (!float.IsNaN(found_pos.x))
                                    {
                                        // Change offset to snap to target
                                        offset -= found_pos - transformedpos;
                                    }
                                }
                                else
                                {
                                    // Change offset to snap onto the line
                                    offset -= nl.NearestOnLine(transformedpos) - transformedpos;
                                }
                            }
                        }
                    }

                    // Snap to grid?
                    if (dosnaptogrid)
                    {
                        // Change offset to align to grid
                        offset -= General.Map.Grid.SnappedToGrid(transformedpos) - transformedpos;
                    }

                    break;

                case ModifyMode.Resizing:

                    // Snap to nearest vertex?
                    if (snaptonearest)
                    {
                        float vrange = BuilderPlug.Me.StitchRange / renderer.Scale;

                        // Try the nearest vertex
                        Vertex nv = MapSet.NearestVertexSquareRange(General.Map.Map.Vertices, snappedmappos, vrange);
                        if (nv != null)
                        {
                            snappedmappos = nv.Position;
                            dosnaptogrid  = false;
                        }
                    }

                    // Snap to grid?
                    if (dosnaptogrid)
                    {
                        // Aligned to grid
                        snappedmappos = General.Map.Grid.SnappedToGrid(snappedmappos);
                    }

                    float newscale = 1f / resizeaxis.GetNearestOnLine(snappedmappos);
                    if (float.IsInfinity(newscale) || float.IsNaN(newscale))
                    {
                        newscale = 99999f;
                    }
                    scale = (newscale * resizefilter) + scale * (1.0f - resizefilter);
                    if (float.IsInfinity(scale.x) || float.IsNaN(scale.x))
                    {
                        scale.x = 99999f;
                    }
                    if (float.IsInfinity(scale.y) || float.IsNaN(scale.y))
                    {
                        scale.y = 99999f;
                    }

                    // Show the extension line so that the user knows what it is aligning to
                    UpdateRectangleComponents();
                    Line2D edgeline;
                    if (resizefilter.x > resizefilter.y)
                    {
                        edgeline = new Line2D(corners[1], corners[2]);
                    }
                    else
                    {
                        edgeline = new Line2D(corners[3], corners[2]);
                    }
                    float nearestonedge = edgeline.GetNearestOnLine(snappedmappos);
                    if (nearestonedge > 0.5f)
                    {
                        extensionline = new Line2D(edgeline.v1, snappedmappos);
                    }
                    else
                    {
                        extensionline = new Line2D(edgeline.v2, snappedmappos);
                    }

                    break;

                case ModifyMode.Rotating:

                    // Snap to nearest vertex?
                    extensionline = new Line2D();
                    if (snaptonearest)
                    {
                        float vrange = BuilderPlug.Me.StitchRange / renderer.Scale;

                        // Try the nearest vertex
                        Vertex nv = MapSet.NearestVertexSquareRange(General.Map.Map.Vertices, snappedmappos, vrange);
                        if (nv != null)
                        {
                            snappedmappos = nv.Position;
                            dosnaptogrid  = false;

                            // Show the extension line so that the user knows what it is aligning to
                            extensionline = new Line2D(corners[0], snappedmappos);
                        }
                    }

                    Vector2D delta      = snappedmappos - rotationcenter;
                    float    deltaangle = -delta.GetAngle();

                    // Snap to grid?
                    if (dosnaptogrid)
                    {
                        // We make 8 vectors that the rotation can snap to
                        float founddistance = float.MaxValue;
                        float foundrotation = rotation;
                        for (int i = 0; i < 8; i++)
                        {
                            // Make the vectors
                            float    angle   = (float)i * Angle2D.PI * 0.25f;
                            Vector2D gridvec = Vector2D.FromAngle(angle);
                            Vector3D rotvec  = Vector2D.FromAngle(deltaangle + rotationoffset);

                            // Check distance
                            float dist = 2.0f - Vector2D.DotProduct(gridvec, rotvec);
                            if (dist < founddistance)
                            {
                                foundrotation = angle;
                                founddistance = dist;
                            }
                        }

                        // Keep rotation
                        rotation = foundrotation - sectorinfo[0].rotation;
                    }
                    else
                    {
                        rotation = deltaangle + rotationoffset - sectorinfo[0].rotation;
                    }
                    break;
                }

                UpdateSectors();
                General.Interface.RedrawDisplay();
            }
        }
Пример #5
0
        private void InsertVertex()
        {
            bool snaptogrid    = General.Interface.ShiftState ^ General.Interface.SnapToGrid;
            bool snaptonearest = General.Interface.CtrlState ^ General.Interface.AutoMerge;

            // Mouse in window?
            if (General.Interface.MouseInDisplay)
            {
                Vector2D insertpos;

                // Create undo
                General.Map.UndoRedo.CreateUndo("Insert vertex");

                // Snap to geometry?
                Linedef l = MapSet.NearestLinedefRange(blockmap, mousemappos, BuilderPlug.Me.SplitLinedefsRange / renderer.Scale);
                if (snaptonearest && (l != null))
                {
                    // Snip to grid also?
                    if (snaptogrid)
                    {
                        // Find all points where the grid intersects the line
                        List <Vector2D> points = l.GetGridIntersections(General.Map.Grid.GridRotate, General.Map.Grid.GridOriginX, General.Map.Grid.GridOriginY);
                        if (points.Count == 0)
                        {
                            //mxd. Just use the nearest point on line
                            insertpos = l.NearestOnLine(mousemappos);
                        }
                        else
                        {
                            insertpos = mousemappos;
                            double distance = double.MaxValue;
                            foreach (Vector2D p in points)
                            {
                                double pdist = Vector2D.DistanceSq(p, mousemappos);
                                if (pdist < distance)
                                {
                                    insertpos = p;
                                    distance  = pdist;
                                }
                            }
                        }
                    }
                    else
                    {
                        // Just use the nearest point on line
                        insertpos = l.NearestOnLine(mousemappos);
                    }
                }
                // Snap to grid?
                else if (snaptogrid)
                {
                    // Snap to grid
                    insertpos = General.Map.Grid.SnappedToGrid(mousemappos);
                }
                else
                {
                    // Just insert here, don't snap to anything
                    insertpos = mousemappos;
                }

                // Make the vertex
                Vertex v = General.Map.Map.CreateVertex(insertpos);
                if (v == null)
                {
                    General.Map.UndoRedo.WithdrawUndo();
                    return;
                }

                // Snap to map format accuracy
                v.SnapToAccuracy();

                // Split the line with this vertex
                if (snaptonearest)
                {
                    //mxd. Check if snapped vertex is still on top of a linedef
                    l = MapSet.NearestLinedefRange(blockmap, v.Position, BuilderPlug.Me.SplitLinedefsRange / renderer.Scale);

                    if (l != null)
                    {
                        //mxd
                        if (v.Position == l.Start.Position || v.Position == l.End.Position)
                        {
                            General.Interface.DisplayStatus(StatusType.Info, "There's already a vertex here.");
                            General.Map.UndoRedo.WithdrawUndo();
                            return;
                        }

                        General.Interface.DisplayStatus(StatusType.Action, "Split a linedef.");
                        Linedef sld = l.Split(v);
                        if (sld == null)
                        {
                            General.Map.UndoRedo.WithdrawUndo();
                            return;
                        }
                        //BuilderPlug.Me.AdjustSplitCoordinates(l, sld);
                    }
                }
                else
                {
                    General.Interface.DisplayStatus(StatusType.Action, "Inserted a vertex.");
                }

                // Create the blockmap
                CreateBlockmap();

                // Update
                General.Map.Map.Update();

                // Redraw screen
                General.Interface.RedrawDisplay();
            }
        }
Пример #6
0
        // Mouse moves
        public override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (panning)
            {
                return;                     //mxd. Skip all this jazz while panning
            }
            //mxd
            if (selectpressed && !editpressed && !selecting)
            {
                // Check if moved enough pixels for multiselect
                Vector2D delta = mousedownpos - mousepos;
                if ((Math.Abs(delta.x) > BuilderPlug.Me.MouseSelectionThreshold) ||
                    (Math.Abs(delta.y) > BuilderPlug.Me.MouseSelectionThreshold))
                {
                    // Start multiselecting
                    StartMultiSelection();
                }
            }
            else if (paintselectpressed && !editpressed && !selecting)             //mxd. Drag-select
            {
                // Find the nearest thing within highlight range
                Vertex v = General.Map.Map.NearestVertexSquareRange(mousemappos, BuilderPlug.Me.HighlightRange / renderer.Scale);

                if (v != null)
                {
                    if (v != highlighted)
                    {
                        //toggle selected state
                        if (General.Interface.ShiftState ^ BuilderPlug.Me.AdditivePaintSelect)
                        {
                            v.Selected = true;
                        }
                        else if (General.Interface.CtrlState)
                        {
                            v.Selected = false;
                        }
                        else
                        {
                            v.Selected = !v.Selected;
                        }
                        highlighted = v;

                        UpdateSelectionInfo();                         //mxd

                        // Update entire display
                        General.Interface.RedrawDisplay();
                    }
                }
                else if (highlighted != null)
                {
                    highlighted = null;
                    Highlight(null);

                    // Update entire display
                    General.Interface.RedrawDisplay();
                }
            }
            else if (e.Button == MouseButtons.None)            // Not holding any buttons?
            {
                //mxd. Render insert vertex preview
                Linedef l = MapSet.NearestLinedefRange(blockmap, mousemappos, BuilderPlug.Me.SplitLinedefsRange / renderer.Scale);

                if (l != null)
                {
                    // Snip to grid?
                    if (General.Interface.ShiftState ^ General.Interface.SnapToGrid)
                    {
                        // Find all points where the grid intersects the line
                        List <Vector2D> points = l.GetGridIntersections(General.Map.Grid.GridRotate, General.Map.Grid.GridOriginX, General.Map.Grid.GridOriginY);

                        if (points.Count == 0)
                        {
                            insertpreview = l.NearestOnLine(mousemappos);
                        }
                        else
                        {
                            insertpreview = mousemappos;
                            double distance = double.MaxValue;
                            foreach (Vector2D p in points)
                            {
                                double pdist = Vector2D.DistanceSq(p, mousemappos);
                                if (pdist < distance)
                                {
                                    insertpreview = p;
                                    distance      = pdist;
                                }
                            }
                        }
                    }
                    else
                    {
                        // Just use the nearest point on line
                        insertpreview = l.NearestOnLine(mousemappos);
                    }

                    //render preview
                    if (renderer.StartOverlay(true))
                    {
                        double dist  = Math.Min(Vector2D.Distance(mousemappos, insertpreview), BuilderPlug.Me.SplitLinedefsRange);
                        byte   alpha = (byte)(255 - (dist / BuilderPlug.Me.SplitLinedefsRange) * 128);
                        float  vsize = (renderer.VertexSize + 1.0f) / renderer.Scale;
                        renderer.RenderRectangleFilled(new RectangleF((float)(insertpreview.x - vsize), (float)(insertpreview.y - vsize), vsize * 2.0f, vsize * 2.0f), General.Colors.InfoLine.WithAlpha(alpha), true);
                        renderer.Finish();
                        renderer.Present();
                    }
                }
                else if (insertpreview.IsFinite())
                {
                    insertpreview.x = float.NaN;

                    //undraw preveiw
                    if (renderer.StartOverlay(true))
                    {
                        renderer.Finish();
                        renderer.Present();
                    }
                }

                // Find the nearest vertex within highlight range
                Vertex v = General.Map.Map.NearestVertexSquareRange(mousemappos, BuilderPlug.Me.HighlightRange / renderer.Scale);

                // Highlight if not the same
                if (v != highlighted)
                {
                    Highlight(v);
                }
            }
        }
Пример #7
0
        // Start editing
        protected override void OnEditBegin()
        {
            bool snaptogrid    = General.Interface.ShiftState ^ General.Interface.SnapToGrid;
            bool snaptonearest = General.Interface.CtrlState ^ General.Interface.AutoMerge;

            // Vertex highlighted?
            if ((highlighted != null) && !highlighted.IsDisposed)
            {
                // Edit pressed in this mode
                editpressed = true;

                // Highlighted item not selected?
                if (!highlighted.Selected && (BuilderPlug.Me.AutoClearSelection || (General.Map.Map.SelectedVerticessCount == 0)))
                {
                    // Make this the only selection
                    selectionfromhighlight = true;                     //mxd
                    General.Map.Map.ClearSelectedVertices();
                    highlighted.Selected = true;
                    UpdateSelectionInfo();                     //mxd
                    General.Interface.RedrawDisplay();
                }

                // Update display
                if (renderer.StartPlotter(false))
                {
                    // Redraw highlight to show selection
                    renderer.PlotVertex(highlighted, renderer.DetermineVertexColor(highlighted));
                    renderer.Finish();
                    renderer.Present();
                }
            }
            else if (!selecting)            //mxd. We don't want to do this stuff while multiselecting
            {
                // Find the nearest linedef within highlight range
                Linedef l = MapSet.NearestLinedefRange(blockmap, mousemappos, BuilderPlug.Me.SplitLinedefsRange / renderer.Scale);
                if (l != null)
                {
                    // Create undo
                    General.Map.UndoRedo.CreateUndo("Split linedef");

                    Vector2D insertpos;

                    // Snip to grid also?
                    if (snaptogrid)
                    {
                        // Find all points where the grid intersects the line
                        List <Vector2D> points = l.GetGridIntersections(General.Map.Grid.GridRotate, General.Map.Grid.GridOriginX, General.Map.Grid.GridOriginY);
                        insertpos = mousemappos;
                        double distance = double.MaxValue;
                        foreach (Vector2D p in points)
                        {
                            double pdist = Vector2D.DistanceSq(p, mousemappos);
                            if (pdist < distance)
                            {
                                insertpos = p;
                                distance  = pdist;
                            }
                        }
                    }
                    else
                    {
                        // Just use the nearest point on line
                        insertpos = l.NearestOnLine(mousemappos);
                    }

                    // Make the vertex
                    Vertex v = General.Map.Map.CreateVertex(insertpos);
                    if (v == null)
                    {
                        General.Map.UndoRedo.WithdrawUndo();
                        return;
                    }

                    // Snap to map format accuracy
                    v.SnapToAccuracy();

                    // Split the line with this vertex
                    Linedef sld = l.Split(v);
                    if (sld == null)
                    {
                        General.Map.UndoRedo.WithdrawUndo();
                        return;
                    }
                    //BuilderPlug.Me.AdjustSplitCoordinates(l, sld);

                    // Create the blockmap
                    CreateBlockmap();

                    // Update
                    General.Map.Map.Update();

                    // Highlight it
                    Highlight(v);

                    // Redraw display
                    General.Interface.RedrawDisplay();
                }
                else if (BuilderPlug.Me.AutoDrawOnEdit)
                {
                    // Start drawing mode
                    DrawGeometryMode drawmode = new DrawGeometryMode();
                    DrawnVertex      v        = DrawGeometryMode.GetCurrentPosition(mousemappos, snaptonearest, snaptogrid, false, false, renderer, new List <DrawnVertex>());

                    if (drawmode.DrawPointAt(v))
                    {
                        General.Editing.ChangeMode(drawmode);
                    }
                    else
                    {
                        General.Interface.DisplayStatus(StatusType.Warning, "Failed to draw point: outside of map boundaries.");
                    }
                }
            }

            base.OnEditBegin();
        }
Пример #8
0
        // This moves the selected geometry relatively
        // Returns true when geometry has actually moved
        private bool MoveGeometryRelative(Vector2D offset, bool snapgrid, bool snapgridincrement, bool snapnearest, bool snapcardinal)
        {
            //mxd. If snap to cardinal directions is enabled, modify the offset
            if (snapcardinal)
            {
                double angle = Angle2D.DegToRad((General.ClampAngle((int)Angle2D.RadToDeg(offset.GetAngle()) + 44)) / 90 * 90);
                offset            = new Vector2D(0, -offset.GetLength()).GetRotated(angle);
                snapgridincrement = true;                 // We don't want to move the geometry away from the cardinal directions
            }

            Vector2D oldpos = dragitem.Position;
            Vector2D anchorpos = dragitemposition + offset;
            Vector2D tl, br;

            // don't move if the offset contains invalid data
            if (!offset.IsFinite())
            {
                return(false);
            }

            // Find the outmost vertices
            tl = br = oldpositions[0];
            for (int i = 0; i < oldpositions.Count; i++)
            {
                if (oldpositions[i].x < tl.x)
                {
                    tl.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].x > br.x)
                {
                    br.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].y > tl.y)
                {
                    tl.y = (int)oldpositions[i].y;
                }
                if (oldpositions[i].y < br.y)
                {
                    br.y = (int)oldpositions[i].y;
                }
            }

            // Snap to nearest?
            if (snapnearest)
            {
                // Find nearest unselected vertex within range
                Vertex nv = MapSet.NearestVertexSquareRange(unselectedverts, anchorpos, BuilderPlug.Me.StitchRange / renderer.Scale);
                if (nv != null)
                {
                    // Move the dragged item
                    dragitem.Move(nv.Position);

                    // Adjust the offset
                    offset = nv.Position - dragitemposition;

                    // Do not snap to grid!
                    snapgrid            = false;
                    snaptogridincrement = false;                     //mxd
                }
                else
                {
                    // Find the nearest unselected line within range
                    Linedef nl = MapSet.NearestLinedefRange(snaptolines, anchorpos, BuilderPlug.Me.StitchRange / renderer.Scale);
                    if (nl != null)
                    {
                        // Snap to grid?
                        if (snapgrid || snapgridincrement)
                        {
                            // Get grid intersection coordinates
                            List <Vector2D> coords = nl.GetGridIntersections(snapgridincrement ? dragstartoffset : new Vector2D(),
                                                                             General.Map.Grid.GridRotate, General.Map.Grid.GridOriginX, General.Map.Grid.GridOriginY);

                            // mxd. Do the rest only if we actually have some coordinates
                            if (coords.Count > 0)
                            {
                                // Find nearest grid intersection
                                double   found_distance = double.MaxValue;
                                Vector2D found_coord    = new Vector2D();

                                foreach (Vector2D v in coords)
                                {
                                    Vector2D delta = anchorpos - v;
                                    if (delta.GetLengthSq() < found_distance)
                                    {
                                        found_distance = delta.GetLengthSq();
                                        found_coord    = v;
                                    }
                                }

                                // Move the dragged item
                                dragitem.Move(found_coord);

                                // Align to line here
                                offset = found_coord - dragitemposition;

                                // Do not snap to grid anymore
                                snapgrid          = false;
                                snapgridincrement = false;                                 //mxd
                            }
                        }
                        else
                        {
                            // Move the dragged item
                            dragitem.Move(nl.NearestOnLine(anchorpos));

                            // Align to line here
                            offset = nl.NearestOnLine(anchorpos) - dragitemposition;
                        }
                    }
                }
            }

            // Snap to grid or grid increment?
            if (snapgrid || snapgridincrement)
            {
                // Move the dragged item
                dragitem.Move(anchorpos);

                // Snap item to grid increment
                if (snapgridincrement)                //mxd
                {
                    dragitem.Move(General.Map.Grid.SnappedToGrid(dragitem.Position) - dragstartoffset);
                }
                else                 // Or to the grid itself
                {
                    dragitem.SnapToGrid();
                }

                // Adjust the offset
                offset += dragitem.Position - anchorpos;
            }

            // Make sure the offset is inside the map boundaries
            if (offset.x + tl.x < General.Map.Config.LeftBoundary)
            {
                offset.x = General.Map.Config.LeftBoundary - tl.x;
            }
            if (offset.x + br.x > General.Map.Config.RightBoundary)
            {
                offset.x = General.Map.Config.RightBoundary - br.x;
            }
            if (offset.y + tl.y > General.Map.Config.TopBoundary)
            {
                offset.y = General.Map.Config.TopBoundary - tl.y;
            }
            if (offset.y + br.y < General.Map.Config.BottomBoundary)
            {
                offset.y = General.Map.Config.BottomBoundary - br.y;
            }

            // Drag item moved?
            if ((!snapgrid && !snapgridincrement) || (dragitem.Position != oldpos))
            {
                int i = 0;

                // Move selected geometry
                foreach (Vertex v in selectedverts)
                {
                    // Move vertex from old position relative to the mouse position change since drag start
                    v.Move(oldpositions[i++] + offset);
                }

                //mxd. Move selected things
                i = 0;
                foreach (Thing t in thingstodrag)
                {
                    t.Move(oldthingpositions[i++] + offset);
                }

                // Update labels
                int index = 0;
                foreach (Linedef l in unstablelines)
                {
                    labels[index++].Move(l.Start.Position, l.End.Position);
                }

                // Moved
                return(true);
            }

            // No changes
            return(false);
        }
        // Mouse moves
        public override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            // Not holding any buttons?
            if (e.Button == MouseButtons.None)
            {
                General.Interface.SetCursor(Cursors.Default);

                //mxd. Find the nearest linedef within default highlight range
                Linedef nl = MapSet.NearestLinedefRange(blockmap, mousemappos, 20 / renderer.Scale);
                //mxd. We are not interested in single-sided lines (unless they have "blocksound" flag set)...
                if (nl != null && (nl.Front == null || nl.Back == null) && !nl.IsFlagSet(BlockSoundFlag))
                {
                    nl = null;
                }

                //mxd. Set as highlighted
                bool redrawrequired = (highlightedline != nl);
                highlightedline = nl;

                // Find the nearest linedef within highlight range
                Linedef l = MapSet.NearestLinedef(blockmap, mousemappos);
                if (l != null)
                {
                    // Check on which side of the linedef the mouse is
                    double side = l.SideOfLine(mousemappos);
                    if (side > 0)
                    {
                        // Is there a sidedef here?
                        if (l.Back != null)
                        {
                            // Highlight if not the same
                            if (l.Back.Sector != highlighted)
                            {
                                Highlight(l.Back.Sector);
                                redrawrequired = true;                                 //mxd
                            }
                        }
                        else if (highlighted != null)
                        {
                            // Highlight nothing
                            Highlight(null);
                            redrawrequired = true;                             //mxd
                        }
                    }
                    else
                    {
                        // Is there a sidedef here?
                        if (l.Front != null)
                        {
                            // Highlight if not the same
                            if (l.Front.Sector != highlighted)
                            {
                                Highlight(l.Front.Sector);
                                redrawrequired = true;                                 //mxd
                            }
                        }
                        else if (highlighted != null)
                        {
                            // Highlight nothing
                            Highlight(null);
                            redrawrequired = true;                             //mxd
                        }
                    }
                }
                else if (highlighted != null)
                {
                    // Highlight nothing
                    Highlight(null);
                    redrawrequired = true;                     //mxd
                }

                //mxd
                if (redrawrequired)
                {
                    // Show highlight info
                    if (highlightedline != null && !highlightedline.IsDisposed)
                    {
                        General.Interface.ShowLinedefInfo(highlightedline);
                    }
                    else if (highlighted != null && !highlighted.IsDisposed)
                    {
                        General.Interface.ShowSectorInfo(highlighted);
                    }
                    else
                    {
                        General.Interface.HideInfo();
                    }

                    // Redraw display
                    General.Interface.RedrawDisplay();
                }
            }
        }