diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs index c8c9a007aa03c17d75d3b525138f6c4e6157c33f..7960c1a37f3dfadeedf158ad0c2cab57699cbee5 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs @@ -1639,25 +1639,49 @@ namespace CodeImp.DoomBuilder.BuilderModes } //mxd - internal List<IVisualEventReceiver> RemoveDuplicateSidedefs(List<IVisualEventReceiver> objs) + private static IEnumerable<IVisualEventReceiver> RemoveDuplicateSidedefs(IEnumerable<IVisualEventReceiver> objs) { HashSet<Sidedef> processed = new HashSet<Sidedef>(); List<IVisualEventReceiver> result = new List<IVisualEventReceiver>(); - foreach(IVisualEventReceiver i in objs) + if(General.Map.UDMF) { - BaseVisualGeometrySidedef sidedef = i as BaseVisualGeometrySidedef; - if(sidedef != null) + // For UDMF maps, we only need to remove duplicate extrafloor sidedefs + foreach(IVisualEventReceiver i in objs) { - if(!processed.Contains(sidedef.Sidedef)) + if(i is VisualMiddle3D) + { + VisualMiddle3D vm = i as VisualMiddle3D; + if(!processed.Contains(vm.Sidedef)) + { + processed.Add(vm.Sidedef); + result.Add(i); + } + } + else { - processed.Add(sidedef.Sidedef); result.Add(i); } } - else + } + else + { + // For Doom/Hexen maps, we need to remove all duplicates + foreach(IVisualEventReceiver i in objs) { - result.Add(i); + BaseVisualGeometrySidedef sidedef = i as BaseVisualGeometrySidedef; + if(sidedef != null) + { + if(!processed.Contains(sidedef.Sidedef)) + { + processed.Add(sidedef.Sidedef); + result.Add(i); + } + } + else + { + result.Add(i); + } } } @@ -2598,8 +2622,7 @@ namespace CodeImp.DoomBuilder.BuilderModes private void MoveTextureByOffset(int ox, int oy) { PreAction(UndoGroup.TextureOffsetChange); - List<IVisualEventReceiver> objs = GetSelectedObjects(true, true, false, false); - if(!General.Map.UDMF) objs = RemoveDuplicateSidedefs(objs); + IEnumerable<IVisualEventReceiver> objs = RemoveDuplicateSidedefs(GetSelectedObjects(true, true, false, false)); foreach(IVisualEventReceiver i in objs) i.OnChangeTextureOffset(ox, oy, true); PostAction(); } diff --git a/Source/Plugins/BuilderModes/VisualModes/EffectLineSlope.cs b/Source/Plugins/BuilderModes/VisualModes/EffectLineSlope.cs index a89b5ca2e19640d8ae9a1417f584be11d53fc38e..80497f8e68da57fc812962ade23f33399cd58259 100644 --- a/Source/Plugins/BuilderModes/VisualModes/EffectLineSlope.cs +++ b/Source/Plugins/BuilderModes/VisualModes/EffectLineSlope.cs @@ -1,5 +1,6 @@ #region === Copyright (c) 2010 Pascal van der Heiden === +using System.Collections.Generic; using CodeImp.DoomBuilder.Geometry; using CodeImp.DoomBuilder.Map; @@ -114,14 +115,46 @@ namespace CodeImp.DoomBuilder.BuilderModes //mxd. Update outer sidedef geometry if(updatesides) { - foreach(Sidedef side in data.Sector.Sidedefs) + UpdateSectorSides(data.Sector); + + // Update sectors with PlaneCopySlope Effect... + List<SectorData> toupdate = new List<SectorData>(); + foreach(Sector s in data.UpdateAlso.Keys) { - if(side.Other != null && side.Other.Sector != null && data.Mode.VisualSectorExists(side.Other.Sector)) + SectorData osd = data.Mode.GetSectorDataEx(s); + if(osd == null) continue; + foreach(SectorEffect e in osd.Effects) { - BaseVisualSector vs = (BaseVisualSector)data.Mode.GetVisualSector(side.Other.Sector); - vs.GetSidedefParts(side.Other).SetupAllParts(); + if(e is EffectPlaneCopySlope) + { + toupdate.Add(osd); + break; + } } } + + // Do it in 2 steps, because SectorData.Reset() may change SectorData.UpdateAlso collection... + foreach(SectorData sd in toupdate) + { + // Update PlaneCopySlope Effect... + sd.Reset(false); + + // Update outer sides... + UpdateSectorSides(sd.Sector); + } + } + } + + //mxd + private void UpdateSectorSides(Sector s) + { + foreach(Sidedef side in s.Sidedefs) + { + if(side.Other != null && side.Other.Sector != null && data.Mode.VisualSectorExists(side.Other.Sector)) + { + BaseVisualSector vs = (BaseVisualSector)data.Mode.GetVisualSector(side.Other.Sector); + vs.GetSidedefParts(side.Other).SetupAllParts(); + } } } } diff --git a/Source/Plugins/BuilderModes/VisualModes/EffectPlaneCopySlope.cs b/Source/Plugins/BuilderModes/VisualModes/EffectPlaneCopySlope.cs index 946380c32420b023e42363aaefb6b206ce77ed6d..a158ff4b0308bce7e932b14ff109fe39a0e9843c 100644 --- a/Source/Plugins/BuilderModes/VisualModes/EffectPlaneCopySlope.cs +++ b/Source/Plugins/BuilderModes/VisualModes/EffectPlaneCopySlope.cs @@ -1,4 +1,5 @@ -using CodeImp.DoomBuilder.Map; +using System.Collections.Generic; +using CodeImp.DoomBuilder.Map; namespace CodeImp.DoomBuilder.BuilderModes { @@ -26,6 +27,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { Sector sourcesector = null; SectorData sourcesectordata = null; + bool updatesides = false; // Copy slopes from tagged sectors //check which arguments we must use @@ -51,6 +53,8 @@ namespace CodeImp.DoomBuilder.BuilderModes data.Floor.plane = sourcesectordata.Floor.plane; sourcesectordata.AddUpdateSector(data.Sector, true); + + updatesides = true; } } @@ -77,6 +81,8 @@ namespace CodeImp.DoomBuilder.BuilderModes data.Ceiling.plane = sourcesectordata.Ceiling.plane; sourcesectordata.AddUpdateSector(data.Sector, true); + + updatesides = true; } } @@ -105,26 +111,73 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Copy slope across the line - if(!copyFloor && !copyCeiling) return; + if((copyFloor || copyCeiling) && linedef.Front != null && linedef.Back != null) + { + // Get appropriate source sector data + sourcesectordata = data.Mode.GetSectorData(front ? linedef.Back.Sector : linedef.Front.Sector); + if(!sourcesectordata.Updated) sourcesectordata.Update(); - //get appropriate source sector data - sourcesectordata = data.Mode.GetSectorData(front ? linedef.Back.Sector : linedef.Front.Sector); - if(!sourcesectordata.Updated) sourcesectordata.Update(); + //copy floor slope? + if(copyFloor) + { + data.Floor.plane = sourcesectordata.Floor.plane; + sourcesectordata.AddUpdateSector(data.Sector, true); + } - //copy floor slope? - if(copyFloor) + //copy ceiling slope? + if(copyCeiling) + { + data.Ceiling.plane = sourcesectordata.Ceiling.plane; + sourcesectordata.AddUpdateSector(data.Sector, true); + } + + updatesides = true; + } + + // Update outer sidedef geometry + if(updatesides) { - data.Floor.plane = sourcesectordata.Floor.plane; - sourcesectordata.AddUpdateSector(data.Sector, true); + UpdateSectorSides(data.Sector); + + // Update sectors with PlaneCopySlope Effect... + List<SectorData> toupdate = new List<SectorData>(); + foreach(Sector s in data.UpdateAlso.Keys) + { + SectorData osd = data.Mode.GetSectorDataEx(s); + if(osd == null) continue; + foreach(SectorEffect e in osd.Effects) + { + if(e is EffectPlaneCopySlope) + { + toupdate.Add(osd); + break; + } + } + } + + // Do it in 2 steps, because SectorData.Reset() may change SectorData.UpdateAlso collection... + foreach(SectorData sd in toupdate) + { + // Update PlaneCopySlope Effect... + sd.Reset(false); + + // Update outer sides... + UpdateSectorSides(sd.Sector); + } } + } - //copy ceiling slope? - if(copyCeiling) + //mxd + private void UpdateSectorSides(Sector s) + { + foreach(Sidedef side in s.Sidedefs) { - data.Ceiling.plane = sourcesectordata.Ceiling.plane; - sourcesectordata.AddUpdateSector(data.Sector, true); + if(side.Other != null && side.Other.Sector != null && data.Mode.VisualSectorExists(side.Other.Sector)) + { + BaseVisualSector vs = (BaseVisualSector)data.Mode.GetVisualSector(side.Other.Sector); + vs.GetSidedefParts(side.Other).SetupAllParts(); + } } - } } } diff --git a/Source/Plugins/BuilderModes/VisualModes/SectorData.cs b/Source/Plugins/BuilderModes/VisualModes/SectorData.cs index bf49f892c653d60d632051697f5de0971be82586..b156b2d45b28bf5a6ee4a601d636e2a5edb6b293 100644 --- a/Source/Plugins/BuilderModes/VisualModes/SectorData.cs +++ b/Source/Plugins/BuilderModes/VisualModes/SectorData.cs @@ -66,6 +66,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public bool CeilingChanged { get { return ceilingchanged; } set { ceilingchanged |= value; } } public List<SectorLevel> LightLevels { get { return lightlevels; } } public List<Effect3DFloor> ExtraFloors { get { return extrafloors; } } + public List<SectorEffect> Effects { get { return alleffects; } } //mxd public SectorLevel Floor { get { return floor; } } public SectorLevel Ceiling { get { return ceiling; } } public BaseVisualMode Mode { get { return mode; } }