]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Fix prediction of jumping onto ledges
authorMario <mario@smbclan.net>
Mon, 30 Nov 2015 06:07:04 +0000 (16:07 +1000)
committerMario <mario@smbclan.net>
Mon, 30 Nov 2015 06:07:04 +0000 (16:07 +1000)
qcsrc/common/physics.qc
qcsrc/common/physics.qh
qcsrc/common/triggers/trigger/impulse.qc
qcsrc/lib/csqcmodel/cl_player.qc

index 7e85ef3b81d13782c24e41c8387bf790b2dd1274..d21579fa653f422d90d239e94a2325e6ea33a127 100644 (file)
@@ -80,8 +80,6 @@ float GeomLerp(float a, float lerp, float b)
                : a * pow(fabs(b / a), lerp);
 }
 
-noref float pmove_waterjumptime;
-
 #define unstick_offsets(X) \
 /* 1 no nudge (just return the original if this test passes) */ \
        X(' 0.000  0.000  0.000') \
@@ -122,6 +120,7 @@ void PM_ClientMovement_Unstick(entity this)
 
 void PM_ClientMovement_UpdateStatus(entity this, bool ground)
 {
+#ifdef CSQC
        // make sure player is not stuck
        PM_ClientMovement_Unstick(this);
 
@@ -145,7 +144,7 @@ void PM_ClientMovement_UpdateStatus(entity this, bool ground)
        vector origin1 = this.origin + '0 0 1';
        vector origin2 = this.origin - '0 0 1';
 
-       if (ground)
+       if (ground && autocvar_cl_movement != 3)
        {
                tracebox(origin1, this.mins, this.maxs, origin2, MOVE_NORMAL, this);
                if (trace_fraction < 1.0 && trace_plane_normal.z > 0.7)
@@ -183,8 +182,9 @@ void PM_ClientMovement_UpdateStatus(entity this, bool ground)
                }
        }
 
-       if (IS_ONGROUND(this) || this.velocity.z <= 0 || pmove_waterjumptime <= 0)
-               pmove_waterjumptime = 0;
+       if (IS_ONGROUND(this) || this.velocity.z <= 0 || PHYS_TELEPORT_TIME(this) <= 0)
+               PHYS_TELEPORT_TIME(this) = 0;
+#endif
 }
 
 void PM_ClientMovement_Move(entity this)
@@ -274,7 +274,7 @@ void PM_ClientMovement_Move(entity this)
                f = (this.velocity * trace1_plane_normal);
                this.velocity = this.velocity + -f * trace1_plane_normal;
        }
-       if(pmove_waterjumptime > 0)
+       if(PHYS_TELEPORT_TIME(this) > 0)
                this.velocity = primalvelocity;
 #endif
 }
@@ -542,11 +542,7 @@ void CheckWaterJump(entity this)
                        this.velocity_z = 225;
                        this.flags |= FL_WATERJUMP;
                        SET_JUMP_HELD(this);
-#ifdef SVQC
-                       this.teleport_time = time + 2;  // safety net
-#elif defined(CSQC)
-                       pmove_waterjumptime = time + 2;
-#endif
+                       PHYS_TELEPORT_TIME(this) = time + 2;    // safety net
                }
        }
 }
@@ -782,9 +778,7 @@ void PM_fly(entity this, float maxspd_mod)
        // acceleration
        vector wishdir = normalize(wishvel);
        float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(this) * maxspd_mod);
-#ifdef SVQC
-       if (time >= this.teleport_time)
-#endif
+       if(time >= PHYS_TELEPORT_TIME(this))
                PM_Accelerate(this, wishdir, wishspeed, wishspeed, PHYS_ACCELERATE(this) * maxspd_mod, 1, 0, 0, 0);
        PM_ClientMovement_Move(this);
 }
@@ -813,7 +807,7 @@ void PM_swim(entity this, float maxspd_mod)
                        {
                                this.velocity = forward * 50;
                                this.velocity_z = 310;
-                               pmove_waterjumptime = 2;
+                               PHYS_TELEPORT_TIME(this) = 2;
                                UNSET_ONGROUND(this);
                                SET_JUMP_HELD(this);
                        }
@@ -917,9 +911,7 @@ void PM_ladder(entity this, float maxspd_mod)
        // acceleration
        vector wishdir = normalize(wishvel);
        float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(this) * maxspd_mod);
-#ifdef SVQC
-       if (time >= this.teleport_time)
-#endif
+       if(time >= PHYS_TELEPORT_TIME(this))
                // water acceleration
                PM_Accelerate(this, wishdir, wishspeed, wishspeed, PHYS_ACCELERATE(this)*maxspd_mod, 1, 0, 0, 0);
        PM_ClientMovement_Move(this);
@@ -1146,11 +1138,7 @@ void PM_air(entity this, float buttons_prev, float maxspd_mod)
        vector wishdir = normalize(wishvel);
        float wishspeed = vlen(wishvel);
 
-#ifdef SVQC
-       if (time >= this.teleport_time)
-#else
-       if (pmove_waterjumptime <= 0)
-#endif
+       if(PHYS_TELEPORT_TIME(this) < time)
        {
                float maxairspd = PHYS_MAXAIRSPEED(this) * min(maxspd_mod, 1);
 
@@ -1245,7 +1233,7 @@ void PM_Main(entity this)
        this.team = myteam + 1; // is this correct?
        if (!(PHYS_INPUT_BUTTON_JUMP(this))) // !jump
                UNSET_JUMP_HELD(this); // canjump = true
-       pmove_waterjumptime -= PHYS_INPUT_TIMELENGTH;
+       PHYS_TELEPORT_TIME(this) -= PHYS_INPUT_TIMELENGTH;
 
        PM_ClientMovement_UpdateStatus(this, true);
 #endif
@@ -1418,10 +1406,10 @@ void PM_Main(entity this)
        {
                this.velocity_x = this.movedir.x;
                this.velocity_y = this.movedir.y;
-               if (time > this.teleport_time || this.waterlevel == WATERLEVEL_NONE)
+               if (time > PHYS_TELEPORT_TIME(this) || this.waterlevel == WATERLEVEL_NONE)
                {
                        this.flags &= ~FL_WATERJUMP;
-                       this.teleport_time = 0;
+                       PHYS_TELEPORT_TIME(this) = 0;
                }
        }
 
@@ -1478,10 +1466,4 @@ void CSQC_ClientMovement_PlayerMove_Frame(entity this)
        SELFPARAM();
 #endif
        PM_Main(this);
-#ifdef CSQC
-       this.pmove_flags =
-                       ((this.flags & FL_DUCKED) ? PMF_DUCKED : 0) |
-                       (!(this.flags & FL_JUMPRELEASED) ? PMF_JUMP_HELD : 0) |
-                       ((this.flags & FL_ONGROUND) ? PMF_ONGROUND : 0);
-#endif
 }
index b266c3c0f5373b30f60d7f93e311c84003c582fe..9c1bed68f4cfee9204c14068731e8ed6d1294206 100644 (file)
@@ -93,6 +93,8 @@ bool IsFlying(entity a);
 
 #ifdef CSQC
 
+       noref float pmove_waterjumptime;
+
        const int FL_WATERJUMP = 2048;  // player jumping out of water
        const int FL_JUMPRELEASED = 4096;       // for jump debouncing
 
@@ -111,6 +113,8 @@ bool IsFlying(entity a);
        //float player_multijump;
        //float player_jumpheight;
 
+       #define PHYS_TELEPORT_TIME(s)                           pmove_waterjumptime
+
        #define TICRATE ticrate
 
        #define PHYS_INPUT_ANGLES(s)                            input_angles
@@ -175,6 +179,8 @@ bool IsFlying(entity a);
        /** Not real stats */
        .string stat_jumpspeedcap_min, stat_jumpspeedcap_max;
 
+       #define PHYS_TELEPORT_TIME(s)                           s.teleport_time
+
        #define TICRATE sys_frametime
 
        #define PHYS_INPUT_ANGLES(s)                            s.v_angle
index 77c491c356b58647ad0c34c2d467b2e138d92c4b..e8d85a013f3b4fee7c97d3ebbbc0f2935539bc8b 100644 (file)
@@ -21,7 +21,11 @@ void trigger_impulse_touch1()
                return;
        }
 
+#ifdef SVQC
        str = min(self.radius, vlen(self.origin - other.origin));
+#elif defined(CSQC)
+       str = min(self.radius, vlen(self.move_origin - other.move_origin));
+#endif
 
        if(self.falloff == 1)
                str = (str / self.radius) * self.strength;
@@ -37,18 +41,35 @@ void trigger_impulse_touch1()
 
        if(self.spawnflags & 64)
        {
+#ifdef SVQC
                float addspeed = str - other.velocity * normalize(targ.origin - self.origin);
                if (addspeed > 0)
                {
                        float accelspeed = min(8 * pushdeltatime * str, addspeed);
                        other.velocity += accelspeed * normalize(targ.origin - self.origin);
                }
+#elif defined(CSQC)
+               float addspeed = str - other.move_velocity * normalize(targ.move_origin - self.move_origin);
+               if (addspeed > 0)
+               {
+                       float accelspeed = min(8 * pushdeltatime * str, addspeed);
+                       other.move_velocity += accelspeed * normalize(targ.move_origin - self.move_origin);
+               }
+#endif
        }
        else
+#ifdef SVQC
                other.velocity = other.velocity + normalize(targ.origin - self.origin) * str * pushdeltatime;
-       other.flags &= ~FL_ONGROUND;
+#elif defined(CSQC)
+               other.move_velocity = other.move_velocity + normalize(targ.move_origin - self.move_origin) * str * pushdeltatime;
+#endif
+
 #ifdef SVQC
+       other.flags &= ~FL_ONGROUND;
+
        UpdateCSQCProjectile(other);
+#elif defined(CSQC)
+       other.move_flags &= ~FL_ONGROUND;
 #endif
 }
 
@@ -71,9 +92,12 @@ void trigger_impulse_touch2()
        if(!pushdeltatime) return;
 
        // div0: ticrate independent, 1 = identity (not 20)
-       other.velocity = other.velocity * pow(self.strength, pushdeltatime);
 #ifdef SVQC
+       other.velocity = other.velocity * pow(self.strength, pushdeltatime);
+
        UpdateCSQCProjectile(other);
+#elif defined(CSQC)
+       other.move_velocity = other.move_velocity * pow(self.strength, pushdeltatime);
 #endif
 }
 
@@ -98,7 +122,11 @@ void trigger_impulse_touch3()
 
        setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius);
 
+#ifdef SVQC
        str = min(self.radius, vlen(self.origin - other.origin));
+#elif defined(CSQC)
+       str = min(self.radius, vlen(self.move_origin - other.move_origin));
+#endif
 
        if(self.falloff == 1)
                str = (1 - str / self.radius) * self.strength; // 1 in the inside
@@ -107,9 +135,12 @@ void trigger_impulse_touch3()
        else
                str = self.strength;
 
-       other.velocity = other.velocity + normalize(other.origin - self.origin) * str * pushdeltatime;
 #ifdef SVQC
+       other.velocity = other.velocity + normalize(other.origin - self.origin) * str * pushdeltatime;
+
        UpdateCSQCProjectile(other);
+#elif defined(CSQC)
+       other.move_velocity = other.move_velocity + normalize(other.move_origin - self.move_origin) * str * pushdeltatime;
 #endif
 }
 
@@ -133,10 +164,11 @@ Use a brush textured with common/origin in the trigger entity to determine the o
 in directional and sperical mode. For damper/accelerator mode this is not nessesary (and has no effect).
 */
 #ifdef SVQC
-bool trigger_impulse_send(entity to, int sf)
-{SELFPARAM();
+bool trigger_impulse_send(entity this, entity to, int sf)
+{
        WriteHeader(MSG_ENTITY, ENT_CLIENT_TRIGGER_IMPULSE);
 
+       WriteInt24_t(MSG_ENTITY, self.spawnflags);
        WriteCoord(MSG_ENTITY, self.radius);
        WriteCoord(MSG_ENTITY, self.strength);
        WriteByte(MSG_ENTITY, self.falloff);
@@ -149,7 +181,7 @@ bool trigger_impulse_send(entity to, int sf)
 
 void trigger_impulse_link()
 {
-       //Net_LinkEntity(self, 0, false, trigger_impulse_send);
+       Net_LinkEntity(self, 0, false, trigger_impulse_send);
 }
 
 spawnfunc(trigger_impulse)
@@ -184,6 +216,7 @@ spawnfunc(trigger_impulse)
 #elif defined(CSQC)
 NET_HANDLE(ENT_CLIENT_TRIGGER_IMPULSE, bool isnew)
 {
+       self.spawnflags = ReadInt24_t();
        self.radius = ReadCoord();
        self.strength = ReadCoord();
        self.falloff = ReadByte();
@@ -195,12 +228,12 @@ NET_HANDLE(ENT_CLIENT_TRIGGER_IMPULSE, bool isnew)
        self.classname = "trigger_impulse";
        self.solid = SOLID_TRIGGER;
        self.entremove = trigger_remove_generic;
-       self.draw = trigger_draw_generic;
+       //self.draw = trigger_draw_generic;
        self.drawmask = MASK_NORMAL;
        self.move_time = time;
 
-       if(self.radius) { self.trigger_touch = trigger_impulse_touch3; }
-       else if(self.target) { self.trigger_touch = trigger_impulse_touch1; }
-       else { self.trigger_touch = trigger_impulse_touch2; }
+       if(self.radius) { self.move_touch = trigger_impulse_touch3; }
+       else if(self.target) { self.move_touch = trigger_impulse_touch1; }
+       else { self.move_touch = trigger_impulse_touch2; }
 }
 #endif
index fc6979ed5d831ed4a3854bbc6c068ad00344d64f..ff8d4ff620a811090b92f57bf62adc5f00ca6db6 100644 (file)
@@ -141,6 +141,9 @@ void Movetype_Physics_Spam(entity this)  // optimized
        this.velocity = this.move_velocity;
        this.angles = this.move_angles;
        this.flags = BITSET(this.flags, FL_ONGROUND, boolean(this.move_flags & FL_ONGROUND));
+       this.flags = BITSET(this.flags, FL_WATERJUMP, boolean(this.move_flags & FL_WATERJUMP));
+       this.waterlevel = this.move_waterlevel;
+       this.watertype = this.move_watertype;
        setorigin(this, this.move_origin);
 }
 
@@ -158,8 +161,16 @@ void CSQCPlayer_Physics(entity this)
                        this.move_velocity = this.velocity;
                        this.move_avelocity = this.avelocity;
                        this.move_flags = BITSET(this.move_flags, FL_ONGROUND, boolean(this.flags & FL_ONGROUND));
+                       this.move_flags = BITSET(this.move_flags, FL_WATERJUMP, boolean(this.flags & FL_WATERJUMP));
+                       this.move_waterlevel = this.waterlevel;
+                       this.move_watertype = this.watertype;
                        Movetype_Physics_Spam(this);
                }
+
+               this.pmove_flags =
+                               ((this.flags & FL_DUCKED) ? PMF_DUCKED : 0) |
+                               (!(this.flags & FL_JUMPRELEASED) ? PMF_JUMP_HELD : 0) |
+                               ((this.flags & FL_ONGROUND) ? PMF_ONGROUND : 0);
        }
 }