// This sets the linedef (passive: this doesn't tell the linedef and doesn't record) internal void SetLinedefP(Linedef ld) { linedef = ld; }
// This puts a single linedef in all blocks it crosses public virtual void AddLinedef(Linedef line) { int dirx, diry; // Get coordinates Vector2D v1 = line.Start.Position; Vector2D v2 = line.End.Position; // Find start and end block Point pos = GetBlockCoordinates(v1); Point end = GetBlockCoordinates(v2); v1 -= rangelefttop; v2 -= rangelefttop; // Horizontal straight line? if (pos.Y == end.Y) { // Simple loop pos.X = CropToRangeX(pos.X); end.X = CropToRangeX(end.X); if (IsInRange(new Point(pos.X, pos.Y))) { dirx = Math.Sign(v2.x - v1.x); if (dirx != 0) { for (int x = pos.X; x != end.X; x += dirx) { blockmap[x, pos.Y].Lines.Add(line); } } blockmap[end.X, end.Y].Lines.Add(line); } } // Vertical straight line? else if (pos.X == end.X) { // Simple loop pos.Y = CropToRangeY(pos.Y); end.Y = CropToRangeY(end.Y); if (IsInRange(new Point(pos.X, pos.Y))) { diry = Math.Sign(v2.y - v1.y); if (diry != 0) { for (int y = pos.Y; y != end.Y; y += diry) { blockmap[pos.X, y].Lines.Add(line); } } blockmap[end.X, end.Y].Lines.Add(line); } } else { // Add lines to this block if (IsInRange(pos)) { blockmap[pos.X, pos.Y].Lines.Add(line); } // Moving outside the block? if (pos != end) { // Calculate current block edges float cl = pos.X * blocksize; float cr = (pos.X + 1) * blocksize; float ct = pos.Y * blocksize; float cb = (pos.Y + 1) * blocksize; // Line directions dirx = Math.Sign(v2.x - v1.x); diry = Math.Sign(v2.y - v1.y); // Calculate offset and delta movement over x float posx, deltax; if (dirx == 0) { posx = float.MaxValue; deltax = float.MaxValue; } else if (dirx > 0) { posx = (cr - v1.x) / (v2.x - v1.x); deltax = blocksize / (v2.x - v1.x); } else { // Calculate offset and delta movement over x posx = (v1.x - cl) / (v1.x - v2.x); deltax = blocksize / (v1.x - v2.x); } // Calculate offset and delta movement over y float posy, deltay; if (diry == 0) { posy = float.MaxValue; deltay = float.MaxValue; } else if (diry > 0) { posy = (cb - v1.y) / (v2.y - v1.y); deltay = blocksize / (v2.y - v1.y); } else { posy = (v1.y - ct) / (v1.y - v2.y); deltay = blocksize / (v1.y - v2.y); } // Continue while not reached the end while (pos != end) { // Check in which direction to move if (posx < posy) { // Move horizontally posx += deltax; if (pos.X != end.X) { pos.X += dirx; } } else { // Move vertically posy += deltay; if (pos.Y != end.Y) { pos.Y += diry; } } // Add lines to this block if (IsInRange(pos)) { blockmap[pos.X, pos.Y].Lines.Add(line); } } } } }
//mxd public static Geometry.Plane GetCeilingPlane(Sector s) { if (General.Map.UDMF) { // UDMF Sector slope? if (s.CeilSlope.GetLengthSq() > 0 && !float.IsNaN(s.CeilSlopeOffset / s.CeilSlope.z)) { return(new Geometry.Plane(s.CeilSlope, s.CeilSlopeOffset)); } if (s.sidedefs.Count == 3) { Geometry.Plane ceiling = new Geometry.Plane(new Vector3D(0, 0, -1), s.CeilHeight); Vector3D[] verts = new Vector3D[3]; bool sloped = false; int index = 0; // Check vertices foreach (Sidedef sd in s.Sidedefs) { Vertex v = sd.IsFront ? sd.Line.End : sd.Line.Start; //create "normal" vertices verts[index] = new Vector3D(v.Position); // Check floor if (!float.IsNaN(v.ZCeiling)) { //vertex offset is absolute verts[index].z = v.ZCeiling; sloped = true; } else { verts[index].z = ceiling.GetZ(v.Position); } index++; } // Have slope? return(sloped ? new Geometry.Plane(verts[0], verts[2], verts[1], false) : ceiling); } } // Have line slope? foreach (Sidedef side in s.sidedefs) { // Carbon copy of EffectLineSlope class here... if (side.Line.Action == 181 && ((side.Line.Args[1] == 1 && side == side.Line.Front) || side.Line.Args[1] == 2) && side.Other != null) { Linedef l = side.Line; // Find the vertex furthest from the line Vertex foundv = null; float founddist = -1.0f; foreach (Sidedef sd in s.Sidedefs) { Vertex v = sd.IsFront ? sd.Line.Start : sd.Line.End; float d = l.DistanceToSq(v.Position, false); if (d > founddist) { foundv = v; founddist = d; } } Vector3D v1 = new Vector3D(l.Start.Position.x, l.Start.Position.y, side.Other.Sector.CeilHeight); Vector3D v2 = new Vector3D(l.End.Position.x, l.End.Position.y, side.Other.Sector.CeilHeight); Vector3D v3 = new Vector3D(foundv.Position.x, foundv.Position.y, s.CeilHeight); return(l.SideOfLine(v3) > 0.0f ? new Geometry.Plane(v1, v2, v3, false) : new Geometry.Plane(v2, v1, v3, false)); } } //TODO: other types of slopes... // Normal (flat) ceiling plane return(new Geometry.Plane(new Vector3D(0, 0, -1), s.CeilHeight)); }
// This joins the line with another line // This line will be disposed // Returns false when the operation could not be completed public bool Join(Linedef other) { Sector l1fs, l1bs, l2fs, l2bs; bool l1was2s, l2was2s; // Check which lines were 2 sided l1was2s = ((other.Front != null) && (other.Back != null)); l2was2s = ((this.Front != null) && (this.Back != null)); // Get sector references if (other.front != null) { l1fs = other.front.Sector; } else { l1fs = null; } if (other.back != null) { l1bs = other.back.Sector; } else { l1bs = null; } if (this.front != null) { l2fs = this.front.Sector; } else { l2fs = null; } if (this.back != null) { l2bs = this.back.Sector; } else { l2bs = null; } // This line has no sidedefs? if ((l2fs == null) && (l2bs == null)) { // We have no sidedefs, so we have no influence // Nothing to change on the other line } // Other line has no sidedefs? else if ((l1fs == null) && (l1bs == null)) { // The other has no sidedefs, so it has no influence // Copy my sidedefs to the other if (this.Start == other.Start) { if (!JoinChangeSidedefs(other, true, front)) { return(false); } if (!JoinChangeSidedefs(other, false, back)) { return(false); } } else { if (!JoinChangeSidedefs(other, false, front)) { return(false); } if (!JoinChangeSidedefs(other, true, back)) { return(false); } } // Copy my properties to the other this.CopyPropertiesTo(other); } else { // Compare front sectors if ((l1fs != null) && (l1fs == l2fs)) { // Copy textures if (other.front != null) { other.front.AddTexturesTo(this.back); } if (this.front != null) { this.front.AddTexturesTo(other.back); } // Change sidedefs if (!JoinChangeSidedefs(other, true, back)) { return(false); } } // Compare back sectors else if ((l1bs != null) && (l1bs == l2bs)) { // Copy textures if (other.back != null) { other.back.AddTexturesTo(this.front); } if (this.back != null) { this.back.AddTexturesTo(other.front); } // Change sidedefs if (!JoinChangeSidedefs(other, false, front)) { return(false); } } // Compare front and back else if ((l1fs != null) && (l1fs == l2bs)) { // Copy textures if (other.front != null) { other.front.AddTexturesTo(this.front); } if (this.back != null) { this.back.AddTexturesTo(other.back); } // Change sidedefs if (!JoinChangeSidedefs(other, true, front)) { return(false); } } // Compare back and front else if ((l1bs != null) && (l1bs == l2fs)) { // Copy textures if (other.back != null) { other.back.AddTexturesTo(this.back); } if (this.front != null) { this.front.AddTexturesTo(other.front); } // Change sidedefs if (!JoinChangeSidedefs(other, false, back)) { return(false); } } else { // Other line single sided? if (other.back == null) { // This line with its back to the other? if (this.start == other.end) { // Copy textures if (other.back != null) { other.back.AddTexturesTo(this.front); } if (this.back != null) { this.back.AddTexturesTo(other.front); } // Change sidedefs if (!JoinChangeSidedefs(other, false, front)) { return(false); } } else { // Copy textures if (other.back != null) { other.back.AddTexturesTo(this.back); } if (this.front != null) { this.front.AddTexturesTo(other.front); } // Change sidedefs if (!JoinChangeSidedefs(other, false, back)) { return(false); } } } // This line single sided? else if (this.back == null) { // Other line with its back to this? if (other.start == this.end) { // Copy textures if (other.back != null) { other.back.AddTexturesTo(this.front); } if (this.back != null) { this.back.AddTexturesTo(other.front); } // Change sidedefs if (!JoinChangeSidedefs(other, false, front)) { return(false); } } else { // Copy textures if (other.front != null) { other.front.AddTexturesTo(this.front); } if (this.back != null) { this.back.AddTexturesTo(other.back); } // Change sidedefs if (!JoinChangeSidedefs(other, true, front)) { return(false); } } } else { // This line with its back to the other? if (this.start == other.end) { // Copy textures if (other.back != null) { other.back.AddTexturesTo(this.front); } if (this.back != null) { this.back.AddTexturesTo(other.front); } // Change sidedefs if (!JoinChangeSidedefs(other, false, front)) { return(false); } } else { // Copy textures if (other.back != null) { other.back.AddTexturesTo(this.back); } if (this.front != null) { this.front.AddTexturesTo(other.front); } // Change sidedefs if (!JoinChangeSidedefs(other, false, back)) { return(false); } } } } // Apply single/double sided flags if the double-sided-ness changed if ((!l1was2s && ((other.Front != null) && (other.Back != null))) || (l1was2s && ((other.Front == null) || (other.Back == null)))) { other.ApplySidedFlags(); } // Remove unneeded textures if (other.front != null) { other.front.RemoveUnneededTextures(!(l1was2s && l2was2s)); } if (other.back != null) { other.back.RemoveUnneededTextures(!(l1was2s && l2was2s)); } } // If either of the two lines was selected, keep the other selected if (this.Selected) { other.Selected = true; } if (this.marked) { other.marked = true; } // I got killed by the other. this.Dispose(); General.Map.IsChanged = true; return(true); }