Пример #1
0
        /// <summary>
        /// SV_movestep
        /// Called by monster program code.
        /// The move will be adjusted for slopes and stairs, but if the move isn't
        /// possible, no move is done, false is returned, and
        /// pr_global_struct.trace_normal is set to the normal of the blocking wall
        /// </summary>
        public static bool MoveStep(edict_t ent, ref v3f move, bool relink)
        {
            trace_t trace;

            // try the move
            v3f oldorg = ent.v.origin;
            v3f neworg;

            Mathlib.VectorAdd(ref ent.v.origin, ref move, out neworg);

            // flying monsters don't step up
            if (((int)ent.v.flags & (EdictFlags.FL_SWIM | EdictFlags.FL_FLY)) != 0)
            {
                // try one move with vertical motion, then one without
                for (int i = 0; i < 2; i++)
                {
                    Mathlib.VectorAdd(ref ent.v.origin, ref move, out neworg);
                    edict_t enemy = ProgToEdict(ent.v.enemy);
                    if (i == 0 && enemy != sv.edicts[0])
                    {
                        float dz = ent.v.origin.z - enemy.v.origin.z;
                        if (dz > 40)
                        {
                            neworg.z -= 8;
                        }
                        if (dz < 30)
                        {
                            neworg.z += 8;
                        }
                    }

                    trace = Move(ref ent.v.origin, ref ent.v.mins, ref ent.v.maxs, ref neworg, 0, ent);
                    if (trace.fraction == 1)
                    {
                        if (((int)ent.v.flags & EdictFlags.FL_SWIM) != 0 &&
                            PointContents(ref trace.endpos) == Contents.CONTENTS_EMPTY)
                        {
                            return(false);       // swim monster left water
                        }
                        Mathlib.Copy(ref trace.endpos, out ent.v.origin);
                        if (relink)
                        {
                            LinkEdict(ent, true);
                        }
                        return(true);
                    }

                    if (enemy == sv.edicts[0])
                    {
                        break;
                    }
                }

                return(false);
            }

            // push down from a step height above the wished position
            neworg.z += STEPSIZE;
            v3f end = neworg;

            end.z -= STEPSIZE * 2;

            trace = Move(ref neworg, ref ent.v.mins, ref ent.v.maxs, ref end, 0, ent);

            if (trace.allsolid)
            {
                return(false);
            }

            if (trace.startsolid)
            {
                neworg.z -= STEPSIZE;
                trace     = Move(ref neworg, ref ent.v.mins, ref ent.v.maxs, ref end, 0, ent);
                if (trace.allsolid || trace.startsolid)
                {
                    return(false);
                }
            }
            if (trace.fraction == 1)
            {
                // if monster had the ground pulled out, go ahead and fall
                if (((int)ent.v.flags & EdictFlags.FL_PARTIALGROUND) != 0)
                {
                    Mathlib.VectorAdd(ref ent.v.origin, ref move, out ent.v.origin);
                    if (relink)
                    {
                        LinkEdict(ent, true);
                    }
                    ent.v.flags = (int)ent.v.flags & ~EdictFlags.FL_ONGROUND;
                    return(true);
                }

                return(false);           // walked off an edge
            }

            // check point traces down for dangling corners
            Mathlib.Copy(ref trace.endpos, out ent.v.origin);

            if (!CheckBottom(ent))
            {
                if (((int)ent.v.flags & EdictFlags.FL_PARTIALGROUND) != 0)
                {
                    // entity had floor mostly pulled out from underneath it
                    // and is trying to correct
                    if (relink)
                    {
                        LinkEdict(ent, true);
                    }
                    return(true);
                }
                ent.v.origin = oldorg;
                return(false);
            }

            if (((int)ent.v.flags & EdictFlags.FL_PARTIALGROUND) != 0)
            {
                ent.v.flags = (int)ent.v.flags & ~EdictFlags.FL_PARTIALGROUND;
            }
            ent.v.groundentity = EdictToProg(trace.ent);

            // the move is ok
            if (relink)
            {
                LinkEdict(ent, true);
            }
            return(true);
        }
Пример #2
0
 static unsafe void Copy(float *src, ref v3f dest)
 {
     dest.x = src[0];
     dest.y = src[1];
     dest.z = src[2];
 }
Пример #3
0
 public static void Copy(ref Vector3 src, out v3f dest)
 {
     dest.x = src.X;
     dest.y = src.Y;
     dest.z = src.Z;
 }
Пример #4
0
 public static float LengthXY(ref v3f v)
 {
     return((float)Math.Sqrt(v.x * v.x + v.y * v.y));
 }
Пример #5
0
 public static float DotProduct(ref v3f a, ref v3f b)
 {
     return(a.x * b.x + a.y * b.y + a.z * b.z);
 }
Пример #6
0
        //static Vector3 PerpendicularVector(ref Vector3 src)
        //{
        //    float minelem = 1.0f;

        //    // find the smallest magnitude axially aligned vector
        //    Vector3 tempvec = Vector3.Zero;
        //    if (Math.Abs(src.X) < minelem)
        //    {
        //        minelem = Math.Abs(src.X);
        //        tempvec.X = 1;
        //    }
        //    if (Math.Abs(src.Y) < minelem)
        //    {
        //        minelem = Math.Abs(src.Y);
        //        tempvec = new Vector3(0, 1, 0);
        //    }
        //    else if (Math.Abs(src.Z) < minelem)
        //    {
        //        tempvec = new Vector3(0, 0, 1);
        //    }

        //    // project the point onto the plane defined by src
        //    Vector3 dst = ProjectPointOnPlane(ref tempvec, ref src);

        //    Normalize(ref dst);

        //    return dst;
        //}

        //static Vector3 ProjectPointOnPlane(ref Vector3 p, ref Vector3 normal)
        //{
        //    float inv_denom = 1.0f / normal.LengthSquared;
        //    float d = Vector3.Dot(normal, p) * inv_denom;
        //    Vector3 n = normal * inv_denom;

        //    return p - d * n;
        //}

        public static void Copy(ref v3f src, out Vector3 dest)
        {
            dest.X = src.x;
            dest.Y = src.y;
            dest.Z = src.z;
        }
Пример #7
0
 public static void VectorSubtract(ref byte[] a, ref byte[] b, out v3f c)
 {
     c.x = a[0] - b[0];
     c.y = a[1] - b[1];
     c.z = a[2] - b[2];
 }
Пример #8
0
 public static void Clamp(ref v3f src, ref Vector3 min, ref Vector3 max, out v3f dest)
 {
     dest.x = Math.Max(Math.Min(src.x, max.X), min.X);
     dest.y = Math.Max(Math.Min(src.y, max.Y), min.Y);
     dest.z = Math.Max(Math.Min(src.z, max.Z), min.Z);
 }
Пример #9
0
 public static void VectorSubtract(ref v3f a, ref v3f b, out v3f c)
 {
     c.x = a.x - b.x;
     c.y = a.y - b.y;
     c.z = a.z - b.z;
 }
Пример #10
0
 public static void VectorAdd(ref v3f a, ref v3f b, out v3f c)
 {
     c.x = a.x + b.x;
     c.y = a.y + b.y;
     c.z = a.z + b.z;
 }
Пример #11
0
 public static void VectorScale(ref v3f a, float scale, out v3f b)
 {
     b.x = a.x * scale;
     b.y = a.y * scale;
     b.z = a.z * scale;
 }
Пример #12
0
 /// <summary>
 /// c = a + b * scale;
 /// </summary>
 public static void VectorMA(ref v3f a, float scale, ref v3f b, out v3f c)
 {
     c.x = a.x + b.x * scale;
     c.y = a.y + b.y * scale;
     c.z = a.z + b.z * scale;
 }
Пример #13
0
        /// <summary>
        /// SV_SetIdealPitch
        /// </summary>
        public static void SetIdealPitch()
        {
            if (((int)_Player.v.flags & EdictFlags.FL_ONGROUND) == 0)
            {
                return;
            }

            double angleval = _Player.v.angles.y * Math.PI * 2 / 360;
            double sinval   = Math.Sin(angleval);
            double cosval   = Math.Cos(angleval);

            float[] z = new float[MAX_FORWARD];
            for (int i = 0; i < MAX_FORWARD; i++)
            {
                v3f top = _Player.v.origin;
                top.x += (float)(cosval * (i + 3) * 12);
                top.y += (float)(sinval * (i + 3) * 12);
                top.z += _Player.v.view_ofs.z;

                v3f bottom = top;
                bottom.z -= 160;

                trace_t tr = Move(ref top, ref Common.ZeroVector3f, ref Common.ZeroVector3f, ref bottom, 1, _Player);
                if (tr.allsolid)
                {
                    return;     // looking at a wall, leave ideal the way is was
                }
                if (tr.fraction == 1)
                {
                    return;     // near a dropoff
                }
                z[i] = top.z + tr.fraction * (bottom.z - top.z);
            }

            float dir   = 0; // Uze: int in original code???
            int   steps = 0;

            for (int j = 1; j < MAX_FORWARD; j++)
            {
                float step = z[j] - z[j - 1];                          // Uze: int in original code???
                if (step > -QDef.ON_EPSILON && step < QDef.ON_EPSILON) // Uze: comparing int with ON_EPSILON (0.1)???
                {
                    continue;
                }

                if (dir != 0 && (step - dir > QDef.ON_EPSILON || step - dir < -QDef.ON_EPSILON))
                {
                    return;             // mixed changes
                }
                steps++;
                dir = step;
            }

            if (dir == 0)
            {
                _Player.v.idealpitch = 0;
                return;
            }

            if (steps < 2)
            {
                return;
            }
            _Player.v.idealpitch = -dir * _IdealPitchScale.Value;
        }