diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj index 58bcf64..5f8d27d 100644 --- a/Source/Core/Builder.csproj +++ b/Source/Core/Builder.csproj @@ -550,7 +550,9 @@ - + + False + False diff --git a/Source/Core/Geometry/Tools.cs b/Source/Core/Geometry/Tools.cs index fe87246..6cb4d50 100644 --- a/Source/Core/Geometry/Tools.cs +++ b/Source/Core/Geometry/Tools.cs @@ -225,8 +225,13 @@ namespace CodeImp.DoomBuilder.Geometry LinedefTracePath tracepath = new LinedefTracePath(innerlines); EarClipPolygon innerpoly = tracepath.MakePolygon(true); + //mxd. Check bbox first... + Vector2D foundsidepoint = foundline.GetSidePoint(foundlinefront); + RectangleF innerbbox = innerpoly.CreateBBox(); + bool outsidebbox = (foundsidepoint.x < innerbbox.Left || foundsidepoint.x > innerbbox.Right || foundsidepoint.y < innerbbox.Top || foundsidepoint.y > innerbbox.Bottom); + // Check if the front of the line is outside the polygon - if(!innerpoly.Intersect(foundline.GetSidePoint(foundlinefront))) + if(outsidebbox || !innerpoly.Intersect(foundsidepoint)) { // Valid hole found! alllines.AddRange(innerlines); @@ -246,6 +251,7 @@ namespace CodeImp.DoomBuilder.Geometry { Linedef scanline = line; bool scanfront = front; + Vector2D sidepoint = line.GetSidePoint(front); //mxd do { @@ -257,8 +263,12 @@ namespace CodeImp.DoomBuilder.Geometry LinedefTracePath tracepath = new LinedefTracePath(pathlines); EarClipPolygon poly = tracepath.MakePolygon(true); + //mxd. Check bbox first... + RectangleF bbox = poly.CreateBBox(); + bool outsidebbox = (sidepoint.x < bbox.Left || sidepoint.x > bbox.Right || sidepoint.y < bbox.Top || sidepoint.y > bbox.Bottom); + // Check if the front of the line is inside the polygon - if(poly.Intersect(line.GetSidePoint(front))) + if(!outsidebbox && poly.Intersect(sidepoint)) { // Outer lines found! alllines.AddRange(pathlines); @@ -923,6 +933,11 @@ namespace CodeImp.DoomBuilder.Geometry List nonmergeverts = new List(General.Map.Map.Vertices); MapSet map = General.Map.Map; + //mxd. Let's use a blockmap... + RectangleF area = MapSet.CreateArea(oldlines); + BlockMap oldlinesmap = new BlockMap(area); + oldlinesmap.AddLinedefsSet(oldlines); + General.Map.Map.ClearAllMarks(false); // Any points to do? @@ -1067,7 +1082,7 @@ namespace CodeImp.DoomBuilder.Geometry foreach(Linedef ld in newlines) { Vector2D ldcp = ld.GetCenterPoint(); - Linedef nld = MapSet.NearestLinedef(oldlines, ldcp); + Linedef nld = MapSet.NearestLinedef(oldlinesmap, ldcp); //mxd. Lines collection -> Blockmap if(nld != null) { float ldside = nld.SideOfLine(ldcp); @@ -1104,7 +1119,7 @@ namespace CodeImp.DoomBuilder.Geometry List endpoints = new List(); // Find out where the start will stitch and create test points - Linedef l1 = MapSet.NearestLinedefRange(oldlines, firstline.Start.Position, MapSet.STITCH_DISTANCE); + Linedef l1 = MapSet.NearestLinedefRange(oldlinesmap, firstline.Start.Position, MapSet.STITCH_DISTANCE); //mxd. Lines collection -> Blockmap Vertex vv1 = null; if(l1 != null) { @@ -1129,7 +1144,7 @@ namespace CodeImp.DoomBuilder.Geometry } // Find out where the end will stitch and create test points - Linedef l2 = MapSet.NearestLinedefRange(oldlines, lastline.End.Position, MapSet.STITCH_DISTANCE); + Linedef l2 = MapSet.NearestLinedefRange(oldlinesmap, lastline.End.Position, MapSet.STITCH_DISTANCE); //mxd. Lines collection -> Blockmap Vertex vv2 = null; if(l2 != null) { @@ -2200,15 +2215,23 @@ namespace CodeImp.DoomBuilder.Geometry { if(l.Front != null && (l.Front.Sector != null && !SectorWasInvalid(l.Front.Sector))) { - if(!sectorsidesref.ContainsKey(l.Front.Sector)) sectorsidesref.Add(l.Front.Sector, new HashSet()); - sectorsidesref[l.Front.Sector].Add(l.Front); + // Add only multipart sectors + if(l.Front.Sector.Triangles.IslandVertices.Count > 1) + { + if(!sectorsidesref.ContainsKey(l.Front.Sector)) sectorsidesref[l.Front.Sector] = new HashSet(); + sectorsidesref[l.Front.Sector].Add(l.Front); + } drawnsides.Add(l.Front); } if(l.Back != null && (l.Back.Sector != null && !SectorWasInvalid(l.Back.Sector))) { - if(!sectorsidesref.ContainsKey(l.Back.Sector)) sectorsidesref.Add(l.Back.Sector, new HashSet()); - sectorsidesref[l.Back.Sector].Add(l.Back); + // Add only multipart sectors + if(l.Back.Sector.Triangles.IslandVertices.Count > 1) + { + if(!sectorsidesref.ContainsKey(l.Back.Sector)) sectorsidesref[l.Back.Sector] = new HashSet(); + sectorsidesref[l.Back.Sector].Add(l.Back); + } drawnsides.Add(l.Back); } } @@ -2402,28 +2425,6 @@ namespace CodeImp.DoomBuilder.Geometry return 0; } - //mxd - public static Sector FindSectorContaining(Linedef line, bool front) - { - List sectorsides = FindPotentialSectorAt(line, front); - if(sectorsides == null) return null; - - // Check potential sectors - foreach(LinedefSide sectorside in sectorsides) - { - Sidedef target = (sectorside.Front ? sectorside.Line.Front : sectorside.Line.Back); - if(target != null && target.Sector != null) - { - // Check if target line is inside the found sector - if(target.Sector.Intersect(line.Start.Position, false) && target.Sector.Intersect(line.End.Position, false)) - return target.Sector; - } - } - - // No dice... - return null; - } - #endregion #region ================== Misc Exported Functions diff --git a/Source/Core/Map/BlockMap.cs b/Source/Core/Map/BlockMap.cs index 6711a9c..38e9058 100644 --- a/Source/Core/Map/BlockMap.cs +++ b/Source/Core/Map/BlockMap.cs @@ -105,7 +105,7 @@ namespace CodeImp.DoomBuilder.Map #region ================== Methods // This returns the block coordinates - protected Point GetBlockCoordinates(Vector2D v) + internal Point GetBlockCoordinates(Vector2D v) { return new Point((int)(v.x - range.Left) >> blocksizeshift, (int)(v.y - range.Top) >> blocksizeshift); @@ -119,7 +119,7 @@ namespace CodeImp.DoomBuilder.Map } // This returns true when the given block is inside range - protected bool IsInRange(Point p) + internal bool IsInRange(Point p) { return (p.X >= 0) && (p.X < size.Width) && (p.Y >= 0) && (p.Y < size.Height); } @@ -356,6 +356,9 @@ namespace CodeImp.DoomBuilder.Map // This puts a sector in the blockmap public virtual void AddSector(Sector s) { + //mxd. Check range. Sector can be bigger than blockmap range + if(!range.IntersectsWith(s.BBox)) return; + Point p1 = GetBlockCoordinates(new Vector2D(s.BBox.Left, s.BBox.Top)); Point p2 = GetBlockCoordinates(new Vector2D(s.BBox.Right, s.BBox.Bottom)); p1 = CropToRange(p1); diff --git a/Source/Core/Map/MapSet.cs b/Source/Core/Map/MapSet.cs index 9130a01..dff7a2e 100644 --- a/Source/Core/Map/MapSet.cs +++ b/Source/Core/Map/MapSet.cs @@ -1988,6 +1988,32 @@ namespace CodeImp.DoomBuilder.Map return new RectangleF(l, t, r - l, b - t); } + /// This increases and existing area with the given linedefs. + public static RectangleF IncreaseArea(RectangleF area, ICollection lines) //mxd + { + float l = area.Left; + float t = area.Top; + float r = area.Right; + float b = area.Bottom; + + // Go for all vertices + foreach(Linedef ld in lines) + { + // Adjust boundaries by vertices + if(ld.Start.Position.x < l) l = ld.Start.Position.x; + if(ld.Start.Position.x > r) r = ld.Start.Position.x; + if(ld.Start.Position.y < t) t = ld.Start.Position.y; + if(ld.Start.Position.y > b) b = ld.Start.Position.y; + if(ld.End.Position.x < l) l = ld.End.Position.x; + if(ld.End.Position.x > r) r = ld.End.Position.x; + if(ld.End.Position.y < t) t = ld.End.Position.y; + if(ld.End.Position.y > b) b = ld.End.Position.y; + } + + // Return a rect + return new RectangleF(l, t, r - l, b - t); + } + /// This filters lines by a rectangular area. public static HashSet FilterByArea(ICollection lines, ref RectangleF area) { @@ -2436,12 +2462,21 @@ namespace CodeImp.DoomBuilder.Map if(line.Front == null) linesmissingfront.Add(line); } + // Anything to do? + if(linesmissingfront.Count == 0 && linesmissingback.Count == 0) return; + + // Let's use a blockmap... + RectangleF area = CreateArea(linesmissingfront); + area = IncreaseArea(area, linesmissingback); + BlockMap blockmap = new BlockMap(area); + blockmap.AddSectorsSet(General.Map.Map.Sectors); + // Find sectors to join singlesided lines Dictionary linefrontsectorref = new Dictionary(); foreach(Linedef line in linesmissingfront) { - // Line is now inside a sector? (check from the missing side!) - Sector nearest = Tools.FindSectorContaining(line, true); + // Line is now inside a sector? + Sector nearest = FindSectorContaining(blockmap, line); // We can reattach our line! if(nearest != null) linefrontsectorref[line] = nearest; @@ -2450,8 +2485,8 @@ namespace CodeImp.DoomBuilder.Map Dictionary linebacksectorref = new Dictionary(); foreach(Linedef line in linesmissingback) { - // Line is now inside a sector? (check from the missing side!) - Sector nearest = Tools.FindSectorContaining(line, false); + // Line is now inside a sector? + Sector nearest = FindSectorContaining(blockmap, line); // We can reattach our line! if(nearest != null) linebacksectorref[line] = nearest; @@ -2512,6 +2547,28 @@ namespace CodeImp.DoomBuilder.Map } } + //mxd + private static Sector FindSectorContaining(BlockMap sectorsmap, Linedef line) + { + HashSet blocks = new HashSet + { + sectorsmap.GetBlockAt(line.Start.Position), + sectorsmap.GetBlockAt(line.End.Position), + }; + + foreach(BlockEntry be in blocks) + { + foreach(Sector sector in be.Sectors) + { + // Check if target line is inside the found sector + if(sector.Intersect(line.Start.Position, false) && sector.Intersect(line.End.Position, false)) + return sector; + } + } + + return null; + } + //mxd private static string GetAdjacentMiddleTexture(Vertex v) { @@ -2727,46 +2784,78 @@ namespace CodeImp.DoomBuilder.Map do { + //mxd. Create blockmap + ICollection biggerset, smallerset; + bool keepsmaller; + if(set1.Count > set2.Count) + { + biggerset = set1; + smallerset = set2; + keepsmaller = !keepsecond; + } + else + { + biggerset = set2; + smallerset = set1; + keepsmaller = keepsecond; + } + + RectangleF area = CreateArea(biggerset); + BlockMap blockmap = new BlockMap(area); + blockmap.AddVerticesSet(biggerset); + // No joins yet joined = false; - // Go for all vertices in the first set - foreach(Vertex v1 in set1) + // Go for all vertices in the smaller set + foreach(Vertex v1 in smallerset) { - // Go for all vertices in the second set - foreach(Vertex v2 in set2) + HashSet blocks = new HashSet { - // Check if vertices are close enough - if(v1.DistanceToSq(v2.Position) <= joindist2) + blockmap.GetBlockAt(v1.Position), + blockmap.GetBlockAt(new Vector2D(v1.Position.x + joindist, v1.Position.y + joindist)), + blockmap.GetBlockAt(new Vector2D(v1.Position.x + joindist, v1.Position.y - joindist)), + blockmap.GetBlockAt(new Vector2D(v1.Position.x - joindist, v1.Position.y + joindist)), + blockmap.GetBlockAt(new Vector2D(v1.Position.x - joindist, v1.Position.y - joindist)) + }; + + foreach(BlockEntry be in blocks) + { + if(be == null) continue; + foreach(Vertex v2 in be.Vertices) { - // Check if not the same vertex - if(v1 != v2) + // Check if vertices are close enough + if(v1.DistanceToSq(v2.Position) <= joindist2) { - // Move the second vertex to match the first - v2.Move(v1.Position); - - // Check which one to keep - if(keepsecond) + // Check if not the same vertex + if(v1 != v2) { - // Join the first into the second - // Second is kept, first is removed - v1.Join(v2); - set1.Remove(v1); - set2.Remove(v1); + // Move the second vertex to match the first + v2.Move(v1.Position); + + // Check which one to keep + if(keepsmaller) + { + // Join the first into the second + // Second is kept, first is removed + v1.Join(v2); + biggerset.Remove(v1); + smallerset.Remove(v1); + } + else + { + // Join the second into the first + // First is kept, second is removed + v2.Join(v1); + biggerset.Remove(v2); + smallerset.Remove(v2); + } + + // Count the join + joinsdone++; + joined = true; + break; } - else - { - // Join the second into the first - // First is kept, second is removed - v2.Join(v1); - set1.Remove(v2); - set2.Remove(v2); - } - - // Count the join - joinsdone++; - joined = true; - break; } } } @@ -3176,6 +3265,62 @@ namespace CodeImp.DoomBuilder.Map return closest; } + /// This finds the line closest to the specified position. + public static Linedef NearestLinedef(BlockMap selectionmap, Vector2D pos) //mxd + { + Linedef closest = null; + float distance = float.MaxValue; + + Point p = selectionmap.GetBlockCoordinates(pos); + int minx = p.X; + int maxx = p.X; + int miny = p.Y; + int maxy = p.Y; + int step = 0; + + // Check square block ranges around pos... + while(true) + { + bool noblocksfound = true; + for(int x = minx; x < maxx + 1; x++) + { + for(int y = miny; y < maxy + 1; y++) + { + // Skip inner blocks... + if(x > minx && x < maxx && y > miny && y < maxy) continue; + if(!selectionmap.IsInRange(new Point(x, y))) continue; + + // Go for all linedefs in block + BlockEntry be = selectionmap.Map[x, y]; + foreach(Linedef l in be.Lines) + { + // Calculate distance and check if closer than previous find + float d = l.SafeDistanceToSq(pos, true); + if(d < distance) + { + // This one is closer + closest = l; + distance = d; + } + } + + noblocksfound = false; + } + } + + // Abort if line was found or when outside of blockmap range... + // Check at least 3x3 blocks, because there's a possibility that a line closer to pos exists in a nearby block than in the first block + if(noblocksfound || (closest != null && step > 0)) return closest; + + // Increase search range... + minx--; + maxx++; + miny--; + maxy++; + step++; + } + } + /// This finds the line closest to the specified position. public static Linedef NearestLinedef(ICollection selection, Vector2D pos) { @@ -3223,6 +3368,48 @@ namespace CodeImp.DoomBuilder.Map return closest; } + /// This finds the line closest to the specified position. + public static Linedef NearestLinedefRange(BlockMap selectionmap, Vector2D pos, float maxrange) //mxd + { + Linedef closest = null; + float distance = float.MaxValue; + float maxrangesq = maxrange * maxrange; + HashSet processed = new HashSet(); + + HashSet blocks = new HashSet + { + selectionmap.GetBlockAt(pos), + selectionmap.GetBlockAt(new Vector2D(pos.x + maxrange, pos.y + maxrange)), + selectionmap.GetBlockAt(new Vector2D(pos.x + maxrange, pos.y - maxrange)), + selectionmap.GetBlockAt(new Vector2D(pos.x - maxrange, pos.y + maxrange)), + selectionmap.GetBlockAt(new Vector2D(pos.x - maxrange, pos.y - maxrange)) + }; + + foreach(BlockEntry be in blocks) + { + if(be == null) continue; + + foreach(Linedef l in be.Lines) + { + if(processed.Contains(l)) continue; + + // Calculate distance and check if closer than previous find + float d = l.SafeDistanceToSq(pos, true); + if(d < distance && d <= maxrangesq) + { + // This one is closer + closest = l; + distance = d; + } + + processed.Add(l); + } + } + + // Return result + return closest; + } + /// mxd. This finds the line closest to the specified position excluding given list of linedefs. public Linedef NearestLinedef(Vector2D pos, HashSet linesToExclude) { diff --git a/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs index 7dd2f0c..78c707e 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs @@ -399,6 +399,7 @@ namespace CodeImp.DoomBuilder.BuilderModes else if(editpressed && prevoffset != 0) { int diff = (int)Math.Round((offset - prevoffset) * renderer.Scale); + if(panel.FixedCurve) diff *= Math.Sign(panel.Distance); // Special cases... if(panel.Angle + diff > 0) panel.Angle += diff; } diff --git a/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs b/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs index e92ec98..32357f9 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs @@ -1589,6 +1589,13 @@ namespace CodeImp.DoomBuilder.BuilderModes // Go for all sidedes in the new geometry List newsides = General.Map.Map.GetMarkedSidedefs(true); + List oldlines = General.Map.Map.GetMarkedLinedefs(false); //mxd + + //mxd. Let's use a blockmap... + RectangleF area = MapSet.CreateArea(oldlines); + BlockMap blockmap = new BlockMap(area); + blockmap.AddLinedefsSet(oldlines); + foreach(Sidedef s in newsides) { // Connected to a virtual sector? @@ -1607,7 +1614,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { // Find out in which sector this was pasted Vector2D testpoint = s.Line.GetSidePoint(!s.IsFront); - Linedef nl = MapSet.NearestLinedef(General.Map.Map.GetMarkedLinedefs(false), testpoint); + Linedef nl = MapSet.NearestLinedef(blockmap, testpoint); //mxd if(nl != null) { Sidedef joinsidedef = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back); diff --git a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs index b8db2ce..dd1edcd 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs @@ -1810,6 +1810,11 @@ namespace CodeImp.DoomBuilder.BuilderModes // Go into curve linedefs mode General.Editing.ChangeMode(new CurveLinedefsMode()); } + else + { + //mxd + General.Interface.DisplayStatus(StatusType.Warning, "This action requres a selection!"); + } } [BeginAction("fliplinedefs")] diff --git a/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.Designer.cs b/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.Designer.cs index 1e7449c..4e6d6a7 100644 --- a/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.Designer.cs +++ b/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.Designer.cs @@ -35,12 +35,13 @@ this.distance = new CodeImp.DoomBuilder.Controls.ToolStripNumericUpDown(); this.anglelabel = new System.Windows.Forms.ToolStripLabel(); this.angle = new CodeImp.DoomBuilder.Controls.ToolStripNumericUpDown(); + this.reset = new System.Windows.Forms.ToolStripButton(); this.separator1 = new System.Windows.Forms.ToolStripSeparator(); this.fixedcurve = new System.Windows.Forms.ToolStripButton(); this.separator2 = new System.Windows.Forms.ToolStripSeparator(); this.apply = new System.Windows.Forms.ToolStripButton(); this.cancel = new System.Windows.Forms.ToolStripButton(); - this.reset = new System.Windows.Forms.ToolStripButton(); + this.flip = new System.Windows.Forms.ToolStripButton(); this.toolstrip.SuspendLayout(); this.SuspendLayout(); // @@ -53,6 +54,7 @@ this.distance, this.anglelabel, this.angle, + this.flip, this.reset, this.separator1, this.fixedcurve, @@ -61,7 +63,7 @@ this.cancel}); this.toolstrip.Location = new System.Drawing.Point(0, 0); this.toolstrip.Name = "toolstrip"; - this.toolstrip.Size = new System.Drawing.Size(620, 25); + this.toolstrip.Size = new System.Drawing.Size(760, 25); this.toolstrip.TabIndex = 0; this.toolstrip.Text = "toolStrip1"; // @@ -170,6 +172,17 @@ 0}); this.angle.ValueChanged += new System.EventHandler(this.OnUIValuesChanged); // + // reset + // + this.reset.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.reset.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Reset; + this.reset.ImageTransparentColor = System.Drawing.Color.Magenta; + this.reset.Margin = new System.Windows.Forms.Padding(0, 1, 3, 2); + this.reset.Name = "reset"; + this.reset.Size = new System.Drawing.Size(23, 22); + this.reset.Text = "Reset"; + this.reset.Click += new System.EventHandler(this.reset_Click); + // // separator1 // this.separator1.Name = "separator1"; @@ -212,16 +225,15 @@ this.cancel.Text = "Cancel"; this.cancel.Click += new System.EventHandler(this.cancel_Click); // - // reset + // flip // - this.reset.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.reset.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Reset; - this.reset.ImageTransparentColor = System.Drawing.Color.Magenta; - this.reset.Margin = new System.Windows.Forms.Padding(0, 1, 3, 2); - this.reset.Name = "reset"; - this.reset.Size = new System.Drawing.Size(23, 22); - this.reset.Text = "Reset"; - this.reset.Click += new System.EventHandler(this.reset_Click); + this.flip.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.flip.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Flip; + this.flip.ImageTransparentColor = System.Drawing.Color.Magenta; + this.flip.Name = "flip"; + this.flip.Size = new System.Drawing.Size(23, 22); + this.flip.Text = "Flip Curve"; + this.flip.Click += new System.EventHandler(this.flip_Click); // // CurveLinedefsOptionsPanel // @@ -229,7 +241,7 @@ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.Controls.Add(this.toolstrip); this.Name = "CurveLinedefsOptionsPanel"; - this.Size = new System.Drawing.Size(620, 60); + this.Size = new System.Drawing.Size(760, 60); this.toolstrip.ResumeLayout(false); this.toolstrip.PerformLayout(); this.ResumeLayout(false); @@ -252,5 +264,6 @@ private System.Windows.Forms.ToolStripButton apply; private System.Windows.Forms.ToolStripButton cancel; private System.Windows.Forms.ToolStripButton reset; + private System.Windows.Forms.ToolStripButton flip; } } diff --git a/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.cs b/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.cs index f6b13ce..b687dcd 100644 --- a/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.cs +++ b/Source/Plugins/BuilderModes/Interface/CurveLinedefsOptionsPanel.cs @@ -60,6 +60,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Interface General.Interface.AddButton(distance); General.Interface.AddButton(anglelabel); General.Interface.AddButton(angle); + General.Interface.AddButton(flip); General.Interface.AddButton(reset); General.Interface.AddButton(separator1); General.Interface.AddButton(fixedcurve); @@ -77,6 +78,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Interface General.Interface.RemoveButton(fixedcurve); General.Interface.RemoveButton(separator1); General.Interface.RemoveButton(reset); + General.Interface.RemoveButton(flip); General.Interface.RemoveButton(angle); General.Interface.RemoveButton(anglelabel); General.Interface.RemoveButton(distance); @@ -115,6 +117,11 @@ namespace CodeImp.DoomBuilder.BuilderModes.Interface if(!blockevents && OnValueChanged != null) OnValueChanged(this, EventArgs.Empty); } + private void flip_Click(object sender, EventArgs e) + { + distance.Value = -distance.Value; + } + private void reset_Click(object sender, EventArgs e) { SetValues(CurveLinedefsMode.DEFAULT_VERTICES_COUNT, CurveLinedefsMode.DEFAULT_DISTANCE, CurveLinedefsMode.DEFAULT_ANGLE, false);