From 59153e6a52af4c074925d7e521388a037a179c75 Mon Sep 17 00:00:00 2001 From: MaxED Date: Thu, 12 May 2016 11:32:10 +0000 Subject: [PATCH] Changed, Visual mode: "Auto-align textures" and "Paste Textures Floodfill" actions now use visual mode geometry to determine whether a sidedef part should be processed. This fixes inability to apply said actions to sidedef parts only visible because of slopes. Fixed, Visual mode: both "With same texture" and "With same height" Select modifiers are now checked when both of them are used at once (previously a sidedef part/floor/ceiling was selected when any of those matched). --- .../VisualModes/BaseVisualGeometrySidedef.cs | 8 +-- .../VisualModes/BaseVisualMode.cs | 63 ++++++++++--------- .../VisualModes/IVisualEventReceiver.cs | 8 ++- .../VisualModes/NullVisualEventReceiver.cs | 3 +- .../BuilderModes/VisualModes/VisualCeiling.cs | 16 ++--- .../BuilderModes/VisualModes/VisualFloor.cs | 21 ++++--- 6 files changed, 61 insertions(+), 58 deletions(-) diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs index 712864b..6e2a8b5 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs @@ -652,12 +652,6 @@ namespace CodeImp.DoomBuilder.BuilderModes } } - //mxd - public virtual bool IsSelected() - { - return selected; - } - //mxd protected void FitTexture(FitTextureOptions options) { @@ -1082,7 +1076,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Do the alignment - Tools.FloodfillTextures(this.Sidedef, oldtexturelong, newtexture, false); + BuilderModesTools.FloodfillTextures(mode, Sidedef, texturehashes, newtexture, false); // Get the changed sidedefs List changes = General.Map.Map.GetMarkedSidedefs(true); diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs index ae24ac1..ab0997a 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs @@ -640,7 +640,7 @@ namespace CodeImp.DoomBuilder.BuilderModes foreach(IVisualEventReceiver obj in selectedobjects) { - if(!obj.IsSelected()) continue; + if(!obj.Selected) continue; if(obj is BaseVisualThing) numThings++; else if(obj is BaseVisualVertex) numVerts++; @@ -2203,7 +2203,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { if(General.Interface.AltState) { - target.SelectNeighbours(target.IsSelected(), General.Interface.ShiftState, General.Interface.CtrlState); + target.SelectNeighbours(target.Selected, General.Interface.ShiftState, General.Interface.CtrlState); } else { @@ -2211,7 +2211,7 @@ namespace CodeImp.DoomBuilder.BuilderModes selectedobjects.CopyTo(selection); foreach(IVisualEventReceiver obj in selection) - obj.SelectNeighbours(target.IsSelected(), General.Interface.ShiftState, General.Interface.CtrlState); + obj.SelectNeighbours(target.Selected, General.Interface.ShiftState, General.Interface.CtrlState); } } @@ -4484,7 +4484,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Wrap the value within the width of the texture (to prevent ridiculous values) // NOTE: We don't use ScaledWidth here because the texture offset is in pixels, not mappixels - if(texture.IsImageLoaded && Tools.SidedefTextureMatch(j.sidedef, texture.LongName)) + if(texture.IsImageLoaded && BuilderModesTools.SidedefTextureMatch(this, j.sidedef, texturehashes)) { if (alignx) { @@ -4529,7 +4529,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Wrap the value within the width of the texture (to prevent ridiculous values) // NOTE: We don't use ScaledWidth here because the texture offset is in pixels, not mappixels - if(texture.IsImageLoaded && Tools.SidedefTextureMatch(j.sidedef, texture.LongName)) + if(texture.IsImageLoaded && BuilderModesTools.SidedefTextureMatch(this, j.sidedef, texturehashes)) { if(alignx) j.sidedef.OffsetX %= texture.Width; if (aligny) @@ -4556,7 +4556,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // When resetsidemarks is set to true, all sidedefs will first be marked false (not aligned). // Setting resetsidemarks to false is usefull to align only within a specific selection // (set the marked property to true for the sidedefs outside the selection) - private void AutoAlignTexturesUDMF(BaseVisualGeometrySidedef start, ImageData texture, bool alignx, bool aligny, bool resetsidemarks, bool checkSelectedSidedefParts) + private void AutoAlignTexturesUDMF(BaseVisualGeometrySidedef start, ImageData texture, bool alignx, bool aligny, bool resetsidemarks, bool checkselectedsidedefparts) { // Mark all sidedefs false (they will be marked true when the texture is aligned) if(resetsidemarks) General.Map.Map.ClearMarkedSidedefs(false); @@ -4566,14 +4566,8 @@ namespace CodeImp.DoomBuilder.BuilderModes float scalex = (General.Map.Config.ScaledTextureOffsets && !texture.WorldPanning) ? texture.Scale.x : 1.0f; float scaley = (General.Map.Config.ScaledTextureOffsets && !texture.WorldPanning) ? texture.Scale.y : 1.0f; - SidedefAlignJob first = new SidedefAlignJob(); - first.sidedef = start.Sidedef; - first.offsetx = start.Sidedef.OffsetX; - - if(start.GeometryType == VisualGeometryType.WALL_MIDDLE_3D) - first.controlSide = start.GetControlLinedef().Front; - else - first.controlSide = start.Sidedef; + SidedefAlignJob first = new SidedefAlignJob { sidedef = start.Sidedef, offsetx = start.Sidedef.OffsetX }; + first.controlSide = (start.GeometryType == VisualGeometryType.WALL_MIDDLE_3D ? start.GetControlLinedef().Front : start.Sidedef); //mxd. We potentially need to deal with 2 textures (because of long and short texture names)... HashSet texturehashes = new HashSet { texture.LongName }; @@ -4595,7 +4589,7 @@ namespace CodeImp.DoomBuilder.BuilderModes //mxd List selectedVisualSides = new List(); - if(checkSelectedSidedefParts && !singleselection) + if(checkselectedsidedefparts && !singleselection) { foreach(IVisualEventReceiver i in selectedobjects) { @@ -4667,23 +4661,34 @@ namespace CodeImp.DoomBuilder.BuilderModes while(todo.Count > 0) { Vertex v; - float forwardoffset; - float backwardoffset; + float forwardoffset, backwardoffset; + bool matchtop = false; + bool matchmid = false; + bool matchbottom = false; // Get the align job to do SidedefAlignJob j = todo.Pop(); - bool matchtop = (!j.sidedef.Marked && (!singleselection || texturehashes.Contains(j.sidedef.LongHighTexture)) && j.sidedef.HighRequired()); - bool matchbottom = (!j.sidedef.Marked && (!singleselection || texturehashes.Contains(j.sidedef.LongLowTexture)) && j.sidedef.LowRequired()); - bool matchmid = ((!singleselection || texturehashes.Contains(j.controlSide.LongMiddleTexture)) && (j.controlSide.MiddleRequired() || j.controlSide.LongMiddleTexture != MapSet.EmptyLongName)); //mxd - - //mxd. If there's a selection, check if matched part is actually selected - if(checkSelectedSidedefParts && !singleselection) + //mxd. Get visual parts + if(VisualSectorExists(j.sidedef.Sector)) { - if(matchtop) matchtop = SidePartIsSelected(selectedVisualSides, j.sidedef, VisualGeometryType.WALL_UPPER); - if(matchbottom) matchbottom = SidePartIsSelected(selectedVisualSides, j.sidedef, VisualGeometryType.WALL_LOWER); - if(matchmid) matchmid = SidePartIsSelected(selectedVisualSides, j.sidedef, VisualGeometryType.WALL_MIDDLE) || - SidePartIsSelected(selectedVisualSides, j.sidedef, VisualGeometryType.WALL_MIDDLE_3D); + VisualSidedefParts parts = ((BaseVisualSector)GetVisualSector(j.sidedef.Sector)).GetSidedefParts(j.sidedef); + VisualSidedefParts controlparts = (j.sidedef != j.controlSide ? ((BaseVisualSector)GetVisualSector(j.controlSide.Sector)).GetSidedefParts(j.controlSide) : parts); + + matchtop = (!j.sidedef.Marked && (!singleselection || texturehashes.Contains(j.sidedef.LongHighTexture)) && (parts.upper != null && parts.upper.Triangles > 0)); + matchbottom = (!j.sidedef.Marked && (!singleselection || texturehashes.Contains(j.sidedef.LongLowTexture)) && (parts.lower != null && parts.lower.Triangles > 0)); + matchmid = ((!singleselection || texturehashes.Contains(j.controlSide.LongMiddleTexture)) + && ((controlparts.middledouble != null && controlparts.middledouble.Triangles > 0) || (controlparts.middlesingle != null && controlparts.middlesingle.Triangles > 0))); //mxd + + //mxd. If there's a selection, check if matched part is actually selected + if(checkselectedsidedefparts && !singleselection) + { + if(matchtop) matchtop = parts.upper.Selected; + if(matchbottom) matchbottom = parts.lower.Selected; + if(matchmid) matchmid = ((parts.middledouble != null && parts.middledouble.Selected) + || (parts.middlesingle != null && parts.middlesingle.Selected) + || SidePartIsSelected(selectedVisualSides, j.sidedef, VisualGeometryType.WALL_MIDDLE_3D)); + } } if(!matchbottom && !matchtop && !matchmid) continue; //mxd @@ -4930,7 +4935,7 @@ namespace CodeImp.DoomBuilder.BuilderModes foreach(Sidedef s in controlSides) { - if(!singleselection || Tools.SidedefTextureMatch(s, texturelongnames)) + if(!singleselection || BuilderModesTools.SidedefTextureMatch(this, s, texturelongnames)) { SidedefAlignJob nj = new SidedefAlignJob(); nj.forward = forward; @@ -4948,7 +4953,7 @@ namespace CodeImp.DoomBuilder.BuilderModes foreach(Sidedef s in controlSides) { - if(!singleselection || Tools.SidedefTextureMatch(s, texturelongnames)) + if(!singleselection || BuilderModesTools.SidedefTextureMatch(this, s, texturelongnames)) { SidedefAlignJob nj = new SidedefAlignJob(); nj.forward = forward; diff --git a/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs b/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs index 2cee5b7..64a5640 100644 --- a/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs +++ b/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs @@ -24,6 +24,9 @@ namespace CodeImp.DoomBuilder.BuilderModes { internal interface IVisualEventReceiver { + //mxd. Properties + bool Selected { get; } + // The events that must be handled void OnSelectBegin(); void OnSelectEnd(); @@ -62,7 +65,6 @@ namespace CodeImp.DoomBuilder.BuilderModes // Other methods string GetTextureName(); - void SelectNeighbours(bool select, bool matchtexture, bool matchheight); //mxd - bool IsSelected(); //mxd - } + void SelectNeighbours(bool select, bool matchtexture, bool matchheight); //mxd + } } diff --git a/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs b/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs index 857ab88..dce96a4 100644 --- a/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs +++ b/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs @@ -25,6 +25,8 @@ namespace CodeImp.DoomBuilder.BuilderModes // This doesn't do jack shit. internal class NullVisualEventReceiver : IVisualEventReceiver { + public bool Selected { get { return false; } } //mxd + public void OnSelectBegin() { } public void OnSelectEnd() { } public void OnEditBegin() { } @@ -59,6 +61,5 @@ namespace CodeImp.DoomBuilder.BuilderModes public void ApplyLinedefFlag(string flag, bool set) { } public string GetTextureName() { return ""; } public void SelectNeighbours(bool select, bool withSameTexture, bool withSameHeight) { } //mxd - public bool IsSelected() { return false; } //mxd } } diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs b/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs index 3bcc4ca..4e06645 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs @@ -634,8 +634,8 @@ namespace CodeImp.DoomBuilder.BuilderModes // When current ceiling is part of a 3d floor, it looks like a floor, so we need to select adjacent floors if(level.sector != Sector.Sector && !regularorvavoom) { - if((withSameTexture && side.Other.Sector.LongFloorTexture == level.sector.LongCeilTexture) || - (withSameHeight && side.Other.Sector.FloorHeight == level.sector.CeilHeight)) + if((!withSameTexture || side.Other.Sector.LongFloorTexture == level.sector.LongCeilTexture) && + (!withSameHeight || side.Other.Sector.FloorHeight == level.sector.CeilHeight)) { neighbours.Add(side.Other.Sector); @@ -647,8 +647,8 @@ namespace CodeImp.DoomBuilder.BuilderModes else // Regular ceiling or vavoom-type extra ceiling { // (De)select adjacent ceilings - if((withSameTexture && side.Other.Sector.LongCeilTexture == level.sector.LongCeilTexture) || - (withSameHeight && side.Other.Sector.CeilHeight == level.sector.CeilHeight)) + if((!withSameTexture || side.Other.Sector.LongCeilTexture == level.sector.LongCeilTexture) && + (!withSameHeight || side.Other.Sector.CeilHeight == level.sector.CeilHeight)) { neighbours.Add(side.Other.Sector); @@ -662,8 +662,8 @@ namespace CodeImp.DoomBuilder.BuilderModes foreach(VisualCeiling ec in vs.ExtraCeilings) { if(select == ec.Selected || ec.extrafloor.VavoomType != regularorvavoom) continue; - if((withSameTexture && level.sector.LongCeilTexture == ec.level.sector.LongCeilTexture) || - (withSameHeight && level.sector.CeilHeight == ec.level.sector.CeilHeight)) + if((!withSameTexture || level.sector.LongCeilTexture == ec.level.sector.LongCeilTexture) && + (!withSameHeight || level.sector.CeilHeight == ec.level.sector.CeilHeight)) { ec.SelectNeighbours(select, withSameTexture, withSameHeight); } @@ -673,8 +673,8 @@ namespace CodeImp.DoomBuilder.BuilderModes foreach(VisualFloor ef in vs.ExtraFloors) { if(select == ef.Selected || ef.ExtraFloor.VavoomType == regularorvavoom) continue; - if((withSameTexture && level.sector.LongCeilTexture == ef.Level.sector.LongFloorTexture) || - (withSameHeight && level.sector.CeilHeight == ef.Level.sector.FloorHeight)) + if((!withSameTexture || level.sector.LongCeilTexture == ef.Level.sector.LongFloorTexture) && + (!withSameHeight || level.sector.CeilHeight == ef.Level.sector.FloorHeight)) { ef.SelectNeighbours(select, withSameTexture, withSameHeight); } diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs b/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs index 888ff2c..c6f6710 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs @@ -588,8 +588,8 @@ namespace CodeImp.DoomBuilder.BuilderModes // When current floor is part of a 3d floor, it looks like a ceiling, so we need to select adjacent ceilings if(level.sector != Sector.Sector && !regularorvavoom) { - if((withSameTexture && side.Other.Sector.LongCeilTexture == level.sector.LongFloorTexture) || - (withSameHeight && side.Other.Sector.CeilHeight == level.sector.FloorHeight)) + if((!withSameTexture || side.Other.Sector.LongCeilTexture == level.sector.LongFloorTexture) && + (!withSameHeight || side.Other.Sector.CeilHeight == level.sector.FloorHeight)) { neighbours.Add(side.Other.Sector); @@ -601,8 +601,8 @@ namespace CodeImp.DoomBuilder.BuilderModes else // Regular floor or vavoom-type extrafloor { // (De)select adjacent floor - if((withSameTexture && side.Other.Sector.LongFloorTexture == level.sector.LongFloorTexture) || - (withSameHeight && side.Other.Sector.FloorHeight == level.sector.FloorHeight)) + if((!withSameTexture || side.Other.Sector.LongFloorTexture == level.sector.LongFloorTexture) && + (!withSameHeight || side.Other.Sector.FloorHeight == level.sector.FloorHeight)) { neighbours.Add(side.Other.Sector); @@ -616,8 +616,8 @@ namespace CodeImp.DoomBuilder.BuilderModes foreach(VisualFloor ef in vs.ExtraFloors) { if(select == ef.Selected || ef.extrafloor.VavoomType != regularorvavoom) continue; - if((withSameTexture && level.sector.LongFloorTexture == ef.level.sector.LongFloorTexture) || - (withSameHeight && level.sector.FloorHeight == ef.level.sector.FloorHeight)) + if((!withSameTexture || level.sector.LongFloorTexture == ef.level.sector.LongFloorTexture) && + (!withSameHeight || level.sector.FloorHeight == ef.level.sector.FloorHeight)) { ef.SelectNeighbours(select, withSameTexture, withSameHeight); } @@ -627,8 +627,8 @@ namespace CodeImp.DoomBuilder.BuilderModes foreach(VisualCeiling ec in vs.ExtraCeilings) { if(select == ec.Selected || ec.ExtraFloor.VavoomType == regularorvavoom) continue; - if((withSameTexture && level.sector.LongFloorTexture == ec.Level.sector.LongCeilTexture) || - (withSameHeight && level.sector.FloorHeight == ec.Level.sector.CeilHeight)) + if((!withSameTexture || level.sector.LongFloorTexture == ec.Level.sector.LongCeilTexture) && + (!withSameHeight || level.sector.FloorHeight == ec.Level.sector.CeilHeight)) { ec.SelectNeighbours(select, withSameTexture, withSameHeight); } @@ -664,8 +664,9 @@ namespace CodeImp.DoomBuilder.BuilderModes slopeSource = side.Line; isFront = true; break; - } - else if(side.Line.Args[0] == 2 && side.Line.Back != null && side.Line.Back == side) + } + + if(side.Line.Args[0] == 2 && side.Line.Back != null && side.Line.Back == side) { slopeSource = side.Line; break;