예제 #1
0
        /*
        =============
        SV_Physics_Toss

        Toss, bounce, and fly movement.  When onground, do nothing.
        =============
        */
        static void SV_Physics_Toss(prog.edict_t ent)
        {
            world.trace_t	trace= new world.trace_t();
            double[]	move = new double[3] {0, 0, 0};
            double      backoff;

            // regular thinking
            if (!SV_RunThink (ent))
                return;

            // if onground, return without moving
            if ( ((int)ent.v.flags & FL_ONGROUND) != 0 )
                return;

            SV_CheckVelocity (ent);

            // add gravity
            if (ent.v.movetype != MOVETYPE_FLY
            && ent.v.movetype != MOVETYPE_FLYMISSILE)
                SV_AddGravity (ent);

            // move angles
            mathlib.VectorMA (ent.v.angles, host.host_frametime, ent.v.avelocity, ent.v.angles);

            // move origin
            mathlib.VectorScale (ent.v.velocity, host.host_frametime, move);
            trace = SV_PushEntity (ent, move);
            if (trace.fraction == 1)
                return;
            if (ent.free)
                return;

            if (ent.v.movetype == MOVETYPE_BOUNCE)
                backoff = 1.5;
            else
                backoff = 1;

            ClipVelocity(ent.v.velocity, trace.plane.normal, ent.v.velocity, backoff);

            // stop if on ground
            if (trace.plane.normal[2] > 0.7)
            {
                if (ent.v.velocity[2] < 60 || ent.v.movetype != MOVETYPE_BOUNCE)
                {
                    ent.v.flags = (int)ent.v.flags | FL_ONGROUND;
                    ent.v.groundentity = prog.EDICT_TO_PROG(trace.ent);
                    mathlib.VectorCopy(mathlib.vec3_origin, ent.v.velocity);
                    mathlib.VectorCopy(mathlib.vec3_origin, ent.v.avelocity);
                }
            }

            // check for in water
            SV_CheckWaterTransition(ent);
        }
예제 #2
0
        private static void SV_Physics_Step(prog.edict_t ent)
        {
            bool hitsound;

            // freefall if not onground
            if (!(((int)ent.v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM)) != 0))
            {
                if (ent.v.velocity[2] < sv_gravity.value * -0.1)
                    hitsound = true;
                else
                    hitsound = false;

                SV_AddGravity(ent);
                SV_CheckVelocity(ent);
                var unused_trace_t = new world.trace_t(); // null was passed into SV_FlyMove in original
                SV_FlyMove(ent, host.host_frametime, ref unused_trace_t);
                world.SV_LinkEdict(ent, true);

                if (((int)ent.v.flags & FL_ONGROUND) != 0) // just hit ground
                {
                    if (hitsound)
                        SV_StartSound(ent, 0, "demon/dland2.wav", 255, 1);
                }
            }

            // regular thinking
            SV_RunThink(ent);

            SV_CheckWaterTransition(ent);
        }
예제 #3
0
        /*
        ================
        SV_Physics_Client

        Player character actions
        ================
        */
        static void SV_Physics_Client(prog.edict_t ent, int num)
        {
            //Debug.WriteLine("SV_Physics_Client");
            if ( ! svs.clients[num-1].active )
                return;		// unconnected slot

            //
            // call standard client pre-think
            //
            prog.pr_global_struct[0].time = sv.time;
            prog.pr_global_struct[0].self = prog.EDICT_TO_PROG(ent);
            prog.PR_ExecuteProgram(prog.pr_functions[prog.pr_global_struct[0].PlayerPreThink]);

            //
            // do a move
            //
            SV_CheckVelocity (ent);

            //
            // decide which move function to call
            //
            switch ((int)ent.v.movetype)
            {
            case MOVETYPE_NONE:
                if (!SV_RunThink (ent))
                    return;
                break;

            case MOVETYPE_WALK:
                if (!SV_RunThink (ent))
                    return;
                if (!SV_CheckWater (ent) && ! (((int)ent.v.flags & FL_WATERJUMP) != 0) )
                    SV_AddGravity (ent);
                SV_CheckStuck (ent);
                SV_WalkMove (ent);
                break;

            case MOVETYPE_TOSS:
            case MOVETYPE_BOUNCE:
                SV_Physics_Toss (ent);
                break;

            case MOVETYPE_FLY:
                if (!SV_RunThink (ent))
                    return;
                var unused_trace_t = new world.trace_t(); // null was passed into SV_FlyMove in original
                SV_FlyMove(ent, host.host_frametime, ref unused_trace_t);
                break;

            case MOVETYPE_NOCLIP:
                if (!SV_RunThink (ent))
                    return;
                mathlib.VectorMA (ent.v.origin, host.host_frametime, ent.v.velocity, ent.v.origin);
                break;

            default:
                sys_linux.Sys_Error ("SV_Physics_client: bad movetype " + (int)ent.v.movetype);
                break;
            }

            //
            // call standard player post-think
            //
               world.SV_LinkEdict (ent, true);

            prog.pr_global_struct[0].time = sv.time;
            prog.pr_global_struct[0].self = prog.EDICT_TO_PROG(ent);
            prog.PR_ExecuteProgram(prog.pr_functions[prog.pr_global_struct[0].PlayerPostThink]);
        }
예제 #4
0
        /*
        =====================
        SV_WalkMove

        Only used by players
        ======================
        */
        public static void SV_WalkMove(prog.edict_t ent)
        {
            double[] upmove = new double[3] {0, 0, 0}, downmove = new double[3] {0, 0, 0};
            double[] oldorg = new double[3] {0, 0, 0}, oldvel = new double[3] {0, 0, 0};
            double[] nosteporg = new double[3] {0, 0, 0}, nostepvel = new double[3] {0, 0, 0};
            int clip;
            int oldonground;
            world.trace_t steptrace = new world.trace_t(), downtrace = new world.trace_t();

            //
            // do a regular slide move unless it looks like you ran into a step
            //
            oldonground = (int)ent.v.flags & FL_ONGROUND;
            ent.v.flags = (int)ent.v.flags & ~FL_ONGROUND;

            mathlib.VectorCopy(ent.v.origin, oldorg);
            mathlib.VectorCopy(ent.v.velocity, oldvel);

            clip = SV_FlyMove(ent, host.host_frametime, ref steptrace);

            if (!((clip & 2) != 0))
                return; // move didn't block on a step

            if (!(oldonground != 0) && ent.v.waterlevel == 0)
                return; // don't stair up while jumping

            if (ent.v.movetype != MOVETYPE_WALK)
                return; // gibbed by a trigger

            if (sv_nostep.value != 0.0)
                return;

            if (((int)sv_player.v.flags & FL_WATERJUMP) != 0)
                return;

            mathlib.VectorCopy(ent.v.origin, nosteporg);
            mathlib.VectorCopy(ent.v.velocity, nostepvel);

            //
            // try moving up and forward to go up a step
            //
            mathlib.VectorCopy(oldorg, ent.v.origin); // back to start pos

            mathlib.VectorCopy(mathlib.vec3_origin, upmove);
            mathlib.VectorCopy(mathlib.vec3_origin, downmove);
            upmove[2] = STEPSIZE;
            downmove[2] = -STEPSIZE + oldvel[2] * host.host_frametime;

            // move up
            SV_PushEntity(ent, upmove); // FIXME: don't link?

            // move forward
            ent.v.velocity[0] = oldvel[0];
            ent.v.velocity[1] = oldvel[1];
            ent.v.velocity[2] = 0;
            clip = SV_FlyMove(ent, host.host_frametime, ref steptrace);

            // check for stuckness, possibly due to the limited precision of floats
            // in the clipping hulls
            if (clip != 0)
            {
                if ( Math.Abs(oldorg[1] - ent.v.origin[1]) < 0.03125 &&  Math.Abs(oldorg[0] - ent.v.origin[0]) < 0.03125)
                {
                    // stepping up didn't make any progress
                    clip = SV_TryUnstick(ent, oldvel);
                }
            }

            // extra friction based on view angle
            if ((clip & 2) != 0)
                SV_WallFriction(ent, steptrace);

            // move down
            downtrace = SV_PushEntity(ent, downmove); // FIXME: don't link?

            if (downtrace.plane.normal[2] > 0.7)
            {
                if (ent.v.solid == SOLID_BSP)
                {
                    ent.v.flags = (int)ent.v.flags | FL_ONGROUND;
                    ent.v.groundentity = prog.EDICT_TO_PROG(downtrace.ent);
                }
            }
            else
            {
                // if the push down didn't end up on good ground, use the move without
                // the step up.  This happens near wall / slope combinations, and can
                // cause the player to hop up higher on a slope too steep to climb
                mathlib.VectorCopy(nosteporg, ent.v.origin);
                mathlib.VectorCopy(nostepvel, ent.v.velocity);
            }
        }
예제 #5
0
        /*
        =====================
        SV_TryUnstick

        Player has come to a dead stop, possibly due to the problem with limited
        float precision at some angle joins in the BSP hull.

        Try fixing by pushing one pixel in each direction.

        This is a hack, but in the interest of good gameplay...
        ======================
        */
        static int SV_TryUnstick(prog.edict_t ent, double[] oldvel)
        {
            int		i;
            double[]	oldorg = new double[3] {0, 0, 0};
            double[]	dir = new double[3] {0, 0, 0};
            int		clip;
            world.trace_t	steptrace = new world.trace_t();

            mathlib.VectorCopy (ent.v.origin, oldorg);
            mathlib.VectorCopy (mathlib.vec3_origin, dir);

            for (i=0 ; i<8 ; i++)
            {
            // try pushing a little in an axial direction
                switch (i)
                {
                    case 0:	dir[0] = 2; dir[1] = 0; break;
                    case 1:	dir[0] = 0; dir[1] = 2; break;
                    case 2:	dir[0] = -2; dir[1] = 0; break;
                    case 3:	dir[0] = 0; dir[1] = -2; break;
                    case 4:	dir[0] = 2; dir[1] = 2; break;
                    case 5:	dir[0] = -2; dir[1] = 2; break;
                    case 6:	dir[0] = 2; dir[1] = -2; break;
                    case 7:	dir[0] = -2; dir[1] = -2; break;
                }

                SV_PushEntity (ent, dir);

            // retry the original move
                ent.v.velocity[0] = oldvel[0];
                ent.v. velocity[1] = oldvel[1];
                ent.v. velocity[2] = 0;
                clip = SV_FlyMove (ent, 0.1f, ref steptrace);

                if (  Math.Abs(oldorg[1] - ent.v.origin[1]) > 4
                ||  Math.Abs(oldorg[0] - ent.v.origin[0]) > 4 )
                {
            //Con_DPrintf ("unstuck!\n");
                    return clip;
                }

            // go back to the original pos and try again
                mathlib.VectorCopy (oldorg, ent.v.origin);
            }

            mathlib.VectorCopy (mathlib.vec3_origin, ent.v.velocity);
            return 7;		// still not moving
        }
예제 #6
0
파일: chase.cs 프로젝트: sbrown345/quakejs
        static void TraceLine(double[] start, double[] end, double[] impact)
        {
            world.trace_t trace;

            trace = new world.trace_t();
            world.SV_RecursiveHullCheck(client.cl.worldmodel.hulls[0], 0, 0, 1, start, end, trace);

            mathlib.VectorCopy(trace.endpos, impact);
        }