Пример #1
0
        private static int SV_FlyMove(prog.edict_t ent, double time /*was float*/, ref world.trace_t steptrace)
        {
            int bumpcount, numbumps;
            double[] dir = new double[3] {0, 0, 0};
            double d;
            int numplanes;
            double[][] planes =
                {
                    ArrayHelpers.ExplcitDoubleArray(3), ArrayHelpers.ExplcitDoubleArray(3),
                    ArrayHelpers.ExplcitDoubleArray(3), ArrayHelpers.ExplcitDoubleArray(3),
                    ArrayHelpers.ExplcitDoubleArray(3)
                };
            double[] primal_velocity = new double[3] {0, 0, 0}, original_velocity = new double[3] {0, 0, 0}, new_velocity = new double[3] {0, 0, 0};
            int i, j;
            world.trace_t trace;
            double[] end = new double[3] {0, 0, 0};
            double time_left;
            int blocked;

            numbumps = 4;

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

            time_left = time;

            //Debug.WriteLine("SV_FlyMove");
            for (bumpcount = 0; bumpcount < numbumps; bumpcount++)
            {
                if (ent.v.velocity[0] == 0.0 && ent.v.velocity[1] == 0.0 && ent.v.velocity[2] == 0.0)
                    break;

                for (i = 0; i < 3; i++)
                    end[i] = ent.v.origin[i] + time_left * ent.v.velocity[i];

                trace = world.SV_Move(ent.v.origin, ent.v.mins, ent.v.maxs, end, 0, ent);

                if (trace.allsolid)
                {
                    //Debug.WriteLine("allsolid");
                    // entity is trapped in another solid
                    mathlib.VectorCopy(mathlib.vec3_origin, ent.v.velocity);
                    return 3;
                }

                //Debug.WriteLine(string.Format("fraction {0}", trace.fraction));
                if (trace.fraction > 0)
                {
                    // actually covered some distance
                    mathlib.VectorCopy(trace.endpos, ent.v.origin);
                    mathlib.VectorCopy(ent.v.velocity, original_velocity);
                    numplanes = 0;
                }

                if (trace.fraction == 1.0)
                    break; // moved the entire distance

                if (trace.ent == null)
                    sys_linux.Sys_Error("SV_FlyMove: !trace.ent");

                if (trace.plane.normal[2] > 0.7)
                {
                    //Debug.WriteLine("trace.plane.normal[2] > 0.7");
                    blocked |= 1; // floor
                    if (trace.ent.v.solid == SOLID_BSP)
                    {
                        ent.v.flags = (int)ent.v.flags | FL_ONGROUND;
                        ent.v.groundentity = prog.EDICT_TO_PROG(trace.ent);
                    }
                }
                if (!(trace.plane.normal[2] != 0.0))
                {
                    //Debug.WriteLine("!trace.plane.normal[2]");
                    blocked |= 2; // step
                    if (steptrace != null)
                        steptrace = trace; // save for player extrafriction
                }

                //
                // run the impact function
                //
                //Debug.WriteLine("SV_Impact");
                SV_Impact(ent, trace.ent);
                if (ent.free)
                {
                    //Debug.WriteLine("ent.fre");
                    break; // removed by the impact function
                }

                time_left -= time_left * trace.fraction;

                // cliped to another plane
                if (numplanes >= MAX_CLIP_PLANES)
                {
                    //Debug.WriteLine("numplanes >= MAX_CLIP_PLANES");
                    // this shouldn't really happen
                    mathlib.VectorCopy(mathlib.vec3_origin, ent.v.velocity);
                    return 3;
                }

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

                //
                // modify original_velocity so it parallels all of the clip planes
                //
                for (i = 0; i < numplanes; i++)
                {
                    ClipVelocity(original_velocity, planes[i], new_velocity, 1);
                    for (j = 0; j < numplanes; j++)
                        if (j != i)
                        {
                            if (mathlib.DotProduct(new_velocity, planes[j]) < 0)
                                break; // not ok
                        }
                    if (j == numplanes)
                        break;
                }

                if (i != numplanes)
                {
                    // go along this plane
                    //Debug.WriteLine("i != numplanes");
                    mathlib.VectorCopy(new_velocity, ent.v.velocity);
                }
                else
                {
                    // go along the crease
                    if (numplanes != 2)
                    {
                        //				Con_Printf ("clip velocity, numplanes == %i\n",numplanes);
                        mathlib.VectorCopy(mathlib.vec3_origin, ent.v.velocity);
                        return 7;
                    }
                    mathlib.CrossProduct(planes[0], planes[1], dir);
                    d = mathlib.DotProduct(dir, ent.v.velocity);
                    mathlib.VectorScale(dir, d, ent.v.velocity);
                }

                //
                // if original velocity is against the original velocity, stop dead
                // to avoid tiny occilations in sloping corners
                //
                if (mathlib.DotProduct(ent.v.velocity, primal_velocity) <= 0)
                {
                    //Debug.WriteLine("DotProductstuff");
                    mathlib.VectorCopy(mathlib.vec3_origin, ent.v.velocity);
                    return blocked;
                }
            }

            return blocked;
        }
Пример #2
0
        /*
        ============
        SV_WallFriction

        ============
        */
        static void SV_WallFriction(prog.edict_t ent, world.trace_t trace)
        {
            double[] forward = new double[3] {0, 0, 0}, right = new double[3] {0, 0, 0}, up = new double[3] {0, 0, 0};
            double d, i;
            double[] into = new double[3] {0, 0, 0}, side = new double[3] {0, 0, 0};

            mathlib.AngleVectors(ent.v.v_angle, forward, right, up);
            d = mathlib.DotProduct(trace.plane.normal, forward);

            d += 0.5;
            if (d >= 0)
                return;

            // cut the tangential velocity
            i = mathlib.DotProduct(trace.plane.normal, ent.v.velocity);
            mathlib.VectorScale(trace.plane.normal, i, into);
            mathlib.VectorSubtract(ent.v.velocity, into, side);

            ent.v.velocity[0] = side[0] * (1 + d);
            ent.v.velocity[1] = side[1] * (1 + d);
        }