// This detaches a sidedef from the front internal void DetachSidedefP(Sidedef s) { // Sidedef is on the front? if (front == s) { // Remove sidedef reference if (front != null) { front.SetLinedefP(null); } front = null; updateneeded = true; } // Sidedef is on the back? else if (back == s) { // Remove sidedef reference if (back != null) { back.SetLinedefP(null); } back = null; updateneeded = true; } //else throw new Exception("Specified Sidedef is not attached to this Linedef."); }
// This changes sidedefs (used for joining lines) // target: The linedef on which to remove or create a new sidedef // front: Side on which to remove or create the sidedef (true for front side) // newside: The side from which to copy the properties to the new sidedef. // If this is null, no sidedef will be created (only removed) // Returns false when the operation could not be completed. private bool JoinChangeSidedefs(Linedef target, bool front, Sidedef newside) { Sidedef sd; // Change sidedefs if (front) { if (target.front != null) { target.front.Dispose(); } } else { if (target.back != null) { target.back.Dispose(); } } if (newside != null) { sd = map.CreateSidedef(target, front, newside.Sector); if (sd == null) { return(false); } newside.CopyPropertiesTo(sd); sd.Marked = newside.Marked; } return(true); }
public int GetLowerColor(Sidedef s) { //if (s.Line.IsFlagSet("67108864")) //return s.Sector.TopColor.color.ToInt(); return(GetColor(s.Sector.LowerColor)); }
/// <summary>Sets all traced edges to [sector], or creates a new sector using properties /// from [sector_copy] if none given</summary> internal void CreateSector(Sector sector, Sector sector_copy) { // Create the sector if needed if (sector == null) { sector = General.Map.Map.CreateSector(); if (sector == null) { return; } sector.Marked = true; //mxd // Find potential sector to copy if none specified if (sector_copy == null) { sector_copy = FindCopySector(); } if (sector_copy != null) { sector_copy.CopyPropertiesTo(sector); } } //DebugConsole.WriteLine(" "); //DebugConsole.WriteLine("Creating sector " + sector.Index + " from " + sector_edges.Count + " lines"); //DebugConsole.WriteLine("*************************************************************"); //DebugConsole.WriteLine(" "); // Set sides to new sector foreach (LinedefSide edge in sector_edges) { Sidedef target = (edge.Front ? edge.Line.Front : edge.Line.Back); if (target != null) { if (target.Sector != sector) { bool targetwas2s = (target.Other != null); target.SetSector(sector); //mxd. Reattach side //mxd. Mark for texture adjustments if sidedness was changed. //mxd. Also keep existing mark if the side was already marked. target.Marked |= ((targetwas2s && target.Other == null) || (!targetwas2s && target.Other != null)); } } else { target = General.Map.Map.CreateSidedef(edge.Line, edge.Front, sector); //mxd. Create new side target.Marked = true; //mxd. Mark it for texture adjustments if (target.Other != null) { //mxd. Better than nothing target.Other.CopyPropertiesTo(target); //mxd. Other was singlesided. We'll need to adjust it's textures as well target.Other.Marked = true; } } } }
// Disposer public override void Dispose() { // Not already disposed? if (!isdisposed) { // Already set isdisposed so that changes can be prohibited isdisposed = true; // Dispose sidedefs if ((front != null) && map.AutoRemove) { front.Dispose(); } else { AttachFrontP(null); } if ((back != null) && map.AutoRemove) { back.Dispose(); } else { AttachBackP(null); } if (map == General.Map.Map) { General.Map.UndoRedo.RecRemLinedef(this); } // Remove from main list map.RemoveLinedef(listindex); // Detach from vertices if (startvertexlistitem != null) { start.DetachLinedefP(startvertexlistitem); } startvertexlistitem = null; start = null; if (endvertexlistitem != null) { end.DetachLinedefP(endvertexlistitem); } endvertexlistitem = null; end = null; // Clean up start = null; end = null; front = null; back = null; map = null; // Clean up base base.Dispose(); } }
public int GetTopColor(Sidedef s) { if (s.Line.IsFlagSet("67108864")) { return(GetColor(s.Sector.LowerColor)); } return(GetColor(s.Sector.TopColor)); }
// This attaches a sidedef on the back internal void AttachBack(Sidedef s) { if (map == General.Map.Map) { General.Map.UndoRedo.RecRefLinedefBack(this); } // Attach and recalculate AttachBackP(s); }
// Passive version, does not record the change internal void AttachBackP(Sidedef s) { // Attach and recalculate back = s; if (back != null) { back.SetLinedefP(this); } updateneeded = true; }
// Passive version, does not record the change internal void AttachFrontP(Sidedef s) { // Attach and recalculate front = s; if (front != null) { front.SetLinedefP(this); } updateneeded = true; }
// This copies textures to another sidedef // And possibly also the offsets public void AddTexturesTo(Sidedef s) { int copyoffsets = 0; // s cannot be null if (s == null) { return; } s.BeforePropsChange(); // Upper texture set? if ((texnamehigh.Length > 0) && (texnamehigh[0] != '-')) { // Copy upper texture s.texnamehigh = texnamehigh; s.longtexnamehigh = longtexnamehigh; // Counts as a half coice for copying offsets copyoffsets += 1; } // Middle texture set? if ((texnamemid.Length > 0) && (texnamemid[0] != '-')) { // Copy middle texture s.texnamemid = texnamemid; s.longtexnamemid = longtexnamemid; // Counts for copying offsets copyoffsets += 2; } // Lower texture set? if ((texnamelow.Length > 0) && (texnamelow[0] != '-')) { // Copy middle texture s.texnamelow = texnamelow; s.longtexnamelow = longtexnamelow; // Counts as a half coice for copying offsets copyoffsets += 1; } // Copy offsets also? if (copyoffsets >= 2) { // Copy offsets s.offsetx = offsetx; s.offsety = offsety; } General.Map.IsChanged = true; }
// This flips the sidedefs public void FlipSidedefs() { // Flip sidedefs Sidedef oldfront = front; Sidedef oldback = back; AttachFront(oldback); AttachBack(oldfront); General.Map.IsChanged = true; }
/// <summary> /// This returns the height of the lower wall part. Returns 0 when no lower part exists. /// </summary> public int GetLowHeight() { Sidedef other = this.Other; if (other != null) { int top = other.sector.FloorHeight; int bottom = this.sector.FloorHeight; int height = top - bottom; return((height > 0) ? height : 0); } return(0); }
// This copies all properties to another sidedef public void CopyPropertiesTo(Sidedef s) { s.BeforePropsChange(); // Copy properties s.offsetx = offsetx; s.offsety = offsety; s.texnamehigh = texnamehigh; s.texnamemid = texnamemid; s.texnamelow = texnamelow; s.longtexnamehigh = longtexnamehigh; s.longtexnamemid = longtexnamemid; s.longtexnamelow = longtexnamelow; base.CopyPropertiesTo(s); }
/// <summary> /// This returns the height of the upper wall part. Returns 0 when no upper part exists. /// </summary> public int GetHighHeight() { Sidedef other = this.Other; if (other != null) { int top = this.sector.CeilHeight; int bottom = other.sector.CeilHeight; int height = top - bottom; return((height > 0) ? height : 0); } else { return(0); } }
// This copies all properties to another sidedef public void CopyPropertiesTo(Sidedef s) { s.BeforePropsChange(); // Copy properties s.offsetx = offsetx; s.offsety = offsety; s.texnamehigh = texnamehigh; s.texnamemid = texnamemid; s.texnamelow = texnamelow; s.longtexnamehigh = longtexnamehigh; s.longtexnamemid = longtexnamemid; s.longtexnamelow = longtexnamelow; s.flags = new Dictionary <string, bool>(flags); //mxd base.CopyPropertiesTo(s); }
/// <summary> /// This returns the height of the middle wall part. /// </summary> public int GetMiddleHeight() { Sidedef other = this.Other; if (other != null) { int top = Math.Min(this.Sector.CeilHeight, other.Sector.CeilHeight); int bottom = Math.Max(this.Sector.FloorHeight, other.Sector.FloorHeight); int height = top - bottom; return((height > 0) ? height : 0); } else { int top = this.Sector.CeilHeight; int bottom = this.Sector.FloorHeight; int height = top - bottom; return((height > 0) ? height : 0); } }
// ano - used for swapping indices, sort of, // except not really, because we're really swapping // all the data of the linedef. // the reason for this approach is related to // architectural complications // with the way the undo system works. public void SwapProperties(Linedef l) { l.BeforePropsChange(); BeforePropsChange(); // ano - a bit ugly, but i don't see a better solution // because of the inability to make a Linedef that // is not a part of the MapSet and doesn't pollute // the undo state either int tempaction = l.action; int[] tempargs = l.args; Dictionary <string, bool> tempflags = l.flags; int temptag = l.tag; int tempactivate = l.activate; bool tempimpassableflag = l.impassableflag; bool tempblocksoundflag = l.blocksoundflag; UniFields tempfields = l.fields; l.fields = fields; l.action = action; l.args = args; l.flags = flags; l.tag = tag; l.activate = activate; l.impassableflag = impassableflag; l.blocksoundflag = blocksoundflag; action = tempaction; args = tempargs; flags = tempflags; tag = temptag; activate = tempactivate; impassableflag = tempimpassableflag; blocksoundflag = tempblocksoundflag; fields = tempfields; // ano - ok so we have a choice here // choice 1: add selection groups to the undo manager // choice 2: swapping linedef indices does not swap the selection // group, meaning the selection group appears to "swap" // choice 3: swapping linedef indices DOES swap, making it appear // normal, until you undo, which does not revert that, // making it appear to swap on undo. // choice 2 & 3 essentially appear to the enduser as bugs (yuck) // but i really do not have the energy to deal with choice 1 at // this time, and i'm unsure of the larger architectural // consquences. also. a quick poll of discord shows that mappers // seems unaware that the selection group feature exists?? // (need to examine if this is just bad discoverability, // or if it's just actually not very useful?) // so for now we are doing choice #3 l.SwapSelectionGroup(this); // flipping this boolean makes sure that we // vertices don't get auto deleted when we detach them // (i would not have architected this with this pseudo-global) bool oldautoremove = General.Map.Map.AutoRemove; General.Map.Map.AutoRemove = false; // note that calling setstartvertex / setendvertex handles setting updateneeded Vertex tempstart = start; SetStartVertex(l.start); l.SetStartVertex(tempstart); Vertex tempend = end; SetEndVertex(l.end); l.SetEndVertex(tempend); // have to record before detaching and call Attach P version // because otherwise detaching wont record undo correctly Sidedef tempfront = front; General.Map.UndoRedo.RecRefLinedefFront(l); AttachFront(l.front); l.AttachFrontP(tempfront); Sidedef tempback = back; General.Map.UndoRedo.RecRefLinedefBack(l); AttachBack(l.back); l.AttachBackP(tempback); General.Map.Map.AutoRemove = oldautoremove; }
// This attaches a sidedef and returns the listitem internal LinkedListNode <Sidedef> AttachSidedefP(Sidedef sd) { updateneeded = true; triangulationneeded = true; return(sidedefs.AddLast(sd)); }
// This copies textures to another sidedef // And possibly also the offsets public void AddTexturesTo(Sidedef s) { int copyoffsets = 0; // s cannot be null if (s == null) { return; } s.BeforePropsChange(); // Upper texture set? if ((texnamehigh.Length > 0) && (texnamehigh != "-")) { // Copy upper texture s.texnamehigh = texnamehigh; s.longtexnamehigh = longtexnamehigh; // Counts as a half coice for copying offsets copyoffsets += 1; //mxd. Also copy UDMF offsets and scale if (General.Map.UDMF) { UniFields.SetFloat(s.Fields, "offsetx_top", Fields.GetValue("offsetx_top", 0.0), 0.0); UniFields.SetFloat(s.Fields, "offsety_top", Fields.GetValue("offsety_top", 0.0), 0.0); UniFields.SetFloat(s.Fields, "scalex_top", Fields.GetValue("scalex_top", 1.0), 1.0); UniFields.SetFloat(s.Fields, "scaley_top", Fields.GetValue("scaley_top", 1.0), 1.0); } } // Middle texture set? if ((texnamemid.Length > 0) && (texnamemid != "-")) { // Copy middle texture s.texnamemid = texnamemid; s.longtexnamemid = longtexnamemid; // Counts for copying offsets copyoffsets += 2; //mxd. Also copy UDMF offsets and scale if (General.Map.UDMF) { UniFields.SetFloat(s.Fields, "offsetx_mid", Fields.GetValue("offsetx_mid", 0.0), 0.0); UniFields.SetFloat(s.Fields, "offsety_mid", Fields.GetValue("offsety_mid", 0.0), 0.0); UniFields.SetFloat(s.Fields, "scalex_mid", Fields.GetValue("scalex_mid", 1.0), 1.0); UniFields.SetFloat(s.Fields, "scaley_mid", Fields.GetValue("scaley_mid", 1.0), 1.0); } } // Lower texture set? if ((texnamelow.Length > 0) && (texnamelow != "-")) { // Copy middle texture s.texnamelow = texnamelow; s.longtexnamelow = longtexnamelow; // Counts as a half coice for copying offsets copyoffsets += 1; //mxd. Also copy UDMF offsets and scale if (General.Map.UDMF) { UniFields.SetFloat(s.Fields, "offsetx_bottom", Fields.GetValue("offsetx_bottom", 0.0), 0.0); UniFields.SetFloat(s.Fields, "offsety_bottom", Fields.GetValue("offsety_bottom", 0.0), 0.0); UniFields.SetFloat(s.Fields, "scalex_bottom", Fields.GetValue("scalex_bottom", 1.0), 1.0); UniFields.SetFloat(s.Fields, "scaley_bottom", Fields.GetValue("scaley_bottom", 1.0), 1.0); } } // Copy offsets also? if (copyoffsets >= 2) { // Copy offsets s.offsetx = offsetx; s.offsety = offsety; } General.Map.IsChanged = true; }
public int UnpegUpperLight(Sidedef s) { int height; Lights c = new Lights(); int sh1; int sh2; Sector front; Sector back; float r1, g1, b1; float r2, g2, b2; Lights ltop, lbottom; if (s.Line.IsFlagSet("67108864")) { ltop = s.Sector.LowerColor; lbottom = s.Sector.TopColor; } else { ltop = s.Sector.TopColor; lbottom = s.Sector.LowerColor; } ltop.color = GetFactor(ltop); lbottom.color = GetFactor(lbottom); if (s.Line.IsFlagSet("2097152")) { return(lbottom.color.ToInt()); } if (s.IsFront) { front = s.Line.Front.Sector; back = s.Line.Back.Sector; } else { front = s.Line.Back.Sector; back = s.Line.Front.Sector; } height = front.CeilHeight - front.FloorHeight; if (height == 0) { return(lbottom.color.ToInt()); } sh1 = back.CeilHeight - front.FloorHeight; sh2 = front.CeilHeight - back.CeilHeight; r1 = ltop.color.r; g1 = ltop.color.g; b1 = ltop.color.b; r2 = lbottom.color.r; g2 = lbottom.color.g; b2 = lbottom.color.b; r1 = ((r1 / height) * sh1); g1 = ((g1 / height) * sh1); b1 = ((b1 / height) * sh1); r2 = ((r2 / height) * sh2); g2 = ((g2 / height) * sh2); b2 = ((b2 / height) * sh2); c.color.r = (byte)Math.Min((int)(r1 + r2), (int)255); c.color.g = (byte)Math.Min((int)(g1 + g2), (int)255); c.color.b = (byte)Math.Min((int)(b1 + b2), (int)255); c.color.a = 255; return(c.color.ToInt()); }