]> 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 bf555d4fcd173d4fa245f1635d7c610594c7d45e..37242874e8c5c5f7ce926584424e31e5b89e2de8 100644 (file)
@@ -1,3 +1,33 @@
+#include "_all.qh"
+#include "bot/bot.qh"
+#include "g_damage.qh"
+
+#if defined(CSQC)
+#elif defined(MENUQC)
+#elif defined(SVQC)
+       #include "../dpdefs/progsdefs.qh"
+    #include "../dpdefs/dpextensions.qh"
+    #include "../warpzonelib/mathlib.qh"
+    #include "../warpzonelib/server.qh"
+    #include "../common/constants.qh"
+    #include "../common/util.qh"
+    #include "../common/animdecide.qh"
+    #include "../common/monsters/sv_monsters.qh"
+    #include "../common/weapons/all.qh"
+    #include "t_items.qh"
+    #include "autocvars.qh"
+    #include "defs.qh"
+    #include "../common/notifications.qh"
+    #include "mutators/mutators_include.qh"
+    #include "../common/mapinfo.qh"
+    #include "../csqcmodellib/sv_model.qh"
+    #include "anticheat.qh"
+    #include "cheats.qh"
+    #include "g_hook.qh"
+    #include "race.qh"
+    #include "playerdemo.qh"
+#endif
+
 .float race_penalty;
 .float restart_jump;
 
 .entity ladder_entity;
 .float gravity;
 .float swamp_slowdown;
-.float lastflags;
+.int lastflags;
 .float lastground;
 .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))
+       {
+               string var = sprintf("g_physics_%s_%s", pl.cvar_cl_physics, option);
+               if(cvar_type(var) & 1)
+                       return cvar(var);
+       }
+       if(autocvar_g_physics_clientselect && autocvar_g_physics_clientselect_default)
+       {
+               string var = sprintf("g_physics_%s_%s", autocvar_g_physics_clientselect_default, option);
+               if(cvar_type(var) & 1)
+                       return cvar(var);
+       }
+       return cvar(strcat("sv_", option));
+}
+
 /*
 =============
 PlayerJump
 
 When you press the jump key
-returns TRUE if handled
+returns true if handled
 =============
 */
 float PlayerJump (void)
 {
        if(self.frozen)
-               return TRUE; // no jumping in freezetag when frozen
+               return true; // no jumping in freezetag when frozen
 
        if(self.player_blocked)
-               return TRUE; // no jumping while blocked
+               return true; // no jumping while blocked
 
-       float doublejump = FALSE;
-       float mjumpheight = autocvar_sv_jumpvelocity;
+       bool doublejump = false;
+       float mjumpheight = self.stat_sv_jumpvelocity;
 
        player_multijump = doublejump;
        player_jumpheight = mjumpheight;
        if(MUTATOR_CALLHOOK(PlayerJump))
-               return TRUE;
+               return true;
 
        doublejump = player_multijump;
        mjumpheight = player_jumpheight;
@@ -40,9 +100,9 @@ float PlayerJump (void)
        if (autocvar_sv_doublejump)
        {
                tracebox(self.origin + '0 0 0.01', self.mins, self.maxs, self.origin - '0 0 0.01', MOVE_NORMAL, self);
-               if (trace_fraction < 1 && trace_plane_normal_z > 0.7)
+               if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
                {
-                       doublejump = TRUE;
+                       doublejump = true;
 
                        // we MUST clip velocity here!
                        float f;
@@ -55,7 +115,7 @@ float PlayerJump (void)
        if (self.waterlevel >= WATERLEVEL_SWIMMING)
        {
                self.velocity_z = self.stat_sv_maxspeed * 0.7;
-               return TRUE;
+               return true;
        }
 
        if (!doublejump)
@@ -64,7 +124,7 @@ float PlayerJump (void)
 
        if(self.cvar_cl_movement_track_canjump)
                if (!(self.flags & FL_JUMPRELEASED))
-                       return TRUE;
+                       return true;
 
        // sv_jumpspeedcap_min/sv_jumpspeedcap_max act as baseline
        // velocity bounds.  Final velocity is bound between (jumpheight *
@@ -76,8 +136,8 @@ float PlayerJump (void)
 
                minjumpspeed = mjumpheight * stof(autocvar_sv_jumpspeedcap_min);
 
-               if (self.velocity_z < minjumpspeed)
-                       mjumpheight += minjumpspeed - self.velocity_z;
+               if (self.velocity.z < minjumpspeed)
+                       mjumpheight += minjumpspeed - self.velocity.z;
        }
 
        if(autocvar_sv_jumpspeedcap_max != "")
@@ -85,14 +145,14 @@ float PlayerJump (void)
                // don't do jump speedcaps on ramps to preserve old xonotic ramjump style
                tracebox(self.origin + '0 0 0.01', self.mins, self.maxs, self.origin - '0 0 0.01', MOVE_NORMAL, self);
 
-               if(!(trace_fraction < 1 && trace_plane_normal_z < 0.98 && autocvar_sv_jumpspeedcap_max_disable_on_ramps))
+               if(!(trace_fraction < 1 && trace_plane_normal.z < 0.98 && autocvar_sv_jumpspeedcap_max_disable_on_ramps))
                {
                        float maxjumpspeed;
 
                        maxjumpspeed = mjumpheight * stof(autocvar_sv_jumpspeedcap_max);
 
-                       if (self.velocity_z > maxjumpspeed)
-                               mjumpheight -= self.velocity_z - maxjumpspeed;
+                       if (self.velocity.z > maxjumpspeed)
+                               mjumpheight -= self.velocity.z - maxjumpspeed;
                }
        }
 
@@ -110,20 +170,20 @@ float PlayerJump (void)
                self.jumppadcount = 0;
        }
 
-       self.velocity_z = self.velocity_z + mjumpheight;
-       self.oldvelocity_z = self.velocity_z;
+       self.velocity_z = self.velocity.z + mjumpheight;
+       self.oldvelocity_z = self.velocity.z;
 
        self.flags &= ~FL_ONGROUND;
        self.flags &= ~FL_JUMPRELEASED;
 
-       animdecide_setaction(self, ANIMACTION_JUMP, TRUE);
+       animdecide_setaction(self, ANIMACTION_JUMP, true);
 
        if(autocvar_g_jump_grunt)
                PlayerSound(playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
 
        self.restart_jump = -1; // restart jump anim next time
        // value -1 is used to not use the teleport bit (workaround for tiny hitch when re-jumping)
-       return TRUE;
+       return true;
 }
 void CheckWaterJump()
 {
@@ -132,17 +192,17 @@ void CheckWaterJump()
 // check for a jump-out-of-water
        makevectors (self.angles);
        start = self.origin;
-       start_z = start_z + 8;
-       v_forward_z = 0;
+       start.z = start.z + 8;
+       v_forward.z = 0;
        normalize(v_forward);
        end = start + v_forward*24;
-       traceline (start, end, TRUE, self);
+       traceline (start, end, true, self);
        if (trace_fraction < 1)
        {       // solid at waist
-               start_z = start_z + self.maxs_z - 8;
+               start.z = start.z + self.maxs.z - 8;
                end = start + v_forward*24;
                self.movedir = trace_plane_normal * -50;
-               traceline (start, end, TRUE, self);
+               traceline (start, end, true, self);
                if (trace_fraction == 1)
                {       // open at eye level
                        self.flags |= FL_WATERJUMP;
@@ -177,7 +237,7 @@ void CheckPlayerJump()
                                Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_JETPACK_NOFUEL);
                        else if (activate)
                                Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_JETPACK_NOFUEL);
-                       self.jetpack_stopped = TRUE;
+                       self.jetpack_stopped = true;
                        self.items &= ~IT_USING_JETPACK;
                }
                else if (activate && !self.frozen)
@@ -185,7 +245,7 @@ void CheckPlayerJump()
        }
        else
        {
-               self.jetpack_stopped = FALSE;
+               self.jetpack_stopped = false;
                self.items &= ~IT_USING_JETPACK;
        }
        if (!self.BUTTON_JUMP)
@@ -224,8 +284,8 @@ void RaceCarPhysics()
        vector angles_save, rigvel;
 
        angles_save = self.angles;
-       accel = bound(-1, self.movement_x / self.stat_sv_maxspeed, 1);
-       steer = bound(-1, self.movement_y / self.stat_sv_maxspeed, 1);
+       accel = bound(-1, self.movement.x / self.stat_sv_maxspeed, 1);
+       steer = bound(-1, self.movement.y / self.stat_sv_maxspeed, 1);
 
        if(g_bugrigs_reverse_speeding)
        {
@@ -325,7 +385,7 @@ void RaceCarPhysics()
                vector rigvel_xy, neworigin, up;
                float mt;
 
-               rigvel_z -= frametime * autocvar_sv_gravity; // 4x gravity plays better
+               rigvel.z -= frametime * autocvar_sv_gravity; // 4x gravity plays better
                rigvel_xy = vec2(rigvel);
 
                if(g_bugrigs_planar_movement_car_jumping)
@@ -341,7 +401,7 @@ void RaceCarPhysics()
                tracebox(trace_endpos, self.mins, self.maxs, trace_endpos + rigvel_xy * frametime, mt, self);
 
                // align to surface
-               tracebox(trace_endpos, self.mins, self.maxs, trace_endpos - up + '0 0 1' * rigvel_z * frametime, mt, self);
+               tracebox(trace_endpos, self.mins, self.maxs, trace_endpos - up + '0 0 1' * rigvel.z * frametime, mt, self);
 
                if(trace_fraction < 0.5)
                {
@@ -355,11 +415,11 @@ void RaceCarPhysics()
                {
                        // now set angles_x so that the car points parallel to the surface
                        self.angles = vectoangles(
-                                       '1 0 0' * v_forward_x * trace_plane_normal_z
+                                       '1 0 0' * v_forward.x * trace_plane_normal.z
                                        +
-                                       '0 1 0' * v_forward_y * trace_plane_normal_z
+                                       '0 1 0' * v_forward.y * trace_plane_normal.z
                                        +
-                                       '0 0 1' * -(v_forward_x * trace_plane_normal_x + v_forward_y * trace_plane_normal_y)
+                                       '0 0 1' * -(v_forward.x * trace_plane_normal.x + v_forward.y * trace_plane_normal.y)
                                        );
                        self.flags |= FL_ONGROUND;
                }
@@ -374,7 +434,7 @@ void RaceCarPhysics()
        }
        else
        {
-               rigvel_z -= frametime * autocvar_sv_gravity; // 4x gravity plays better
+               rigvel.z -= frametime * autocvar_sv_gravity; // 4x gravity plays better
                self.velocity = rigvel;
                self.movetype = MOVETYPE_FLY;
        }
@@ -384,11 +444,11 @@ void RaceCarPhysics()
        if(trace_fraction != 1)
        {
                self.angles = vectoangles2(
-                               '1 0 0' * v_forward_x * trace_plane_normal_z
+                               '1 0 0' * v_forward.x * trace_plane_normal.z
                                +
-                               '0 1 0' * v_forward_y * trace_plane_normal_z
+                               '0 1 0' * v_forward.y * trace_plane_normal.z
                                +
-                               '0 0 1' * -(v_forward_x * trace_plane_normal_x + v_forward_y * trace_plane_normal_y),
+                               '0 0 1' * -(v_forward.x * trace_plane_normal.x + v_forward.y * trace_plane_normal.y),
                                trace_plane_normal
                                );
        }
@@ -396,12 +456,12 @@ void RaceCarPhysics()
        {
                vector vel_local;
 
-               vel_local_x = v_forward * self.velocity;
-               vel_local_y = v_right * self.velocity;
-               vel_local_z = v_up * self.velocity;
+               vel_local.x = v_forward * self.velocity;
+               vel_local.y = v_right * self.velocity;
+               vel_local.z = v_up * self.velocity;
 
-               self.angles_x = racecar_angle(vel_local_x, vel_local_z);
-               self.angles_z = racecar_angle(-vel_local_y, vel_local_z);
+               self.angles_x = racecar_angle(vel_local.x, vel_local.z);
+               self.angles_z = racecar_angle(-vel_local.y, vel_local.z);
        }
 
        // smooth the angles
@@ -416,15 +476,15 @@ void RaceCarPhysics()
        vf1 = vf1 + v_forward * (1 - f);
        vu1 = vu1 + v_up * (1 - f);
        smoothangles = vectoangles2(vf1, vu1);
-       self.angles_x = -smoothangles_x;
-       self.angles_z =  smoothangles_z;
+       self.angles_x = -smoothangles.x;
+       self.angles_z =  smoothangles.z;
 }
 
 float IsMoveInDirection(vector mv, float angle) // key mix factor
 {
-       if(mv_x == 0 && mv_y == 0)
+       if(mv.x == 0 && mv.y == 0)
                return 0; // avoid division by zero
-       angle -= RAD2DEG * atan2(mv_y, mv_x);
+       angle -= RAD2DEG * atan2(mv.y, mv.x);
        angle = remainder(angle, 360) / 45;
        if(angle >  1)
                return 0;
@@ -458,7 +518,7 @@ void CPM_PM_Aircontrol(vector wishdir, float wishspeed)
 
 #if 0
        // this doesn't play well with analog input
-       if(self.movement_x == 0 || self.movement_y != 0)
+       if(self.movement_x == 0 || self.movement.y != 0)
                return; // can't control movement if not moving forward or backward
        k = 32;
 #else
@@ -467,9 +527,9 @@ 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;
+       zspeed = self.velocity.z;
        self.velocity_z = 0;
        xyspeed = vlen(self.velocity); self.velocity = normalize(self.velocity);
 
@@ -477,9 +537,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);
        }
 
@@ -500,7 +560,7 @@ float AdjustAirAccelQW(float accelqw, float factor)
 void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float accel, float accelqw, float stretchfactor, float sidefric, float speedlimit)
 {
        float vel_straight;
-       float vel_z;
+       float velZ;
        vector vel_perpend;
        float step;
 
@@ -523,7 +583,7 @@ void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float acce
                wishspeed0 = wishspeed;
 
        vel_straight = self.velocity * wishdir;
-       vel_z = self.velocity_z;
+       velZ = self.velocity.z;
        vel_xy = vec2(self.velocity);
        vel_perpend = vel_xy - vel_straight * wishdir;
 
@@ -571,7 +631,7 @@ void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float acce
                }
        }
 
-       self.velocity = vel_xy + vel_z * '0 0 1';
+       self.velocity = vel_xy + velZ * '0 0 1';
 }
 
 void PM_AirAccelerate(vector wishdir, float wishspeed)
@@ -584,31 +644,31 @@ void PM_AirAccelerate(vector wishdir, float wishspeed)
                return;
 
        curvel = self.velocity;
-       curvel_z = 0;
+       curvel.z = 0;
        curspeed = vlen(curvel);
 
        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;
@@ -633,32 +693,6 @@ void SpecialCommand()
 #endif
 }
 
-float speedaward_speed;
-string speedaward_holder;
-string speedaward_uid;
-void race_send_speedaward(float msg)
-{
-       // send the best speed of the round
-       WriteByte(msg, SVC_TEMPENTITY);
-       WriteByte(msg, TE_CSQC_RACE);
-       WriteByte(msg, RACE_NET_SPEED_AWARD);
-       WriteInt24_t(msg, floor(speedaward_speed+0.5));
-       WriteString(msg, speedaward_holder);
-}
-
-float speedaward_alltimebest;
-string speedaward_alltimebest_holder;
-string speedaward_alltimebest_uid;
-void race_send_speedaward_alltimebest(float msg)
-{
-       // send the best speed
-       WriteByte(msg, SVC_TEMPENTITY);
-       WriteByte(msg, TE_CSQC_RACE);
-       WriteByte(msg, RACE_NET_SPEED_AWARD_BEST);
-       WriteInt24_t(msg, floor(speedaward_alltimebest+0.5));
-       WriteString(msg, speedaward_alltimebest_holder);
-}
-
 string GetMapname(void);
 float speedaward_lastupdate;
 float speedaward_lastsent;
@@ -667,7 +701,7 @@ void SV_PlayerPhysics()
        vector wishvel, wishdir, v;
        float wishspeed, f, maxspd_mod, spd, maxairspd, airaccel, swampspd_mod, buttons;
        string temps;
-       float buttons_prev;
+       int buttons_prev;
        float not_allowed_to_move;
        string c;
 
@@ -682,13 +716,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())
@@ -702,7 +757,7 @@ void SV_PlayerPhysics()
 
        anticheat_physics();
 
-       buttons = self.BUTTON_ATCK + 2 * self.BUTTON_JUMP + 4 * self.BUTTON_ATCK2 + 8 * self.BUTTON_ZOOM + 16 * self.BUTTON_CROUCH + 32 * self.BUTTON_HOOK + 64 * self.BUTTON_USE + 128 * (self.movement_x < 0) + 256 * (self.movement_x > 0) + 512 * (self.movement_y < 0) + 1024 * (self.movement_y > 0);
+       buttons = self.BUTTON_ATCK + 2 * self.BUTTON_JUMP + 4 * self.BUTTON_ATCK2 + 8 * self.BUTTON_ZOOM + 16 * self.BUTTON_CROUCH + 32 * self.BUTTON_HOOK + 64 * self.BUTTON_USE + 128 * (self.movement.x < 0) + 256 * (self.movement.x > 0) + 512 * (self.movement.y < 0) + 1024 * (self.movement.y > 0);
 
        if(!buttons)
                c = "x";
@@ -756,7 +811,7 @@ void SV_PlayerPhysics()
                        self.angles_x = random() * 360;
                        self.angles_y = random() * 360;
                        // at least I'm not forcing retardedview by also assigning to angles_z
-                       self.fixangle = TRUE;
+                       self.fixangle = true;
                }
        }
 
@@ -794,7 +849,6 @@ void SV_PlayerPhysics()
                not_allowed_to_move = 0;
                if(self.race_penalty)
                        not_allowed_to_move = 1;
-               if(!autocvar_sv_ready_restart_after_countdown)
                if(time < game_starttime)
                        not_allowed_to_move = 1;
 
@@ -830,9 +884,9 @@ void SV_PlayerPhysics()
        {
                if(autocvar_sv_dodging_frozen && IS_REAL_CLIENT(self))
                {
-                       self.movement_x = bound(-5, self.movement_x, 5);
-                       self.movement_y = bound(-5, self.movement_y, 5);
-                       self.movement_z = bound(-5, self.movement_z, 5);
+                       self.movement_x = bound(-5, self.movement.x, 5);
+                       self.movement_y = bound(-5, self.movement.y, 5);
+                       self.movement_z = bound(-5, self.movement.z, 5);
                }
                else
                        self.movement = '0 0 0';
@@ -890,7 +944,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;
@@ -911,7 +965,7 @@ void SV_PlayerPhysics()
        if (!self.fixangle && !g_bugrigs)
        {
                self.angles_x = 0;
-               self.angles_y = self.v_angle_y;
+               self.angles_y = self.v_angle.y;
                self.angles_z = 0;
        }
 
@@ -946,8 +1000,8 @@ void SV_PlayerPhysics()
 
        if (self.flags & FL_WATERJUMP )
        {
-               self.velocity_x = self.movedir_x;
-               self.velocity_y = self.movedir_y;
+               self.velocity_x = self.movedir.x;
+               self.velocity_y = self.movedir.y;
                if (time > self.teleport_time || self.waterlevel == WATERLEVEL_NONE)
                {
                        self.flags &= ~FL_WATERJUMP;
@@ -963,17 +1017,17 @@ 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;
+               wishvel = v_forward * self.movement.x + v_right * self.movement.y + '0 0 1' * self.movement.z;
                // acceleration
                wishdir = normalize(wishvel);
                wishspeed = vlen(wishvel);
                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)
        {
@@ -982,7 +1036,7 @@ void SV_PlayerPhysics()
 
                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;
+               wishvel = v_forward * self.movement.x + v_right * self.movement.y + '0 0 1' * self.movement.z;
                if (wishvel == '0 0 0')
                        wishvel = '0 0 -60'; // drift towards bottom
 
@@ -993,10 +1047,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)
        {
@@ -1013,10 +1067,10 @@ 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;
+               wishvel = v_forward * self.movement.x + v_right * self.movement.y + '0 0 1' * self.movement.z;
                self.velocity_z += g;
                if (self.ladder_entity.classname == "func_water")
                {
@@ -1025,12 +1079,12 @@ void SV_PlayerPhysics()
                                wishvel = wishvel * (self.ladder_entity.speed / f);
 
                        self.watertype = self.ladder_entity.skin;
-                       f = self.ladder_entity.origin_z + self.ladder_entity.maxs_z;
-                       if ((self.origin_z + self.view_ofs_z) < f)
+                       f = self.ladder_entity.origin.z + self.ladder_entity.maxs.z;
+                       if ((self.origin.z + self.view_ofs.z) < f)
                                self.waterlevel = WATERLEVEL_SUBMERGED;
-                       else if ((self.origin_z + (self.mins_z + self.maxs_z) * 0.5) < f)
+                       else if ((self.origin.z + (self.mins.z + self.maxs.z) * 0.5) < f)
                                self.waterlevel = WATERLEVEL_SWIMMING;
-                       else if ((self.origin_z + self.mins_z + 1) < f)
+                       else if ((self.origin.z + self.mins.z + 1) < f)
                                self.waterlevel = WATERLEVEL_WETFEET;
                        else
                        {
@@ -1046,23 +1100,23 @@ 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_USING_JETPACK)
        {
                //makevectors(self.v_angle_y * '0 1 0');
                makevectors(self.v_angle);
-               wishvel = v_forward * self.movement_x + v_right * self.movement_y;
+               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
-               wishvel_z = 0;
+               wishvel.z = 0;
 
                // if(self.BUTTON_JUMP)
-                       wishvel_z = sqrt(max(0, 1 - wishvel * wishvel));
+                       wishvel.z = sqrt(max(0, 1 - wishvel * wishvel));
 
                // it is now normalized, so...
                float a_side, a_up, a_add, a_diff;
@@ -1070,10 +1124,10 @@ void SV_PlayerPhysics()
                a_up = autocvar_g_jetpack_acceleration_up;
                a_add = autocvar_g_jetpack_antigravity * autocvar_sv_gravity;
 
-               wishvel_x *= a_side;
-               wishvel_y *= a_side;
-               wishvel_z *= a_up;
-               wishvel_z += a_add;
+               wishvel.x *= a_side;
+               wishvel.y *= a_side;
+               wishvel.z *= a_up;
+               wishvel.z += a_add;
 
                float best;
                best = 0;
@@ -1116,15 +1170,15 @@ void SV_PlayerPhysics()
                //print("best possible acceleration: ", ftos(best), "\n");
 
                float fxy, fz;
-               fxy = bound(0, 1 - (self.velocity * normalize(wishvel_x * '1 0 0' + wishvel_y * '0 1 0')) / autocvar_g_jetpack_maxspeed_side, 1);
-               if(wishvel_z - autocvar_sv_gravity > 0)
-                       fz = bound(0, 1 - self.velocity_z / autocvar_g_jetpack_maxspeed_up, 1);
+               fxy = bound(0, 1 - (self.velocity * normalize(wishvel.x * '1 0 0' + wishvel.y * '0 1 0')) / autocvar_g_jetpack_maxspeed_side, 1);
+               if(wishvel.z - autocvar_sv_gravity > 0)
+                       fz = bound(0, 1 - self.velocity.z / autocvar_g_jetpack_maxspeed_up, 1);
                else
-                       fz = bound(0, 1 + self.velocity_z / autocvar_g_jetpack_maxspeed_up, 1);
+                       fz = bound(0, 1 + self.velocity.z / autocvar_g_jetpack_maxspeed_up, 1);
 
-               wishvel_x *= fxy;
-               wishvel_y *= fxy;
-               wishvel_z = (wishvel_z - autocvar_sv_gravity) * fz + autocvar_sv_gravity;
+               wishvel.x *= fxy;
+               wishvel.y *= fxy;
+               wishvel.z = (wishvel.z - autocvar_sv_gravity) * fz + autocvar_sv_gravity;
 
                float fvel;
                fvel = min(1, vlen(wishvel) / best);
@@ -1154,8 +1208,8 @@ void SV_PlayerPhysics()
                        Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_JETPACK_NOFUEL);
 
                // walking
-               makevectors(self.v_angle_y * '0 1 0');
-               wishvel = v_forward * self.movement_x + v_right * self.movement_y;
+               makevectors(self.v_angle.y * '0 1 0');
+               wishvel = v_forward * self.movement.x + v_right * self.movement.y;
 
                if(!(self.lastflags & FL_ONGROUND))
                {
@@ -1169,14 +1223,14 @@ void SV_PlayerPhysics()
                }
 
                v = self.velocity;
-               v_z = 0;
+               v.z = 0;
                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
@@ -1213,7 +1267,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
        {
@@ -1224,17 +1278,17 @@ 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');
-               wishvel = v_forward * self.movement_x + v_right * self.movement_y;
+               makevectors(self.v_angle.y * '0 1 0');
+               wishvel = v_forward * self.movement.x + v_right * self.movement.y;
                // acceleration
                wishdir = normalize(wishvel);
                wishspeed = wishspeed0 = vlen(wishvel);
@@ -1256,13 +1310,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.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;
@@ -1273,29 +1327,29 @@ 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);
                }
        }
 
        if((g_cts || g_race) && !IS_OBSERVER(self))
        {
-               if(vlen(self.velocity - self.velocity_z * '0 0 1') > speedaward_speed)
+               if(vlen(self.velocity - self.velocity.z * '0 0 1') > speedaward_speed)
                {
-                       speedaward_speed = vlen(self.velocity - self.velocity_z * '0 0 1');
+                       speedaward_speed = vlen(self.velocity - self.velocity.z * '0 0 1');
                        speedaward_holder = self.netname;
                        speedaward_uid = self.crypto_idfp;
                        speedaward_lastupdate = time;
@@ -1319,7 +1373,7 @@ void SV_PlayerPhysics()
 
        // WEAPONTODO
        float xyspeed;
-       xyspeed = vlen('1 0 0' * self.velocity_x + '0 1 0' * self.velocity_y);
+       xyspeed = vlen('1 0 0' * self.velocity.x + '0 1 0' * self.velocity.y);
        if(self.weapon == WEP_VORTEX && WEP_CVAR(vortex, charge) && WEP_CVAR(vortex, charge_velocity_rate) && xyspeed > WEP_CVAR(vortex, charge_minspeed))
        {
                // add a maximum of charge_velocity_rate when going fast (f = 1), gradually increasing from minspeed (f = 0) to maxspeed