// This updates this virtual the sector and neightbours if needed public void UpdateSectorGeometry(bool includeneighbours) { if (isupdating) { return; } isupdating = true; changed = true; // Not sure what from this part we need, so commented out for now SectorData data = GetSectorData(); data.Reset(); // Update sectors that rely on this sector foreach (KeyValuePair <Sector, bool> s in data.UpdateAlso) { if (mode.VisualSectorExists(s.Key)) { BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(s.Key); vs.UpdateSectorGeometry(s.Value); } } // Go for all things in this sector foreach (Thing t in General.Map.Map.Things) { if (t.Sector == this.Sector) { if (mode.VisualThingExists(t)) { // Update thing BaseVisualThing vt = (mode.GetVisualThing(t) as BaseVisualThing); vt.Changed = true; } } } if (includeneighbours) { // Also rebuild surrounding sectors, because outside sidedefs may need to be adjusted foreach (Sidedef sd in this.Sector.Sidedefs) { if (sd.Other != null) { if (mode.VisualSectorExists(sd.Other.Sector)) { BaseVisualSector bvs = (BaseVisualSector)mode.GetVisualSector(sd.Other.Sector); bvs.Changed = true; } } } } isupdating = false; }
// Insert middle texture public virtual void OnInsert() { // No middle texture yet? if (!Sidedef.MiddleRequired() && (string.IsNullOrEmpty(Sidedef.MiddleTexture) || (Sidedef.MiddleTexture[0] == '-'))) { // Make it now mode.CreateUndo("Create middle texture"); mode.SetActionResult("Created middle texture."); General.Settings.FindDefaultDrawSettings(); Sidedef.SetTextureMid(General.Settings.DefaultTexture); // Update Sector.Changed = true; // Other side as well if (string.IsNullOrEmpty(Sidedef.Other.MiddleTexture) || (Sidedef.Other.MiddleTexture[0] == '-')) { Sidedef.Other.SetTextureMid(General.Settings.DefaultTexture); // Update VisualSector othersector = mode.GetVisualSector(Sidedef.Other.Sector); if (othersector is BaseVisualSector) { (othersector as BaseVisualSector).Changed = true; } } } }
// This resets this sector data and all sectors that require updating after me public void Reset() { if (isupdating) { return; } isupdating = true; // This is set to false so that this sector is rebuilt the next time it is needed! updated = false; // The visual sector associated is now outdated if (mode.VisualSectorExists(sector)) { BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(sector); vs.UpdateSectorGeometry(false); } // Also reset the sectors that depend on this sector foreach (KeyValuePair <Sector, bool> s in updatesectors) { SectorData sd = mode.GetSectorData(s.Key); sd.Reset(); } isupdating = false; }
// Raise/lower thing public virtual void OnChangeTargetHeight(int amount) { if (General.Map.FormatInterface.HasThingHeight) { if ((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket)) { undoticket = mode.CreateUndo("Change thing height"); } Thing.Move(Thing.Position + new Vector3D(0.0f, 0.0f, (float)amount)); mode.SetActionResult("Changed thing height to " + Thing.Position.z + "."); // Update what must be updated ThingData td = mode.GetThingData(this.Thing); foreach (KeyValuePair <Sector, bool> s in td.UpdateAlso) { if (mode.VisualSectorExists(s.Key)) { BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(s.Key); vs.UpdateSectorGeometry(s.Value); } } this.Changed = true; } }
public static void ApplySlope(SectorLevel level, Plane plane, BaseVisualMode mode) { bool applytoceiling = false; Vector2D center = new Vector2D(level.sector.BBox.X + level.sector.BBox.Width / 2, level.sector.BBox.Y + level.sector.BBox.Height / 2); if (level.extrafloor) { // The top side of 3D floors is the ceiling of the sector, but it's a "floor" in UDB, so the // ceiling of the control sector has to be modified if (level.type == SectorLevelType.Floor) { applytoceiling = true; } } else { if (level.type == SectorLevelType.Ceiling) { applytoceiling = true; } } if (applytoceiling) { Plane downplane = plane.GetInverted(); level.sector.CeilSlope = downplane.Normal; level.sector.CeilSlopeOffset = downplane.Offset; level.sector.CeilHeight = (int)new Plane(level.sector.CeilSlope, level.sector.CeilSlopeOffset).GetZ(center); } else { level.sector.FloorSlope = plane.Normal; level.sector.FloorSlopeOffset = plane.Offset; level.sector.FloorHeight = (int)new Plane(level.sector.FloorSlope, level.sector.FloorSlopeOffset).GetZ(center); } // Rebuild sector BaseVisualSector vs; if (mode.VisualSectorExists(level.sector)) { vs = (BaseVisualSector)mode.GetVisualSector(level.sector); } else { vs = mode.CreateBaseVisualSector(level.sector); } if (vs != null) { vs.UpdateSectorGeometry(true); } }
public override void OnActionEnd(CodeImp.DoomBuilder.Actions.Action action) { base.OnActionEnd(action); if (!updateafteraction && action.Name != updateafteractionname) { return; } updateafteraction = false; Dictionary <SlopeVertexGroup, int> updatesvgs = new Dictionary <SlopeVertexGroup, int>(); // Find SVGs that needs to be updated, and change the SV z positions foreach (SlopeVertexGroup svg in slopevertexgroups) { bool update = false; Dictionary <int, List <Sector> > newheights = new Dictionary <int, List <Sector> >(); foreach (Sector s in svg.Sectors) { if (s.Fields == null) { continue; } if ((svg.SectorPlanes[s] & PlaneType.Floor) == PlaneType.Floor) { if (s.Fields.ContainsKey("user_floorplane_id") && s.Fields.GetValue("user_floorplane_id", -1) == svg.Id) { if (svg.Height != s.FloorHeight) { int diff = s.FloorHeight - svg.Height; if (!newheights.ContainsKey(diff)) { newheights.Add(diff, new List <Sector>() { s }); } else { newheights[diff].Add(s); } update = true; //break; } } } if ((svg.SectorPlanes[s] & PlaneType.Ceiling) == PlaneType.Ceiling) { if (s.Fields.ContainsKey("user_ceilingplane_id") && s.Fields.GetValue("user_ceilingplane_id", -1) == svg.Id) { if (svg.Height != s.CeilHeight) { int diff = s.CeilHeight - svg.Height; if (!newheights.ContainsKey(diff)) { newheights.Add(diff, new List <Sector>() { s }); } else { newheights[diff].Add(s); } update = true; //break; } } } } // Debug.WriteLine(String.Format("floordiff: {0} / ceilingdiff: {1} / height: {2}", floordiff, ceilingdiff, svg.Height)); if (update) { if (newheights.Count > 1) { Debug.WriteLine(String.Format("Slope: multiple new heights, doing nothing. Your map is f****d!")); } else if (!updatesvgs.ContainsKey(svg)) { updatesvgs.Add(svg, newheights.First().Key); } } } // Update the slopes, and also update the view if in visual mode foreach (SlopeVertexGroup svg in updatesvgs.Keys) { foreach (SlopeVertex sv in svg.Vertices) { sv.Z += updatesvgs[svg]; } svg.ComputeHeight(); foreach (Sector s in svg.Sectors) { UpdateSlopes(s); } // Save the updated data in the sector svg.StoreInSector(slopedatasector); if (General.Editing.Mode is BaseVisualMode) { List <Sector> sectors = new List <Sector>(); List <VisualSector> visualsectors = new List <VisualSector>(); BaseVisualMode mode = ((BaseVisualMode)General.Editing.Mode); foreach (Sector s in svg.Sectors) { sectors.Add(s); // Get neighbouring sectors and add them to the list foreach (Sidedef sd in s.Sidedefs) { if (sd.Other != null && !sectors.Contains(sd.Other.Sector)) { sectors.Add(sd.Other.Sector); } } } foreach (Sector s in svg.TaggedSectors) { if (!sectors.Contains(s)) { sectors.Add(s); } // Get neighbouring sectors and add them to the list foreach (Sidedef sd in s.Sidedefs) { if (sd.Other != null && !sectors.Contains(sd.Other.Sector)) { sectors.Add(sd.Other.Sector); } } } foreach (Sector s in sectors) { visualsectors.Add(mode.GetVisualSector(s)); } foreach (VisualSector vs in visualsectors) { vs.UpdateSectorGeometry(true); } foreach (VisualSector vs in visualsectors) { vs.UpdateSectorData(); } } } }
public static void ApplySlope(SectorLevel level, Plane plane, BaseVisualMode mode) { bool applytoceiling = false; bool reset = false; int height = 0; Vector2D center = new Vector2D(level.sector.BBox.X + level.sector.BBox.Width / 2, level.sector.BBox.Y + level.sector.BBox.Height / 2); if (level.extrafloor) { // The top side of 3D floors is the ceiling of the sector, but it's a "floor" in UDB, so the // ceiling of the control sector has to be modified if (level.type == SectorLevelType.Floor) { applytoceiling = true; } } else { if (level.type == SectorLevelType.Ceiling) { applytoceiling = true; } } // If the plane horizontal remove the slope and set the sector height instead // Rounding errors can result in offsets of horizontal planes to be a tiny, tiny bit off a whole number, // assume we want to remove the plane in this case double diff = Math.Abs(Math.Round(plane.d) - plane.d); if (plane.Normal.z == 1.0 && diff < 0.000000001) { reset = true; height = -Convert.ToInt32(plane.d); } if (applytoceiling) { if (reset) { level.sector.CeilHeight = height; level.sector.CeilSlope = new Vector3D(); level.sector.CeilSlopeOffset = double.NaN; } else { Plane downplane = plane.GetInverted(); level.sector.CeilSlope = downplane.Normal; level.sector.CeilSlopeOffset = downplane.Offset; } } else { if (reset) { level.sector.FloorHeight = height; level.sector.FloorSlope = new Vector3D(); level.sector.FloorSlopeOffset = double.NaN; } else { level.sector.FloorSlope = plane.Normal; level.sector.FloorSlopeOffset = plane.Offset; } } // Rebuild sector BaseVisualSector vs; if (mode.VisualSectorExists(level.sector)) { vs = (BaseVisualSector)mode.GetVisualSector(level.sector); } else { vs = mode.CreateBaseVisualSector(level.sector); } if (vs != null) { vs.UpdateSectorGeometry(true); } }
// Flood-fill textures public virtual void OnTextureFloodfill() { if (BuilderPlug.Me.CopiedFlat != null) { string oldtexture = GetTextureName(); long oldtexturelong = Lump.MakeLongName(oldtexture); string newtexture = BuilderPlug.Me.CopiedFlat; if (newtexture != oldtexture) { // Get the texture ImageData newtextureimage = General.Map.Data.GetFlatImage(newtexture); if (newtextureimage != null) { bool fillceilings = (this is VisualCeiling); if (fillceilings) { mode.CreateUndo("Flood-fill ceilings with " + newtexture); mode.SetActionResult("Flood-filled ceilings with " + newtexture + "."); } else { mode.CreateUndo("Flood-fill floors with " + newtexture); mode.SetActionResult("Flood-filled floors with " + newtexture + "."); } mode.Renderer.SetCrosshairBusy(true); General.Interface.RedrawDisplay(); if (mode.IsSingleSelection) { // Clear all marks, this will align everything it can General.Map.Map.ClearMarkedSectors(false); } else { // Limit the alignment to selection only General.Map.Map.ClearMarkedSectors(true); List <Sector> sectors = mode.GetSelectedSectors(); foreach (Sector s in sectors) { s.Marked = false; } } // Do the fill Tools.FloodfillFlats(this.Sector.Sector, fillceilings, oldtexturelong, newtextureimage, false); // Get the changed sectors List <Sector> changes = General.Map.Map.GetMarkedSectors(true); foreach (Sector s in changes) { // Update the visual sector if (mode.VisualSectorExists(s)) { BaseVisualSector vs = (mode.GetVisualSector(s) as BaseVisualSector); if (fillceilings) { vs.Ceiling.Setup(); } else { vs.Floor.Setup(); } } } General.Map.Data.UpdateUsedTextures(); mode.Renderer.SetCrosshairBusy(false); mode.ShowTargetInfo(); } } } }