//mxd protected void ClearFields(IEnumerable <string> keys, string undodescription, string resultdescription) { if (!General.Map.UDMF) { return; } mode.CreateUndo(undodescription); mode.SetActionResult(resultdescription); level.sector.Fields.BeforeFieldsChange(); foreach (string key in keys) { if (level.sector.Fields.ContainsKey(key)) { level.sector.Fields.Remove(key); level.sector.UpdateNeeded = true; } } if (level.sector.UpdateNeeded) { if (level.sector != Sector.Sector && mode.VisualSectorExists(level.sector)) { BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(level.sector); vs.UpdateSectorGeometry(false); } else { Sector.UpdateSectorGeometry(false); } } }
// Raise/lower thing public 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, (info.Hangs ? -amount : 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; } }
// 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; } } } }
private void UpdateGeometry(Vertex v) { VertexData vd = mode.GetVertexData(v); foreach (KeyValuePair <Sector, bool> s in vd.UpdateAlso) { if (mode.VisualSectorExists(s.Key)) { BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(s.Key); vs.UpdateSectorGeometry(s.Value); } } }
// 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; * }*/ //mxd. This marks this sector data and all sector datas that require updating as not updated public void Reset(bool resetneighbours) { 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.Changed = true; } // Reset the sectors that depend on this sector if (resetneighbours) { foreach (KeyValuePair <Sector, bool> s in updatesectors) { SectorData sd = mode.GetSectorDataEx(s.Key); if (sd != null) { sd.Reset(s.Value); } } } isupdating = false; }
// Thisvirtuals the secotr and neightbours if needed public void UpdateSectorGeometry(bool includeneighbours) { // Rebuild sector this.Changed = true; // 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; } } } } }
//mxd. This checks if any of the sidedef texture match the given textures public static bool SidedefTextureMatch(BaseVisualMode mode, Sidedef sd, HashSet <long> texturelongnames) { if (!mode.VisualSectorExists(sd.Sector)) { return(false); } VisualSidedefParts parts = ((BaseVisualSector)mode.GetVisualSector(sd.Sector)).GetSidedefParts(sd); return((texturelongnames.Contains(sd.LongHighTexture) && (parts.upper != null && parts.upper.Triangles > 0)) || (texturelongnames.Contains(sd.LongLowTexture) && (parts.lower != null && parts.lower.Triangles > 0)) || (texturelongnames.Contains(sd.LongMiddleTexture) && ((parts.middledouble != null && parts.middledouble.Triangles > 0) || (parts.middlesingle != null && parts.middlesingle.Triangles > 0)))); }
// This performs texture floodfill along all walls that match with the same texture // NOTE: This method uses the sidedefs marking to indicate which sides have been filled // When resetsidemarks is set to true, all sidedefs will first be marked false (not aligned). // Setting resetsidemarks to false is usefull to fill only within a specific selection // (set the marked property to true for the sidedefs outside the selection) public static void FloodfillTextures(BaseVisualMode mode, Sidedef start, HashSet <long> originaltextures, string filltexture, bool resetsidemarks) { Stack <Tools.SidedefFillJob> todo = new Stack <Tools.SidedefFillJob>(50); // Mark all sidedefs false (they will be marked true when the texture is aligned) if (resetsidemarks) { General.Map.Map.ClearMarkedSidedefs(false); } // Begin with first sidedef if (SidedefTextureMatch(mode, start, originaltextures)) { todo.Push(new Tools.SidedefFillJob { sidedef = start, forward = true }); } // Continue until nothing more to align while (todo.Count > 0) { // Get the align job to do Tools.SidedefFillJob j = todo.Pop(); //mxd. Get visual parts if (mode.VisualSectorExists(j.sidedef.Sector)) { VisualSidedefParts parts = ((BaseVisualSector)mode.GetVisualSector(j.sidedef.Sector)).GetSidedefParts(j.sidedef); // Apply texturing if ((parts.upper != null && parts.upper.Triangles > 0) && originaltextures.Contains(j.sidedef.LongHighTexture)) { j.sidedef.SetTextureHigh(filltexture); } if (((parts.middledouble != null && parts.middledouble.Triangles > 0) || (parts.middlesingle != null && parts.middlesingle.Triangles > 0)) && originaltextures.Contains(j.sidedef.LongMiddleTexture)) { j.sidedef.SetTextureMid(filltexture); } if ((parts.lower != null && parts.lower.Triangles > 0) && originaltextures.Contains(j.sidedef.LongLowTexture)) { j.sidedef.SetTextureLow(filltexture); } } j.sidedef.Marked = true; if (j.forward) { // Add sidedefs forward (connected to the right vertex) Vertex v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start; AddSidedefsForFloodfill(mode, todo, v, true, originaltextures); // Add sidedefs backward (connected to the left vertex) v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End; AddSidedefsForFloodfill(mode, todo, v, false, originaltextures); } else { // Add sidedefs backward (connected to the left vertex) Vertex v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End; AddSidedefsForFloodfill(mode, todo, v, false, originaltextures); // Add sidedefs forward (connected to the right vertex) v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start; AddSidedefsForFloodfill(mode, todo, v, true, originaltextures); } } }
// 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(); } } } }
// This updates this virtual the sector and neightbours if needed override 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 = mode.GetSectorDataEx(this.Sector); //mxd if (data != null) //mxd { data.Reset(false); // Update sectors that rely on this sector foreach (KeyValuePair <Sector, bool> s in data.UpdateAlso) { SectorData other = mode.GetSectorDataEx(s.Key); if (other != null) { other.Reset(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 = (BaseVisualThing)mode.GetVisualThing(t); 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)) { SectorData other = mode.GetSectorDataEx(sd.Other.Sector); if (other != null) { other.Reset(other.UpdateAlso.Count > 0 ? true : false); // biwa. Make sure to reset the update status of dependend sectors. This fixes #250, where 3D floors where not updated when the control sector was sloped using line action 181 } else { BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(sd.Other.Sector); vs.Changed = true; } } } } } Sector.UpdateFogColor(); //mxd isupdating = false; }