Exemplo n.º 1
0
        /// <summary>
        /// Checks if this wall blocks a
        /// move between Start and End
        /// </summary>
        /// <param name="Start">A 3D location</param>
        /// <param name="End">A 2D location</param>
        /// <param name="PlayerHeight">Height of the player for ceiling collisions</param>
        /// <returns></returns>
        public bool IsBlocking(V3 Start, V2 End, Real PlayerHeight)
        {
            V2 P1 = GetP1();
            V2 P2 = GetP2();

            V2 Start2D = new V2(Start.X, Start.Z);

            // calculate the sides of the points (returns -1, 0 or 1)
            int startside = Start2D.GetSide(P1, P2);
            int endside   = End.GetSide(P1, P2);

            // if points are not on same side
            // the infinite lines cross
            if (startside != endside)
            {
                // verify also the finite line segments cross
                V2 intersect;

                if (MathUtil.IntersectLineLine(Start2D, End, P1, P2, out intersect))
                {
                    // verify the side we've crossed is flaggged as "nonpassable"
                    // if so, we actually have a collision
                    if ((startside < 0 && LeftSide != null && !LeftSide.Flags.IsPassable) ||
                        (startside > 0 && RightSide != null && !RightSide.Flags.IsPassable))
                    {
                        return(true);
                    }

                    // still check the stepheight from oldheight to new floor if passable
                    // for too high steps
                    Real endheight = 0.0f;
                    Real diff;

                    if (endside <= 0 && LeftSector != null)
                    {
                        endheight = LeftSector.CalculateFloorHeight((int)End.X, (int)End.Y, true);
                    }

                    else if (endside > 0 && RightSector != null)
                    {
                        endheight = RightSector.CalculateFloorHeight((int)End.X, (int)End.Y, true);
                    }

                    diff = endheight - Start.Y;

                    // diff is bigger than max. step height, we have a collision
                    if (diff > GeometryConstants.MAXSTEPHEIGHT)
                    {
                        return(true);
                    }

                    // check the ceiling heights
                    if (endside <= 0 && LeftSector != null)
                    {
                        endheight = LeftSector.CalculateCeilingHeight((int)End.X, (int)End.Y);
                    }

                    else if (endside > 0 && RightSector != null)
                    {
                        endheight = RightSector.CalculateCeilingHeight((int)End.X, (int)End.Y);
                    }

                    // diff is bigger than max. step height, we have a collision
                    if (endheight < Start.Y + PlayerHeight)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Fills in the Z coordinates for the wall.
        /// Make sure to call "ResolveIndices" before!
        /// Taken from "SetWallHeights" in bspload.c
        /// </summary>
        public void CalculateWallSideHeights()
        {
            // no sectors? we're screwed, use defaults and return
            if (RightSector == null && LeftSector == null)
            {
                Z0  = Z1 = 0.0f;
                Z2  = Z3 = (Real)GeometryConstants.FINENESS;
                ZZ0 = ZZ1 = 0.0f;
                ZZ2 = ZZ3 = (Real)GeometryConstants.FINENESS;
                return;
            }

            // only left sector? use heights from there and return
            if (RightSector == null)
            {
                Z0  = Z1 = LeftSector.CalculateFloorHeight(X1, Y1);
                Z2  = Z3 = LeftSector.CalculateCeilingHeight(X1, Y1);
                ZZ0 = ZZ1 = LeftSector.CalculateFloorHeight(X2, Y2);
                ZZ2 = ZZ3 = LeftSector.CalculateCeilingHeight(X2, Y2);
                return;
            }

            // only right sector? use heights from there and return
            if (LeftSector == null)
            {
                Z0  = Z1 = RightSector.CalculateFloorHeight(X1, Y1);
                Z2  = Z3 = RightSector.CalculateCeilingHeight(X1, Y1);
                ZZ0 = ZZ1 = RightSector.CalculateFloorHeight(X2, Y2);
                ZZ2 = ZZ3 = RightSector.CalculateCeilingHeight(X2, Y2);
                return;
            }

            // --  finally, if there are both sectors available ---

            // start with the floor handling
            Real S1_height0 = RightSector.CalculateFloorHeight(X1, Y1);
            Real S2_height0 = LeftSector.CalculateFloorHeight(X1, Y1);
            Real S1_height1 = RightSector.CalculateFloorHeight(X2, Y2);
            Real S2_height1 = LeftSector.CalculateFloorHeight(X2, Y2);

            // S1 is above S2 at first endpoint
            if (S1_height0 > S2_height0)
            {
                if (S1_height1 >= S2_height1)
                {
                    // normal wall - S1 higher at both ends
                    BowtieFlags.Value = 0;

                    Z1  = S1_height0;
                    ZZ1 = S1_height1;
                    Z0  = S2_height0;
                    ZZ0 = S2_height1;
                }
                else
                {
                    // bowtie handling
                    BowtieFlags.IsBelowPos = true;

                    // no extra zNeg here
                    Z1  = S1_height0;
                    ZZ1 = S2_height1;
                    Z0  = S2_height0;
                    ZZ0 = S1_height1;
                }
            }

            // S2 above S1 at first endpoint
            else
            {
                if (S2_height1 >= S1_height1)
                {
                    // normal wall - S2 higher at both ends
                    BowtieFlags.Value = 0;

                    Z1  = S2_height0;
                    ZZ1 = S2_height1;
                    Z0  = S1_height0;
                    ZZ0 = S1_height1;
                }
                else
                {
                    // bowtie handling
                    BowtieFlags.IsBelowNeg = true;

                    // no extra zNeg here
                    Z1  = S2_height0;
                    ZZ1 = S1_height1;
                    Z0  = S1_height0;
                    ZZ0 = S2_height1;
                }
            }

            // start with ceiling handling
            S1_height0 = RightSector.CalculateCeilingHeight(X1, Y1);
            S2_height0 = LeftSector.CalculateCeilingHeight(X1, Y1);
            S1_height1 = RightSector.CalculateCeilingHeight(X2, Y2);
            S2_height1 = LeftSector.CalculateCeilingHeight(X2, Y2);

            if (S1_height0 > S2_height0)
            {
                if (S1_height1 >= S2_height1)
                {
                    // normal wall - S1 higher at both ends
                    //wall->bowtie_bits &= (BYTE)~BT_ABOVE_BOWTIE; // Clear above bowtie bits
                    BowtieFlags.IsAboveBowtie = false;

                    Z3  = S1_height0;
                    ZZ3 = S1_height1;
                    Z2  = S2_height0;
                    ZZ2 = S2_height1;
                }
                else
                {
                    // bowtie - see notes on bowties above
                    //wall->bowtie_bits |= (BYTE)BT_ABOVE_POS; // positive sector is on top at endpoint 0
                    BowtieFlags.IsAbovePos = true;

                    Z3  = S1_height0;
                    ZZ3 = S2_height1;
                    Z2  = S2_height0;
                    ZZ2 = S1_height1;
                }
            }
            else
            {
                if (S2_height1 >= S1_height1)
                {
                    // normal wall - S2 higher at both ends
                    //wall->bowtie_bits &= (BYTE)~BT_ABOVE_BOWTIE;
                    BowtieFlags.IsAboveBowtie = false;

                    Z3  = S2_height0;
                    ZZ3 = S2_height1;
                    Z2  = S1_height0;
                    ZZ2 = S1_height1;
                }
                else
                {
                    // bowtie - see notes on bowties above
                    //wall->bowtie_bits |= (BYTE)BT_ABOVE_NEG; // negative sector is on top at endpoint 0
                    BowtieFlags.IsAboveNeg = true;

                    Z3  = S2_height0;
                    ZZ3 = S1_height1;
                    Z2  = S1_height0;
                    ZZ2 = S2_height1;
                }
            }
        }