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