Fixed, Visual mode: texture offsets were updated multiple times when moving texture offsets of several extrafloor sides linked to the same control sidedef.

Fixed, Visual mode: sidedef geometry of sectors affected by "Copy Slope" effect was not updated when the source slope was modified.
This commit is contained in:
MaxED 2016-05-15 00:38:41 +00:00 committed by spherallic
parent 228a71d477
commit cb882a4340
4 changed files with 140 additions and 30 deletions

View file

@ -1920,25 +1920,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);
}
}
}
@ -2897,8 +2921,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();
}

View file

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

View file

@ -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;
//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)
if((copyFloor || copyCeiling) && linedef.Front != null && linedef.Back != null)
{
data.Floor.plane = sourcesectordata.Floor.plane;
sourcesectordata.AddUpdateSector(data.Sector, true);
// 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 ceiling slope?
if(copyCeiling)
{
data.Ceiling.plane = sourcesectordata.Ceiling.plane;
sourcesectordata.AddUpdateSector(data.Sector, true);
}
updatesides = true;
}
//copy ceiling slope?
if(copyCeiling)
// Update outer sidedef geometry
if(updatesides)
{
data.Ceiling.plane = sourcesectordata.Ceiling.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);
}
}
}
//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();
}
}
}
}
}

View file

@ -70,6 +70,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; } }