Exemple #1
0
 // 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));
        }
Exemple #4
0
        // 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);
        }