示例#1
0
        /**
         * Does not change the entities velocity at all
         */
        public static trace_t SV_PushEntity(edict_t ent, float[] push)
        {
            trace_t trace;

            float[] start = { 0, 0, 0 };
            float[] end   = { 0, 0, 0 };
            int     mask;

            Math3D.VectorCopy(ent.s.origin, start);
            Math3D.VectorAdd(start, push, end);

            // FIXME: test this
            // a goto statement was replaced.
            var retry = false;

            do
            {
                if (ent.clipmask != 0)
                {
                    mask = ent.clipmask;
                }
                else
                {
                    mask = Defines.MASK_SOLID;
                }

                trace = GameBase.gi.trace(start, ent.mins, ent.maxs, end, ent, mask);

                Math3D.VectorCopy(trace.endpos, ent.s.origin);
                GameBase.gi.linkentity(ent);

                retry = false;

                if (trace.fraction != 1.0)
                {
                    SV.SV_Impact(ent, trace);

                    // if the pushed entity went away and the pusher is still there
                    if (!trace.ent.inuse && ent.inuse)
                    {
                        // move the pusher back and try again
                        Math3D.VectorCopy(start, ent.s.origin);
                        GameBase.gi.linkentity(ent);

                        //goto retry;
                        retry = true;
                    }
                }
            }while (retry);

            if (ent.inuse)
            {
                GameBase.G_TouchTriggers(ent);
            }

            return(trace);
        }
示例#2
0
        public static int SV_FlyMove(edict_t ent, float time, int mask)
        {
            edict_t hit;
            int     bumpcount, numbumps;

            float[] dir = { 0.0f, 0.0f, 0.0f };
            float   d;
            int     numplanes;
            var     planes = new float[SV.MAX_CLIP_PLANES][];

            float[] primal_velocity = { 0.0f, 0.0f, 0.0f };
            float[] original_velocity = { 0.0f, 0.0f, 0.0f };
            float[] new_velocity = { 0.0f, 0.0f, 0.0f };
            int     i, j;
            trace_t trace;

            float[] end = { 0.0f, 0.0f, 0.0f };
            float   time_left;
            int     blocked;

            for (var n = 0; n < planes.Length; n++)
            {
                planes[n] = new float[3];
            }

            numbumps = 4;

            blocked = 0;
            Math3D.VectorCopy(ent.velocity, original_velocity);
            Math3D.VectorCopy(ent.velocity, primal_velocity);
            numplanes = 0;

            time_left = time;

            ent.groundentity = null;

            for (bumpcount = 0; bumpcount < numbumps; bumpcount++)
            {
                for (i = 0; i < 3; i++)
                {
                    end[i] = ent.s.origin[i] + time_left * ent.velocity[i];
                }

                trace = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs, end, ent, mask);

                if (trace.allsolid)
                {
                    // entity is trapped in another solid
                    Math3D.VectorCopy(Globals.vec3_origin, ent.velocity);

                    return(3);
                }

                if (trace.fraction > 0)
                {
                    // actually covered some distance
                    Math3D.VectorCopy(trace.endpos, ent.s.origin);
                    Math3D.VectorCopy(ent.velocity, original_velocity);
                    numplanes = 0;
                }

                if (trace.fraction == 1)
                {
                    break;                     // moved the entire distance
                }
                hit = trace.ent;

                if (trace.plane.normal[2] > 0.7)
                {
                    blocked |= 1;                     // floor

                    if (hit.solid == Defines.SOLID_BSP)
                    {
                        ent.groundentity           = hit;
                        ent.groundentity_linkcount = hit.linkcount;
                    }
                }

                if (trace.plane.normal[2] == 0.0f)
                {
                    blocked |= 2;                     // step
                }
                //
                //	   run the impact function
                //
                SV.SV_Impact(ent, trace);

                if (!ent.inuse)
                {
                    break;                     // removed by the impact function
                }
                time_left -= time_left * trace.fraction;

                // cliped to another plane
                if (numplanes >= SV.MAX_CLIP_PLANES)
                {
                    // this shouldn't
                    // really happen
                    Math3D.VectorCopy(Globals.vec3_origin, ent.velocity);

                    return(3);
                }

                Math3D.VectorCopy(trace.plane.normal, planes[numplanes]);
                numplanes++;

                //
                //	   modify original_velocity so it parallels all of the clip planes
                //
                for (i = 0; i < numplanes; i++)
                {
                    GameBase.ClipVelocity(original_velocity, planes[i], new_velocity, 1);

                    for (j = 0; j < numplanes; j++)
                    {
                        if (j != i && !Math3D.VectorEquals(planes[i], planes[j]))
                        {
                            if (Math3D.DotProduct(new_velocity, planes[j]) < 0)
                            {
                                break;                                 // not ok
                            }
                        }
                    }

                    if (j == numplanes)
                    {
                        break;
                    }
                }

                if (i != numplanes)
                {
                    // go along this plane
                    Math3D.VectorCopy(new_velocity, ent.velocity);
                }
                else
                {
                    // go along the crease
                    if (numplanes != 2)
                    {
                        //					gi.dprintf ("clip velocity, numplanes ==
                        // %i\n",numplanes);
                        Math3D.VectorCopy(Globals.vec3_origin, ent.velocity);

                        return(7);
                    }

                    Math3D.CrossProduct(planes[0], planes[1], dir);
                    d = Math3D.DotProduct(dir, ent.velocity);
                    Math3D.VectorScale(dir, d, ent.velocity);
                }

                //
                //	   if original velocity is against the original velocity, stop dead
                //	   to avoid tiny occilations in sloping corners
                //
                if (Math3D.DotProduct(ent.velocity, primal_velocity) <= 0)
                {
                    Math3D.VectorCopy(Globals.vec3_origin, ent.velocity);

                    return(blocked);
                }
            }

            return(blocked);
        }