]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/physics/movetypes/movetypes.qc
Some minor tweaks to the QC physics logic
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / physics / movetypes / movetypes.qc
index e207551838e03cd6bbe0f363f1677d17a1a6738f..2634b8246bedc6e0eb165b772a11f341d6364924 100644 (file)
@@ -6,6 +6,8 @@ void set_movetype(entity this, int mt)
        this.move_movetype = mt;
        if (mt == MOVETYPE_PHYSICS) {
                this.move_qcphysics = false;
+       } else if (autocvar_sv_qcphysics == 2) {
+               this.move_qcphysics = true;
        }
        if(!IL_CONTAINS(g_moveables, this))
                IL_PUSH(g_moveables, this); // add it to the moveable entities list (even if it doesn't move!) logic: if an object never sets its movetype, we assume it never does anything notable
@@ -127,14 +129,14 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, bool applystepno
                return 0;
 
        int blockedflag = 0;
-       int i, j, numplanes = 0;
+       int numplanes = 0;
        float time_left = dt, grav = 0;
        vector push;
        vector primal_velocity, original_velocity;
        vector restore_velocity = this.velocity;
 
-       for(i = 0; i < MAX_CLIP_PLANES; ++i)
-               planes[i] = '0 0 0';
+       for(int j = 0; j < MAX_CLIP_PLANES; ++j)
+               planes[j] = '0 0 0';
 
        if(applygravity)
        {
@@ -158,7 +160,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, bool applystepno
                        break;
 
                push = this.velocity * time_left;
-               if(!_Movetype_PushEntity(this, push, true, false))
+               if(!_Movetype_PushEntity(this, push, false))
                {
                        // we got teleported by a touch function
                        // let's abort the move
@@ -177,6 +179,8 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, bool applystepno
                if(trace_fraction == 1)
                        break;
 
+               time_left *= 1 - trace_fraction;
+
                float my_trace_fraction = trace_fraction;
                vector my_trace_plane_normal = trace_plane_normal;
 
@@ -201,28 +205,30 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, bool applystepno
                {
                        // step - handle it immediately
                        vector org = this.origin;
-                       vector steppush = '0 0 1' * stepheight;
+                       vector steppush = vec3(0, 0, stepheight);
+                       push = this.velocity * time_left;
 
-                       if(!_Movetype_PushEntity(this, steppush, true, false))
+                       if(!_Movetype_PushEntity(this, steppush, false))
                        {
                                blockedflag |= 8;
                                break;
                        }
-                       if(!_Movetype_PushEntity(this, push, true, false))
+                       if(!_Movetype_PushEntity(this, push, false))
                        {
                                blockedflag |= 8;
                                break;
                        }
                        float trace2_fraction = trace_fraction;
                        steppush = vec3(0, 0, org.z - this.origin_z);
-                       if(!_Movetype_PushEntity(this, steppush, true, false))
+                       if(!_Movetype_PushEntity(this, steppush, false))
                        {
                                blockedflag |= 8;
                                break;
                        }
 
                        // accept the new position if it made some progress...
-                       if(fabs(this.origin_x - org.x) >= 0.03125 || fabs(this.origin_y - org.y) >= 0.03125)
+                       // previously this checked if absolute distance >= 0.03125 which made stepping up unreliable
+                       if(this.origin_x - org.x || this.origin_y - org.y)
                        {
                                trace_endpos = this.origin;
                                time_left *= 1 - trace2_fraction;
@@ -248,8 +254,6 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, bool applystepno
                        numplanes = 0;
                }
 
-               time_left *= 1 - my_trace_fraction;
-
                // clipped to another plane
                if(numplanes >= MAX_CLIP_PLANES)
                {
@@ -264,23 +268,25 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, bool applystepno
 
                // modify original_velocity so it parallels all of the clip planes
                vector new_velocity = '0 0 0';
-               for (i = 0;i < numplanes;i++)
+               int plane;
+               for (plane = 0;plane < numplanes;plane++)
                {
-                       new_velocity = _Movetype_ClipVelocity(original_velocity, planes[i], 1);
-                       for (j = 0;j < numplanes;j++)
+                       int newplane;
+                       new_velocity = _Movetype_ClipVelocity(original_velocity, planes[plane], 1);
+                       for (newplane = 0;newplane < numplanes;newplane++)
                        {
-                               if(j != i)
+                               if(newplane != plane)
                                {
                                        // not ok
-                                       if((new_velocity * planes[j]) < 0)
+                                       if((new_velocity * planes[newplane]) < 0)
                                                break;
                                }
                        }
-                       if(j == numplanes)
+                       if(newplane == numplanes)
                                break;
                }
 
-               if(i != numplanes)
+               if(plane != numplanes)
                {
                        // go along this plane
                        this.velocity = new_velocity;
@@ -296,12 +302,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, bool applystepno
                        }
                        vector dir = cross(planes[0], planes[1]);
                        // LordHavoc: thanks to taniwha of QuakeForge for pointing out this fix for slowed falling in corners
-                       float ilength = sqrt((dir * dir));
-                       if(ilength)
-                               ilength = 1.0 / ilength;
-                       dir.x *= ilength;
-                       dir.y *= ilength;
-                       dir.z *= ilength;
+                       dir = normalize(dir);
                        float d = (dir * this.velocity);
                        this.velocity = dir * d;
                }
@@ -412,11 +413,40 @@ void _Movetype_Impact(entity this, entity oth)  // SV_Impact
        if(!this && !oth)
                return;
 
+       // due to a lack of pointers in QC, we must save the trace values and restore them for other functions
+       bool save_trace_allsolid = trace_allsolid;
+       bool save_trace_startsolid = trace_startsolid;
+       float save_trace_fraction = trace_fraction;
+       bool save_trace_inwater = trace_inwater;
+       bool save_trace_inopen = trace_inopen;
+       vector save_trace_endpos = trace_endpos;
+       vector save_trace_plane_normal = trace_plane_normal;
+       float save_trace_plane_dist = trace_plane_dist;
+       entity save_trace_ent = trace_ent;
+       int save_trace_dpstartcontents = trace_dpstartcontents;
+       int save_trace_dphitcontents = trace_dphitcontents;
+       int save_trace_dphitq3surfaceflags = trace_dphitq3surfaceflags;
+       string save_trace_dphittexturename = trace_dphittexturename;
+
        if(this.solid != SOLID_NOT && gettouch(this))
                gettouch(this)(this, oth);
 
        if(oth.solid != SOLID_NOT && gettouch(oth))
                gettouch(oth)(oth, this);
+
+       trace_allsolid = save_trace_allsolid;
+       trace_startsolid = save_trace_startsolid;
+       trace_fraction = save_trace_fraction;
+       trace_inwater = save_trace_inwater;
+       trace_inopen = save_trace_inopen;
+       trace_endpos = save_trace_endpos;
+       trace_plane_normal = save_trace_plane_normal;
+       trace_plane_dist = save_trace_plane_dist;
+       trace_ent = save_trace_ent;
+       trace_dpstartcontents = save_trace_dpstartcontents;
+       trace_dphitcontents = save_trace_dphitcontents;
+       trace_dphitq3surfaceflags = save_trace_dphitq3surfaceflags;
+       trace_dphittexturename = save_trace_dphittexturename;
 }
 
 void _Movetype_LinkEdict_TouchAreaGrid(entity this)  // SV_LinkEdict_TouchAreaGrid
@@ -424,6 +454,21 @@ void _Movetype_LinkEdict_TouchAreaGrid(entity this)  // SV_LinkEdict_TouchAreaGr
        if(this.solid == SOLID_NOT)
                return;
 
+       // due to a lack of pointers in QC, we must save the trace values and restore them for other functions
+       bool save_trace_allsolid = trace_allsolid;
+       bool save_trace_startsolid = trace_startsolid;
+       float save_trace_fraction = trace_fraction;
+       bool save_trace_inwater = trace_inwater;
+       bool save_trace_inopen = trace_inopen;
+       vector save_trace_endpos = trace_endpos;
+       vector save_trace_plane_normal = trace_plane_normal;
+       float save_trace_plane_dist = trace_plane_dist;
+       entity save_trace_ent = trace_ent;
+       int save_trace_dpstartcontents = trace_dpstartcontents;
+       int save_trace_dphitcontents = trace_dphitcontents;
+       int save_trace_dphitq3surfaceflags = trace_dphitq3surfaceflags;
+       string save_trace_dphittexturename = trace_dphittexturename;
+
     FOREACH_ENTITY_RADIUS_ORDERED(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin), true, {
                if (it.solid == SOLID_TRIGGER && it != this)
                if (it.move_nomonsters != MOVE_NOMONSTERS && it.move_nomonsters != MOVE_WORLDONLY)
@@ -446,6 +491,20 @@ void _Movetype_LinkEdict_TouchAreaGrid(entity this)  // SV_LinkEdict_TouchAreaGr
                        gettouch(it)(it, this);
                }
     });
+
+       trace_allsolid = save_trace_allsolid;
+       trace_startsolid = save_trace_startsolid;
+       trace_fraction = save_trace_fraction;
+       trace_inwater = save_trace_inwater;
+       trace_inopen = save_trace_inopen;
+       trace_endpos = save_trace_endpos;
+       trace_plane_normal = save_trace_plane_normal;
+       trace_plane_dist = save_trace_plane_dist;
+       trace_ent = save_trace_ent;
+       trace_dpstartcontents = save_trace_dpstartcontents;
+       trace_dphitcontents = save_trace_dphitcontents;
+       trace_dphitq3surfaceflags = save_trace_dphitq3surfaceflags;
+       trace_dphittexturename = save_trace_dphittexturename;
 }
 
 bool autocvar__movetype_debug = false;
@@ -605,7 +664,7 @@ void _Movetype_CheckStuck(entity this)  // SV_CheckStuck
        }
 }
 
-vector _Movetype_ClipVelocity(vector vel, vector norm, float f)  // SV_ClipVelocity
+vector _Movetype_ClipVelocity(vector vel, vector norm, float f)  // ClipVelocity
 {
        vel -= ((vel * norm) * norm) * f;
 
@@ -634,12 +693,12 @@ void _Movetype_PushEntityTrace(entity this, vector push)
        tracebox(this.origin, this.mins, this.maxs, end, type, this);
 }
 
-bool _Movetype_PushEntity(entity this, vector push, bool failonstartsolid, bool dolink)  // SV_PushEntity
+bool _Movetype_PushEntity(entity this, vector push, bool dolink)  // SV_PushEntity
 {
        _Movetype_PushEntityTrace(this, push);
 
        // NOTE: this is a workaround for the QC's lack of a worldstartsolid trace parameter
-       if(trace_startsolid && failonstartsolid)
+       if(trace_startsolid)
        {
                int oldtype = this.move_nomonsters;
                this.move_nomonsters = MOVE_WORLDONLY;
@@ -694,9 +753,6 @@ void _Movetype_Physics_Frame(entity this, float movedt)
                case MOVETYPE_FLY:
                case MOVETYPE_FLY_WORLDONLY:
                        _Movetype_Physics_Toss(this, movedt);
-                       if(wasfreed(this))
-                               return;
-                       _Movetype_LinkEdict(this, true);
                        break;
                case MOVETYPE_PHYSICS:
                        break;
@@ -723,15 +779,11 @@ void _Movetype_Physics_ClientFrame(entity this, float movedt)
                        this.angles = this.angles + movedt * this.avelocity;
                        break;
                case MOVETYPE_STEP:
-                       if (GAMEPLAYFIX_UNSTICKPLAYERS(this) == 2)
-                               _Movetype_CheckStuck(this);
                        _Movetype_Physics_Step(this, movedt);
                        break;
                case MOVETYPE_WALK:
                case MOVETYPE_FLY:
                case MOVETYPE_FLY_WORLDONLY:
-                       if (movedt > 0 && GAMEPLAYFIX_UNSTICKPLAYERS(this) == 2)
-                               _Movetype_CheckStuck(this);
                        _Movetype_Physics_Walk(this, movedt);
                        break;
                case MOVETYPE_TOSS: