From 5d8e62f8873332101ad60662f96ba6c5fb0ac77f Mon Sep 17 00:00:00 2001 From: MaxED Date: Thu, 18 Sep 2014 22:06:35 +0000 Subject: [PATCH] Visual mode: "Select" action with "with the same textures" / "with the same height" modifiers (Shift/Ctrl + LMB) now works when used on sides of a 3d floor. Visual mode: "Select" action with "with the same textures" modifier (Shift + LMB) now selects adjacent sidedefs only when their height intersects with the height of the current sidedef. Visual mode: "Select" action with "with the same textures" modifier (Shift + LMB) was not selecting connected one-sided sidedefs when used on a sidedef without a texture. Cosmetic: fixed a couple of action descriptions in BuilderModes' Actions.cfg. Cosmetic: MainForm.UpdateToolStripSeparators was working incorrectly in some cases. Cosmetic: ErrorChecksForm's title was not updated when no errors were found. --- Source/Core/VisualModes/VisualGeometry.cs | 7 +- Source/Core/Windows/MainForm.cs | 2 +- .../Plugins/BuilderModes/BuilderModes.csproj | 1 + .../BuilderModes/General/BuilderModesTools.cs | 73 ++++++ .../BuilderModes/Interface/ErrorCheckForm.cs | 1 + .../BuilderModes/Resources/Actions.cfg | 6 +- .../VisualModes/BaseVisualGeometrySidedef.cs | 209 ++++++++++++------ .../VisualModes/VisualMiddle3D.cs | 9 +- 8 files changed, 232 insertions(+), 76 deletions(-) create mode 100644 Source/Plugins/BuilderModes/General/BuilderModesTools.cs diff --git a/Source/Core/VisualModes/VisualGeometry.cs b/Source/Core/VisualModes/VisualGeometry.cs index 89ba4d56..4fbad987 100644 --- a/Source/Core/VisualModes/VisualGeometry.cs +++ b/Source/Core/VisualModes/VisualGeometry.cs @@ -42,7 +42,6 @@ namespace CodeImp.DoomBuilder.VisualModes // Desired modulate color private PixelColor modulatecolor; - private Color4 modcolor4; // Selected? protected bool selected; @@ -81,7 +80,6 @@ namespace CodeImp.DoomBuilder.VisualModes internal int VertexOffset { get { return vertexoffset; } set { vertexoffset = value; } } internal int Triangles { get { return triangles; } } internal int RenderPassInt { get { return renderpass; } } - internal Color4 ModColor4 { get { return modcolor4; } } //mxd public Vector3[] BoundingBox { get { return boundingBox; } } @@ -100,7 +98,7 @@ namespace CodeImp.DoomBuilder.VisualModes /// /// Color to modulate the texture pixels with. /// - public PixelColor ModulateColor { get { return modulatecolor; } set { modcolor4 = value.ToColorValue(); modulatecolor = value; } } + public PixelColor ModulateColor { get { return modulatecolor; } set { modulatecolor = value; } } /// /// Returns the VisualSector this geometry has been added to. @@ -248,7 +246,8 @@ namespace CodeImp.DoomBuilder.VisualModes } //mxd - public enum VisualGeometryType{ + public enum VisualGeometryType + { FLOOR, CEILING, WALL_UPPER, diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs index 781ef6c0..f1d6607d 100644 --- a/Source/Core/Windows/MainForm.cs +++ b/Source/Core/Windows/MainForm.cs @@ -1767,7 +1767,7 @@ namespace CodeImp.DoomBuilder.Windows { if (i is ToolStripSeparator) { - i.Visible = !(pvi != null && (!pvi.Visible || pvi is ToolStripSeparator)); + i.Visible = !(pvi == null || (!pvi.Visible || pvi is ToolStripSeparator)); } pvi = i; diff --git a/Source/Plugins/BuilderModes/BuilderModes.csproj b/Source/Plugins/BuilderModes/BuilderModes.csproj index 8ee38227..91714990 100644 --- a/Source/Plugins/BuilderModes/BuilderModes.csproj +++ b/Source/Plugins/BuilderModes/BuilderModes.csproj @@ -275,6 +275,7 @@ + Form diff --git a/Source/Plugins/BuilderModes/General/BuilderModesTools.cs b/Source/Plugins/BuilderModes/General/BuilderModesTools.cs new file mode 100644 index 00000000..2e8235a5 --- /dev/null +++ b/Source/Plugins/BuilderModes/General/BuilderModesTools.cs @@ -0,0 +1,73 @@ +#region ================== Namespaces + +using System; +using System.Drawing; +using CodeImp.DoomBuilder.Map; +using CodeImp.DoomBuilder.VisualModes; + +#endregion + +namespace CodeImp.DoomBuilder.BuilderModes +{ + public static class BuilderModesTools + { + #region ================== Sidedef + + internal static Rectangle GetSidedefPartSize(BaseVisualGeometrySidedef side, VisualGeometryType type) + { + if(type == VisualGeometryType.WALL_MIDDLE_3D) + { + Rectangle rect = new Rectangle(0, 0, 1, 0); + Linedef cl = side.GetControlLinedef(); + if(cl.Front != null && cl.Front.Sector != null) { + rect.Y = cl.Front.Sector.FloorHeight; + rect.Height = cl.Front.GetMiddleHeight(); + } else { + rect.Y = side.Sidedef.Sector.FloorHeight; + rect.Height = side.Sidedef.GetMiddleHeight(); + } + + return rect; + } + + return GetSidedefPartSize(side.Sidedef, type); + } + + public static Rectangle GetSidedefPartSize(Sidedef side, VisualGeometryType type) + { + Rectangle rect = new Rectangle(0, 0, 1, 0); + + switch(type) + { + case VisualGeometryType.WALL_LOWER: + rect.Y = side.Sector.FloorHeight; + rect.Height = side.GetLowHeight(); + break; + + case VisualGeometryType.WALL_UPPER: + if(side.Other != null && side.Other.Sector != null) + { + rect.Y = side.Other.Sector.CeilHeight; + rect.Height = side.GetHighHeight(); + } + else + { + rect.Height = 0; + } + break; + + case VisualGeometryType.WALL_MIDDLE: + rect.Y = side.Sector.FloorHeight; + rect.Height = side.GetMiddleHeight(); + break; + + default: + throw new NotImplementedException("GetSidedefPartSize: got unsupported geometry type: '" + type + "'"); + } + + return rect; + } + + #endregion + } +} diff --git a/Source/Plugins/BuilderModes/Interface/ErrorCheckForm.cs b/Source/Plugins/BuilderModes/Interface/ErrorCheckForm.cs index e26cad9c..67bc887c 100644 --- a/Source/Plugins/BuilderModes/Interface/ErrorCheckForm.cs +++ b/Source/Plugins/BuilderModes/Interface/ErrorCheckForm.cs @@ -199,6 +199,7 @@ namespace CodeImp.DoomBuilder.BuilderModes running = false; blockmap.Dispose(); blockmap = null; + UpdateTitle(); //mxd // When no results found, show "no results" and disable the list if(resultslist.Count == 0) { diff --git a/Source/Plugins/BuilderModes/Resources/Actions.cfg b/Source/Plugins/BuilderModes/Resources/Actions.cfg index 35e1cd60..e6008c51 100644 --- a/Source/Plugins/BuilderModes/Resources/Actions.cfg +++ b/Source/Plugins/BuilderModes/Resources/Actions.cfg @@ -986,7 +986,7 @@ resettexture { title = "Reset Texture Offsets"; category = "visual"; - description = "Resets the texture offsets on the targeted or selected sidedef to 0, 0."; + description = "Resets the texture offsets on the targeted or selected sidedef."; allowkeys = true; allowmouse = true; allowscroll = true; @@ -997,7 +997,7 @@ resettextureudmf { title = "Reset Local Texture Offsets (UDMF)"; category = "visual"; - description = "Resets upper/middle/lower texture offsets on the targeted or selected sidedef to 0, 0. Also resets sidedef's scale and floor/ceiling's scale and rotation."; + description = "Resets upper/middle/lower texture offsets and scale on the targeted or selected sidedef. Resets texture offsets, rotation and scale on targeted or selected floors/ceilings."; allowkeys = true; allowmouse = true; allowscroll = true; @@ -1093,7 +1093,7 @@ pastepropertiesoptions { title = "Paste Properties Options"; category = "edit"; - description = "Opens a window, which lets you pick properties for 'Copy Properties' and 'Paste Properties' actions."; + description = "Opens a window, which lets you pick which properties to paste using 'Paste Properties' action."; allowkeys = true; allowmouse = false; allowscroll = false; diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs index 0be08428..15ce3606 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs @@ -397,13 +397,20 @@ namespace CodeImp.DoomBuilder.BuilderModes } //mxd - protected void selectNeighbours(string texture, bool select, bool withSameTexture, bool withSameHeight) { + protected void selectNeighbours(string texture, bool select, bool withSameTexture, bool withSameHeight) + { if(Sidedef.Sector == null || (!withSameTexture && !withSameHeight)) return; - if(select && !selected) { + Rectangle rect = BuilderModesTools.GetSidedefPartSize(this, geoType); + if(rect.Height == 0) return; + + if(select && !selected) + { selected = true; mode.AddSelectedObject(this); - } else if(!select && selected) { + } + else if(!select && selected) + { selected = false; mode.RemoveSelectedObject(this); } @@ -411,43 +418,20 @@ namespace CodeImp.DoomBuilder.BuilderModes //select List connectedLines = new List(); - foreach(Linedef line in Sidedef.Line.Start.Linedefs) { + foreach(Linedef line in Sidedef.Line.Start.Linedefs) + { if(line.Index == Sidedef.Line.Index) continue; connectedLines.Add(line); } - foreach(Linedef line in Sidedef.Line.End.Linedefs) { + foreach(Linedef line in Sidedef.Line.End.Linedefs) + { if(line.Index == Sidedef.Line.Index) continue; if(!connectedLines.Contains(line)) connectedLines.Add(line); } - int floorHeight = 0; - int ceilingHeight = 0; - - if (withSameHeight) { - bool haveBackSector = Sidedef.Other != null && Sidedef.Other.Sector != null; - - if(geoType == VisualGeometryType.WALL_LOWER) { - floorHeight = Sidedef.Sector.FloorHeight; - ceilingHeight = (haveBackSector ? Sidedef.Other.Sector.FloorHeight : Sidedef.Sector.CeilHeight); - } else if(geoType == VisualGeometryType.WALL_UPPER) { - floorHeight = (haveBackSector ? Sidedef.Other.Sector.CeilHeight : Sidedef.Sector.FloorHeight); - ceilingHeight = Sidedef.Sector.CeilHeight; - } else if(geoType == VisualGeometryType.WALL_MIDDLE) { - floorHeight = Sidedef.Sector.FloorHeight; - ceilingHeight = Sidedef.Sector.CeilHeight; - } else { //should be WALL_MIDDLE_3D - Linedef cl = GetControlLinedef(); - if(cl.Front != null && cl.Front.Sector != null) { - floorHeight = cl.Front.Sector.FloorHeight; - ceilingHeight = cl.Front.Sector.CeilHeight; - } else { - floorHeight = Sidedef.Sector.FloorHeight; - ceilingHeight = Sidedef.Sector.CeilHeight; - } - } - } - - foreach(Linedef line in connectedLines) { + // Check connected lines + foreach(Linedef line in connectedLines) + { bool addFrontTop = false; bool addFrontMiddle = false; bool addFrontBottom = false; @@ -455,59 +439,150 @@ namespace CodeImp.DoomBuilder.BuilderModes bool addBackMiddle = false; bool addBackBottom = false; - if(withSameTexture) { - if(line.Front != null) { - addFrontTop = (line.Front.HighTexture == texture && line.Front.HighRequired()); - addFrontMiddle = (texture != "-" && line.Front.MiddleTexture == texture && line.Front.Sector.CeilHeight > line.Front.Sector.FloorHeight); - addFrontBottom = (line.Front.LowTexture == texture && line.Front.LowRequired()); + bool lineHasFrontSector = (line.Front != null && line.Front.Sector != null); + bool lineHasBackSector = (line.Back != null && line.Back.Sector != null); + bool doublesided = (lineHasFrontSector && lineHasBackSector); + + List extrasides = new List(); + + // Gather 3d floor sides + if (doublesided) + { + BaseVisualSector s = mode.GetVisualSector(line.Front.Sector) as BaseVisualSector; + if (s != null) { + extrasides.AddRange(s.GetSidedefParts(line.Front).middle3d.ToArray()); } - if(line.Back != null) { - addBackTop = (line.Back.HighTexture == texture && line.Back.HighRequired()); - addBackMiddle = (texture != "-" && line.Back.MiddleTexture == texture && line.Back.Sector.CeilHeight > line.Back.Sector.FloorHeight); - addBackBottom = (line.Back.LowTexture == texture && line.Back.LowRequired()); + s = mode.GetVisualSector(line.Back.Sector) as BaseVisualSector; + if(s != null) { + extrasides.AddRange(s.GetSidedefParts(line.Back).middle3d.ToArray()); } } - if(withSameHeight) { - bool lineHasFrontSector = line.Front != null && line.Front.Sector != null; - bool lineHasBackSector = line.Back != null && line.Back.Sector != null; + // Add regular sides + if(withSameTexture) + { + if(line.Front != null) + { + addFrontTop = (line.Front.HighTexture == texture + && line.Front.HighRequired() + && BuilderModesTools.GetSidedefPartSize(line.Front, VisualGeometryType.WALL_UPPER).IntersectsWith(rect)); + + addFrontMiddle = (line.Front.MiddleTexture == texture + && line.Front.MiddleRequired() + && line.Front.GetMiddleHeight() > 0 + && BuilderModesTools.GetSidedefPartSize(line.Front, VisualGeometryType.WALL_MIDDLE).IntersectsWith(rect)); + + addFrontBottom = (line.Front.LowTexture == texture + && line.Front.LowRequired() + && BuilderModesTools.GetSidedefPartSize(line.Front, VisualGeometryType.WALL_LOWER).IntersectsWith(rect)); - //upper parts match? - if((!withSameTexture || addFrontTop) && lineHasFrontSector && line.Front.HighRequired()) { - addFrontTop = (line.Front.Sector.CeilHeight == ceilingHeight && line.Back.Sector.CeilHeight == floorHeight); } - if((!withSameTexture || addBackTop) && lineHasBackSector && line.Back.HighRequired()) { - addBackTop = (line.Back.Sector.CeilHeight == ceilingHeight && line.Front.Sector.CeilHeight == floorHeight); + if(line.Back != null) + { + addBackTop = (line.Back.HighTexture == texture + && line.Back.HighRequired() + && BuilderModesTools.GetSidedefPartSize(line.Back, VisualGeometryType.WALL_UPPER).IntersectsWith(rect)); + + addBackMiddle = (line.Back.MiddleTexture == texture + && line.Back.MiddleRequired() + && line.Back.GetMiddleHeight() > 0 + && BuilderModesTools.GetSidedefPartSize(line.Back, VisualGeometryType.WALL_MIDDLE).IntersectsWith(rect)); + + addBackBottom = (line.Back.LowTexture == texture + && line.Back.LowRequired() + && BuilderModesTools.GetSidedefPartSize(line.Back, VisualGeometryType.WALL_LOWER).IntersectsWith(rect)); } - //middle parts match? - if((!withSameTexture || addFrontMiddle) && lineHasFrontSector && line.Front.Sector.CeilHeight > line.Front.Sector.FloorHeight) { - addFrontMiddle = (line.Front.Sector.CeilHeight == ceilingHeight && line.Front.Sector.FloorHeight == floorHeight); + // Add 3d floor sides + List filtered = new List(); + foreach(VisualMiddle3D side3d in extrasides) + { + Sidedef controlside = side3d.GetControlLinedef().Front; + if (controlside.MiddleTexture == texture && BuilderModesTools.GetSidedefPartSize(controlside, VisualGeometryType.WALL_MIDDLE).IntersectsWith(rect)) + { + filtered.Add(side3d); + } } - if((!withSameTexture || addBackMiddle) && lineHasBackSector && line.Back.Sector.CeilHeight > line.Back.Sector.FloorHeight) { - addBackMiddle = (line.Back.Sector.CeilHeight == ceilingHeight && line.Back.Sector.FloorHeight == floorHeight); - } - - //lower parts match? - if((!withSameTexture || addFrontBottom) && lineHasFrontSector && line.Front.LowRequired()) { - addFrontBottom = (line.Back.Sector.FloorHeight == ceilingHeight && line.Front.Sector.FloorHeight == floorHeight); - } - - if((!withSameTexture || addBackBottom) && lineHasBackSector && line.Back.LowRequired()) { - addBackBottom = (line.Front.Sector.FloorHeight == ceilingHeight && line.Back.Sector.FloorHeight == floorHeight); - } + extrasides = filtered; } - //select front? + if(withSameHeight && rect.Height > 0) + { + // Upper parts match? + if((!withSameTexture || addFrontTop) && doublesided && line.Front.HighRequired()) + { + Rectangle r = BuilderModesTools.GetSidedefPartSize(line.Front, VisualGeometryType.WALL_UPPER); + addFrontTop = (rect.Height == r.Height && rect.Y == r.Y); + } + + if((!withSameTexture || addBackTop) && doublesided && line.Back.HighRequired()) + { + Rectangle r = BuilderModesTools.GetSidedefPartSize(line.Back, VisualGeometryType.WALL_UPPER); + addBackTop = (rect.Height == r.Height && rect.Y == r.Y); + } + + // Middle parts match? + if((!withSameTexture || addFrontMiddle) + && lineHasFrontSector + && (line.Front.MiddleRequired() || line.Front.LongMiddleTexture != MapSet.EmptyLongName) ) + { + Rectangle r = BuilderModesTools.GetSidedefPartSize(line.Front, VisualGeometryType.WALL_MIDDLE); + addFrontMiddle = (rect.Height == r.Height && rect.Y == r.Y); + } + + if((!withSameTexture || addBackMiddle) + && lineHasBackSector + && (line.Back.MiddleRequired() || line.Back.LongMiddleTexture != MapSet.EmptyLongName)) + { + Rectangle r = BuilderModesTools.GetSidedefPartSize(line.Back, VisualGeometryType.WALL_MIDDLE); + addBackMiddle = (rect.Height == r.Height && rect.Y == r.Y); + } + + // Lower parts match? + if((!withSameTexture || addFrontBottom) && doublesided && line.Front.LowRequired()) + { + Rectangle r = BuilderModesTools.GetSidedefPartSize(line.Front, VisualGeometryType.WALL_LOWER); + addFrontBottom = (rect.Height == r.Height && rect.Y == r.Y); + } + + if((!withSameTexture || addBackBottom) && doublesided && line.Back.LowRequired()) + { + Rectangle r = BuilderModesTools.GetSidedefPartSize(line.Back, VisualGeometryType.WALL_LOWER); + addBackBottom = (rect.Height == r.Height && rect.Y == r.Y); + } + + // 3d floor parts match? + List filtered = new List(); + foreach(VisualMiddle3D side3d in extrasides) + { + Sidedef controlside = side3d.GetControlLinedef().Front; + Rectangle r = BuilderModesTools.GetSidedefPartSize(controlside, VisualGeometryType.WALL_MIDDLE); + if(rect.Height == r.Height && rect.Y == r.Y) + { + filtered.Add(side3d); + } + } + + extrasides = filtered; + } + + // Select front? if(addFrontTop || addFrontMiddle || addFrontBottom) mode.SelectSideParts(line.Front, addFrontTop, addFrontMiddle, addFrontBottom, select, withSameTexture, withSameHeight); - //select back? + // Select back? if(addBackTop || addBackMiddle || addBackBottom) mode.SelectSideParts(line.Back, addBackTop, addBackMiddle, addBackBottom, select, withSameTexture, withSameHeight); + + // Select 3d floor sides? + foreach (VisualMiddle3D side3d in extrasides) + { + if( (select && !side3d.Selected) || (!select && side3d.Selected) ) + side3d.SelectNeighbours(select, withSameTexture, withSameHeight); + } } } diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs b/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs index 26417543..e171a6ee 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs @@ -356,9 +356,16 @@ namespace CodeImp.DoomBuilder.BuilderModes } //mxd - public override Linedef GetControlLinedef() { + public override Linedef GetControlLinedef() + { return extrafloor.Linedef; } + + //mxd + public override void SelectNeighbours(bool select, bool withSameTexture, bool withSameHeight) + { + selectNeighbours(extrafloor.Linedef.Front.MiddleTexture, select, withSameTexture, withSameHeight); + } #endregion }