public void BindTag(int tag) { Linedef line = null; // try to find an line without an action foreach (Sidedef sd in sector.Sidedefs) { if (sd.Line.Action == 0 && sd.Line.Tag == 0 && line == null) { line = sd.Line; } // if a line of the control sector already has the tag // nothing has to be done if (sd.Line.Args[0] == tag) { return; } } // no lines without an action, so a line has to get split // find the longest line to split if (line == null) { line = sector.Sidedefs.First().Line; foreach (Sidedef sd in sector.Sidedefs) { if (sd.Line.Length > line.Length) { line = sd.Line; } } // Lines may not have a length of less than 1 after splitting if (line.Length / 2 < 1) { throw new Exception("Can't split more lines in Sector " + line.Front.Sector.Index.ToString() + "."); } Vertex v = General.Map.Map.CreateVertex(line.Line.GetCoordinatesAt(0.5f)); v.SnapToAccuracy(); line = line.Split(v); General.Map.Map.Update(); General.Interface.RedrawDisplay(); } line.Action = 160; line.Args[0] = tag; line.Args[1] = type; line.Args[2] = flags; line.Args[3] = alpha; }
// returns a tuple of vertex, linedef, linedef public DynValue Split(LuaVertex v) { if (linedef.IsDisposed) { throw new ScriptRuntimeException("Linedef has been disposed, can't Split."); } if (v == null) { throw new ScriptRuntimeException("Vertex is null, can't Split (not enough arguments maybe?)."); } if (v.vertex.IsDisposed) { throw new ScriptRuntimeException("Vertex has been disposed, can't Split."); } v.vertex.SnapToAccuracy(); LuaLinedef newline = new LuaLinedef(linedef.Split(v.vertex)); if (newline.linedef == null) { throw new ScriptRuntimeException( "Split returned null linedef (max linedef limit reached? current count is " + General.Map.Map.Linedefs.Count + " of " + General.Map.FormatInterface.MaxLinedefs + ")"); } // Update cached values General.Map.Map.Update(); return(DynValue.NewTuple( DynValue.FromObject(ScriptContext.context.script, v), DynValue.FromObject(ScriptContext.context.script, newline), DynValue.FromObject(ScriptContext.context.script, this) )); }
// This applies the curves and returns to the base mode public override void OnAccept() { // Create undo General.Map.UndoRedo.CreateUndo("Curve linedefs"); // Go for all selected lines foreach (Linedef ld in selectedlines) { // Make curve for line List <Vector2D> points = GenerateCurve(ld); if (points.Count > 0) { // TODO: We may want some sector create/join code in here // to allow curves that overlap lines and some geometry merging // Go for all points to split the line Linedef splitline = ld; for (int i = 0; i < points.Count; i++) { // Make vertex Vertex v = General.Map.Map.CreateVertex(points[i]); if (v == null) { General.Map.UndoRedo.WithdrawUndo(); return; } // Split the line and move on with this line splitline = splitline.Split(v); if (splitline == null) { General.Map.UndoRedo.WithdrawUndo(); return; } } } } // Snap to map format accuracy General.Map.Map.SnapAllToAccuracy(); // Update caches General.Map.Map.Update(); General.Map.IsChanged = true; // Return to base mode General.Editing.ChangeMode(General.Editing.PreviousStableMode.Name); }
// Fix by splitting the line public override bool Button1Click(bool batchMode) { if (!batchMode) { General.Map.UndoRedo.CreateUndo("Split Linedef"); } line.Split(vertex); //check that we don't have duplicate lines List <Linedef> lines = new List <Linedef>(vertex.Linedefs); for (int i = 0; i < lines.Count - 1; i++) { for (int c = i + 1; c < lines.Count; c++) { if ((lines[i].Start == lines[c].Start && lines[i].End == lines[c].End) || (lines[i].Start == lines[c].End && lines[i].End == lines[c].Start)) { lines[c].Join(lines[i]); //mxd. Textures may've become unused if (lines[c].Front != null) { lines[c].Front.RemoveUnneededTextures(lines[c].Back != null, false, true); } if (lines[c].Back != null) { lines[c].Back.RemoveUnneededTextures(lines[c].Front != null, false, true); } } } } General.Map.Map.Update(); return(true); }
public static void InsertVertex(Vector2D mousemappos, float rendererscale) { 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; Linedef l = null; // Create undo General.Map.UndoRedo.CreateUndo("Insert vertex"); // Snap to geometry? l = General.Map.Map.NearestLinedefRange(mousemappos, BuilderPlug.Me.SplitLinedefsRange / rendererscale); if (snaptonearest && (l != null)) { // Snip to grid also? if (snaptogrid) { // Find all points where the grid intersects the line List <Vector2D> points = l.GetGridIntersections(); insertpos = mousemappos; float distance = float.MaxValue; foreach (Vector2D p in points) { float 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 && (l != null)) { 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."); } // Update General.Map.Map.Update(); // Redraw screen General.Interface.RedrawDisplay(); } }
// 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 General.Map.Map.ClearSelectedVertices(); highlighted.Selected = true; 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 { // Find the nearest linedef within highlight range Linedef l = General.Map.Map.NearestLinedefRange(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(); insertpos = mousemappos; float distance = float.MaxValue; foreach (Vector2D p in points) { float 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); // Update General.Map.Map.Update(); // Highlight it Highlight(v); // Redraw display General.Interface.RedrawDisplay(); } else { // Start drawing mode DrawGeometryMode drawmode = new DrawGeometryMode(); DrawnVertex v = DrawGeometryMode.GetCurrentPosition(mousemappos, snaptonearest, snaptogrid, 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 applies the curves and returns to the base mode public override void OnAccept() { // Create undo string rest = (selectedlines.Count == 1 ? "a linedef" : selectedlines.Count + " linedefs"); //mxd General.Map.UndoRedo.CreateUndo("Curve " + rest); //mxd General.Map.Map.ClearAllMarks(false); // Go for all selected lines foreach (Linedef ld in selectedlines) { if (curves[ld].Count < 1) { continue; } // Make curve for line Linedef splitline = ld; //mxd. Mark all changed geometry... splitline.Marked = true; splitline.Start.Marked = true; splitline.End.Marked = true; // Go for all points to split the line foreach (Vector2D p in curves[ld]) { // Make vertex Vertex v = General.Map.Map.CreateVertex(p); if (v == null) { General.Map.UndoRedo.WithdrawUndo(); return; } // Split the line and move on with this line splitline = splitline.Split(v); if (splitline == null) { General.Map.UndoRedo.WithdrawUndo(); return; } //mxd. Mark all changed geometry... splitline.Marked = true; splitline.Start.Marked = true; splitline.End.Marked = true; } } //mxd General.Map.Map.Update(); //mxd. Stitch geometry General.Map.Map.StitchGeometry(General.Settings.MergeGeometryMode); // Snap to map format accuracy General.Map.Map.SnapAllToAccuracy(); // Update caches General.Map.Map.Update(); General.Map.IsChanged = true; // Return to base mode General.Editing.ChangeMode(General.Editing.PreviousStableMode.Name); }
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(); } }