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 toupdate = new List(); 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(); } } } } }