]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/cl_physics.qc
Merge branch 'master' into Mario/physics
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / cl_physics.qc
index 14747fa99aabe535d9074e7e03ae6391adcebf80..797226717cfe3129677584c626a83cabc5bd6c44 100644 (file)
 .float wasFlying;
 .float spectatorspeed;
 
+// client side physics
+float Physics_Valid(string thecvar)
+{
+       if(!autocvar_g_physics_clientselect) { return FALSE; }
+
+       string l = strcat(" ", autocvar_g_physics_clientselect_options, " ");
+
+       if(strstrofs(l, strcat(" ", thecvar, " "), 0) >= 0)
+               return TRUE;
+
+       return FALSE;
+}
+
+float Physics_ClientOption(entity pl, string option)
+{
+       if(Physics_Valid(pl.cvar_cl_physics) && (cvar_type(sprintf("g_physics_%s_%s", pl.cvar_cl_physics, option)) & 1))
+               return cvar(sprintf("g_physics_%s_%s", pl.cvar_cl_physics, option));
+       else
+               return cvar(strcat("sv_", option));
+}
+
 /*
 =============
 PlayerJump
@@ -26,7 +47,7 @@ void PlayerJump (void)
                return; // no jumping while blocked
 
        float doublejump = FALSE;
-       float mjumpheight = autocvar_sv_jumpvelocity;
+       float mjumpheight = self.stat_sv_jumpvelocity;
 
        player_multijump = doublejump;
        player_jumpheight = mjumpheight;
@@ -434,7 +455,7 @@ void CPM_PM_Aircontrol(vector wishdir, float wishspeed)
                return;
 #endif
 
-       k *= bound(0, wishspeed / autocvar_sv_maxairspeed, 1);
+       k *= bound(0, wishspeed / self.stat_sv_maxairspeed, 1);
 
        zspeed = self.velocity_z;
        self.velocity_z = 0;
@@ -444,9 +465,9 @@ void CPM_PM_Aircontrol(vector wishdir, float wishspeed)
 
        if(dot > 0) // we can't change direction while slowing down
        {
-               k *= pow(dot, autocvar_sv_aircontrol_power)*frametime;
-               xyspeed = max(0, xyspeed - autocvar_sv_aircontrol_penalty * sqrt(max(0, 1 - dot*dot)) * k/32);
-               k *= autocvar_sv_aircontrol;
+               k *= pow(dot, self.stat_sv_aircontrol_power)*frametime;
+               xyspeed = max(0, xyspeed - self.stat_sv_aircontrol_penalty * sqrt(max(0, 1 - dot*dot)) * k/32);
+               k *= self.stat_sv_aircontrol;
                self.velocity = normalize(self.velocity * xyspeed + wishdir * k);
        }
 
@@ -556,26 +577,26 @@ void PM_AirAccelerate(vector wishdir, float wishspeed)
 
        if(wishspeed > curspeed * 1.01)
        {
-               wishspeed = min(wishspeed, curspeed + autocvar_sv_warsowbunny_airforwardaccel * self.stat_sv_maxspeed * frametime);
+               wishspeed = min(wishspeed, curspeed + self.stat_sv_warsowbunny_airforwardaccel * self.stat_sv_maxspeed * frametime);
        }
        else
        {
-               f = max(0, (autocvar_sv_warsowbunny_topspeed - curspeed) / (autocvar_sv_warsowbunny_topspeed - self.stat_sv_maxspeed));
-               wishspeed = max(curspeed, self.stat_sv_maxspeed) + autocvar_sv_warsowbunny_accel * f * self.stat_sv_maxspeed * frametime;
+               f = max(0, (self.stat_sv_warsowbunny_topspeed - curspeed) / (self.stat_sv_warsowbunny_topspeed - self.stat_sv_maxspeed));
+               wishspeed = max(curspeed, self.stat_sv_maxspeed) + self.stat_sv_warsowbunny_accel * f * self.stat_sv_maxspeed * frametime;
        }
        wishvel = wishdir * wishspeed;
        acceldir = wishvel - curvel;
        addspeed = vlen(acceldir);
        acceldir = normalize(acceldir);
 
-       accelspeed = min(addspeed, autocvar_sv_warsowbunny_turnaccel * self.stat_sv_maxspeed * frametime);
+       accelspeed = min(addspeed, self.stat_sv_warsowbunny_turnaccel * self.stat_sv_maxspeed * frametime);
 
-       if(autocvar_sv_warsowbunny_backtosideratio < 1)
+       if(self.stat_sv_warsowbunny_backtosideratio < 1)
        {
                curdir = normalize(curvel);
                dot = acceldir * curdir;
                if(dot < 0)
-                       acceldir = acceldir - (1 - autocvar_sv_warsowbunny_backtosideratio) * dot * curdir;
+                       acceldir = acceldir - (1 - self.stat_sv_warsowbunny_backtosideratio) * dot * curdir;
        }
 
        self.velocity += accelspeed * acceldir;
@@ -649,13 +670,34 @@ void SV_PlayerPhysics()
 
        // fix physics stats for g_movement_highspeed
        // TODO maybe rather use maxairspeed? needs testing
-       self.stat_sv_airaccel_qw = AdjustAirAccelQW(autocvar_sv_airaccel_qw, maxspd_mod);
-       if(autocvar_sv_airstrafeaccel_qw)
-               self.stat_sv_airstrafeaccel_qw = AdjustAirAccelQW(autocvar_sv_airstrafeaccel_qw, maxspd_mod);
+       self.stat_sv_airaccel_qw = AdjustAirAccelQW(Physics_ClientOption(self, "airaccel_qw"), maxspd_mod);
+       if(Physics_ClientOption(self, "airstrafeaccel_qw"))
+               self.stat_sv_airstrafeaccel_qw = AdjustAirAccelQW(Physics_ClientOption(self, "airstrafeaccel_qw"), maxspd_mod);
        else
                self.stat_sv_airstrafeaccel_qw = 0;
-       self.stat_sv_airspeedlimit_nonqw = autocvar_sv_airspeedlimit_nonqw * maxspd_mod;
-       self.stat_sv_maxspeed = autocvar_sv_maxspeed * maxspd_mod; // also slow walking
+       self.stat_sv_airspeedlimit_nonqw = Physics_ClientOption(self, "airspeedlimit_nonqw") * maxspd_mod;
+       self.stat_sv_maxspeed = Physics_ClientOption(self, "maxspeed") * maxspd_mod; // also slow walking
+       
+       // fix some new settings
+       self.stat_sv_airaccel_qw_stretchfactor = Physics_ClientOption(self, "airaccel_qw_stretchfactor");
+       self.stat_sv_maxairstrafespeed = Physics_ClientOption(self, "maxairstrafespeed");
+       self.stat_sv_maxairspeed = Physics_ClientOption(self, "maxairspeed");
+       self.stat_sv_airstrafeaccelerate = Physics_ClientOption(self, "airstrafeaccelerate");
+       self.stat_sv_warsowbunny_turnaccel = Physics_ClientOption(self, "warsowbunny_turnaccel");
+       self.stat_sv_airaccel_sideways_friction = Physics_ClientOption(self, "airaccel_sideways_friction");
+       self.stat_sv_aircontrol = Physics_ClientOption(self, "aircontrol");
+       self.stat_sv_aircontrol_power = Physics_ClientOption(self, "aircontrol_power");
+       self.stat_sv_aircontrol_penalty = Physics_ClientOption(self, "aircontrol_penalty");
+       self.stat_sv_warsowbunny_airforwardaccel = Physics_ClientOption(self, "warsowbunny_airforwardaccel");
+       self.stat_sv_warsowbunny_topspeed = Physics_ClientOption(self, "warsowbunny_topspeed");
+       self.stat_sv_warsowbunny_accel = Physics_ClientOption(self, "warsowbunny_accel");
+       self.stat_sv_warsowbunny_backtosideratio = Physics_ClientOption(self, "warsowbunny_backtosideratio");
+       self.stat_sv_friction = Physics_ClientOption(self, "friction");
+       self.stat_sv_accelerate = Physics_ClientOption(self, "accelerate");
+       self.stat_sv_stopspeed = Physics_ClientOption(self, "stopspeed");
+       self.stat_sv_airaccelerate = Physics_ClientOption(self, "airaccelerate");
+       self.stat_sv_airstopaccelerate = Physics_ClientOption(self, "airstopaccelerate");
+       self.stat_sv_jumpvelocity = Physics_ClientOption(self, "jumpvelocity");
 
     if(self.PlayerPhysplug)
         if(self.PlayerPhysplug())
@@ -859,7 +901,7 @@ void SV_PlayerPhysics()
                maxspd_mod = self.spectatorspeed;
        }
 
-       spd = max(self.stat_sv_maxspeed, autocvar_sv_maxairspeed) * maxspd_mod * swampspd_mod;
+       spd = max(self.stat_sv_maxspeed, self.stat_sv_maxairspeed) * maxspd_mod * swampspd_mod;
        if(self.speed != spd)
        {
                self.speed = spd;
@@ -932,7 +974,7 @@ void SV_PlayerPhysics()
                // noclipping or flying
                self.flags &= ~FL_ONGROUND;
 
-               self.velocity = self.velocity * (1 - frametime * autocvar_sv_friction);
+               self.velocity = self.velocity * (1 - frametime * self.stat_sv_friction);
                makevectors(self.v_angle);
                //wishvel = v_forward * self.movement_x + v_right * self.movement_y + v_up * self.movement_z;
                wishvel = v_forward * self.movement_x + v_right * self.movement_y + '0 0 1' * self.movement_z;
@@ -942,7 +984,7 @@ void SV_PlayerPhysics()
                if (wishspeed > self.stat_sv_maxspeed*maxspd_mod)
                        wishspeed = self.stat_sv_maxspeed*maxspd_mod;
                if (time >= self.teleport_time)
-                       PM_Accelerate(wishdir, wishspeed, wishspeed, autocvar_sv_accelerate*maxspd_mod, 1, 0, 0, 0);
+                       PM_Accelerate(wishdir, wishspeed, wishspeed, self.stat_sv_accelerate*maxspd_mod, 1, 0, 0, 0);
        }
        else if (self.waterlevel >= WATERLEVEL_SWIMMING)
        {
@@ -962,10 +1004,10 @@ void SV_PlayerPhysics()
                wishspeed = wishspeed * 0.7;
 
                // water friction
-               self.velocity = self.velocity * (1 - frametime * autocvar_sv_friction);
+               self.velocity = self.velocity * (1 - frametime * self.stat_sv_friction);
 
                // water acceleration
-               PM_Accelerate(wishdir, wishspeed, wishspeed, autocvar_sv_accelerate*maxspd_mod, 1, 0, 0, 0);
+               PM_Accelerate(wishdir, wishspeed, wishspeed, self.stat_sv_accelerate*maxspd_mod, 1, 0, 0, 0);
        }
        else if (time < self.ladder_time)
        {
@@ -982,7 +1024,7 @@ void SV_PlayerPhysics()
                        self.velocity_z += g;
                }
 
-               self.velocity = self.velocity * (1 - frametime * autocvar_sv_friction);
+               self.velocity = self.velocity * (1 - frametime * self.stat_sv_friction);
                makevectors(self.v_angle);
                //wishvel = v_forward * self.movement_x + v_right * self.movement_y + v_up * self.movement_z;
                wishvel = v_forward * self.movement_x + v_right * self.movement_y + '0 0 1' * self.movement_z;
@@ -1015,7 +1057,7 @@ void SV_PlayerPhysics()
                if (time >= self.teleport_time)
                {
                        // water acceleration
-                       PM_Accelerate(wishdir, wishspeed, wishspeed, autocvar_sv_accelerate*maxspd_mod, 1, 0, 0, 0);
+                       PM_Accelerate(wishdir, wishspeed, wishspeed, self.stat_sv_accelerate*maxspd_mod, 1, 0, 0, 0);
                }
        }
        else if ((self.items & IT_JETPACK) && self.BUTTON_HOOK && (!autocvar_g_jetpack_fuel || self.ammo_fuel >= 0.01 || self.items & IT_UNLIMITED_WEAPON_AMMO) && !self.frozen)
@@ -1024,7 +1066,7 @@ void SV_PlayerPhysics()
                makevectors(self.v_angle);
                wishvel = v_forward * self.movement_x + v_right * self.movement_y;
                // add remaining speed as Z component
-               maxairspd = autocvar_sv_maxairspeed*max(1, maxspd_mod);
+               maxairspd = self.stat_sv_maxairspeed*max(1, maxspd_mod);
                // fix speedhacks :P
                wishvel = normalize(wishvel) * min(vlen(wishvel) / maxairspd, 1);
                // add the unused velocity as up component
@@ -1157,10 +1199,10 @@ void SV_PlayerPhysics()
                f = vlen(v);
                if(f > 0)
                {
-                       if (f < autocvar_sv_stopspeed)
-                               f = 1 - frametime * (autocvar_sv_stopspeed / f) * autocvar_sv_friction;
+                       if (f < self.stat_sv_stopspeed)
+                               f = 1 - frametime * (self.stat_sv_stopspeed / f) * self.stat_sv_friction;
                        else
-                               f = 1 - frametime * autocvar_sv_friction;
+                               f = 1 - frametime * self.stat_sv_friction;
                        if (f > 0)
                                self.velocity = self.velocity * f;
                        else
@@ -1197,7 +1239,7 @@ void SV_PlayerPhysics()
                if (self.crouch)
                        wishspeed = wishspeed * 0.5;
                if (time >= self.teleport_time)
-                       PM_Accelerate(wishdir, wishspeed, wishspeed, autocvar_sv_accelerate*maxspd_mod, 1, 0, 0, 0);
+                       PM_Accelerate(wishdir, wishspeed, wishspeed, self.stat_sv_accelerate*maxspd_mod, 1, 0, 0, 0);
        }
        else
        {
@@ -1208,13 +1250,13 @@ void SV_PlayerPhysics()
 
                if(maxspd_mod < 1)
                {
-                       maxairspd = autocvar_sv_maxairspeed*maxspd_mod;
-                       airaccel = autocvar_sv_airaccelerate*maxspd_mod;
+                       maxairspd = self.stat_sv_maxairspeed*maxspd_mod;
+                       airaccel = self.stat_sv_airaccelerate*maxspd_mod;
                }
                else
                {
-                       maxairspd = autocvar_sv_maxairspeed;
-                       airaccel = autocvar_sv_airaccelerate;
+                       maxairspd = self.stat_sv_maxairspeed;
+                       airaccel = self.stat_sv_airaccelerate;
                }
                // airborn
                makevectors(self.v_angle_y * '0 1 0');
@@ -1240,13 +1282,13 @@ void SV_PlayerPhysics()
                        wishspeed2 = wishspeed;
 
                        // CPM
-                       if(autocvar_sv_airstopaccelerate)
+                       if(self.stat_sv_airstopaccelerate)
                        {
                                vector curdir;
                                curdir = self.velocity;
                                curdir_z = 0;
                                curdir = normalize(curdir);
-                               airaccel = airaccel + (autocvar_sv_airstopaccelerate*maxspd_mod - airaccel) * max(0, -(curdir * wishdir));
+                               airaccel = airaccel + (self.stat_sv_airstopaccelerate*maxspd_mod - airaccel) * max(0, -(curdir * wishdir));
                        }
                        // note that for straight forward jumping:
                        // step = accel * frametime * wishspeed0;
@@ -1257,20 +1299,20 @@ void SV_PlayerPhysics()
                        // log dv/dt = logaccel + logmaxspeed (when slow)
                        // log dv/dt = logaccel + logmaxspeed + log(1 - accelqw) (when fast)
                        strafity = IsMoveInDirection(self.movement, -90) + IsMoveInDirection(self.movement, +90); // if one is nonzero, other is always zero
-                       if(autocvar_sv_maxairstrafespeed)
-                               wishspeed = min(wishspeed, GeomLerp(autocvar_sv_maxairspeed*maxspd_mod, strafity, autocvar_sv_maxairstrafespeed*maxspd_mod));
-                       if(autocvar_sv_airstrafeaccelerate)
-                               airaccel = GeomLerp(airaccel, strafity, autocvar_sv_airstrafeaccelerate*maxspd_mod);
+                       if(self.stat_sv_maxairstrafespeed)
+                               wishspeed = min(wishspeed, GeomLerp(self.stat_sv_maxairspeed*maxspd_mod, strafity, self.stat_sv_maxairstrafespeed*maxspd_mod));
+                       if(self.stat_sv_airstrafeaccelerate)
+                               airaccel = GeomLerp(airaccel, strafity, self.stat_sv_airstrafeaccelerate*maxspd_mod);
                        if(self.stat_sv_airstrafeaccel_qw)
                                airaccelqw = copysign(1-GeomLerp(1-fabs(self.stat_sv_airaccel_qw), strafity, 1-fabs(self.stat_sv_airstrafeaccel_qw)), ((strafity > 0.5) ? self.stat_sv_airstrafeaccel_qw : self.stat_sv_airaccel_qw));
                        // !CPM
 
-                       if(autocvar_sv_warsowbunny_turnaccel && accelerating && self.movement_y == 0 && self.movement_x != 0)
+                       if(self.stat_sv_warsowbunny_turnaccel && accelerating && self.movement_y == 0 && self.movement_x != 0)
                                PM_AirAccelerate(wishdir, wishspeed);
                        else
-                               PM_Accelerate(wishdir, wishspeed, wishspeed0, airaccel, airaccelqw, autocvar_sv_airaccel_qw_stretchfactor, autocvar_sv_airaccel_sideways_friction / maxairspd, self.stat_sv_airspeedlimit_nonqw);
+                               PM_Accelerate(wishdir, wishspeed, wishspeed0, airaccel, airaccelqw, self.stat_sv_airaccel_qw_stretchfactor, self.stat_sv_airaccel_sideways_friction / maxairspd, self.stat_sv_airspeedlimit_nonqw);
 
-                       if(autocvar_sv_aircontrol)
+                       if(self.stat_sv_aircontrol)
                                CPM_PM_Aircontrol(wishdir, wishspeed2);
                }
        }