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).
This commit is contained in:
MaxED 2016-05-12 11:32:10 +00:00 committed by spherallic
parent 8fdb230f52
commit 59153e6a52
6 changed files with 61 additions and 58 deletions

View file

@ -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<Sidedef> changes = General.Map.Map.GetMarkedSidedefs(true);

View file

@ -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<long> texturehashes = new HashSet<long> { texture.LongName };
@ -4595,7 +4589,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd
List<BaseVisualGeometrySidedef> selectedVisualSides = new List<BaseVisualGeometrySidedef>();
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;

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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);
}

View file

@ -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;