Make the QC physics match the engine a bit more accurately, fixes some issues with...
authorMario <mario.mario@y7mail.com>
Sun, 29 Dec 2019 11:16:25 +0000 (21:16 +1000)
committerMario <mario.mario@y7mail.com>
Sun, 29 Dec 2019 11:16:25 +0000 (21:16 +1000)
qcsrc/common/mapobjects/trigger/jumppads.qc
qcsrc/common/physics/movetypes/movetypes.qc
qcsrc/common/physics/movetypes/movetypes.qh
qcsrc/common/physics/movetypes/toss.qc
qcsrc/common/stats.qh

index f438fbf01f5f8295032f45aa8e76647825377b04..f4b3e455a1309e1f0a0d44b7542f4ae38689117c 100644 (file)
@@ -36,8 +36,8 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht, entity p
        torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5;
 
        grav = PHYS_GRAVITY(NULL);
-       if(pushed_entity && PHYS_ENTGRAVITY(pushed_entity))
-               grav *= PHYS_ENTGRAVITY(pushed_entity);
+       if(pushed_entity && pushed_entity.gravity)
+               grav *= pushed_entity.gravity;
 
        zdist = torg.z - org.z;
        sdist = vlen(torg - org - zdist * '0 0 1');
index 8eb2277d54ad9cd2b98c2d9dc5d2199725245c7c..108782ef95f78df41bd385f938dec22210c72403 100644 (file)
@@ -54,7 +54,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, bool applystepno
        if(applygravity)
        {
                this.move_didgravity = 1;
-               grav = dt * (PHYS_ENTGRAVITY(this) ? PHYS_ENTGRAVITY(this) : 1) * PHYS_GRAVITY(this);
+               grav = dt * (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
 
                if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !IS_ONGROUND(this))
                {
@@ -324,11 +324,24 @@ void _Movetype_CheckWaterTransition(entity ent)  // SV_CheckWaterTransition
 
 void _Movetype_Impact(entity this, entity oth)  // SV_Impact
 {
-       if(gettouch(this))
+       if(!this && !oth)
+               return;
+
+       if(this.solid != SOLID_NOT && gettouch(this))
                gettouch(this)(this, oth);
 
-       if(gettouch(oth))
+       if(oth.solid != SOLID_NOT && gettouch(oth))
+       {
+               trace_endpos = oth.origin;
+               trace_plane_normal = -trace_plane_normal;
+               trace_plane_dist = -trace_plane_dist;
+               trace_ent = this;
+               trace_dpstartcontents = 0;
+               trace_dphitcontents = 0;
+               trace_dphitq3surfaceflags = 0;
+               trace_dphittexturename = string_null;
                gettouch(oth)(oth, this);
+       }
 }
 
 void _Movetype_LinkEdict_TouchAreaGrid(entity this)  // SV_LinkEdict_TouchAreaGrid
@@ -526,12 +539,10 @@ bool _Movetype_PushEntity(entity this, vector push, bool failonstartsolid, bool
 
        vector last_origin = this.origin;
 
-       if(dolink)
-               _Movetype_LinkEdict(this, true);
+       _Movetype_LinkEdict(this, dolink);
 
-       if(trace_fraction < 1)
-               if(this.solid >= SOLID_TRIGGER && trace_ent && (!IS_ONGROUND(this) || (this.groundentity != trace_ent)))
-                       _Movetype_Impact(this, trace_ent);
+       if((this.solid >= SOLID_TRIGGER && trace_fraction < 1 && (!IS_ONGROUND(this) || this.groundentity != trace_ent)))
+               _Movetype_Impact(this, trace_ent);
 
        return (this.origin == last_origin); // false if teleported by touch
 }
@@ -657,12 +668,14 @@ void Movetype_Physics_MatchServer(entity this, bool sloppy)
        Movetype_Physics_MatchTicrate(this, TICRATE, sloppy);
 }
 
+// saved .move_*
 .vector tic_origin;
 .vector tic_velocity;
 .int tic_flags;
 .vector tic_avelocity;
 .vector tic_angles;
 
+// saved .*
 .vector tic_saved_origin;
 .vector tic_saved_velocity;
 .int tic_saved_flags;
@@ -670,6 +683,8 @@ void Movetype_Physics_MatchServer(entity this, bool sloppy)
 .vector tic_saved_angles;
 void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Physics_Entity
 {
+       // this hack exists to contain the physics feature
+       // (so entities can place themselves in the world and not need to update .tic_* themselves)
 #define X(s) \
        if(this.(s) != this.tic_saved_##s) \
                this.tic_##s = this.(s)
@@ -681,19 +696,15 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
        X(angles);
 #undef X
 
+       this.flags = this.tic_flags;
+       this.velocity = this.tic_velocity;
+       setorigin(this, this.tic_origin);
+       this.avelocity = this.tic_avelocity;
+       this.angles = this.tic_angles;
+
        if(tr <= 0)
        {
-               this.flags = this.tic_flags;
-               this.velocity = this.tic_velocity;
-               this.origin = this.tic_origin;
-               this.avelocity = this.tic_avelocity;
-               this.angles = this.tic_angles;
                Movetype_Physics_NoMatchServer(this);
-               this.tic_origin = this.origin;
-               this.tic_velocity = this.velocity;
-               this.tic_avelocity = this.avelocity;
-               this.tic_angles = this.angles;
-               this.tic_flags = this.flags;
 
                this.tic_saved_flags = this.flags;
                this.tic_saved_velocity = this.velocity;
@@ -712,23 +723,27 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
        if(!this.move_didgravity)
                this.move_didgravity = ((this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS) && !(this.tic_flags & FL_ONGROUND));
 
-       for (int i = 0; i < n; ++i)
+       for (int j = 0; j < n; ++j)
        {
-               this.flags = this.tic_flags;
-               this.velocity = this.tic_velocity;
-               setorigin(this, this.tic_origin);
-               this.avelocity = this.tic_avelocity;
-               this.angles = this.tic_angles;
                _Movetype_Physics_Frame(this, tr);
-               this.tic_origin = this.origin;
-               this.tic_velocity = this.velocity;
-               this.tic_avelocity = this.avelocity;
-               this.tic_angles = this.angles;
-               this.tic_flags = this.flags;
                if(wasfreed(this))
                        return;
        }
 
+       // update the physics fields
+       this.tic_origin = this.origin;
+       this.tic_velocity = this.velocity;
+       this.tic_avelocity = this.avelocity;
+       this.tic_angles = this.angles;
+       this.tic_flags = this.flags;
+
+       // restore their actual values
+       this.flags = this.tic_saved_flags;
+       this.velocity = this.tic_saved_velocity;
+       setorigin(this, this.tic_saved_origin);
+       //this.avelocity = this.tic_saved_avelocity;
+       this.angles = this.tic_saved_angles;
+
        this.avelocity = this.tic_avelocity;
 
        if(dt > 0 && this.move_movetype != MOVETYPE_NONE && !(this.tic_flags & FL_ONGROUND))
@@ -740,7 +755,7 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
                {
                        this.velocity_z -= (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1)
                            * dt
-                           * (this.gravity ? this.gravity : 1)
+                           * ((this.gravity) ? this.gravity : 1)
                            * PHYS_GRAVITY(this);
                }
 
@@ -752,16 +767,16 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
                }
                else
                {
-                       vector oldorg = this.origin;
-                       this.origin = this.tic_origin;
+                       setorigin(this, this.tic_origin);
                        _Movetype_PushEntityTrace(this, dt * this.velocity);
-                       this.origin = oldorg;
                        if(!trace_startsolid)
                                setorigin(this, trace_endpos);
+                       else
+                               setorigin(this, this.tic_saved_origin);
                }
 
                if(this.move_didgravity > 0 && GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                       this.velocity_z -= 0.5 * dt * (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
+                       this.velocity_z -= 0.5 * dt * ((this.gravity) ? this.gravity : 1) * PHYS_GRAVITY(this);
        }
        else
        {
@@ -770,6 +785,8 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
                setorigin(this, this.tic_origin);
        }
 
+       this.flags = this.tic_flags;
+
        this.tic_saved_flags = this.flags;
        this.tic_saved_velocity = this.velocity;
        this.tic_saved_origin = this.origin;
index 51da5e730c1169de3b2552b93953d0b68b0720b2..0c8bc694850a40fe3aac357936ab7067231606f7 100644 (file)
@@ -19,8 +19,13 @@ const int WATERLEVEL_SUBMERGED = 3;
 #define GAMEPLAYFIX_STEPMULTIPLETIMES(s)    STAT(GAMEPLAYFIX_STEPMULTIPLETIMES)
 #define GAMEPLAYFIX_UNSTICKPLAYERS(s)       STAT(GAMEPLAYFIX_UNSTICKPLAYERS)
 #define GAMEPLAYFIX_WATERTRANSITION(s)                 STAT(GAMEPLAYFIX_WATERTRANSITION)
+#define GAMEPLAYFIX_SLIDEMOVEPROJECTILES(s) STAT(GAMEPLAYFIX_SLIDEMOVEPROJECTILES)
+#define GAMEPLAYFIX_GRENADEBOUNCESLOPES(s)     STAT(GAMEPLAYFIX_GRENADEBOUNCESLOPES)
+#define GAMEPLAYFIX_NOAIRBORNCORPSE(s)                 STAT(GAMEPLAYFIX_NOAIRBORNCORPSE)
+#define NOAIRBORNCORPSE_ALLOWSUSPENDED(s)      STAT(NOAIRBORNCORPSE_ALLOWSUSPENDED)
 #define UPWARD_VELOCITY_CLEARS_ONGROUND(s)  STAT(GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND)
 
+
 #define PHYS_STEPHEIGHT(s)                  STAT(MOVEVARS_STEPHEIGHT)
 #define PHYS_NOSTEP(s)                      STAT(NOSTEP)
 #define PHYS_JUMPSTEP(s)                    STAT(MOVEVARS_JUMPSTEP)
index fc3de0859bba0a22e91c87afec51e63384d8fd59..772eb1b070c59a2be0df4aa72df5bc904e115838 100644 (file)
@@ -2,19 +2,26 @@
 
 void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
 {
-       if (IS_ONGROUND(this))
+       if(IS_ONGROUND(this))
        {
-               if (this.velocity.z >= 1 / 32 && UPWARD_VELOCITY_CLEARS_ONGROUND(this))
+               if(this.velocity.z >= (1 / 32) && UPWARD_VELOCITY_CLEARS_ONGROUND(this))
                {
+                       // don't stick to ground if onground and moving upward
                        UNSET_ONGROUND(this);
                }
-               else if (!this.groundentity)
+               else if(!this.groundentity || !GAMEPLAYFIX_NOAIRBORNCORPSE(this))
                {
                        return;
                }
-               else if (this.move_suspendedinair && wasfreed(this.groundentity))
+               else if(this.move_suspendedinair && wasfreed(this.groundentity))
                {
                        this.groundentity = NULL;
+                       if(NOAIRBORNCORPSE_ALLOWSUSPENDED(this))
+                               return;
+               }
+               else if(boxesoverlap(this.absmin, this.absmax, this.groundentity.absmin, this.groundentity.absmax))
+               {
+                       // don't slide if still touching the groundentity
                        return;
                }
        }
@@ -23,35 +30,37 @@ void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
 
        _Movetype_CheckVelocity(this);
 
-       /*if (this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS)
+       if(this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS)
        {
-               this.move_didgravity = 1;
+               this.move_didgravity = true;
                this.velocity_z -= (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1)
                    * dt
-                   * (this.gravity ? this.gravity : 1)
+                   * ((this.gravity) ? this.gravity : 1)
                    * PHYS_GRAVITY(this);
-       }*/
+       }
 
-       if (this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS)
+       /*if (this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS)
        {
                this.move_didgravity = true;
                this.velocity_z -= (((this.gravity) ? this.gravity : 1) * PHYS_GRAVITY(this) * dt);
-       }
+       }*/
 
        this.angles = this.angles + this.avelocity * dt;
 
        float movetime = dt;
-       for (int bump = 0; bump < MAX_CLIP_PLANES && movetime > 0; ++bump)
+       for (int bump = 0; bump < MAX_CLIP_PLANES && movetime > 0; bump++)
        {
                vector move = this.velocity * movetime;
-               _Movetype_PushEntity(this, move, true, false);
+               if(!_Movetype_PushEntity(this, move, true, true))
+                       return;
                if (wasfreed(this))
                        return;
 
                if (trace_startsolid)
                {
                        _Movetype_UnstickEntity(this);
-                       _Movetype_PushEntity(this, move, false, false);
+                       if(!_Movetype_PushEntity(this, move, true, true))
+                               return;
                        if (wasfreed(this))
                                return;
                }
@@ -63,28 +72,36 @@ void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
 
                if (this.move_movetype == MOVETYPE_BOUNCEMISSILE)
                {
-                       this.velocity = _Movetype_ClipVelocity(this.velocity, trace_plane_normal, 2.0);
+                       float bouncefac = (!this.bouncefactor) ? 1.0 : this.bouncefactor;
+                       this.velocity = _Movetype_ClipVelocity(this.velocity, trace_plane_normal, 1 + bouncefac);
                        UNSET_ONGROUND(this);
+                       if(!GAMEPLAYFIX_SLIDEMOVEPROJECTILES(this))
+                               movetime = 0;
                }
                else if (this.move_movetype == MOVETYPE_BOUNCE)
                {
-                       float bouncefac = this.bouncefactor;     if (!bouncefac)  bouncefac = 0.5;
-                       float bstop = this.bouncestop; if (!bstop) bstop = 60 / 800;
-                       bstop *= (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
+                       float bouncefac = (!this.bouncefactor) ? 0.5 : this.bouncefactor;
+                       float bstop = (!this.bouncestop) ? (60 / 800) : this.bouncestop;
+                       float grav = ((this.gravity) ? this.gravity : 1);
 
                        this.velocity = _Movetype_ClipVelocity(this.velocity, trace_plane_normal, 1 + bouncefac);
 
                        float d = trace_plane_normal * this.velocity;
-                       if (trace_plane_normal.z > 0.7 && d < bstop && d > -bstop)
+                       if(!GAMEPLAYFIX_GRENADEBOUNCESLOPES(this))
+                               d = this.velocity.z;
+                       if (trace_plane_normal.z > 0.7 && d < PHYS_GRAVITY(this) * bstop * grav)
                        {
                                SET_ONGROUND(this);
                                this.groundentity = trace_ent;
                                this.velocity = '0 0 0';
                                this.avelocity = '0 0 0';
+                               movetime = 0;
                        }
                        else
                        {
                                UNSET_ONGROUND(this);
+                               if(!GAMEPLAYFIX_SLIDEMOVEPROJECTILES(this))
+                                       movetime = 0;
                        }
                }
                else
@@ -98,24 +115,27 @@ void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
                                        this.move_suspendedinair = true;
                                this.velocity = '0 0 0';
                                this.avelocity = '0 0 0';
+                               movetime = 0;
                        }
                        else
                        {
                                UNSET_ONGROUND(this);
+                               if(!GAMEPLAYFIX_SLIDEMOVEPROJECTILES(this))
+                                       movetime = 0;
                        }
                }
 
                // DP revision 8905 (just, WHY...)
-               if (this.move_movetype == MOVETYPE_BOUNCEMISSILE)
-                       break;
+               //if (this.move_movetype == MOVETYPE_BOUNCEMISSILE)
+                       //break;
 
                // DP revision 8918 (WHY...)
-               if (IS_ONGROUND(this))
-                       break;
+               //if (IS_ONGROUND(this))
+                       //break;
        }
 
-       //if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE && this.move_didgravity > 0 && !IS_ONGROUND(this))
-       //      this.velocity_z -= 0.5 * dt * (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
+       if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE && this.move_didgravity > 0 && !IS_ONGROUND(this))
+               this.velocity_z -= 0.5 * dt * ((this.gravity) ? this.gravity : 1) * PHYS_GRAVITY(this);
 
        _Movetype_CheckWaterTransition(this);
 }
index 488d44220b19e46ca047d18e11511e3d2d223e0b..1a9b35ec01f393e224d87640ea8d1598ae84ce4a 100644 (file)
@@ -193,6 +193,10 @@ int autocvar_sv_gameplayfix_stepdown = 2;
 int autocvar_sv_gameplayfix_stepmultipletimes = 1;
 int autocvar_sv_gameplayfix_unstickplayers = 1;
 int autocvar_sv_gameplayfix_fixedcheckwatertransition = 1;
+int autocvar_sv_gameplayfix_slidemoveprojectiles = 1;
+int autocvar_sv_gameplayfix_grenadebouncedownslopes = 1;
+int autocvar_sv_gameplayfix_noairborncorpse = 1;
+int autocvar_sv_gameplayfix_noairborncorpse_allowsuspendeditems = 1;
 #endif
 REGISTER_STAT(GAMEPLAYFIX_DOWNTRACEONGROUND, int, autocvar_sv_gameplayfix_downtracesupportsongroundflag)
 REGISTER_STAT(GAMEPLAYFIX_EASIERWATERJUMP, int, autocvar_sv_gameplayfix_easierwaterjump)
@@ -201,6 +205,10 @@ REGISTER_STAT(GAMEPLAYFIX_STEPMULTIPLETIMES, int, autocvar_sv_gameplayfix_stepmu
 REGISTER_STAT(GAMEPLAYFIX_UNSTICKPLAYERS, int, autocvar_sv_gameplayfix_unstickplayers)
 REGISTER_STAT(GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND, int, autocvar_sv_gameplayfix_upwardvelocityclearsongroundflag)
 REGISTER_STAT(GAMEPLAYFIX_WATERTRANSITION, int, autocvar_sv_gameplayfix_fixedcheckwatertransition)
+REGISTER_STAT(GAMEPLAYFIX_SLIDEMOVEPROJECTILES, int, autocvar_sv_gameplayfix_slidemoveprojectiles)
+REGISTER_STAT(GAMEPLAYFIX_GRENADEBOUNCESLOPES, int, autocvar_sv_gameplayfix_grenadebouncedownslopes)
+REGISTER_STAT(GAMEPLAYFIX_NOAIRBORNCORPSE, int, autocvar_sv_gameplayfix_noairborncorpse)
+REGISTER_STAT(NOAIRBORNCORPSE_ALLOWSUSPENDED, int, autocvar_sv_gameplayfix_noairborncorpse_allowsuspendeditems)
 
 REGISTER_STAT(MOVEVARS_JUMPSTEP, int, cvar("sv_jumpstep"))
 REGISTER_STAT(NOSTEP, int, cvar("sv_nostep"))