UltimateZoneBuilder/Source/Plugins/BuilderModes/VisualModes/EffectPlaneCopySlope.cs
MaxED 5f13fa1da4 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.
2016-05-15 00:38:41 +00:00

183 lines
4.7 KiB
C#

using System.Collections.Generic;
using CodeImp.DoomBuilder.Map;
namespace CodeImp.DoomBuilder.BuilderModes
{
internal class EffectPlaneCopySlope : SectorEffect
{
// Linedef that is used to create this effect
private readonly Linedef linedef;
private readonly bool front;
public EffectPlaneCopySlope(SectorData data, Linedef sourcelinedef, bool front) : base(data)
{
this.linedef = sourcelinedef;
this.front = front;
// New effect added: This sector needs an update!
if(data.Mode.VisualSectorExists(data.Sector))
{
BaseVisualSector vs = (BaseVisualSector)data.Mode.GetVisualSector(data.Sector);
vs.UpdateSectorGeometry(true);
}
}
// This makes sure we are updated with the source linedef information
public override void Update()
{
Sector sourcesector = null;
SectorData sourcesectordata = null;
bool updatesides = false;
// Copy slopes from tagged sectors
//check which arguments we must use
int floorArg = (front ? 0 : 2);
int ceilingArg = (front ? 1 : 3);
//find sector to align floor to
if(linedef.Args[floorArg] > 0)
{
foreach(Sector s in General.Map.Map.Sectors)
{
if(s.Tags.Contains(linedef.Args[floorArg]))
{
sourcesector = s;
break;
}
}
if(sourcesector != null)
{
sourcesectordata = data.Mode.GetSectorData(sourcesector);
if(!sourcesectordata.Updated) sourcesectordata.Update();
data.Floor.plane = sourcesectordata.Floor.plane;
sourcesectordata.AddUpdateSector(data.Sector, true);
updatesides = true;
}
}
if(linedef.Args[ceilingArg] > 0)
{
//find sector to align ceiling to
if(linedef.Args[ceilingArg] != linedef.Args[floorArg])
{
sourcesector = null;
foreach(Sector s in General.Map.Map.Sectors)
{
if(s.Tags.Contains(linedef.Args[ceilingArg]))
{
sourcesector = s;
break;
}
}
if(sourcesector != null)
{
sourcesectordata = data.Mode.GetSectorData(sourcesector);
if(!sourcesectordata.Updated) sourcesectordata.Update();
data.Ceiling.plane = sourcesectordata.Ceiling.plane;
sourcesectordata.AddUpdateSector(data.Sector, true);
updatesides = true;
}
}
else if(sourcesector != null) //ceiling uses the same sector as floor
{
data.Ceiling.plane = sourcesectordata.Ceiling.plane;
}
}
//check the flags...
bool copyFloor = false;
bool copyCeiling = false;
if(linedef.Args[4] > 0 && linedef.Args[4] != 3 && linedef.Args[4] != 12)
{
if(front)
{
copyFloor = (linedef.Args[4] & 2) == 2;
copyCeiling = (linedef.Args[4] & 8) == 8;
}
else
{
copyFloor = (linedef.Args[4] & 1) == 1;
copyCeiling = (linedef.Args[4] & 4) == 4;
}
}
// Copy slope across the line
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();
//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;
}
// Update outer sidedef geometry
if(updatesides)
{
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();
}
}
}
}
}