Merge branch 'master' into Mario/qc_physics_prehax
authorMario <zacjardine@y7mail.com>
Wed, 15 Jul 2015 05:43:30 +0000 (15:43 +1000)
committerMario <zacjardine@y7mail.com>
Wed, 15 Jul 2015 05:43:30 +0000 (15:43 +1000)
Conflicts:
qcsrc/server/autocvars.qh
qcsrc/server/defs.qh
qcsrc/server/g_triggers.qc
qcsrc/server/g_triggers.qh

36 files changed:
_hud_common.cfg
commands.cfg
defaultXonotic.cfg
gamemodes.cfg
physics.cfg [new file with mode: 0644]
qcsrc/client/autocvars.qh
qcsrc/client/hud.qc
qcsrc/client/mapvoting.qc
qcsrc/client/mapvoting.qh
qcsrc/client/wall.qc
qcsrc/client/wall.qh
qcsrc/common/constants.qh
qcsrc/common/items/all.inc
qcsrc/common/items/item.qh
qcsrc/common/physics.qc
qcsrc/common/physics.qh
qcsrc/common/triggers/triggers.qc
qcsrc/common/triggers/triggers.qh
qcsrc/menu/xonotic/util.qc
qcsrc/server/autocvars.qh
qcsrc/server/cl_physics.qc [deleted file]
qcsrc/server/command/cmd.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/defs.qh
qcsrc/server/g_models.qc
qcsrc/server/g_world.qc
qcsrc/server/mapvoting.qc
qcsrc/server/mapvoting.qh
qcsrc/server/miscfunctions.qc
qcsrc/server/miscfunctions.qh
qcsrc/server/mutators/gamemode_freezetag.qc
qcsrc/server/mutators/mutator_buffs.qc
qcsrc/server/mutators/mutator_buffs.qh
qcsrc/server/mutators/mutator_instagib.qc
qcsrc/server/mutators/mutator_instagib_items.qc [new file with mode: 0644]
xonotic-credits.txt

index 5aa1bbf..b74eff9 100644 (file)
@@ -38,6 +38,9 @@ seta hud_panel_engineinfo_framecounter_exponentialmovingaverage 1 "use an averag
 seta hud_panel_engineinfo_framecounter_exponentialmovingaverage_new_weight 0.1 "weight of latest data point"
 seta hud_panel_engineinfo_framecounter_exponentialmovingaverage_instantupdate_change_threshold 0.5 "threshold for fps change when to update instantly, to make big fps changes update faster"
 
+seta hud_panel_physics_acceleration_movingaverage 1 "use an averaging method for calculating acceleration instead of the real value"
+seta hud_panel_phisics_update_interval 0.0666 "how often (in seconds) numeric values get updated on screen"
+
 // hud panel aliases
 alias hud_panel_radar_rotate "toggle hud_panel_radar_rotation 0 1 2 3 4"
 alias +hud_panel_radar_maximized "cl_cmd hud radar 1"
index 20f9570..812e572 100644 (file)
@@ -160,6 +160,7 @@ alias sentcvar             "qc_cmd_cmd    sentcvar             ${* ?}" // New sy
 alias mobedit              "qc_cmd_cmd    mobedit              ${* ?}" // Edit a monster's properties
 alias mobkill              "qc_cmd_cmd    mobkill              ${* ?}" // Kill a monster
 alias mobspawn             "qc_cmd_cmd    mobspawn             ${* ?}" // Spawn a monster infront of the player
+alias physics              "qc_cmd_cmd    physics              ${* ?}" // Change physics set
 alias spectate             "qc_cmd_cmd    spectate             ${* ?}" // Become an observer
 alias suggestmap           "qc_cmd_cmd    suggestmap           ${* ?}" // Suggest a map to the mapvote at match end
 //alias tell               "qc_cmd_cmd    tell                 ${* ?}" // Send a message directly to a player
index eb8d9ca..c0d585e 100644 (file)
@@ -1400,6 +1400,7 @@ exec gamemodes.cfg
 exec mutators.cfg
 exec notifications.cfg
 exec monsters.cfg
+exec physics.cfg
 
 // load console command aliases and settings
 exec commands.cfg
index b6cbe92..d660aa1 100644 (file)
@@ -66,8 +66,11 @@ alias sv_hook_gameend
 // =====================
 //  gametype vote hooks
 // =====================
-// these are called when the mode is switched via gametype vote screen, earlier than gamestart hooks (useful for enabling per-gamemode mutators)
-alias sv_vote_gametype_hook_all 
+// These are called when the mode is switched via gametype vote screen,
+// earlier than gamestart hooks (useful for enabling per-gamemode mutators)
+// The _all hook is called before the specific one
+// here it sets g_maxplayers to undo what duel does
+alias sv_vote_gametype_hook_all "set g_maxplayers 0"
 alias sv_vote_gametype_hook_as
 alias sv_vote_gametype_hook_ca
 alias sv_vote_gametype_hook_ctf
@@ -84,6 +87,15 @@ alias sv_vote_gametype_hook_ons
 alias sv_vote_gametype_hook_rc
 alias sv_vote_gametype_hook_tdm
 
+// Preset to allow duel to be used for the gametype voting screen
+// sv_vote_gametype_*_type Must be set to the name of the gametype the option is based on
+// sv_vote_gametype_*_name Contains a human-readable name of the gametype
+// sv_vote_gametype_*_description Contains a longer description
+set sv_vote_gametype_duel_type dm
+set sv_vote_gametype_duel_name Duel
+set sv_vote_gametype_duel_description "One vs One match"
+alias sv_vote_gametype_hook_duel "set g_maxplayers 2"
+
 
 // ===========
 //  leadlimit
diff --git a/physics.cfg b/physics.cfg
new file mode 100644 (file)
index 0000000..58d1b1f
--- /dev/null
@@ -0,0 +1,256 @@
+// ==================================================
+//  Main configuration for client selectable physics
+// ==================================================
+
+
+// ==============
+//  Main options
+// ==============
+seta cl_physics "default" "client selected physics set"
+
+set g_physics_clientselect 0 "allow clients to select their physics set"
+set g_physics_clientselect_options "xonotic nexuiz quake warsow defrag quake3 vecxis quake2 bones"
+set g_physics_clientselect_default "" "override default physics"
+
+// =========
+//  Xonotic
+// =========
+set g_physics_xonotic_airaccel_qw -0.8
+set g_physics_xonotic_airstrafeaccel_qw -0.95
+set g_physics_xonotic_airspeedlimit_nonqw 900
+set g_physics_xonotic_maxspeed 360
+set g_physics_xonotic_jumpvelocity 260
+set g_physics_xonotic_maxairstrafespeed 100
+set g_physics_xonotic_maxairspeed 360
+set g_physics_xonotic_airstrafeaccelerate 18
+set g_physics_xonotic_warsowbunny_turnaccel 0
+set g_physics_xonotic_airaccel_qw_stretchfactor 2
+set g_physics_xonotic_airaccel_sideways_friction 0
+set g_physics_xonotic_aircontrol 100
+set g_physics_xonotic_aircontrol_power 2
+set g_physics_xonotic_aircontrol_penalty 0
+set g_physics_xonotic_warsowbunny_airforwardaccel 1.00001
+set g_physics_xonotic_warsowbunny_topspeed 925
+set g_physics_xonotic_warsowbunny_accel 0.1593
+set g_physics_xonotic_warsowbunny_backtosideratio 0.8
+set g_physics_xonotic_friction 6
+set g_physics_xonotic_accelerate 15
+set g_physics_xonotic_stopspeed 100
+set g_physics_xonotic_airaccelerate 2
+set g_physics_xonotic_airstopaccelerate 3
+
+// ========
+//  Nexuiz
+// ========
+set g_physics_nexuiz_airaccel_qw 0.95
+set g_physics_nexuiz_airstrafeaccel_qw 0
+set g_physics_nexuiz_airspeedlimit_nonqw 0
+set g_physics_nexuiz_maxspeed 400
+set g_physics_nexuiz_jumpvelocity 300 "333 to match xonotic physics"
+set g_physics_nexuiz_maxairstrafespeed 0
+set g_physics_nexuiz_maxairspeed 220
+set g_physics_nexuiz_airstrafeaccelerate 0
+set g_physics_nexuiz_warsowbunny_turnaccel 0
+set g_physics_nexuiz_airaccel_qw_stretchfactor 0
+set g_physics_nexuiz_airaccel_sideways_friction 0.35
+set g_physics_nexuiz_aircontrol 0
+set g_physics_nexuiz_aircontrol_power 2
+set g_physics_nexuiz_aircontrol_penalty 0
+set g_physics_nexuiz_warsowbunny_airforwardaccel 1.00001
+set g_physics_nexuiz_warsowbunny_topspeed 925
+set g_physics_nexuiz_warsowbunny_accel 0.1593
+set g_physics_nexuiz_warsowbunny_backtosideratio 0.8
+set g_physics_nexuiz_friction 7
+set g_physics_nexuiz_accelerate 8
+set g_physics_nexuiz_stopspeed 100
+set g_physics_nexuiz_airaccelerate 5.5
+set g_physics_nexuiz_airstopaccelerate 0
+
+// =======
+//  Quake
+// =======
+set g_physics_quake_airaccel_qw 1
+set g_physics_quake_airstrafeaccel_qw 0
+set g_physics_quake_airspeedlimit_nonqw 0
+set g_physics_quake_maxspeed 320
+set g_physics_quake_jumpvelocity 270
+set g_physics_quake_maxairstrafespeed 0
+set g_physics_quake_maxairspeed 30
+set g_physics_quake_airstrafeaccelerate 0
+set g_physics_quake_warsowbunny_turnaccel 0
+set g_physics_quake_airaccel_qw_stretchfactor 0
+set g_physics_quake_airaccel_sideways_friction 0
+set g_physics_quake_aircontrol 0
+set g_physics_quake_aircontrol_power 2
+set g_physics_quake_aircontrol_penalty 0
+set g_physics_quake_warsowbunny_airforwardaccel 1.00001
+set g_physics_quake_warsowbunny_topspeed 925
+set g_physics_quake_warsowbunny_accel 0.1593
+set g_physics_quake_warsowbunny_backtosideratio 0.8
+set g_physics_quake_friction 4
+set g_physics_quake_accelerate 10
+set g_physics_quake_stopspeed 100
+set g_physics_quake_airaccelerate 106.66666666666666666666
+set g_physics_quake_airstopaccelerate 0
+
+// ========
+//  Warsow
+// ========
+set g_physics_warsow_airaccel_qw 1
+set g_physics_warsow_airstrafeaccel_qw 0
+set g_physics_warsow_airspeedlimit_nonqw 0
+set g_physics_warsow_maxspeed 320
+set g_physics_warsow_jumpvelocity 280
+set g_physics_warsow_maxairstrafespeed 30
+set g_physics_warsow_maxairspeed 320
+set g_physics_warsow_airstrafeaccelerate 70
+set g_physics_warsow_warsowbunny_turnaccel 9
+set g_physics_warsow_airaccel_qw_stretchfactor 0
+set g_physics_warsow_airaccel_sideways_friction 0
+set g_physics_warsow_aircontrol 0
+set g_physics_warsow_aircontrol_power 2
+set g_physics_warsow_aircontrol_penalty 0
+set g_physics_warsow_warsowbunny_airforwardaccel 1.00001
+set g_physics_warsow_warsowbunny_topspeed 925
+set g_physics_warsow_warsowbunny_accel 0.1593
+set g_physics_warsow_warsowbunny_backtosideratio 0.8
+set g_physics_warsow_friction 8
+set g_physics_warsow_accelerate 15
+set g_physics_warsow_stopspeed 100
+set g_physics_warsow_airaccelerate 1
+set g_physics_warsow_airstopaccelerate 2.5
+
+// ========
+//  DeFrag
+// ========
+set g_physics_defrag_airaccel_qw 0.95
+set g_physics_defrag_airstrafeaccel_qw 1
+set g_physics_defrag_airspeedlimit_nonqw 0
+set g_physics_defrag_maxspeed 320
+set g_physics_defrag_jumpvelocity 270
+set g_physics_defrag_maxairstrafespeed 30
+set g_physics_defrag_maxairspeed 320
+set g_physics_defrag_airstrafeaccelerate 70
+set g_physics_defrag_warsowbunny_turnaccel 0
+set g_physics_defrag_airaccel_qw_stretchfactor 0
+set g_physics_defrag_airaccel_sideways_friction 0
+set g_physics_defrag_aircontrol 150
+set g_physics_defrag_aircontrol_power 2
+set g_physics_defrag_aircontrol_penalty 0
+set g_physics_defrag_warsowbunny_airforwardaccel 1.00001
+set g_physics_defrag_warsowbunny_topspeed 925
+set g_physics_defrag_warsowbunny_accel 0.1593
+set g_physics_defrag_warsowbunny_backtosideratio 0.8
+set g_physics_defrag_friction 5.8
+set g_physics_defrag_accelerate 15
+set g_physics_defrag_stopspeed 100
+set g_physics_defrag_airaccelerate 1
+set g_physics_defrag_airstopaccelerate 2.5
+
+// =========
+//  Quake 3
+// =========
+set g_physics_quake3_airaccel_qw 1
+set g_physics_quake3_airstrafeaccel_qw 0
+set g_physics_quake3_airspeedlimit_nonqw 0
+set g_physics_quake3_maxspeed 320
+set g_physics_quake3_jumpvelocity 270
+set g_physics_quake3_maxairstrafespeed 0
+set g_physics_quake3_maxairspeed 320
+set g_physics_quake3_airstrafeaccelerate 0
+set g_physics_quake3_warsowbunny_turnaccel 0
+set g_physics_quake3_airaccel_qw_stretchfactor 0
+set g_physics_quake3_airaccel_sideways_friction 0
+set g_physics_quake3_aircontrol 0
+set g_physics_quake3_aircontrol_power 2
+set g_physics_quake3_aircontrol_penalty 0
+set g_physics_quake3_warsowbunny_airforwardaccel 1.00001
+set g_physics_quake3_warsowbunny_topspeed 925
+set g_physics_quake3_warsowbunny_accel 0.1593
+set g_physics_quake3_warsowbunny_backtosideratio 0.8
+set g_physics_quake3_friction 6
+set g_physics_quake3_accelerate 10
+set g_physics_quake3_stopspeed 100
+set g_physics_quake3_airaccelerate 1
+set g_physics_quake3_airstopaccelerate 0
+
+// ========
+//  Vecxis
+// ========
+set g_physics_vecxis_airaccel_qw 0.93
+set g_physics_vecxis_airstrafeaccel_qw 0
+set g_physics_vecxis_airspeedlimit_nonqw 0
+set g_physics_vecxis_maxspeed 400
+set g_physics_vecxis_jumpvelocity 300 "333 to match xonotic physics"
+set g_physics_vecxis_maxairstrafespeed 0
+set g_physics_vecxis_maxairspeed 220
+set g_physics_vecxis_airstrafeaccelerate 0
+set g_physics_vecxis_warsowbunny_turnaccel 0
+set g_physics_vecxis_airaccel_qw_stretchfactor 0
+set g_physics_vecxis_airaccel_sideways_friction 0.3
+set g_physics_vecxis_aircontrol 0
+set g_physics_vecxis_aircontrol_power 2
+set g_physics_vecxis_aircontrol_penalty 0
+set g_physics_vecxis_warsowbunny_airforwardaccel 1.00001
+set g_physics_vecxis_warsowbunny_topspeed 925
+set g_physics_vecxis_warsowbunny_accel 0.1593
+set g_physics_vecxis_warsowbunny_backtosideratio 0.8
+set g_physics_vecxis_friction 5
+set g_physics_vecxis_accelerate 5.5
+set g_physics_vecxis_stopspeed 100
+set g_physics_vecxis_airaccelerate 5.5
+set g_physics_vecxis_airstopaccelerate 0
+
+// =========
+//  Quake 2
+// =========
+set g_physics_quake2_airaccel_qw 1
+set g_physics_quake2_airstrafeaccel_qw 0
+set g_physics_quake2_airspeedlimit_nonqw 0
+set g_physics_quake2_maxspeed 300
+set g_physics_quake2_jumpvelocity 270
+set g_physics_quake2_maxairstrafespeed 0
+set g_physics_quake2_maxairspeed 300
+set g_physics_quake2_airstrafeaccelerate 0
+set g_physics_quake2_warsowbunny_turnaccel 0
+set g_physics_quake2_airaccel_qw_stretchfactor 0
+set g_physics_quake2_airaccel_sideways_friction 0
+set g_physics_quake2_aircontrol 0
+set g_physics_quake2_aircontrol_power 2
+set g_physics_quake2_aircontrol_penalty 0
+set g_physics_quake2_warsowbunny_airforwardaccel 1.00001
+set g_physics_quake2_warsowbunny_topspeed 925
+set g_physics_quake2_warsowbunny_accel 0.1593
+set g_physics_quake2_warsowbunny_backtosideratio 0.8
+set g_physics_quake2_friction 6
+set g_physics_quake2_accelerate 10
+set g_physics_quake2_stopspeed 100
+set g_physics_quake2_airaccelerate 1
+set g_physics_quake2_airstopaccelerate 0
+
+// =======
+//  Bones
+// =======
+set g_physics_bones_airaccel_qw 1
+set g_physics_bones_airstrafeaccel_qw 1
+set g_physics_bones_airspeedlimit_nonqw 0
+set g_physics_bones_maxspeed 320
+set g_physics_bones_jumpvelocity 270
+set g_physics_bones_maxairstrafespeed 30
+set g_physics_bones_maxairspeed 320
+set g_physics_bones_airstrafeaccelerate 70
+set g_physics_bones_warsowbunny_turnaccel 0
+set g_physics_bones_airaccel_qw_stretchfactor 0
+set g_physics_bones_airaccel_sideways_friction 0
+set g_physics_bones_aircontrol 150
+set g_physics_bones_aircontrol_power 2
+set g_physics_bones_aircontrol_penalty 0
+set g_physics_bones_warsowbunny_airforwardaccel 1.00001
+set g_physics_bones_warsowbunny_topspeed 925
+set g_physics_bones_warsowbunny_accel 0.1593
+set g_physics_bones_warsowbunny_backtosideratio 0.8
+set g_physics_bones_friction 5.97
+set g_physics_bones_accelerate 15
+set g_physics_bones_stopspeed 100
+set g_physics_bones_airaccelerate 1
+set g_physics_bones_airstopaccelerate 2.5
index e35bf82..90faef9 100644 (file)
@@ -282,10 +282,12 @@ float autocvar_hud_panel_notify_fontsize;
 float autocvar_hud_panel_notify_time;
 float autocvar_hud_panel_notify_icon_aspect;
 bool autocvar_hud_panel_physics;
+float autocvar_hud_panel_physics_acceleration_movingaverage = 1;
 float autocvar_hud_panel_physics_acceleration_progressbar_mode;
 float autocvar_hud_panel_physics_acceleration_progressbar_scale;
 float autocvar_hud_panel_physics_acceleration_progressbar_nonlinear;
 float autocvar_hud_panel_physics_acceleration_max;
+float autocvar_hud_panel_physics_update_interval;
 int autocvar_hud_panel_physics_progressbar;
 bool autocvar_hud_panel_physics_acceleration_vertical;
 int autocvar_hud_panel_physics_baralign;
index f3a8d67..b61fe2a 100644 (file)
@@ -3909,6 +3909,7 @@ void HUD_InfoMessages(void)
 //
 vector acc_prevspeed;
 float acc_prevtime, acc_avg, top_speed, top_speed_time;
+float physics_update_time, discrete_speed, discrete_acceleration;
 void HUD_Physics(void)
 {
        if(!autocvar__hud_configure)
@@ -3996,8 +3997,23 @@ void HUD_Physics(void)
                acc_prevspeed = vel;
                acc_prevtime = time;
 
-               f = bound(0, f * 10, 1);
-               acc_avg = acc_avg * (1 - f) + acceleration * f;
+               if(autocvar_hud_panel_physics_acceleration_movingaverage)
+               {
+                       f = bound(0, f * 10, 1);
+                       acc_avg = acc_avg * (1 - f) + acceleration * f;
+                       acceleration = acc_avg;
+               }
+       }
+
+       int acc_decimals = 2;
+       if(time > physics_update_time)
+       {
+               // workaround for ftos_decimals returning a negative 0
+               if(discrete_acceleration > -1 / pow(10, acc_decimals) && discrete_acceleration < 0)
+                       discrete_acceleration = 0;
+               discrete_acceleration = acceleration;
+               discrete_speed = speed;
+               physics_update_time += autocvar_hud_panel_physics_update_interval;
        }
 
        //compute layout
@@ -4051,7 +4067,7 @@ void HUD_Physics(void)
                //else
                        //tmp_offset_x = 0;
                tmp_offset.y = (panel_size.y - tmp_size.y) / 2;
-               drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(speed), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+               drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(discrete_speed), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 
                //draw speed unit
                if (speed_baralign)
@@ -4141,7 +4157,7 @@ void HUD_Physics(void)
 
                f = acceleration/autocvar_hud_panel_physics_acceleration_max;
                if (autocvar_hud_panel_physics_acceleration_progressbar_nonlinear)
-                       f = sqrt(f);
+                       f = (f >= 0 ? sqrt(f) : -sqrt(-f));
 
                if (acceleration_progressbar_scale) // allow progressbar to go out of panel bounds
                {
@@ -4163,12 +4179,16 @@ void HUD_Physics(void)
 
                HUD_Panel_DrawProgressBar(panel_pos + acceleration_offset + tmp_offset, tmp_size, "accelbar", f, 0, acceleration_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
        }
-       tmp_size.x = panel_size.x;
-       tmp_size.y = panel_size.y * text_scale;
-       tmp_offset.x = 0;
-       tmp_offset.y = (panel_size.y - tmp_size.y) / 2;
-       if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 3)
-               drawstring_aspect(panel_pos + acceleration_offset + tmp_offset, strcat(ftos_decimals(acceleration, 2), "g"), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+       if(autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 3)
+       {
+               tmp_size.x = panel_size.x;
+               tmp_size.y = panel_size.y * text_scale;
+               tmp_offset.x = 0;
+               tmp_offset.y = (panel_size.y - tmp_size.y) / 2;
+
+               drawstring_aspect(panel_pos + acceleration_offset + tmp_offset, strcat(ftos_decimals(discrete_acceleration, acc_decimals), "g"), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       }
 
        draw_endBoldFont();
 }
index 665f1b8..f00ee54 100644 (file)
@@ -9,6 +9,41 @@
 
 #include "../dpdefs/keycodes.qh"
 
+
+int mv_num_maps;
+
+float mv_active;
+string mv_maps[MAPVOTE_COUNT];
+string mv_pics[MAPVOTE_COUNT];
+string mv_pk3[MAPVOTE_COUNT]; // map pk3 name or gametype human readable name
+string mv_desc[MAPVOTE_COUNT];
+float mv_preview[MAPVOTE_COUNT];
+float mv_votes[MAPVOTE_COUNT];
+float mv_flags[MAPVOTE_COUNT];
+float mv_flags_start[MAPVOTE_COUNT];
+entity mv_pk3list;
+float mv_abstain;
+float mv_ownvote;
+float mv_detail;
+float mv_timeout;
+float mv_top2_time;
+float mv_top2_alpha;
+
+vector mv_mousepos;
+int mv_selection;
+int mv_columns;
+int mv_mouse_selection;
+int mv_selection_keyboard;
+
+float gametypevote;
+string mapvote_chosenmap;
+vector gtv_text_size;
+vector gtv_text_size_small;
+
+const int NUM_SSDIRS = 4;
+string ssdirs[NUM_SSDIRS];
+int n_ssdirs;
+
 string MapVote_FormatMapItem(int id, string map, float _count, float maxwidth, vector fontsize)
 {
        string pre, post;
@@ -17,7 +52,7 @@ string MapVote_FormatMapItem(int id, string map, float _count, float maxwidth, v
        {
                if(_count == 1)
                        post = _(" (1 vote)");
-               else if(_count >= 0 && mv_avail[id] == GTV_AVAILABLE)
+               else if(_count >= 0 && (mv_flags[id] & GTV_AVAILABLE))
                        post = sprintf(_(" (%d votes)"), _count);
                else
                        post = "";
@@ -29,14 +64,9 @@ string MapVote_FormatMapItem(int id, string map, float _count, float maxwidth, v
        return strcat(pre, map, post);
 }
 
-string GameTypeVote_DescriptionByID(int id)
-{
-       return MapInfo_Type_Description(MapInfo_Type_FromString(mv_maps[id]));
-}
-
 vector MapVote_RGB(int id)
 {
-       if(mv_avail[id] != GTV_AVAILABLE)
+       if(!(mv_flags[id] & GTV_AVAILABLE))
                return '1 1 1';
        if(id == mv_ownvote)
                return '0 1 0';
@@ -48,55 +78,60 @@ vector MapVote_RGB(int id)
 
 void GameTypeVote_DrawGameTypeItem(vector pos, float maxh, float tsize, string gtype, string pic, float _count, int id)
 {
+       // Find the correct alpha
        float alpha;
-       float desc_padding = gtv_text_size.x * 3;
+       if(!(mv_flags_start[id] & GTV_AVAILABLE))
+               alpha = 0.2; // The gametype isn't supported by the map
+       else if ( !(mv_flags[id] & GTV_AVAILABLE) && mv_top2_alpha)
+               alpha = mv_top2_alpha; // Fade away if not one of the top 2 choice
+       else
+               alpha = 1; // Normal, full alpha
+
+       // Bounding box details
        float rect_margin = hud_fontsize.y / 2;
        vector rect_pos = pos - '0.5 0.5 0' * rect_margin;
        vector rect_size = '1 1 0';
        rect_size.x = tsize + rect_margin;
        rect_size.y = maxh + rect_margin;
-       vector rgb = MapVote_RGB(id);
-       vector offset = pos;
-       float nlines = 0;
-
-       if(mv_avail_start[id] != GTV_AVAILABLE)
-               alpha = 0.2;
-       else if ( mv_avail[id] != GTV_AVAILABLE && mv_top2_alpha)
-               alpha = mv_top2_alpha;
-       else
-               alpha = 1;
 
-       if(id == mv_selection && mv_avail[id] == GTV_AVAILABLE)
+       // Highlight selected item
+       if(id == mv_selection && (mv_flags[id] & GTV_AVAILABLE))
        {
                drawfill(rect_pos, rect_size, '1 1 1', 0.1, DRAWFLAG_NORMAL);
        }
+
+       // Highlight current vote
+       vector rgb = MapVote_RGB(id);
        if(id == mv_ownvote)
        {
                drawfill(rect_pos, rect_size, rgb, 0.1*alpha, DRAWFLAG_NORMAL);
                drawborderlines(autocvar_scoreboard_border_thickness, rect_pos, rect_size, rgb, alpha, DRAWFLAG_NORMAL);
        }
 
-       entity title;
-       title = spawn();
-       title.message = MapVote_FormatMapItem(id, MapInfo_Type_ToText(MapInfo_Type_FromString(gtype)),
-                                                                                 _count, tsize, gtv_text_size);
-       title.origin = pos-offset;
-
-       pos.y += gtv_text_size_small.y;
-       pos.y += gtv_text_size.y/2;
+       vector offset = pos;
 
-       maxh -= gtv_text_size.y;
+       float title_gap = gtv_text_size.y * 1.4; // distance between the title and the description
+       pos.y += title_gap;
+       maxh -= title_gap;
 
-       entity picent = spawn();
-       picent.origin = pos-offset;
-       picent.maxs = '1 1 0 ' * min(maxh, desc_padding) * 0.8;
+       // Evaluate the image size
+       vector image_size = '1 1 0' * gtv_text_size.x * 3;
+       if ( maxh < image_size.y )
+               image_size = '1 1 0' * maxh;
+       image_size *= 0.8;
+       float desc_padding = gtv_text_size.x * 0.6;
+       pos.x += image_size.x + desc_padding;
+       tsize -= image_size.x + desc_padding;
 
-       pos.x += desc_padding;
-       tsize -= desc_padding;
+       // Split the description into lines
+       entity title;
+       title = spawn();
+       title.message = MapVote_FormatMapItem(id, mv_pk3[id], _count, tsize, gtv_text_size);
 
-       string thelabel = GameTypeVote_DescriptionByID(id), ts;
+       string thelabel = mv_desc[id], ts;
        entity last = title;
        entity next = world;
+       float nlines = 0;
        if( thelabel != "")
        {
                float i,n = tokenizebyseparator(thelabel, "\n");
@@ -120,14 +155,19 @@ void GameTypeVote_DrawGameTypeItem(vector pos, float maxh, float tsize, string g
                }
        }
 
-       maxh -= max(nlines*gtv_text_size_small.y,picent.maxs.y);
+       // Center the contents in the bounding box
+       maxh -= max(nlines*gtv_text_size_small.y,image_size.y);
        if ( maxh > 0 )
                offset.y += maxh/2;
-       drawstring(title.origin+offset, title.message, gtv_text_size, rgb, alpha, DRAWFLAG_NORMAL);
 
+       // Draw the title
+       drawstring(offset, title.message, gtv_text_size, rgb, alpha, DRAWFLAG_NORMAL);
+
+       // Draw the icon
        if(pic != "")
-               drawpic(picent.origin+offset, pic, picent.maxs, '1 1 1', alpha, DRAWFLAG_NORMAL);
+               drawpic('0 1 0'*title_gap+'0.5 0 0'*desc_padding+offset, pic, image_size, '1 1 1', alpha, DRAWFLAG_NORMAL);
 
+       // Draw the description
        for ( last = title.chain; last ; )
        {
                drawstring(last.origin+offset, last.message, gtv_text_size_small, '1 1 1', alpha, DRAWFLAG_NORMAL);
@@ -136,7 +176,7 @@ void GameTypeVote_DrawGameTypeItem(vector pos, float maxh, float tsize, string g
                remove(next);
        }
 
-       remove(picent);
+       // Cleanup
        remove(title);
 }
 
@@ -161,7 +201,7 @@ void MapVote_DrawMapItem(vector pos, float isize, float tsize, string map, strin
        text_size = stringwidth(label, false, hud_fontsize);
 
        float theAlpha;
-       if (mv_avail[id] != GTV_AVAILABLE && mv_top2_alpha)
+       if (!(mv_flags[id] & GTV_AVAILABLE) && mv_top2_alpha)
                theAlpha = mv_top2_alpha;
        else
                theAlpha = 1;
@@ -191,7 +231,7 @@ void MapVote_DrawMapItem(vector pos, float isize, float tsize, string map, strin
        else
                drawborderlines(autocvar_scoreboard_border_thickness, pos, img_size, '0 0 0', theAlpha, DRAWFLAG_NORMAL);
 
-       if(id == mv_selection && mv_avail[id] == GTV_AVAILABLE)
+       if(id == mv_selection && (mv_flags[id] & GTV_AVAILABLE))
                drawfill(pos, img_size, '1 1 1', 0.1, DRAWFLAG_NORMAL);
 }
 
@@ -466,20 +506,68 @@ void MapVote_ReadMask()
                        mask = ReadLong();
 
                for(i = 0, power = 1; i < mv_num_maps; ++i, power *= 2)
-                       mv_avail[i] = (mask & power) ? GTV_AVAILABLE : GTV_FORBIDDEN;
+               {
+                       if ( mask & power )
+                               mv_flags[i] |= GTV_AVAILABLE;
+                       else
+                               mv_flags[i] &= ~GTV_AVAILABLE;
+               }
        }
        else
        {
                for(i = 0; i < mv_num_maps; ++i )
-                       mv_avail[i] = ReadByte();
+                       mv_flags[i] = ReadByte();
        }
 }
 
-void MapVote_Init()
+void MapVote_ReadOption(int i)
+{
+       string map = strzone(ReadString());
+       string pk3 = strzone(ReadString());
+       int j = bound(0, ReadByte(), n_ssdirs - 1);
+
+       mv_maps[i] = map;
+       mv_pk3[i] = pk3;
+       mv_flags[i] = GTV_AVAILABLE;
+
+       string pic = strzone(strcat(ssdirs[j], "/", map));
+       mv_pics[i] = pic;
+       mv_preview[i] = false;
+       MapVote_CheckPic(pic, pk3, i);
+}
+
+void GameTypeVote_ReadOption(int i)
 {
-       int i, j;
-       string map, pk3, s;
+       string gt = strzone(ReadString());
+
+       mv_maps[i] = gt;
+       mv_flags[i] = ReadByte();
 
+       string mv_picpath = sprintf("gfx/menu/%s/gametype_%s", autocvar_menu_skin, gt);
+       if(precache_pic(mv_picpath) == "")
+               mv_picpath = strcat("gfx/menu/default/gametype_", gt);
+       string pic = strzone(mv_picpath);
+       mv_pics[i] = pic;
+       mv_preview[i] = PreviewExists(pic);
+
+       if ( mv_flags[i] & GTV_CUSTOM )
+       {
+               string name = ReadString();
+               if ( strlen(name) < 1 )
+                       name = gt;
+               mv_pk3[i] = strzone(name);
+               mv_desc[i] = strzone(ReadString());
+       }
+       else
+       {
+               int type = MapInfo_Type_FromString(gt);
+               mv_pk3[i] = strzone(MapInfo_Type_ToText(type));
+               mv_desc[i] = MapInfo_Type_Description(type);
+       }
+}
+
+void MapVote_Init()
+{
        precache_sound ("misc/invshot.wav");
 
        mv_active = 1;
@@ -488,6 +576,7 @@ void MapVote_Init()
        mv_selection = -1;
        mv_selection_keyboard = 0;
 
+       string s;
        for(n_ssdirs = 0; ; ++n_ssdirs)
        {
                s = ReadString();
@@ -538,8 +627,9 @@ void MapVote_Init()
        }
 
        MapVote_ReadMask();
+       int i;
        for(i = 0; i < mv_num_maps; ++i )
-               mv_avail_start[i] = mv_avail[i];
+               mv_flags_start[i] = mv_flags[i];
 
        // Assume mv_pk3list is world, there should only be 1 mapvote per round
        mv_pk3list = world; // I'm still paranoid!
@@ -548,32 +638,10 @@ void MapVote_Init()
        {
                mv_votes[i] = 0;
 
-               map = strzone(ReadString());
-               pk3 = strzone(ReadString());
-               j = bound(0, ReadByte(), n_ssdirs - 1);
-
-               mv_maps[i] = map;
-               mv_pk3[i] = pk3;
-               mv_avail[i] = ReadByte();
-
-               if(gametypevote)
-               {
-                       //map = strzone(strcat("gfx/menu/default/gametype_", map));
-                       //map = strzone(sprintf("gfx/menu/%s/gametype_%s", autocvar_menu_skin, map));
-                       string mv_picpath = sprintf("gfx/menu/%s/gametype_%s", autocvar_menu_skin, map);
-                       if(precache_pic(mv_picpath) == "")
-                               mv_picpath = strcat("gfx/menu/default/gametype_", map);
-                       map = strzone(mv_picpath);
-                       mv_pics[i] = map;
-                       mv_preview[i] = PreviewExists(map);
-               }
+               if ( gametypevote )
+                       GameTypeVote_ReadOption(i);
                else
-               {
-                       map = strzone(strcat(ssdirs[j], "/", map));
-                       mv_pics[i] = map;
-                       mv_preview[i] = false;
-                       MapVote_CheckPic(map, pk3, i);
-               }
+                       MapVote_ReadOption(i);
        }
 
        for(i = 0; i < n_ssdirs; ++i)
@@ -593,7 +661,7 @@ int MapVote_MoveLeft(int pos)
                imp = mv_num_maps - 1;
        else
                imp = pos < 1 ? mv_num_maps - 1 : pos - 1;
-       if ( mv_avail[imp] != GTV_AVAILABLE && imp != mv_ownvote )
+       if ( !(mv_flags[imp] & GTV_AVAILABLE) && imp != mv_ownvote )
                imp = MapVote_MoveLeft(imp);
        return imp;
 }
@@ -604,7 +672,7 @@ int MapVote_MoveRight(int pos)
                imp = 0;
        else
                imp = pos >= mv_num_maps - 1 ? 0 : pos + 1;
-       if ( mv_avail[imp] != GTV_AVAILABLE && imp != mv_ownvote )
+       if ( !(mv_flags[imp] & GTV_AVAILABLE) && imp != mv_ownvote )
                imp = MapVote_MoveRight(imp);
        return imp;
 }
@@ -623,7 +691,7 @@ int MapVote_MoveUp(int pos)
                                imp -= mv_columns;
                }
        }
-       if ( mv_avail[imp] != GTV_AVAILABLE && imp != mv_ownvote )
+       if ( !(mv_flags[imp] & GTV_AVAILABLE) && imp != mv_ownvote )
                imp = MapVote_MoveUp(imp);
        return imp;
 }
@@ -638,7 +706,7 @@ int MapVote_MoveDown(int pos)
                if ( imp >= mv_num_maps )
                        imp = imp % mv_columns;
        }
-       if ( mv_avail[imp] != GTV_AVAILABLE && imp != mv_ownvote )
+       if ( !(mv_flags[imp] & GTV_AVAILABLE) && imp != mv_ownvote )
                imp = MapVote_MoveDown(imp);
        return imp;
 }
@@ -731,7 +799,7 @@ void MapVote_UpdateVotes()
        int i;
        for(i = 0; i < mv_num_maps; ++i)
        {
-               if(mv_avail[i] == GTV_AVAILABLE)
+               if(mv_flags[i] & GTV_AVAILABLE)
                {
                        if(mv_detail)
                                mv_votes[i] = ReadByte();
index cb7b4c6..9c7086e 100644 (file)
@@ -2,81 +2,12 @@
 #define MAPVOTING_H
 
 #include "../common/constants.qh"
-
-int mv_num_maps;
-
-float mv_active;
-string mv_maps[MAPVOTE_COUNT];
-string mv_pics[MAPVOTE_COUNT];
-string mv_pk3[MAPVOTE_COUNT];
-float mv_preview[MAPVOTE_COUNT];
-float mv_votes[MAPVOTE_COUNT];
-float mv_avail[MAPVOTE_COUNT];
-float mv_avail_start[MAPVOTE_COUNT];
-entity mv_pk3list;
-float mv_abstain;
-float mv_ownvote;
-float mv_detail;
-float mv_timeout;
-float mv_top2_time;
-float mv_top2_alpha;
-
-vector mv_mousepos;
-int mv_selection;
-int mv_columns;
-int mv_mouse_selection;
-int mv_selection_keyboard;
-
-float gametypevote;
-string mapvote_chosenmap;
-vector gtv_text_size;
-vector gtv_text_size_small;
-
-string MapVote_FormatMapItem(int id, string map, float count, float maxwidth, vector fontsize);
-
-string GameTypeVote_DescriptionByID(int id);
-
-vector MapVote_RGB(int id);
-
-void GameTypeVote_DrawGameTypeItem(vector pos, float maxh, float tsize, string gtype, string pic, float count, int id);
-
-void MapVote_DrawMapItem(vector pos, float isize, float tsize, string map, string pic, float count, int id);
-
-void MapVote_DrawAbstain(vector pos, float isize, float tsize, float count, int id);
-
-vector MapVote_GridVec(vector gridspec, int i, int m);
-
-float MapVote_Selection(vector topleft, vector cellsize, float rows, float columns);
-
 void MapVote_Draw();
 
 void Cmd_MapVote_MapDownload(float argc);
 
-void MapVote_CheckPK3(string pic, string pk3, int id);
-
-void MapVote_CheckPic(string pic, string pk3, int id);
-
-void MapVote_ReadMask();
-
-const int NUM_SSDIRS = 4;
-string ssdirs[NUM_SSDIRS];
-int n_ssdirs;
-void MapVote_Init();
-
-void MapVote_SendChoice(float index);
-
-int MapVote_MoveLeft(int pos);
-int MapVote_MoveRight(int pos);
-int MapVote_MoveUp(int pos);
-
-int MapVote_MoveDown(int pos);
-
 float MapVote_InputEvent(float bInputType, float nPrimary, float nSecondary);
 
-void MapVote_UpdateMask();
-
-void MapVote_UpdateVotes();
-
 void Ent_MapVote();
 
 void Net_MapVote_Picture();
index f591268..92c1424 100644 (file)
 .float scale;
 .vector movedir;
 
+void Ent_Wall_PreDraw()
+{
+       if (self.inactive)
+       {
+               self.alpha = 0;
+       }
+       else
+       {
+               vector org = getpropertyvec(VF_ORIGIN);
+               if(!checkpvs(org, self))
+                       self.alpha = 0;
+               else if(self.fade_start || self.fade_end) {
+                       vector offset = '0 0 0';
+                       offset_z = self.fade_vertical_offset;
+                       float player_dist = vlen(org - self.origin - 0.5 * (self.mins + self.maxs) + offset);
+                       if (self.fade_end == self.fade_start)
+                       {
+                               if (player_dist >= self.fade_start)
+                                       self.alpha = 0;
+                               else
+                                       self.alpha = 1;
+                       }
+                       else
+                       {
+                               self.alpha = (self.alpha_min + self.alpha_max * bound(0,
+                                                          (self.fade_end - player_dist)
+                                                          / (self.fade_end - self.fade_start), 1)) / 100.0;
+                       }
+               }
+               else
+               {
+                       self.alpha = 1;
+               }
+       }
+       if(self.alpha <= 0)
+               self.drawmask = 0;
+       else
+               self.drawmask = MASK_NORMAL;
+}
+
 void Ent_Wall_Draw()
 {
        float f;
@@ -175,6 +215,12 @@ void Ent_Wall()
                        self.movedir_z = ReadCoord();
                        self.lip = ReadByte() / 255.0;
                }
+               self.fade_start = ReadShort();
+               self.fade_end = ReadShort();
+               self.alpha_max = ReadShort();
+               self.alpha_min = ReadShort();
+               self.inactive = ReadShort();
+               self.fade_vertical_offset = ReadShort();
                BGMScript_InitEntity(self);
        }
 
@@ -184,4 +230,5 @@ void Ent_Wall()
 
        self.entremove = Ent_Wall_Remove;
        self.draw = Ent_Wall_Draw;
+       self.predraw = Ent_Wall_PreDraw;
 }
index 57aef7e..04c0dce 100644 (file)
@@ -8,6 +8,14 @@ class(Wall) .int lodmodelindex0, lodmodelindex1, lodmodelindex2;
 class(Wall) .float loddistance1, loddistance2;
 class(Wall) .vector saved;
 
+// Needed for interactive clientwalls
+.float inactive; // Clientwall disappears when inactive
+.float alpha_max, alpha_min;
+// If fade_start > fade_end, fadeout will be inverted
+// fade_vertical_offset is a vertival offset for player position
+.float fade_start, fade_end, fade_vertical_offset;
+.float default_solid;
+
 void Ent_Wall_Draw();
 
 void Ent_Wall_Remove();
index 8ec5dbe..939c6d7 100644 (file)
@@ -361,8 +361,8 @@ const int URI_GET_UPDATENOTIFICATION = 33;
 const int URI_GET_URLLIB = 128;
 const int URI_GET_URLLIB_END = 191;
 
-// gametype votes
-const int GTV_AVAILABLE = 0;
-// for later use in per-map gametype filtering
-const int GTV_FORBIDDEN = 2;
+// gametype vote flags
+const int GTV_FORBIDDEN = 0; // Cannot be voted
+const int GTV_AVAILABLE = 1; // Can be voted
+const int GTV_CUSTOM    = 2; // Custom entry
 #endif
index 2c4f1de..93901a1 100644 (file)
@@ -1,3 +1,4 @@
+/** If you register a new item, make sure to add it to this list */
 #include "item/ammo.qc"
 #include "item/armor.qc"
 #include "item/buff.qc"
@@ -5,3 +6,4 @@
 #include "item/jetpack.qc"
 #include "item/pickup.qc"
 #include "item/powerup.qc"
+#include "../../server/mutators/mutator_instagib_items.qc"
index da4e7a4..354bed2 100644 (file)
@@ -11,6 +11,7 @@ ENDCLASS(GameItem)
 
 
 int ITEM_COUNT;
+/** If you register a new item, make sure to add it to all.inc */
 #define REGISTER_ITEM(id, class, body)          \
     entity ITEM_##id;                           \
     void RegisterItems_##id() {                 \
index 410c271..60ca3b1 100644 (file)
@@ -6,6 +6,36 @@
 
 #include "../server/miscfunctions.qh"
 
+// client side physics
+bool 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) & CVAR_TYPEFLAG_EXISTS)
+                       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) & CVAR_TYPEFLAG_EXISTS)
+                       return cvar(var);
+       }
+       return cvar(strcat("sv_", option));
+}
+
 void Physics_AddStats()
 {
        // static view offset and hitbox vectors
@@ -61,6 +91,27 @@ void Physics_AddStats()
        addstat(STAT_MOVEVARS_FRICTION_SLICK, AS_FLOAT, stat_sv_friction_slick);
        addstat(STAT_GAMEPLAYFIX_EASIERWATERJUMP, AS_INT, stat_gameplayfix_easierwaterjump);
 
+       // new properties
+       addstat(STAT_MOVEVARS_JUMPVELOCITY, AS_FLOAT, stat_sv_jumpvelocity);
+       addstat(STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, AS_FLOAT, stat_sv_airaccel_qw_stretchfactor);
+       addstat(STAT_MOVEVARS_MAXAIRSTRAFESPEED, AS_FLOAT, stat_sv_maxairstrafespeed);
+       addstat(STAT_MOVEVARS_MAXAIRSPEED, AS_FLOAT, stat_sv_maxairspeed);
+       addstat(STAT_MOVEVARS_AIRSTRAFEACCELERATE, AS_FLOAT, stat_sv_airstrafeaccelerate);
+       addstat(STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL, AS_FLOAT, stat_sv_warsowbunny_turnaccel);
+       addstat(STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, AS_FLOAT, stat_sv_airaccel_sideways_friction);
+       addstat(STAT_MOVEVARS_AIRCONTROL, AS_FLOAT, stat_sv_aircontrol);
+       addstat(STAT_MOVEVARS_AIRCONTROL_POWER, AS_FLOAT, stat_sv_aircontrol_power);
+       addstat(STAT_MOVEVARS_AIRCONTROL_PENALTY, AS_FLOAT, stat_sv_aircontrol_penalty);
+       addstat(STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, AS_FLOAT, stat_sv_warsowbunny_airforwardaccel);
+       addstat(STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED, AS_FLOAT, stat_sv_warsowbunny_topspeed);
+       addstat(STAT_MOVEVARS_WARSOWBUNNY_ACCEL, AS_FLOAT, stat_sv_warsowbunny_accel);
+       addstat(STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, AS_FLOAT, stat_sv_warsowbunny_backtosideratio);
+       addstat(STAT_MOVEVARS_FRICTION, AS_FLOAT, stat_sv_friction);
+       addstat(STAT_MOVEVARS_ACCELERATE, AS_FLOAT, stat_sv_accelerate);
+       addstat(STAT_MOVEVARS_STOPSPEED, AS_FLOAT, stat_sv_stopspeed);
+       addstat(STAT_MOVEVARS_AIRACCELERATE, AS_FLOAT, stat_sv_airaccelerate);
+       addstat(STAT_MOVEVARS_AIRSTOPACCELERATE, AS_FLOAT, stat_sv_airstopaccelerate);
+
        addstat(STAT_GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND, AS_INT, stat_gameplayfix_upvelocityclearsonground);
 }
 
@@ -75,13 +126,14 @@ void Physics_UpdateStats(float maxspd_mod)
        self.stat_pl_crouch_min = PL_CROUCH_MIN;
        self.stat_pl_crouch_max = PL_CROUCH_MAX;
 
-       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
        self.stat_movement_highspeed = PHYS_HIGHSPEED; // TODO: remove this!
 
        self.stat_doublejump = PHYS_DOUBLEJUMP;
@@ -102,6 +154,29 @@ void Physics_UpdateStats(float maxspd_mod)
 
        self.stat_gameplayfix_easierwaterjump = GAMEPLAYFIX_EASIERWATERJUMP;
 
+
+       // old stats
+       // 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");
+
        self.stat_gameplayfix_upvelocityclearsonground = UPWARD_VELOCITY_CLEARS_ONGROUND;
 }
 #endif
@@ -329,7 +404,7 @@ void CPM_PM_Aircontrol(vector wishdir, float wishspeed)
        if (k <= 0)
                return;
 
-       k *= bound(0, wishspeed / PHYS_MAXAIRSPEED, 1);
+       k *= bound(0, wishspeed / PHYS_MAXAIRSPEED(self), 1);
 
        float zspeed = self.velocity_z;
        self.velocity_z = 0;
@@ -1010,7 +1085,9 @@ void PM_check_spider(void)
        if (time >= self.spider_slowness)
                return;
        PHYS_MAXSPEED(self) *= 0.5; // half speed while slow from spider
-       self.stat_sv_airspeedlimit_nonqw *= 0.5;
+       PHYS_MAXAIRSPEED(self) *= 0.5;
+       PHYS_AIRSPEEDLIMIT_NONQW(self) *= 0.5;
+       PHYS_AIRSTRAFEACCELERATE(self) *= 0.5;
 #endif
 }
 
@@ -1293,7 +1370,7 @@ void PM_jetpack(float maxspd_mod)
        vector wishvel = v_forward * self.movement_x
                                        + v_right * self.movement_y;
        // add remaining speed as Z component
-       float maxairspd = PHYS_MAXAIRSPEED * max(1, maxspd_mod);
+       float maxairspd = PHYS_MAXAIRSPEED(self) * max(1, maxspd_mod);
        // fix speedhacks :P
        wishvel = normalize(wishvel) * min(1, vlen(wishvel) / maxairspd);
        // add the unused velocity as up component
@@ -1502,7 +1579,7 @@ void PM_air(float buttons_prev, float maxspd_mod)
        if (pmove_waterjumptime <= 0)
 #endif
        {
-               float maxairspd = PHYS_MAXAIRSPEED * min(maxspd_mod, 1);
+               float maxairspd = PHYS_MAXAIRSPEED(self) * min(maxspd_mod, 1);
 
                // apply air speed limit
                float airaccelqw = PHYS_AIRACCEL_QW(self);
@@ -1531,9 +1608,9 @@ void PM_air(float buttons_prev, float maxspd_mod)
                // log dv/dt = logaccel + logmaxspeed + log(1 - accelqw) (when fast)
                float strafity = IsMoveInDirection(self.movement, -90) + IsMoveInDirection(self.movement, +90); // if one is nonzero, other is always zero
                if (PHYS_MAXAIRSTRAFESPEED)
-                       wishspeed = min(wishspeed, GeomLerp(PHYS_MAXAIRSPEED*maxspd_mod, strafity, PHYS_MAXAIRSTRAFESPEED*maxspd_mod));
-               if (PHYS_AIRSTRAFEACCELERATE)
-                       airaccel = GeomLerp(airaccel, strafity, PHYS_AIRSTRAFEACCELERATE*maxspd_mod);
+                       wishspeed = min(wishspeed, GeomLerp(PHYS_MAXAIRSPEED(self)*maxspd_mod, strafity, PHYS_MAXAIRSTRAFESPEED*maxspd_mod));
+               if (PHYS_AIRSTRAFEACCELERATE(self))
+                       airaccel = GeomLerp(airaccel, strafity, PHYS_AIRSTRAFEACCELERATE(self)*maxspd_mod);
                if (PHYS_AIRSTRAFEACCEL_QW(self))
                        airaccelqw =
                (((strafity > 0.5 ? PHYS_AIRSTRAFEACCEL_QW(self) : PHYS_AIRACCEL_QW(self)) >= 0) ? +1 : -1)
@@ -1741,7 +1818,7 @@ void PM_Main()
                maxspeed_mod = self.spectatorspeed;
        }
 
-       float spd = max(PHYS_MAXSPEED(self), PHYS_MAXAIRSPEED) * maxspeed_mod;
+       float spd = max(PHYS_MAXSPEED(self), PHYS_MAXAIRSPEED(self)) * maxspeed_mod;
        if(self.speed != spd)
        {
                self.speed = spd;
index 599eee5..17de7b2 100644 (file)
@@ -135,7 +135,7 @@ bool IsFlying(entity a);
        #define PHYS_AIRSPEEDLIMIT_NONQW(s)                     getstatf(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW)
        #define PHYS_AIRSTOPACCELERATE                          getstatf(STAT_MOVEVARS_AIRSTOPACCELERATE)
        #define PHYS_AIRSTRAFEACCEL_QW(s)                       getstatf(STAT_MOVEVARS_AIRSTRAFEACCEL_QW)
-       #define PHYS_AIRSTRAFEACCELERATE                        getstatf(STAT_MOVEVARS_AIRSTRAFEACCELERATE)
+       #define PHYS_AIRSTRAFEACCELERATE(s)                     getstatf(STAT_MOVEVARS_AIRSTRAFEACCELERATE)
        #define PHYS_ENTGRAVITY(s)                                      getstatf(STAT_MOVEVARS_ENTGRAVITY)
        #define PHYS_FRICTION                                           getstatf(STAT_MOVEVARS_FRICTION)
        #define PHYS_FRICTION_SLICK                                     getstatf(STAT_MOVEVARS_FRICTION_SLICK)
@@ -143,7 +143,7 @@ bool IsFlying(entity a);
        #define PHYS_GRAVITY                                            getstatf(STAT_MOVEVARS_GRAVITY)
        #define PHYS_HIGHSPEED                                          getstatf(STAT_MOVEVARS_HIGHSPEED)
        #define PHYS_JUMPVELOCITY                                       getstatf(STAT_MOVEVARS_JUMPVELOCITY)
-       #define PHYS_MAXAIRSPEED                                        getstatf(STAT_MOVEVARS_MAXAIRSPEED)
+       #define PHYS_MAXAIRSPEED(s)                                     getstatf(STAT_MOVEVARS_MAXAIRSPEED)
        #define PHYS_MAXAIRSTRAFESPEED                          getstatf(STAT_MOVEVARS_MAXAIRSTRAFESPEED)
        #define PHYS_MAXSPEED(s)                                        getstatf(STAT_MOVEVARS_MAXSPEED)
        #define PHYS_STEPHEIGHT                                         getstatf(STAT_MOVEVARS_STEPHEIGHT)
@@ -170,6 +170,8 @@ bool IsFlying(entity a);
 
 #elif defined(SVQC)
 
+       bool Physics_Valid(string thecvar);
+
        .vector stat_pl_view_ofs;
        .vector stat_pl_crouch_view_ofs;
 
@@ -221,6 +223,27 @@ bool IsFlying(entity a);
        .float stat_bugrigs_reverse_spinning;
        .float stat_bugrigs_reverse_stopping;
 
+       // new properties
+       .float stat_sv_jumpvelocity;
+       .float stat_sv_airaccel_qw_stretchfactor;
+       .float stat_sv_maxairstrafespeed;
+       .float stat_sv_maxairspeed;
+       .float stat_sv_airstrafeaccelerate;
+       .float stat_sv_warsowbunny_turnaccel;
+       .float stat_sv_airaccel_sideways_friction;
+       .float stat_sv_aircontrol;
+       .float stat_sv_aircontrol_power;
+       .float stat_sv_aircontrol_penalty;
+       .float stat_sv_warsowbunny_airforwardaccel;
+       .float stat_sv_warsowbunny_topspeed;
+       .float stat_sv_warsowbunny_accel;
+       .float stat_sv_warsowbunny_backtosideratio;
+       .float stat_sv_friction;
+       .float stat_sv_accelerate;
+       .float stat_sv_stopspeed;
+       .float stat_sv_airaccelerate;
+       .float stat_sv_airstopaccelerate;
+
        .float stat_nostep;
        .float stat_jumpstep;
 
@@ -301,35 +324,35 @@ bool IsFlying(entity a);
        #define PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS       autocvar_sv_jumpspeedcap_max_disable_on_ramps
 
        #define PHYS_TRACK_CANJUMP(s)                           s.cvar_cl_movement_track_canjump
-       #define PHYS_ACCELERATE                                         autocvar_sv_accelerate
+       #define PHYS_ACCELERATE                                         self.stat_sv_accelerate
        #define PHYS_AIRACCEL_QW(s)                                     s.stat_sv_airaccel_qw
-       #define PHYS_AIRACCEL_QW_STRETCHFACTOR(s)       autocvar_sv_airaccel_qw_stretchfactor
-       #define PHYS_AIRACCEL_SIDEWAYS_FRICTION         autocvar_sv_airaccel_sideways_friction
-       #define PHYS_AIRACCELERATE                                      autocvar_sv_airaccelerate
-       #define PHYS_AIRCONTROL                                         autocvar_sv_aircontrol
-       #define PHYS_AIRCONTROL_PENALTY                         autocvar_sv_aircontrol_penalty
-       #define PHYS_AIRCONTROL_POWER                           autocvar_sv_aircontrol_power
+       #define PHYS_AIRACCEL_QW_STRETCHFACTOR(s)       self.stat_sv_airaccel_qw_stretchfactor
+       #define PHYS_AIRACCEL_SIDEWAYS_FRICTION         self.stat_sv_airaccel_sideways_friction
+       #define PHYS_AIRACCELERATE                                      self.stat_sv_airaccelerate
+       #define PHYS_AIRCONTROL                                         self.stat_sv_aircontrol
+       #define PHYS_AIRCONTROL_PENALTY                         self.stat_sv_aircontrol_penalty
+       #define PHYS_AIRCONTROL_POWER                           self.stat_sv_aircontrol_power
        #define PHYS_AIRSPEEDLIMIT_NONQW(s)                     s.stat_sv_airspeedlimit_nonqw
-       #define PHYS_AIRSTOPACCELERATE                          autocvar_sv_airstopaccelerate
+       #define PHYS_AIRSTOPACCELERATE                          self.stat_sv_airstopaccelerate
        #define PHYS_AIRSTRAFEACCEL_QW(s)                       s.stat_sv_airstrafeaccel_qw
-       #define PHYS_AIRSTRAFEACCELERATE                        autocvar_sv_airstrafeaccelerate
+       #define PHYS_AIRSTRAFEACCELERATE(s)                     s.stat_sv_airstrafeaccelerate
        #define PHYS_ENTGRAVITY(s)                                      s.gravity
-       #define PHYS_FRICTION                                           autocvar_sv_friction
+       #define PHYS_FRICTION                                           self.stat_sv_friction
        #define PHYS_FRICTION_SLICK                                     autocvar_sv_friction_slick
        #define PHYS_FRICTION_ONLAND                            autocvar_sv_friction_on_land
        #define PHYS_GRAVITY                                            autocvar_sv_gravity
        #define PHYS_HIGHSPEED                                          autocvar_g_movement_highspeed
-       #define PHYS_JUMPVELOCITY                                       autocvar_sv_jumpvelocity
-       #define PHYS_MAXAIRSPEED                                        autocvar_sv_maxairspeed
-       #define PHYS_MAXAIRSTRAFESPEED                          autocvar_sv_maxairstrafespeed
+       #define PHYS_JUMPVELOCITY                                       self.stat_sv_jumpvelocity
+       #define PHYS_MAXAIRSPEED(s)                                     self.stat_sv_maxairspeed
+       #define PHYS_MAXAIRSTRAFESPEED                          self.stat_sv_maxairstrafespeed
        #define PHYS_MAXSPEED(s)                                        s.stat_sv_maxspeed
        #define PHYS_STEPHEIGHT                                         autocvar_sv_stepheight
-       #define PHYS_STOPSPEED                                          autocvar_sv_stopspeed
-       #define PHYS_WARSOWBUNNY_ACCEL                          autocvar_sv_warsowbunny_accel
-       #define PHYS_WARSOWBUNNY_BACKTOSIDERATIO        autocvar_sv_warsowbunny_backtosideratio
-       #define PHYS_WARSOWBUNNY_AIRFORWARDACCEL        autocvar_sv_warsowbunny_airforwardaccel
-       #define PHYS_WARSOWBUNNY_TOPSPEED                       autocvar_sv_warsowbunny_topspeed
-       #define PHYS_WARSOWBUNNY_TURNACCEL                      autocvar_sv_warsowbunny_turnaccel
+       #define PHYS_STOPSPEED                                          self.stat_sv_stopspeed
+       #define PHYS_WARSOWBUNNY_ACCEL                          self.stat_sv_warsowbunny_accel
+       #define PHYS_WARSOWBUNNY_BACKTOSIDERATIO        self.stat_sv_warsowbunny_backtosideratio
+       #define PHYS_WARSOWBUNNY_AIRFORWARDACCEL        self.stat_sv_warsowbunny_airforwardaccel
+       #define PHYS_WARSOWBUNNY_TOPSPEED                       self.stat_sv_warsowbunny_topspeed
+       #define PHYS_WARSOWBUNNY_TURNACCEL                      self.stat_sv_warsowbunny_turnaccel
 
        #define PHYS_WALLFRICTION                                       cvar("sv_wallfriction")
 
index da03017..1e7715a 100644 (file)
@@ -209,6 +209,9 @@ void SUB_UseTargets()
                }
                if (s != "")
                {
+                       // Flag to set func_clientwall state
+                       // 1 == deactivate, 2 == activate, 0 == do nothing
+                       float aw_flag = self.antiwall_flag;
                        for(t = world; (t = find(t, targetname, s)); )
                        if(t.use)
                        {
@@ -218,6 +221,8 @@ void SUB_UseTargets()
                                }
                                else
                                {
+                                       if (t.classname == "func_clientwall" || t.classname == "func_clientillusionary")
+                                               t.antiwall_flag = aw_flag;
                                        self = t;
                                        other = stemp;
                                        activator = act;
index 3baff30..474f797 100644 (file)
@@ -10,6 +10,9 @@ const float   SPAWNFLAG_NOTOUCH = 1;
 
 .void() trigger_touch;
 
+.float antiwall_flag; // Variable to define what to do with func_clientwall
+// 0 == do nothing, 1 == deactivate, 2 == activate
+
 .float height;
 
 .float nottargeted;
index 216b575..a50fb4c 100644 (file)
@@ -665,20 +665,20 @@ float updateCompression()
 
 // note: include only those that should be in the menu!
 #define GAMETYPES \
-       GAMETYPE(MAPINFO_TYPE_ASSAULT) \
+       GAMETYPE(MAPINFO_TYPE_DEATHMATCH) \
+       GAMETYPE(MAPINFO_TYPE_TEAM_DEATHMATCH) \
        GAMETYPE(MAPINFO_TYPE_CTF) \
        GAMETYPE(MAPINFO_TYPE_CA) \
-       GAMETYPE(MAPINFO_TYPE_DEATHMATCH) \
-       GAMETYPE(MAPINFO_TYPE_DOMINATION) \
        GAMETYPE(MAPINFO_TYPE_FREEZETAG) \
        GAMETYPE(MAPINFO_TYPE_KEEPAWAY) \
        GAMETYPE(MAPINFO_TYPE_KEYHUNT) \
        GAMETYPE(MAPINFO_TYPE_LMS) \
+       GAMETYPE(MAPINFO_TYPE_DOMINATION) \
        GAMETYPE(MAPINFO_TYPE_NEXBALL) \
        GAMETYPE(MAPINFO_TYPE_ONSLAUGHT) \
+       GAMETYPE(MAPINFO_TYPE_ASSAULT) \
        if (cvar("developer")) GAMETYPE(MAPINFO_TYPE_RACE) \
        GAMETYPE(MAPINFO_TYPE_CTS) \
-       GAMETYPE(MAPINFO_TYPE_TEAM_DEATHMATCH) \
        //GAMETYPE(MAPINFO_TYPE_INVASION) \
        /* nothing */
 
index 58ce4f3..51b14aa 100644 (file)
@@ -585,20 +585,8 @@ float autocvar_skill_auto;
 float autocvar_snd_soundradius;
 int autocvar_spawn_debug;
 bool autocvar_speedmeter;
-float autocvar_sv_accelerate;
 float autocvar_sv_accuracy_data_share = 1;
 string autocvar_sv_adminnick;
-float autocvar_sv_airaccel_qw;
-float autocvar_sv_airaccel_qw_stretchfactor;
-float autocvar_sv_airaccel_sideways_friction;
-float autocvar_sv_airaccelerate;
-float autocvar_sv_aircontrol;
-float autocvar_sv_aircontrol_penalty;
-float autocvar_sv_aircontrol_power;
-float autocvar_sv_airspeedlimit_nonqw;
-float autocvar_sv_airstopaccelerate;
-float autocvar_sv_airstrafeaccel_qw;
-float autocvar_sv_airstrafeaccelerate;
 bool autocvar_sv_autoscreenshot;
 int autocvar_sv_cheats;
 float autocvar_sv_clientcommand_antispam_time;
@@ -632,7 +620,6 @@ int autocvar_sv_eventlog_files_counter;
 string autocvar_sv_eventlog_files_nameprefix;
 string autocvar_sv_eventlog_files_namesuffix;
 bool autocvar_sv_eventlog_files_timestamps;
-float autocvar_sv_friction;
 float autocvar_sv_friction_on_land;
 var float autocvar_sv_friction_slick = 0.5;
 float autocvar_sv_gameplayfix_q2airaccelerate;
@@ -649,7 +636,6 @@ bool autocvar_sv_logscores_file;
 string autocvar_sv_logscores_filename;
 float autocvar_sv_mapchange_delay;
 float autocvar_sv_maxairspeed;
-float autocvar_sv_maxairstrafespeed;
 float autocvar_sv_maxspeed;
 string autocvar_sv_motd;
 bool autocvar_sv_precacheplayermodels;
@@ -663,7 +649,6 @@ int autocvar_sv_spectate;
 float autocvar_sv_spectator_speed_multiplier;
 bool autocvar_sv_status_privacy;
 float autocvar_sv_stepheight;
-float autocvar_sv_stopspeed;
 float autocvar_sv_strengthsound_antispam_refire_threshold;
 float autocvar_sv_strengthsound_antispam_time;
 bool autocvar_sv_teamnagger;
@@ -697,11 +682,6 @@ float autocvar_sv_vote_stop;
 float autocvar_sv_vote_timeout;
 float autocvar_sv_vote_wait;
 bool autocvar_sv_vote_gamestart;
-float autocvar_sv_warsowbunny_accel;
-float autocvar_sv_warsowbunny_airforwardaccel;
-float autocvar_sv_warsowbunny_backtosideratio;
-float autocvar_sv_warsowbunny_topspeed;
-float autocvar_sv_warsowbunny_turnaccel;
 float autocvar_sv_waypointsprite_deadlifetime;
 float autocvar_sv_waypointsprite_deployed_lifetime;
 float autocvar_sv_waypointsprite_limitedrange;
@@ -856,6 +836,9 @@ float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay;
 float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death;
 int autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health;
 bool autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath;
+bool autocvar_g_physics_clientselect;
+string autocvar_g_physics_clientselect_options;
+string autocvar_g_physics_clientselect_default;
 float autocvar_g_buffs_waypoint_distance;
 bool autocvar_g_buffs_randomize;
 float autocvar_g_buffs_random_lifetime;
diff --git a/qcsrc/server/cl_physics.qc b/qcsrc/server/cl_physics.qc
deleted file mode 100644 (file)
index 67c57ae..0000000
+++ /dev/null
@@ -1,1344 +0,0 @@
-#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;
-
-.float ladder_time;
-.entity ladder_entity;
-.float gravity;
-.float swamp_slowdown;
-.int lastflags;
-.float lastground;
-.float wasFlying;
-.float spectatorspeed;
-
-/*
-=============
-PlayerJump
-
-When you press the jump key
-returns true if handled
-=============
-*/
-float PlayerJump (void)
-{
-       if(self.frozen)
-               return true; // no jumping in freezetag when frozen
-
-       if(self.player_blocked)
-               return true; // no jumping while blocked
-
-       float doublejump = false;
-       float mjumpheight = autocvar_sv_jumpvelocity;
-
-       player_multijump = doublejump;
-       player_jumpheight = mjumpheight;
-       if(MUTATOR_CALLHOOK(PlayerJump))
-               return true;
-
-       doublejump = player_multijump;
-       mjumpheight = player_jumpheight;
-
-       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)
-               {
-                       doublejump = true;
-
-                       // we MUST clip velocity here!
-                       float f;
-                       f = self.velocity * trace_plane_normal;
-                       if(f < 0)
-                               self.velocity -= f * trace_plane_normal;
-               }
-       }
-
-       if (self.waterlevel >= WATERLEVEL_SWIMMING)
-       {
-               self.velocity_z = self.stat_sv_maxspeed * 0.7;
-               return true;
-       }
-
-       if (!doublejump)
-               if (!(self.flags & FL_ONGROUND))
-                       return !(self.flags & FL_JUMPRELEASED);
-
-       if(self.cvar_cl_movement_track_canjump)
-               if (!(self.flags & FL_JUMPRELEASED))
-                       return true;
-
-       // sv_jumpspeedcap_min/sv_jumpspeedcap_max act as baseline
-       // velocity bounds.  Final velocity is bound between (jumpheight *
-       // min + jumpheight) and (jumpheight * max + jumpheight);
-
-       if(autocvar_sv_jumpspeedcap_min != "")
-       {
-               float minjumpspeed;
-
-               minjumpspeed = mjumpheight * stof(autocvar_sv_jumpspeedcap_min);
-
-               if (self.velocity.z < minjumpspeed)
-                       mjumpheight += minjumpspeed - self.velocity.z;
-       }
-
-       if(autocvar_sv_jumpspeedcap_max != "")
-       {
-               // 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))
-               {
-                       float maxjumpspeed;
-
-                       maxjumpspeed = mjumpheight * stof(autocvar_sv_jumpspeedcap_max);
-
-                       if (self.velocity.z > maxjumpspeed)
-                               mjumpheight -= self.velocity.z - maxjumpspeed;
-               }
-       }
-
-       if(!(self.lastflags & FL_ONGROUND))
-       {
-               if(autocvar_speedmeter)
-                       dprint(strcat("landing velocity: ", vtos(self.velocity), " (abs: ", ftos(vlen(self.velocity)), ")\n"));
-               if(self.lastground < time - 0.3)
-               {
-                       self.velocity_x *= (1 - autocvar_sv_friction_on_land);
-                       self.velocity_y *= (1 - autocvar_sv_friction_on_land);
-               }
-               if(self.jumppadcount > 1)
-                       dprint(strcat(ftos(self.jumppadcount), "x jumppad combo\n"));
-               self.jumppadcount = 0;
-       }
-
-       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);
-
-       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;
-}
-void CheckWaterJump()
-{
-       vector start, end;
-
-// check for a jump-out-of-water
-       makevectors (self.angles);
-       start = self.origin;
-       start.z = start.z + 8;
-       v_forward.z = 0;
-       normalize(v_forward);
-       end = start + v_forward*24;
-       traceline (start, end, true, self);
-       if (trace_fraction < 1)
-       {       // solid at waist
-               start.z = start.z + self.maxs.z - 8;
-               end = start + v_forward*24;
-               self.movedir = trace_plane_normal * -50;
-               traceline (start, end, true, self);
-               if (trace_fraction == 1)
-               {       // open at eye level
-                       self.flags |= FL_WATERJUMP;
-                       self.velocity_z = 225;
-                       self.flags &= ~FL_JUMPRELEASED;
-                       self.teleport_time = time + 2;  // safety net
-                       return;
-               }
-       }
-}
-
-.float jetpack_stopped;
-// Hack: shouldn't need to know about this
-.float multijump_count;
-void CheckPlayerJump()
-{
-       float was_flying = self.items & IT_USING_JETPACK;
-
-       if (self.cvar_cl_jetpack_jump < 2)
-               self.items &= ~IT_USING_JETPACK;
-
-       if (self.BUTTON_JUMP || self.BUTTON_JETPACK)
-       {
-               float air_jump = !PlayerJump() || self.multijump_count > 0; // PlayerJump() has important side effects
-               float activate = self.cvar_cl_jetpack_jump && air_jump && self.BUTTON_JUMP || self.BUTTON_JETPACK;
-               float has_fuel = !autocvar_g_jetpack_fuel || self.ammo_fuel || self.items & IT_UNLIMITED_WEAPON_AMMO;
-               if (!(self.items & IT_JETPACK)) { }
-               else if (self.jetpack_stopped) { }
-               else if (!has_fuel)
-               {
-                       if (was_flying) // TODO: ran out of fuel message
-                               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.items &= ~IT_USING_JETPACK;
-               }
-               else if (activate && !self.frozen)
-                       self.items |= IT_USING_JETPACK;
-       }
-       else
-       {
-               self.jetpack_stopped = false;
-               self.items &= ~IT_USING_JETPACK;
-       }
-       if (!self.BUTTON_JUMP)
-               self.flags |= FL_JUMPRELEASED;
-
-       if (self.waterlevel == WATERLEVEL_SWIMMING)
-               CheckWaterJump ();
-}
-
-float racecar_angle(float forward, float down)
-{
-       float ret, angle_mult;
-
-       if(forward < 0)
-       {
-               forward = -forward;
-               down = -down;
-       }
-
-       ret = vectoyaw('0 1 0' * down + '1 0 0' * forward);
-
-       angle_mult = forward / (800 + forward);
-
-       if(ret > 180)
-               return ret * angle_mult + 360 * (1 - angle_mult);
-       else
-               return ret * angle_mult;
-}
-
-void RaceCarPhysics()
-{
-       // using this move type for "big rigs"
-       // the engine does not push the entity!
-
-       float accel, steer, f, myspeed, steerfactor;
-       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);
-
-       if(g_bugrigs_reverse_speeding)
-       {
-               if(accel < 0)
-               {
-                       // back accel is DIGITAL
-                       // to prevent speedhack
-                       if(accel < -0.5)
-                               accel = -1;
-                       else
-                               accel = 0;
-               }
-       }
-
-       self.angles_x = 0;
-       self.angles_z = 0;
-       makevectors(self.angles); // new forward direction!
-
-       if(self.flags & FL_ONGROUND || g_bugrigs_air_steering)
-       {
-               float upspeed, accelfactor;
-
-               myspeed = self.velocity * v_forward;
-               upspeed = self.velocity * v_up;
-
-               // responsiveness factor for steering and acceleration
-               f = 1 / (1 + pow(max(-myspeed, myspeed) / g_bugrigs_speed_ref, g_bugrigs_speed_pow));
-               //MAXIMA: f(v) := 1 / (1 + (v / g_bugrigs_speed_ref) ^ g_bugrigs_speed_pow);
-
-               if(myspeed < 0 && g_bugrigs_reverse_spinning)
-                       steerfactor = -myspeed * g_bugrigs_steer;
-               else
-                       steerfactor = -myspeed * f * g_bugrigs_steer;
-
-               if(myspeed < 0 && g_bugrigs_reverse_speeding)
-                       accelfactor = g_bugrigs_accel;
-               else
-                       accelfactor = f * g_bugrigs_accel;
-               //MAXIMA: accel(v) := f(v) * g_bugrigs_accel;
-
-               if(accel < 0)
-               {
-                       if(myspeed > 0)
-                       {
-                               myspeed = max(0, myspeed - frametime * (g_bugrigs_friction_floor - g_bugrigs_friction_brake * accel));
-                       }
-                       else
-                       {
-                               if(!g_bugrigs_reverse_speeding)
-                                       myspeed = min(0, myspeed + frametime * g_bugrigs_friction_floor);
-                       }
-               }
-               else
-               {
-                       if(myspeed >= 0)
-                       {
-                               myspeed = max(0, myspeed - frametime * g_bugrigs_friction_floor);
-                       }
-                       else
-                       {
-                               if(g_bugrigs_reverse_stopping)
-                                       myspeed = 0;
-                               else
-                                       myspeed = min(0, myspeed + frametime * (g_bugrigs_friction_floor + g_bugrigs_friction_brake * accel));
-                       }
-               }
-               // terminal velocity = velocity at which 50 == accelfactor, that is, 1549 units/sec
-               //MAXIMA: friction(v) := g_bugrigs_friction_floor;
-
-               self.angles_y += steer * frametime * steerfactor; // apply steering
-               makevectors(self.angles); // new forward direction!
-
-               myspeed += accel * accelfactor * frametime;
-
-               rigvel = myspeed * v_forward + '0 0 1' * upspeed;
-       }
-       else
-       {
-               myspeed = vlen(self.velocity);
-
-               // responsiveness factor for steering and acceleration
-               f = 1 / (1 + pow(max(0, myspeed / g_bugrigs_speed_ref), g_bugrigs_speed_pow));
-               steerfactor = -myspeed * f;
-               self.angles_y += steer * frametime * steerfactor; // apply steering
-
-               rigvel = self.velocity;
-               makevectors(self.angles); // new forward direction!
-       }
-
-       rigvel = rigvel * max(0, 1 - vlen(rigvel) * g_bugrigs_friction_air * frametime);
-       //MAXIMA: airfriction(v) := v * v * g_bugrigs_friction_air;
-       //MAXIMA: total_acceleration(v) := accel(v) - friction(v) - airfriction(v);
-       //MAXIMA: solve(total_acceleration(v) = 0, v);
-
-       if(g_bugrigs_planar_movement)
-       {
-               vector rigvel_xy, neworigin, up;
-               float mt;
-
-               rigvel.z -= frametime * autocvar_sv_gravity; // 4x gravity plays better
-               rigvel_xy = vec2(rigvel);
-
-               if(g_bugrigs_planar_movement_car_jumping)
-                       mt = MOVE_NORMAL;
-               else
-                       mt = MOVE_NOMONSTERS;
-
-               tracebox(self.origin, self.mins, self.maxs, self.origin + '0 0 1024', mt, self);
-               up = trace_endpos - self.origin;
-
-               // BUG RIGS: align the move to the surface instead of doing collision testing
-               // can we move?
-               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);
-
-               if(trace_fraction < 0.5)
-               {
-                       trace_fraction = 1;
-                       neworigin = self.origin;
-               }
-               else
-                       neworigin = trace_endpos;
-
-               if(trace_fraction < 1)
-               {
-                       // 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
-                                       +
-                                       '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)
-                                       );
-                       self.flags |= FL_ONGROUND;
-               }
-               else
-               {
-                       // now set angles_x so that the car points forward, but is tilted in velocity direction
-                       self.flags &= ~FL_ONGROUND;
-               }
-
-               self.velocity = (neworigin - self.origin) * (1.0 / frametime);
-               self.movetype = MOVETYPE_NOCLIP;
-       }
-       else
-       {
-               rigvel.z -= frametime * autocvar_sv_gravity; // 4x gravity plays better
-               self.velocity = rigvel;
-               self.movetype = MOVETYPE_FLY;
-       }
-
-       trace_fraction = 1;
-       tracebox(self.origin, self.mins, self.maxs, self.origin - '0 0 4', MOVE_NORMAL, self);
-       if(trace_fraction != 1)
-       {
-               self.angles = vectoangles2(
-                               '1 0 0' * v_forward.x * 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),
-                               trace_plane_normal
-                               );
-       }
-       else
-       {
-               vector vel_local;
-
-               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);
-       }
-
-       // smooth the angles
-       vector vf1, vu1, smoothangles;
-       makevectors(self.angles);
-       f = bound(0, frametime * g_bugrigs_angle_smoothing, 1);
-       if(f == 0)
-               f = 1;
-       vf1 = v_forward * f;
-       vu1 = v_up * f;
-       makevectors(angles_save);
-       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;
-}
-
-float IsMoveInDirection(vector mv, float angle) // key mix factor
-{
-       if(mv.x == 0 && mv.y == 0)
-               return 0; // avoid division by zero
-       angle -= RAD2DEG * atan2(mv.y, mv.x);
-       angle = remainder(angle, 360) / 45;
-       if(angle >  1)
-               return 0;
-       if(angle < -1)
-               return 0;
-       return 1 - fabs(angle);
-}
-
-float GeomLerp(float a, float lerp, float b)
-{
-       if(a == 0)
-       {
-               if(lerp < 1)
-                       return 0;
-               else
-                       return b;
-       }
-       if(b == 0)
-       {
-               if(lerp > 0)
-                       return 0;
-               else
-                       return a;
-       }
-       return a * pow(fabs(b / a), lerp);
-}
-
-void CPM_PM_Aircontrol(vector wishdir, float wishspeed)
-{
-       float zspeed, xyspeed, dot, k;
-
-#if 0
-       // this doesn't play well with analog input
-       if(self.movement_x == 0 || self.movement.y != 0)
-               return; // can't control movement if not moving forward or backward
-       k = 32;
-#else
-       k = 32 * (2 * IsMoveInDirection(self.movement, 0) - 1);
-       if(k <= 0)
-               return;
-#endif
-
-       k *= bound(0, wishspeed / autocvar_sv_maxairspeed, 1);
-
-       zspeed = self.velocity.z;
-       self.velocity_z = 0;
-       xyspeed = vlen(self.velocity); self.velocity = normalize(self.velocity);
-
-       dot = self.velocity * wishdir;
-
-       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;
-               self.velocity = normalize(self.velocity * xyspeed + wishdir * k);
-       }
-
-       self.velocity = self.velocity * xyspeed;
-       self.velocity_z = zspeed;
-}
-
-float AdjustAirAccelQW(float accelqw, float factor)
-{
-       return copysign(bound(0.000001, 1 - (1 - fabs(accelqw)) * factor, 1), accelqw);
-}
-
-// example config for alternate speed clamping:
-//   sv_airaccel_qw 0.8
-//   sv_airaccel_sideways_friction 0
-//   prvm_globalset server speedclamp_mode 1
-//     (or 2)
-void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float accel, float accelqw, float stretchfactor, float sidefric, float speedlimit)
-{
-       float vel_straight;
-       float velZ;
-       vector vel_perpend;
-       float step;
-
-       vector vel_xy;
-       float vel_xy_current;
-       float vel_xy_backward, vel_xy_forward;
-       float speedclamp;
-
-       if(stretchfactor > 0)
-               speedclamp = stretchfactor;
-       else if(accelqw < 0)
-               speedclamp = 1; // full clamping, no stretch
-       else
-               speedclamp = -1; // no clamping
-
-       if(accelqw < 0)
-               accelqw = -accelqw;
-
-       if(autocvar_sv_gameplayfix_q2airaccelerate)
-               wishspeed0 = wishspeed;
-
-       vel_straight = self.velocity * wishdir;
-       velZ = self.velocity.z;
-       vel_xy = vec2(self.velocity);
-       vel_perpend = vel_xy - vel_straight * wishdir;
-
-       step = accel * frametime * wishspeed0;
-
-       vel_xy_current  = vlen(vel_xy);
-       if(speedlimit)
-               accelqw = AdjustAirAccelQW(accelqw, (speedlimit - bound(wishspeed, vel_xy_current, speedlimit)) / max(1, speedlimit - wishspeed));
-       vel_xy_forward  = vel_xy_current + bound(0, wishspeed - vel_xy_current, step) * accelqw + step * (1 - accelqw);
-       vel_xy_backward = vel_xy_current - bound(0, wishspeed + vel_xy_current, step) * accelqw - step * (1 - accelqw);
-       if(vel_xy_backward < 0)
-               vel_xy_backward = 0; // not that it REALLY occurs that this would cause wrong behaviour afterwards
-
-       vel_straight = vel_straight + bound(0, wishspeed - vel_straight, step) * accelqw + step * (1 - accelqw);
-
-       if(sidefric < 0 && (vel_perpend*vel_perpend))
-               // negative: only apply so much sideways friction to stay below the speed you could get by "braking"
-       {
-               float f, fminimum;
-               f = max(0, 1 + frametime * wishspeed * sidefric);
-               fminimum = (vel_xy_backward*vel_xy_backward - vel_straight*vel_straight) / (vel_perpend*vel_perpend);
-               // this cannot be > 1
-               if(fminimum <= 0)
-                       vel_perpend = vel_perpend * max(0, f);
-               else
-               {
-                       fminimum = sqrt(fminimum);
-                       vel_perpend = vel_perpend * max(fminimum, f);
-               }
-       }
-       else
-               vel_perpend = vel_perpend * max(0, 1 - frametime * wishspeed * sidefric);
-
-       vel_xy = vel_straight * wishdir + vel_perpend;
-
-       if(speedclamp >= 0)
-       {
-               float vel_xy_preclamp;
-               vel_xy_preclamp = vlen(vel_xy);
-               if(vel_xy_preclamp > 0) // prevent division by zero
-               {
-                       vel_xy_current += (vel_xy_forward - vel_xy_current) * speedclamp;
-                       if(vel_xy_current < vel_xy_preclamp)
-                               vel_xy = vel_xy * (vel_xy_current / vel_xy_preclamp);
-               }
-       }
-
-       self.velocity = vel_xy + velZ * '0 0 1';
-}
-
-void PM_AirAccelerate(vector wishdir, float wishspeed)
-{
-       vector curvel, wishvel, acceldir, curdir;
-       float addspeed, accelspeed, curspeed, f;
-       float dot;
-
-       if(wishspeed == 0)
-               return;
-
-       curvel = self.velocity;
-       curvel.z = 0;
-       curspeed = vlen(curvel);
-
-       if(wishspeed > curspeed * 1.01)
-       {
-               wishspeed = min(wishspeed, curspeed + autocvar_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;
-       }
-       wishvel = wishdir * wishspeed;
-       acceldir = wishvel - curvel;
-       addspeed = vlen(acceldir);
-       acceldir = normalize(acceldir);
-
-       accelspeed = min(addspeed, autocvar_sv_warsowbunny_turnaccel * self.stat_sv_maxspeed * frametime);
-
-       if(autocvar_sv_warsowbunny_backtosideratio < 1)
-       {
-               curdir = normalize(curvel);
-               dot = acceldir * curdir;
-               if(dot < 0)
-                       acceldir = acceldir - (1 - autocvar_sv_warsowbunny_backtosideratio) * dot * curdir;
-       }
-
-       self.velocity += accelspeed * acceldir;
-}
-
-.vector movement_old;
-.float buttons_old;
-.vector v_angle_old;
-.string lastclassname;
-
-.float() PlayerPhysplug;
-
-string specialcommand = "xwxwxsxsxaxdxaxdx1x ";
-.float specialcommand_pos;
-void SpecialCommand()
-{
-#ifdef TETRIS
-       TetrisImpulse();
-#else
-       if(!CheatImpulse(99))
-               print("A hollow voice says \"Plugh\".\n");
-#endif
-}
-
-string GetMapname(void);
-float speedaward_lastupdate;
-float speedaward_lastsent;
-void SV_PlayerPhysics()
-{
-       vector wishvel, wishdir, v;
-       float wishspeed, f, maxspd_mod, spd, maxairspd, airaccel, swampspd_mod, buttons;
-       string temps;
-       int buttons_prev;
-       float not_allowed_to_move;
-       string c;
-
-       WarpZone_PlayerPhysics_FixVAngle();
-
-       maxspd_mod = 1;
-       if(self.ballcarried)
-               if(g_keepaway)
-                       maxspd_mod *= autocvar_g_keepaway_ballcarrier_highspeed;
-
-       maxspd_mod *= autocvar_g_movement_highspeed;
-
-       // 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);
-       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
-
-    if(self.PlayerPhysplug)
-        if(self.PlayerPhysplug())
-            return;
-
-       self.race_movetime_frac += frametime;
-       f = floor(self.race_movetime_frac);
-       self.race_movetime_frac -= f;
-       self.race_movetime_count += f;
-       self.race_movetime = self.race_movetime_frac + self.race_movetime_count;
-
-       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);
-
-       if(!buttons)
-               c = "x";
-       else if(buttons == 1)
-               c = "1";
-       else if(buttons == 2)
-               c = " ";
-       else if(buttons == 128)
-               c = "s";
-       else if(buttons == 256)
-               c = "w";
-       else if(buttons == 512)
-               c = "a";
-       else if(buttons == 1024)
-               c = "d";
-       else
-               c = "?";
-
-       if(c == substring(specialcommand, self.specialcommand_pos, 1))
-       {
-               self.specialcommand_pos += 1;
-               if(self.specialcommand_pos >= strlen(specialcommand))
-               {
-                       self.specialcommand_pos = 0;
-                       SpecialCommand();
-                       return;
-               }
-       }
-       else if(self.specialcommand_pos && (c != substring(specialcommand, self.specialcommand_pos - 1, 1)))
-               self.specialcommand_pos = 0;
-
-       if(sv_maxidle > 0)
-       {
-               if(buttons != self.buttons_old || self.movement != self.movement_old || self.v_angle != self.v_angle_old)
-                       self.parm_idlesince = time;
-       }
-       buttons_prev = self.buttons_old;
-       self.buttons_old = buttons;
-       self.movement_old = self.movement;
-       self.v_angle_old = self.v_angle;
-
-       if(time < self.nickspamtime)
-       if(self.nickspamcount >= autocvar_g_nick_flood_penalty_yellow)
-       {
-               // slight annoyance for nick change scripts
-               self.movement = -1 * self.movement;
-               self.BUTTON_ATCK = self.BUTTON_JUMP = self.BUTTON_ATCK2 = self.BUTTON_ZOOM = self.BUTTON_CROUCH = self.BUTTON_HOOK = self.BUTTON_USE = 0;
-
-               if(self.nickspamcount >= autocvar_g_nick_flood_penalty_red) // if you are persistent and the slight annoyance above does not stop you, I'll show you!
-               {
-                       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;
-               }
-       }
-
-       if (self.punchangle != '0 0 0')
-       {
-               f = vlen(self.punchangle) - 10 * frametime;
-               if (f > 0)
-                       self.punchangle = normalize(self.punchangle) * f;
-               else
-                       self.punchangle = '0 0 0';
-       }
-
-       if (self.punchvector != '0 0 0')
-       {
-               f = vlen(self.punchvector) - 30 * frametime;
-               if (f > 0)
-                       self.punchvector = normalize(self.punchvector) * f;
-               else
-                       self.punchvector = '0 0 0';
-       }
-
-       if (IS_BOT_CLIENT(self))
-       {
-               if(playerdemo_read())
-                       return;
-               bot_think();
-       }
-
-       if(IS_PLAYER(self))
-       {
-               if(self.race_penalty)
-                       if(time > self.race_penalty)
-                               self.race_penalty = 0;
-
-               not_allowed_to_move = 0;
-               if(self.race_penalty)
-                       not_allowed_to_move = 1;
-               if(time < game_starttime)
-                       not_allowed_to_move = 1;
-
-               if(not_allowed_to_move)
-               {
-                       self.velocity = '0 0 0';
-                       self.movetype = MOVETYPE_NONE;
-                       self.disableclientprediction = 2;
-               }
-               else if(self.disableclientprediction == 2)
-               {
-                       if(self.movetype == MOVETYPE_NONE)
-                               self.movetype = MOVETYPE_WALK;
-                       self.disableclientprediction = 0;
-               }
-       }
-
-       if (self.movetype == MOVETYPE_NONE)
-               return;
-
-       // when we get here, disableclientprediction cannot be 2
-       self.disableclientprediction = 0;
-       if(time < self.ladder_time)
-               self.disableclientprediction = 1;
-
-       if(time < self.spider_slowness)
-       {
-               self.stat_sv_maxspeed *= 0.5; // half speed while slow from spider
-               self.stat_sv_airspeedlimit_nonqw *= 0.5;
-       }
-
-       if(self.frozen)
-       {
-               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);
-               }
-               else
-                       self.movement = '0 0 0';
-               self.disableclientprediction = 1;
-
-               vector midpoint = ((self.absmin + self.absmax) * 0.5);
-               if(pointcontents(midpoint) == CONTENT_WATER)
-               {
-                       self.velocity = self.velocity * 0.5;
-
-                       if(pointcontents(midpoint + '0 0 16') == CONTENT_WATER)
-                               { self.velocity_z = 200; }
-               }
-       }
-
-       MUTATOR_CALLHOOK(PlayerPhysics);
-
-       if(self.player_blocked)
-       {
-               self.movement = '0 0 0';
-               self.disableclientprediction = 1;
-       }
-
-       maxspd_mod = 1;
-
-       swampspd_mod = 1;
-       if(self.in_swamp) {
-               swampspd_mod = self.swamp_slowdown; //cvar("g_balance_swamp_moverate");
-       }
-
-       // conveyors: first fix velocity
-       if(self.conveyor.state)
-               self.velocity -= self.conveyor.movedir;
-
-       if (!IS_PLAYER(self))
-       {
-               maxspd_mod = autocvar_sv_spectator_speed_multiplier;
-               if(!self.spectatorspeed)
-                       self.spectatorspeed = maxspd_mod;
-               if(self.impulse && self.impulse <= 19 || (self.impulse >= 200 && self.impulse <= 209) || (self.impulse >= 220 && self.impulse <= 229))
-               {
-                       if(self.lastclassname != "player")
-                       {
-                               if(self.impulse == 10 || self.impulse == 15 || self.impulse == 18 || (self.impulse >= 200 && self.impulse <= 209))
-                                       self.spectatorspeed = bound(1, self.spectatorspeed + 0.5, 5);
-                               else if(self.impulse == 11)
-                                       self.spectatorspeed = maxspd_mod;
-                               else if(self.impulse == 12 || self.impulse == 16  || self.impulse == 19 || (self.impulse >= 220 && self.impulse <= 229))
-                                       self.spectatorspeed = bound(1, self.spectatorspeed - 0.5, 5);
-                               else if(self.impulse >= 1 && self.impulse <= 9)
-                                       self.spectatorspeed = 1 + 0.5 * (self.impulse - 1);
-                       } // otherwise just clear
-                       self.impulse = 0;
-               }
-               maxspd_mod = self.spectatorspeed;
-       }
-
-       spd = max(self.stat_sv_maxspeed, autocvar_sv_maxairspeed) * maxspd_mod * swampspd_mod;
-       if(self.speed != spd)
-       {
-               self.speed = spd;
-               temps = ftos(spd);
-               stuffcmd(self, strcat("cl_forwardspeed ", temps, "\n"));
-               stuffcmd(self, strcat("cl_backspeed ", temps, "\n"));
-               stuffcmd(self, strcat("cl_sidespeed ", temps, "\n"));
-               stuffcmd(self, strcat("cl_upspeed ", temps, "\n"));
-       }
-
-       maxspd_mod *= swampspd_mod; // only one common speed modder please!
-       swampspd_mod = 1;
-
-       // if dead, behave differently
-       if (self.deadflag)
-               goto end;
-
-       if (!self.fixangle && !g_bugrigs)
-       {
-               self.angles_x = 0;
-               self.angles_y = self.v_angle.y;
-               self.angles_z = 0;
-       }
-
-       if(self.flags & FL_ONGROUND)
-       if(IS_PLAYER(self)) // no fall sounds for observers thank you very much
-       if(self.wasFlying)
-       {
-               self.wasFlying = 0;
-
-               if(self.waterlevel < WATERLEVEL_SWIMMING)
-               if(time >= self.ladder_time)
-               if (!self.hook)
-               {
-                       self.nextstep = time + 0.3 + random() * 0.1;
-                       trace_dphitq3surfaceflags = 0;
-                       tracebox(self.origin, self.mins, self.maxs, self.origin - '0 0 1', MOVE_NOMONSTERS, self);
-                       if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOSTEPS))
-                       {
-                               if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_METALSTEPS)
-                                       GlobalSound(globalsound_metalfall, CH_PLAYER, VOICETYPE_PLAYERSOUND);
-                               else
-                                       GlobalSound(globalsound_fall, CH_PLAYER, VOICETYPE_PLAYERSOUND);
-                       }
-               }
-       }
-
-       if(IsFlying(self))
-               self.wasFlying = 1;
-
-       if(IS_PLAYER(self))
-               CheckPlayerJump();
-
-       if (self.flags & FL_WATERJUMP )
-       {
-               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;
-                       self.teleport_time = 0;
-               }
-       }
-       else if (g_bugrigs && IS_PLAYER(self))
-       {
-               RaceCarPhysics();
-       }
-       else if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY || self.movetype == MOVETYPE_FLY_WORLDONLY)
-       {
-               // noclipping or flying
-               self.flags &= ~FL_ONGROUND;
-
-               self.velocity = self.velocity * (1 - frametime * autocvar_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;
-               // 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);
-       }
-       else if (self.waterlevel >= WATERLEVEL_SWIMMING)
-       {
-               // swimming
-               self.flags &= ~FL_ONGROUND;
-
-               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;
-               if (wishvel == '0 0 0')
-                       wishvel = '0 0 -60'; // drift towards bottom
-
-               wishdir = normalize(wishvel);
-               wishspeed = vlen(wishvel);
-               if (wishspeed > self.stat_sv_maxspeed*maxspd_mod)
-                       wishspeed = self.stat_sv_maxspeed*maxspd_mod;
-               wishspeed = wishspeed * 0.7;
-
-               // water friction
-               self.velocity = self.velocity * (1 - frametime * autocvar_sv_friction);
-
-               // water acceleration
-               PM_Accelerate(wishdir, wishspeed, wishspeed, autocvar_sv_accelerate*maxspd_mod, 1, 0, 0, 0);
-       }
-       else if (time < self.ladder_time)
-       {
-               // on a spawnfunc_func_ladder or swimming in spawnfunc_func_water
-               self.flags &= ~FL_ONGROUND;
-
-               float g;
-               g = autocvar_sv_gravity * frametime;
-               if(self.gravity)
-                       g *= self.gravity;
-               if(autocvar_sv_gameplayfix_gravityunaffectedbyticrate)
-               {
-                       g *= 0.5;
-                       self.velocity_z += g;
-               }
-
-               self.velocity = self.velocity * (1 - frametime * autocvar_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;
-               self.velocity_z += g;
-               if (self.ladder_entity.classname == "func_water")
-               {
-                       f = vlen(wishvel);
-                       if (f > self.ladder_entity.speed)
-                               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)
-                               self.waterlevel = WATERLEVEL_SUBMERGED;
-                       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)
-                               self.waterlevel = WATERLEVEL_WETFEET;
-                       else
-                       {
-                               self.waterlevel = WATERLEVEL_NONE;
-                               self.watertype = CONTENT_EMPTY;
-                       }
-               }
-               // 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)
-               {
-                       // water acceleration
-                       PM_Accelerate(wishdir, wishspeed, wishspeed, autocvar_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;
-               // add remaining speed as Z component
-               maxairspd = autocvar_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;
-
-               // if(self.BUTTON_JUMP)
-                       wishvel.z = sqrt(max(0, 1 - wishvel * wishvel));
-
-               // it is now normalized, so...
-               float a_side, a_up, a_add, a_diff;
-               a_side = autocvar_g_jetpack_acceleration_side;
-               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;
-
-               float best;
-               best = 0;
-               //////////////////////////////////////////////////////////////////////////////////////
-               // finding the maximum over all vectors of above form
-               // with wishvel having an absolute value of 1
-               //////////////////////////////////////////////////////////////////////////////////////
-               // we're finding the maximum over
-               //   f(a_side, a_up, a_add, z) := a_side * (1 - z^2) + (a_add + a_up * z)^2;
-               // for z in the range from -1 to 1
-               //////////////////////////////////////////////////////////////////////////////////////
-               // maximum is EITHER attained at the single extreme point:
-               a_diff = a_side * a_side - a_up * a_up;
-               if(a_diff != 0)
-               {
-                       f = a_add * a_up / a_diff; // this is the zero of diff(f(a_side, a_up, a_add, z), z)
-                       if(f > -1 && f < 1) // can it be attained?
-                       {
-                               best = (a_diff + a_add * a_add) * (a_diff + a_up * a_up) / a_diff;
-                               //print("middle\n");
-                       }
-               }
-               // OR attained at z = 1:
-               f = (a_up + a_add) * (a_up + a_add);
-               if(f > best)
-               {
-                       best = f;
-                       //print("top\n");
-               }
-               // OR attained at z = -1:
-               f = (a_up - a_add) * (a_up - a_add);
-               if(f > best)
-               {
-                       best = f;
-                       //print("bottom\n");
-               }
-               best = sqrt(best);
-               //////////////////////////////////////////////////////////////////////////////////////
-
-               //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);
-               else
-                       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;
-
-               float fvel;
-               fvel = min(1, vlen(wishvel) / best);
-               if(autocvar_g_jetpack_fuel && !(self.items & IT_UNLIMITED_WEAPON_AMMO))
-                       f = min(1, self.ammo_fuel / (autocvar_g_jetpack_fuel * frametime * fvel));
-               else
-                       f = 1;
-
-               //print("this acceleration: ", ftos(vlen(wishvel) * f), "\n");
-
-               if (f > 0 && wishvel != '0 0 0')
-               {
-                       self.velocity = self.velocity + wishvel * f * frametime;
-                       if (!(self.items & IT_UNLIMITED_WEAPON_AMMO))
-                               self.ammo_fuel -= autocvar_g_jetpack_fuel * frametime * fvel * f;
-                       self.flags &= ~FL_ONGROUND;
-                       self.items |= IT_USING_JETPACK;
-
-                       // jetpack also inhibits health regeneration, but only for 1 second
-                       self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen);
-               }
-       }
-       else if (self.flags & FL_ONGROUND)
-       {
-               // we get here if we ran out of ammo
-               if((self.items & IT_JETPACK) && self.BUTTON_HOOK && !(buttons_prev & 32) && self.ammo_fuel < 0.01)
-                       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;
-
-               if(!(self.lastflags & FL_ONGROUND))
-               {
-                       if(autocvar_speedmeter)
-                               dprint(strcat("landing velocity: ", vtos(self.velocity), " (abs: ", ftos(vlen(self.velocity)), ")\n"));
-                       if(self.lastground < time - 0.3)
-                               self.velocity = self.velocity * (1 - autocvar_sv_friction_on_land);
-                       if(self.jumppadcount > 1)
-                               dprint(strcat(ftos(self.jumppadcount), "x jumppad combo\n"));
-                       self.jumppadcount = 0;
-               }
-
-               v = self.velocity;
-               v.z = 0;
-               f = vlen(v);
-               if(f > 0)
-               {
-                       if (f < autocvar_sv_stopspeed)
-                               f = 1 - frametime * (autocvar_sv_stopspeed / f) * autocvar_sv_friction;
-                       else
-                               f = 1 - frametime * autocvar_sv_friction;
-                       if (f > 0)
-                               self.velocity = self.velocity * f;
-                       else
-                               self.velocity = '0 0 0';
-                       /*
-                          Mathematical analysis time!
-
-                          Our goal is to invert this mess.
-
-                          For the two cases we get:
-                               v = v0 * (1 - frametime * (autocvar_sv_stopspeed / v0) * autocvar_sv_friction)
-                                 = v0 - frametime * autocvar_sv_stopspeed * autocvar_sv_friction
-                               v0 = v + frametime * autocvar_sv_stopspeed * autocvar_sv_friction
-                          and
-                               v = v0 * (1 - frametime * autocvar_sv_friction)
-                               v0 = v / (1 - frametime * autocvar_sv_friction)
-
-                          These cases would be chosen ONLY if:
-                               v0 < autocvar_sv_stopspeed
-                               v + frametime * autocvar_sv_stopspeed * autocvar_sv_friction < autocvar_sv_stopspeed
-                               v < autocvar_sv_stopspeed * (1 - frametime * autocvar_sv_friction)
-                          and, respectively:
-                               v0 >= autocvar_sv_stopspeed
-                               v / (1 - frametime * autocvar_sv_friction) >= autocvar_sv_stopspeed
-                               v >= autocvar_sv_stopspeed * (1 - frametime * autocvar_sv_friction)
-                        */
-               }
-
-               // acceleration
-               wishdir = normalize(wishvel);
-               wishspeed = vlen(wishvel);
-               if (wishspeed > self.stat_sv_maxspeed*maxspd_mod)
-                       wishspeed = self.stat_sv_maxspeed*maxspd_mod;
-               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);
-       }
-       else
-       {
-               float wishspeed0;
-               // we get here if we ran out of ammo
-               if((self.items & IT_JETPACK) && self.BUTTON_HOOK && !(buttons_prev & 32) && self.ammo_fuel < 0.01)
-                       Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_JETPACK_NOFUEL);
-
-               if(maxspd_mod < 1)
-               {
-                       maxairspd = autocvar_sv_maxairspeed*maxspd_mod;
-                       airaccel = autocvar_sv_airaccelerate*maxspd_mod;
-               }
-               else
-               {
-                       maxairspd = autocvar_sv_maxairspeed;
-                       airaccel = autocvar_sv_airaccelerate;
-               }
-               // airborn
-               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);
-               if (wishspeed0 > self.stat_sv_maxspeed*maxspd_mod)
-                       wishspeed0 = self.stat_sv_maxspeed*maxspd_mod;
-               if (wishspeed > maxairspd)
-                       wishspeed = maxairspd;
-               if (self.crouch)
-                       wishspeed = wishspeed * 0.5;
-               if (time >= self.teleport_time)
-               {
-                       float accelerating;
-                       float wishspeed2;
-                       float airaccelqw;
-                       float strafity;
-
-                       airaccelqw = self.stat_sv_airaccel_qw;
-                       accelerating = (self.velocity * wishdir > 0);
-                       wishspeed2 = wishspeed;
-
-                       // CPM
-                       if(autocvar_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));
-                       }
-                       // note that for straight forward jumping:
-                       // step = accel * frametime * wishspeed0;
-                       // accel  = bound(0, wishspeed - vel_xy_current, step) * accelqw + step * (1 - accelqw);
-                       // -->
-                       // dv/dt = accel * maxspeed (when slow)
-                       // dv/dt = accel * maxspeed * (1 - accelqw) (when fast)
-                       // 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_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)
-                               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);
-
-                       if(autocvar_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)
-               {
-                       speedaward_speed = vlen(self.velocity - self.velocity.z * '0 0 1');
-                       speedaward_holder = self.netname;
-                       speedaward_uid = self.crypto_idfp;
-                       speedaward_lastupdate = time;
-               }
-               if(speedaward_speed > speedaward_lastsent && time - speedaward_lastupdate > 1)
-               {
-                       string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
-                       race_send_speedaward(MSG_ALL);
-                       speedaward_lastsent = speedaward_speed;
-                       if (speedaward_speed > speedaward_alltimebest && speedaward_uid != "")
-                       {
-                               speedaward_alltimebest = speedaward_speed;
-                               speedaward_alltimebest_holder = speedaward_holder;
-                               speedaward_alltimebest_uid = speedaward_uid;
-                               db_put(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed"), ftos(speedaward_alltimebest));
-                               db_put(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp"), speedaward_alltimebest_uid);
-                               race_send_speedaward_alltimebest(MSG_ALL);
-                       }
-               }
-       }
-
-       // WEAPONTODO
-       float xyspeed;
-       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
-               xyspeed = min(xyspeed, WEP_CVAR(vortex, charge_maxspeed));
-               f = (xyspeed - WEP_CVAR(vortex, charge_minspeed)) / (WEP_CVAR(vortex, charge_maxspeed) - WEP_CVAR(vortex, charge_minspeed));
-               // add the extra charge
-               self.vortex_charge = min(1, self.vortex_charge + WEP_CVAR(vortex, charge_velocity_rate) * f * frametime);
-       }
-:end
-       if(self.flags & FL_ONGROUND)
-               self.lastground = time;
-
-       // conveyors: then break velocity again
-       if(self.conveyor.state)
-               self.velocity += self.conveyor.movedir;
-
-       self.lastflags = self.flags;
-       self.lastclassname = self.classname;
-}
index 7471438..828c863 100644 (file)
@@ -377,6 +377,46 @@ void ClientCommand_mobspawn(float request, float argc)
        }
 }
 
+void ClientCommand_physics(float request, float argc)
+{
+       switch(request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       string command = strtolower(argv(1));
+                       
+                       if(!autocvar_g_physics_clientselect)
+                       {
+                               sprint(self, "Client physics selection is currently disabled.\n");
+                               return;
+                       }
+
+                       if(command == "list" || command == "help")
+                       {
+                               sprint(self, strcat("Available physics sets: \n\n", autocvar_g_physics_clientselect_options, " default\n"));
+                               return;
+                       }
+                       
+                       if(Physics_Valid(command) || command == "default")
+                       {
+                               stuffcmd(self, strcat("\nseta cl_physics ", command, "\nsendcvar cl_physics\n"));
+                               sprint(self, strcat("^2Physics set successfully changed to ^3", command, "\n"));
+                               return;
+                       }
+               }
+       
+               default:
+                       sprint(self, strcat("Current physics set: ^3", self.cvar_cl_physics, "\n"));
+               case CMD_REQUEST_USAGE:
+               {
+                       sprint(self, "\nUsage:^3 cmd physics <physics>\n");
+                       sprint(self, "  See 'cmd physics list' for available physics sets.\n");
+                       sprint(self, "  Argument 'default' resets to standard physics.\n");
+                       return;
+               }
+       }
+}
+
 void ClientCommand_ready(float request) // todo: anti-spam for toggling readyness
 {
        switch(request)
@@ -769,6 +809,7 @@ void ClientCommand_(float request)
        CLIENT_COMMAND("mobedit", ClientCommand_mobedit(request, arguments), "Edit your monster's properties") \
        CLIENT_COMMAND("mobkill", ClientCommand_mobkill(request), "Kills your monster") \
        CLIENT_COMMAND("mobspawn", ClientCommand_mobspawn(request, arguments), "Spawn monsters infront of yourself") \
+       CLIENT_COMMAND("physics", ClientCommand_physics(request, arguments), "Change physics set") \
        CLIENT_COMMAND("ready", ClientCommand_ready(request), "Qualify as ready to end warmup stage (or restart server if allowed)") \
        CLIENT_COMMAND("say", ClientCommand_say(request, arguments, command), "Print a message to chat to all players") \
        CLIENT_COMMAND("say_team", ClientCommand_say_team(request, arguments, command), "Print a message to chat to all team mates") \
index 43c5379..0bf2df3 100644 (file)
@@ -1399,7 +1399,8 @@ void GameCommand_shuffleteams(float request)
                                // count the total amount of players and total amount of teams
                                t_players = 0;
                                t_teams = 0;
-                               FOR_EACH_PLAYER(tmp_player)
+                               FOR_EACH_CLIENT(tmp_player)
+                               if(IS_PLAYER(tmp_player) || tmp_player.caplayer)
                                {
                                        CheckAllowedTeams(tmp_player);
 
@@ -1412,7 +1413,8 @@ void GameCommand_shuffleteams(float request)
                                }
 
                                // build a list of the players in a random order
-                               FOR_EACH_PLAYER(tmp_player)
+                               FOR_EACH_CLIENT(tmp_player)
+                               if(IS_PLAYER(tmp_player) || tmp_player.caplayer)
                                {
                                        for (;;)
                                        {
index 8e1d292..9637cc6 100644 (file)
@@ -68,6 +68,11 @@ float server_is_dedicated;
 //.string      map;
 
 //.float       worldtype;
+// Needed for dynamic clientwalls
+.float inactive; // Clientwall disappears when inactive
+.float alpha_max, alpha_min;
+.float fade_start, fade_end, fade_vertical_offset;
+.float default_solid; // Variable to store default self.solid for clientwalls
 
 .float pain_finished;                  //Added by Supajoe
 .float pain_frame;                     //"
@@ -557,6 +562,8 @@ const int MIF_GUIDED_TAG = 128;
 .float elos;
 .float ranks;
 
+.string cvar_cl_physics;
+
 .float init_for_player_needed;
 .void(entity) init_for_player;
 
index 11cf642..62b2cfb 100644 (file)
@@ -26,7 +26,22 @@ void g_model_setcolormaptoactivator (void)
 void g_clientmodel_setcolormaptoactivator (void)
 {
        g_model_setcolormaptoactivator();
-       self.SendFlags |= 1;
+       self.SendFlags |= (8 | 1);
+}
+
+void g_clientmodel_use(void)
+{
+       if (self.antiwall_flag == 1)
+       {
+               self.inactive = 1;
+               self.solid = SOLID_NOT;
+       }
+       else if (self.antiwall_flag == 2)
+       {
+               self.inactive = 0;
+               self.solid = self.default_solid;
+       }
+       g_clientmodel_setcolormaptoactivator();
 }
 
 void g_model_dropbyspawnflags()
@@ -62,7 +77,7 @@ float g_clientmodel_genericsendentity (entity to, int sf)
        sf = sf & 0x0F;
        if(self.angles != '0 0 0')
                sf |= 0x10;
-       if(self.solid && (self.mins != '0 0 0' || self.maxs != '0 0 0'))
+       if(self.mins != '0 0 0' || self.maxs != '0 0 0')
                sf |= 0x20;
        if(self.colormap != 0)
                sf |= 0x40;
@@ -130,6 +145,12 @@ float g_clientmodel_genericsendentity (entity to, int sf)
                        WriteCoord(MSG_ENTITY, self.movedir.z);
                        WriteByte(MSG_ENTITY, floor(self.lip * 255));
                }
+               WriteShort(MSG_ENTITY, self.fade_start);
+               WriteShort(MSG_ENTITY, self.fade_end);
+               WriteShort(MSG_ENTITY, self.alpha_max);
+               WriteShort(MSG_ENTITY, self.alpha_min);
+               WriteShort(MSG_ENTITY, self.inactive);
+               WriteShort(MSG_ENTITY, self.fade_vertical_offset);
        }
 
        return true;
@@ -148,11 +169,12 @@ float g_clientmodel_genericsendentity (entity to, int sf)
        if(self.geomtype) if(autocvar_physics_ode && checkextension("DP_PHYSICS_ODE")) self.movetype = MOVETYPE_PHYSICS; \
        if(!self.scale) self.scale = self.modelscale; \
        SetBrushEntityModel(); \
-       self.use = g_clientmodel_setcolormaptoactivator; \
+       self.use = g_clientmodel_use; \
        InitializeEntity(self, g_clientmodel_dropbyspawnflags, INITPRIO_DROPTOFLOOR); \
        if(!self.solid) self.solid = (sol); else if(self.solid < 0) self.solid = SOLID_NOT; \
        if(!self.bgmscriptsustain) self.bgmscriptsustain = 1; else if(self.bgmscriptsustain < 0) self.bgmscriptsustain = 0; \
-       Net_LinkEntity(self, true, 0, g_clientmodel_genericsendentity);
+       Net_LinkEntity(self, true, 0, g_clientmodel_genericsendentity); \
+       self.default_solid = sol;
 
 // non-solid model entities:
 void spawnfunc_misc_gamemodel()         { self.angles_x = -self.angles.x; G_MODEL_INIT      (SOLID_NOT) } // model entity
index 948367f..9c2003c 100644 (file)
@@ -272,6 +272,7 @@ void cvar_changes_init()
                BADCVAR("g_domination_default_teams");
                BADCVAR("g_freezetag");
                BADCVAR("g_freezetag_teams");
+               BADCVAR("g_invasion_teams");
                BADCVAR("g_keepaway");
                BADCVAR("g_keyhunt");
                BADCVAR("g_keyhunt_teams");
@@ -375,6 +376,7 @@ void cvar_changes_init()
                BADCVAR("g_ca_teams_override");
                BADCVAR("g_ctf_ignore_frags");
                BADCVAR("g_domination_point_limit");
+               BADCVAR("g_domination_teams_override");
                BADCVAR("g_freezetag_teams_override");
                BADCVAR("g_friendlyfire");
                BADCVAR("g_fullbrightitems");
@@ -395,6 +397,7 @@ void cvar_changes_init()
                BADCVAR("g_nexball_goallimit");
                BADCVAR("g_powerups");
                BADCVAR("g_start_delay");
+               BADCVAR("g_tdm_teams_override");
                BADCVAR("g_warmup");
                BADCVAR("g_weapon_stay"); BADPRESUFFIX("g_", "_weapon_stay");
                BADCVAR("hostname");
@@ -819,6 +822,27 @@ void spawnfunc_worldspawn (void)
        // physics
        Physics_AddStats();
 
+       // new properties
+       addstat(STAT_MOVEVARS_JUMPVELOCITY, AS_FLOAT, stat_sv_jumpvelocity);
+       addstat(STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, AS_FLOAT, stat_sv_airaccel_qw_stretchfactor);
+       addstat(STAT_MOVEVARS_MAXAIRSTRAFESPEED, AS_FLOAT, stat_sv_maxairstrafespeed);
+       addstat(STAT_MOVEVARS_MAXAIRSPEED, AS_FLOAT, stat_sv_maxairspeed);
+       addstat(STAT_MOVEVARS_AIRSTRAFEACCELERATE, AS_FLOAT, stat_sv_airstrafeaccelerate);
+       addstat(STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL, AS_FLOAT, stat_sv_warsowbunny_turnaccel);
+       addstat(STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, AS_FLOAT, stat_sv_airaccel_sideways_friction);
+       addstat(STAT_MOVEVARS_AIRCONTROL, AS_FLOAT, stat_sv_aircontrol);
+       addstat(STAT_MOVEVARS_AIRCONTROL_POWER, AS_FLOAT, stat_sv_aircontrol_power);
+       addstat(STAT_MOVEVARS_AIRCONTROL_PENALTY, AS_FLOAT, stat_sv_aircontrol_penalty);
+       addstat(STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, AS_FLOAT, stat_sv_warsowbunny_airforwardaccel);
+       addstat(STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED, AS_FLOAT, stat_sv_warsowbunny_topspeed);
+       addstat(STAT_MOVEVARS_WARSOWBUNNY_ACCEL, AS_FLOAT, stat_sv_warsowbunny_accel);
+       addstat(STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, AS_FLOAT, stat_sv_warsowbunny_backtosideratio);
+       addstat(STAT_MOVEVARS_FRICTION, AS_FLOAT, stat_sv_friction);
+       addstat(STAT_MOVEVARS_ACCELERATE, AS_FLOAT, stat_sv_accelerate);
+       addstat(STAT_MOVEVARS_STOPSPEED, AS_FLOAT, stat_sv_stopspeed);
+       addstat(STAT_MOVEVARS_AIRACCELERATE, AS_FLOAT, stat_sv_airaccelerate);
+       addstat(STAT_MOVEVARS_AIRSTOPACCELERATE, AS_FLOAT, stat_sv_airstopaccelerate);
+
        // secrets
        addstat(STAT_SECRETS_TOTAL, AS_FLOAT, stat_secrets_total);
        addstat(STAT_SECRETS_FOUND, AS_FLOAT, stat_secrets_found);
index cf5df9d..952ce5b 100644 (file)
@@ -9,21 +9,72 @@
 #include "../common/playerstats.qh"
 #include "../common/util.qh"
 
-float GameTypeVote_AvailabilityStatus(string gtname)
+
+// definitions
+
+float mapvote_nextthink;
+float mapvote_keeptwotime;
+float mapvote_timeout;
+string mapvote_message;
+const float MAPVOTE_SCREENSHOT_DIRS_COUNT = 4;
+string mapvote_screenshot_dirs[MAPVOTE_SCREENSHOT_DIRS_COUNT];
+float mapvote_screenshot_dirs_count;
+
+float mapvote_count;
+float mapvote_count_real;
+string mapvote_maps[MAPVOTE_COUNT];
+float mapvote_maps_screenshot_dir[MAPVOTE_COUNT];
+string mapvote_maps_pakfile[MAPVOTE_COUNT];
+float mapvote_maps_suggested[MAPVOTE_COUNT];
+string mapvote_suggestions[MAPVOTE_COUNT];
+float mapvote_suggestion_ptr;
+float mapvote_voters;
+float mapvote_selections[MAPVOTE_COUNT];
+float mapvote_maps_flags[MAPVOTE_COUNT];
+float mapvote_run;
+float mapvote_detail;
+float mapvote_abstain;
+.float mapvote;
+
+entity mapvote_ent;
+
+/**
+ * Returns the gamtype ID from its name, if type_name isn't a real gametype it
+ * checks for sv_vote_gametype_(type_name)_type
+ */
+float GameTypeVote_Type_FromString(string type_name)
+{
+       float type = MapInfo_Type_FromString(type_name);
+       if ( type == 0 )
+               type = MapInfo_Type_FromString(cvar_string(
+                       strcat("sv_vote_gametype_",type_name,"_type")));
+       return type;
+}
+
+int GameTypeVote_AvailabilityStatus(string type_name)
 {
-       float type = MapInfo_Type_FromString(gtname);
+       int flag = GTV_FORBIDDEN;
+
+       float type = MapInfo_Type_FromString(type_name);
+       if ( type == 0 )
+       {
+               type = MapInfo_Type_FromString(cvar_string(
+                       strcat("sv_vote_gametype_",type_name,"_type")));
+               flag |= GTV_CUSTOM;
+       }
+
        if( type == 0 )
-               return GTV_FORBIDDEN;
+               return flag;
 
        if ( autocvar_nextmap != "" )
        {
                if ( !MapInfo_Get_ByName(autocvar_nextmap, false, 0) )
-                       return GTV_FORBIDDEN;
+                       return flag;
                if (!(MapInfo_Map_supportedGametypes & type))
-                       return GTV_FORBIDDEN;
+                       return flag;
        }
 
-       return GTV_AVAILABLE;
+       return flag | GTV_AVAILABLE;
 }
 
 float GameTypeVote_GetMask()
@@ -33,7 +84,7 @@ float GameTypeVote_GetMask()
        n = min(MAPVOTE_COUNT, n);
        gametype_mask = 0;
        for(j = 0; j < n; ++j)
-               gametype_mask |= MapInfo_Type_FromString(argv(j));
+               gametype_mask |= GameTypeVote_Type_FromString(argv(j));
        return gametype_mask;
 }
 
@@ -147,7 +198,7 @@ void MapVote_AddVotable(string nextMap, float isSuggestion)
 
        mapvote_maps_screenshot_dir[mapvote_count] = i;
        mapvote_maps_pakfile[mapvote_count] = strzone(pakfile);
-       mapvote_maps_availability[mapvote_count] = GTV_AVAILABLE;
+       mapvote_maps_flags[mapvote_count] = GTV_AVAILABLE;
 
        mapvote_count += 1;
 }
@@ -229,7 +280,7 @@ void MapVote_WriteMask()
                float mask,power;
                mask = 0;
                for(i = 0, power = 1; i < mapvote_count; ++i, power *= 2)
-                       if(mapvote_maps_availability[i] == GTV_AVAILABLE )
+                       if(mapvote_maps_flags[i] & GTV_AVAILABLE )
                                mask |= power;
 
                if(mapvote_count < 8)
@@ -242,7 +293,53 @@ void MapVote_WriteMask()
        else
        {
                for ( i = 0; i < mapvote_count; ++i )
-                       WriteByte(MSG_ENTITY, mapvote_maps_availability[i]);
+                       WriteByte(MSG_ENTITY, mapvote_maps_flags[i]);
+       }
+}
+
+/*
+ * Sends a single map vote option to the client
+ */
+void MapVote_SendOption(int i)
+{
+       // abstain
+       if(mapvote_abstain && i == mapvote_count - 1)
+       {
+               WriteString(MSG_ENTITY, ""); // abstain needs no text
+               WriteString(MSG_ENTITY, ""); // abstain needs no pack
+               WriteByte(MSG_ENTITY, 0); // abstain needs no screenshot dir
+       }
+       else
+       {
+               WriteString(MSG_ENTITY, mapvote_maps[i]);
+               WriteString(MSG_ENTITY, mapvote_maps_pakfile[i]);
+               WriteByte(MSG_ENTITY, mapvote_maps_screenshot_dir[i]);
+       }
+}
+
+/*
+ * Sends a single gametype vote option to the client
+ */
+void GameTypeVote_SendOption(int i)
+{
+       // abstain
+       if(mapvote_abstain && i == mapvote_count - 1)
+       {
+               WriteString(MSG_ENTITY, ""); // abstain needs no text
+               WriteByte(MSG_ENTITY, GTV_AVAILABLE);
+       }
+       else
+       {
+               string type_name = mapvote_maps[i];
+               WriteString(MSG_ENTITY, type_name);
+               WriteByte(MSG_ENTITY, mapvote_maps_flags[i]);
+               if ( mapvote_maps_flags[i] & GTV_CUSTOM )
+               {
+                       WriteString(MSG_ENTITY, cvar_string(
+                               strcat("sv_vote_gametype_",type_name,"_name")));
+                       WriteString(MSG_ENTITY, cvar_string(
+                               strcat("sv_vote_gametype_",type_name,"_description")));
+               }
        }
 }
 
@@ -275,7 +372,7 @@ float MapVote_SendEntity(entity to, int sf)
                }
                else if ( autocvar_sv_vote_gametype )
                {
-                        // map vote but gametype has been chosen via voting screen
+                       // map vote but gametype has been chosen via voting screen
                        WriteByte(MSG_ENTITY, 2);
                        WriteString(MSG_ENTITY, MapInfo_Type_ToText(MapInfo_CurrentGametype()));
                }
@@ -284,22 +381,13 @@ float MapVote_SendEntity(entity to, int sf)
 
                MapVote_WriteMask();
 
+               // Send data for the vote options
                for(i = 0; i < mapvote_count; ++i)
                {
-                       if(mapvote_abstain && i == mapvote_count - 1)
-                       {
-                               WriteString(MSG_ENTITY, ""); // abstain needs no text
-                               WriteString(MSG_ENTITY, ""); // abstain needs no pack
-                               WriteByte(MSG_ENTITY, 0); // abstain needs no screenshot dir
-                               WriteByte(MSG_ENTITY, GTV_AVAILABLE);
-                       }
+                       if(gametypevote)
+                               GameTypeVote_SendOption(i);
                        else
-                       {
-                               WriteString(MSG_ENTITY, mapvote_maps[i]);
-                               WriteString(MSG_ENTITY, mapvote_maps_pakfile[i]);
-                               WriteByte(MSG_ENTITY, mapvote_maps_screenshot_dir[i]);
-                               WriteByte(MSG_ENTITY, mapvote_maps_availability[i]);
-                       }
+                               MapVote_SendOption(i);
                }
        }
 
@@ -313,7 +401,7 @@ float MapVote_SendEntity(entity to, int sf)
        {
                if(mapvote_detail)
                        for(i = 0; i < mapvote_count; ++i)
-                               if ( mapvote_maps_availability[i] == GTV_AVAILABLE )
+                               if ( mapvote_maps_flags[i] & GTV_AVAILABLE )
                                        WriteByte(MSG_ENTITY, mapvote_selections[i]);
 
                WriteByte(MSG_ENTITY, to.mapvote);
@@ -352,7 +440,7 @@ float MapVote_Finished(float mappos)
                result = strcat(result, ":", ftos(mapvote_selections[mappos]), "::");
                didntvote = mapvote_voters;
                for(i = 0; i < mapvote_count; ++i)
-                       if(mapvote_maps_availability[i] == GTV_AVAILABLE )
+                       if(mapvote_maps_flags[i] & GTV_AVAILABLE )
                        {
                                didntvote -= mapvote_selections[i];
                                if(i != mappos)
@@ -401,7 +489,7 @@ void MapVote_CheckRules_1()
        float i;
 
        for(i = 0; i < mapvote_count; ++i)
-               if( mapvote_maps_availability[i] == GTV_AVAILABLE )
+               if( mapvote_maps_flags[i] & GTV_AVAILABLE )
                {
                        //dprint("Map ", ftos(i), ": "); dprint(mapvote_maps[i], "\n");
                        mapvote_selections[i] = 0;
@@ -439,7 +527,7 @@ float MapVote_CheckRules_2()
        currentPlace = 0;
        currentVotes = -1;
        for(i = 0; i < mapvote_count_real; ++i)
-               if ( mapvote_maps_availability[i] == GTV_AVAILABLE )
+               if ( mapvote_maps_flags[i] & GTV_AVAILABLE )
                {
                        RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]);
                        if ( gametypevote &&  mapvote_maps[i] == MapInfo_Type_ToString(MapInfo_CurrentGametype()) )
@@ -460,7 +548,7 @@ float MapVote_CheckRules_2()
        RandomSelection_Init();
        for(i = 0; i < mapvote_count_real; ++i)
                if(i != firstPlace)
-               if ( mapvote_maps_availability[i] == GTV_AVAILABLE )
+               if ( mapvote_maps_flags[i] & GTV_AVAILABLE )
                        RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]);
        secondPlace = RandomSelection_chosen_float;
        secondPlaceVotes = RandomSelection_best_priority;
@@ -495,7 +583,7 @@ float MapVote_CheckRules_2()
                                                result = strcat(result, ":", ftos(mapvote_selections[i]));
                                                if(i < mapvote_count_real)
                                                {
-                                                       mapvote_maps_availability[i] = GTV_FORBIDDEN;
+                                                       mapvote_maps_flags[i] &= ~GTV_AVAILABLE;
                                                }
                                        }
                        }
@@ -534,11 +622,11 @@ void MapVote_Tick()
                }
 
                // clear possibly invalid votes
-               if ( mapvote_maps_availability[other.mapvote-1] != GTV_AVAILABLE )
+               if ( !(mapvote_maps_flags[other.mapvote-1] & GTV_AVAILABLE) )
                        other.mapvote = 0;
                // use impulses as new vote
                if(other.impulse >= 1 && other.impulse <= mapvote_count)
-                       if( mapvote_maps_availability[other.impulse - 1] == GTV_AVAILABLE )
+                       if( mapvote_maps_flags[other.impulse - 1] & GTV_AVAILABLE )
                        {
                                other.mapvote = other.impulse;
                                MapVote_TouchVotes(other);
@@ -658,7 +746,7 @@ float GameTypeVote_Finished(float pos)
        if(!gametypevote || gametypevote_finished)
                return false;
 
-       if ( !GameTypeVote_SetGametype(MapInfo_Type_FromString(mapvote_maps[pos])) )
+       if ( !GameTypeVote_SetGametype(GameTypeVote_Type_FromString(mapvote_maps[pos])) )
        {
                dprint("Selected gametype is not supported by any map");
        }
@@ -674,7 +762,7 @@ float GameTypeVote_Finished(float pos)
 float GameTypeVote_AddVotable(string nextMode)
 {
        float j;
-       if ( nextMode == "" || MapInfo_Type_FromString(nextMode) == 0 )
+       if ( nextMode == "" || GameTypeVote_Type_FromString(nextMode) == 0 )
                return false;
        for(j = 0; j < mapvote_count; ++j)
                if(mapvote_maps[j] == nextMode)
@@ -685,7 +773,7 @@ float GameTypeVote_AddVotable(string nextMode)
 
        mapvote_maps_screenshot_dir[mapvote_count] = 0;
        mapvote_maps_pakfile[mapvote_count] = strzone("");
-       mapvote_maps_availability[mapvote_count] = GameTypeVote_AvailabilityStatus(nextMode);
+       mapvote_maps_flags[mapvote_count] = GameTypeVote_AvailabilityStatus(nextMode);
 
        mapvote_count += 1;
 
@@ -713,7 +801,7 @@ float GameTypeVote_Start()
        for(j = 0; j < n; ++j)
        {
                if ( GameTypeVote_AddVotable(argv(j)) )
-               if ( mapvote_maps_availability[j] == GTV_AVAILABLE )
+               if ( mapvote_maps_flags[j] & GTV_AVAILABLE )
                {
                        really_available++;
                        which_available = j;
index 18194b7..e4e6b0b 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef MAPVOTING_H
 #define MAPVOTING_H
 
-#include "../common/constants.qh"
-
 // definitions for functions used outside mapvoting.qc
 void MapVote_Start();
 void MapVote_Spawn();
@@ -12,34 +10,7 @@ float GameTypeVote_Start();
 float GameTypeVote_Finished(float pos);
 string GameTypeVote_MapInfo_FixName(string m);
 
-// definitions
 float gametypevote;
 string getmapname_stored;
 float mapvote_initialized;
-
-float mapvote_nextthink;
-float mapvote_keeptwotime;
-float mapvote_timeout;
-string mapvote_message;
-const float MAPVOTE_SCREENSHOT_DIRS_COUNT = 4;
-string mapvote_screenshot_dirs[MAPVOTE_SCREENSHOT_DIRS_COUNT];
-float mapvote_screenshot_dirs_count;
-
-float mapvote_count;
-float mapvote_count_real;
-string mapvote_maps[MAPVOTE_COUNT];
-float mapvote_maps_screenshot_dir[MAPVOTE_COUNT];
-string mapvote_maps_pakfile[MAPVOTE_COUNT];
-float mapvote_maps_suggested[MAPVOTE_COUNT];
-string mapvote_suggestions[MAPVOTE_COUNT];
-float mapvote_suggestion_ptr;
-float mapvote_voters;
-float mapvote_selections[MAPVOTE_COUNT];
-float mapvote_maps_availability[MAPVOTE_COUNT];
-float mapvote_run;
-float mapvote_detail;
-float mapvote_abstain;
-.float mapvote;
-
-entity mapvote_ent;
 #endif
index e0ea62a..2354e12 100644 (file)
@@ -436,6 +436,7 @@ void GetCvars(float f)
        GetCvars_handleFloat(s, f, cvar_cl_autoscreenshot, "cl_autoscreenshot");
        GetCvars_handleFloat(s, f, cvar_cl_jetpack_jump, "cl_jetpack_jump");
        GetCvars_handleString(s, f, cvar_g_xonoticversion, "g_xonoticversion");
+       GetCvars_handleString(s, f, cvar_cl_physics, "cl_physics");
        GetCvars_handleFloat(s, f, cvar_cl_handicap, "cl_handicap");
        GetCvars_handleFloat(s, f, cvar_cl_clippedspectating, "cl_clippedspectating");
        GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriority, "cl_weaponpriority", W_FixWeaponOrder_ForceComplete_AndBuildImpulseList);
@@ -567,7 +568,7 @@ void readplayerstartcvars()
        s = cvar_string("g_weaponarena");
        if (s == "0" || s == "")
        {
-               if(g_ca)
+               if(g_ca || g_freezetag)
                        s = "most";
        }
 
@@ -696,7 +697,7 @@ void readplayerstartcvars()
                warmup_start_weapons_default = start_weapons_default;
                warmup_start_weapons_defaultmask = start_weapons_defaultmask;
 
-               if (!g_weaponarena && !g_ca)
+               if (!g_weaponarena && !g_ca && !g_freezetag)
                {
                        warmup_start_ammo_shells = cvar("g_warmup_start_ammo_shells");
                        warmup_start_ammo_nails = cvar("g_warmup_start_ammo_nails");
index fd21149..12dbe3a 100644 (file)
@@ -15,7 +15,7 @@
 #else
 string cvar_string_normal(string n)
 {
-       if (!(cvar_type(n) & 1))
+       if (!(cvar_type(n) & CVAR_TYPEFLAG_EXISTS))
                backtrace(strcat("Attempt to access undefined cvar: ", n));
        return builtin_cvar_string(n);
 }
index 3b251e7..fd3a9de 100644 (file)
@@ -524,6 +524,21 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
        return 1;
 }
 
+MUTATOR_HOOKFUNCTION(freezetag_SetStartItems)
+{
+       start_items &= ~IT_UNLIMITED_AMMO;
+       //start_health       = warmup_start_health       = cvar("g_lms_start_health");
+       //start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
+       start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
+       start_ammo_nails   = warmup_start_ammo_nails   = cvar("g_lms_start_ammo_nails");
+       start_ammo_rockets = warmup_start_ammo_rockets = cvar("g_lms_start_ammo_rockets");
+       start_ammo_cells   = warmup_start_ammo_cells   = cvar("g_lms_start_ammo_cells");
+       start_ammo_plasma  = warmup_start_ammo_plasma  = cvar("g_lms_start_ammo_plasma");
+       start_ammo_fuel    = warmup_start_ammo_fuel    = cvar("g_lms_start_ammo_fuel");
+
+       return 0;
+}
+
 MUTATOR_HOOKFUNCTION(freezetag_BotRoles)
 {
        if (!self.deadflag)
@@ -571,6 +586,7 @@ MUTATOR_DEFINITION(gamemode_freezetag)
        MUTATOR_HOOK(reset_map_players, freezetag_reset_map_players, CBC_ORDER_ANY);
        MUTATOR_HOOK(GiveFragsForKill, freezetag_GiveFragsForKill, CBC_ORDER_FIRST);
        MUTATOR_HOOK(PlayerPreThink, freezetag_PlayerPreThink, CBC_ORDER_FIRST);
+       MUTATOR_HOOK(SetStartItems, freezetag_SetStartItems, CBC_ORDER_ANY);
        MUTATOR_HOOK(HavocBot_ChooseRole, freezetag_BotRoles, CBC_ORDER_ANY);
        MUTATOR_HOOK(GetTeamCount, freezetag_GetTeamCount, CBC_ORDER_EXCLUSIVE);
 
index 4e8d1d6..315a120 100644 (file)
@@ -466,7 +466,6 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerJump)
 {
        if(self.buffs & BUFF_JUMP)
                player_jumpheight = autocvar_g_buffs_jump_height;
-       self.stat_jumpheight = player_jumpheight;
 
        return false;
 }
@@ -758,7 +757,6 @@ void buffs_Initialize()
        precache_sound("keepaway/respawn.wav");
 
        addstat(STAT_BUFFS, AS_INT, buffs);
-       addstat(STAT_MOVEVARS_JUMPVELOCITY, AS_FLOAT, stat_jumpheight);
 
        InitializeEntity(world, buffs_DelayedInit, INITPRIO_FINDTARGET);
 }
index 06a76b1..2d72e5b 100644 (file)
@@ -9,9 +9,6 @@
 .float buff_invisible_prev_alpha;
 // flight
 .float buff_flight_prev_gravity;
-// jump
-.float stat_jumpheight;
-//const float STAT_MOVEVARS_JUMPVELOCITY = 250; // engine hack
 // disability
 .float buff_disability_time;
 .float buff_disability_effect_time;
index 161dba9..17381d3 100644 (file)
@@ -5,47 +5,7 @@
 #include "../cl_client.qh"
 #include "../../common/buffs.qh"
 
-#include "../../common/items/item.qh"
-
-#define WITH(it) this.m_##it;
-#define CONFIGURE(...) MAP(WITH, __VA_ARGS__)
-
-float instagib_respawntime_ammo = 45;
-float instagib_respawntimejitter_ammo = 0;
-GETTER(float, instagib_respawntime_ammo)
-GETTER(float, instagib_respawntimejitter_ammo)
-
-REGISTER_ITEM(VaporizerCells, Pickup, APPLY(UNWORDS
-    ,APPLY(CONFIGURE
-    ,   model               =   "models/items/a_cells.md3"
-    ,   sound               =   "misc/itempickup.wav"
-    ,   name                =   "Vaporizer Ammo"
-    )
-    ,IF(SV, CONFIGURE
-    ,   botvalue            =   100
-    ,   itemid              =   IT_CELLS
-    ,   respawntime         =         GET(instagib_respawntime_ammo)
-    ,   respawntimejitter   =   GET(instagib_respawntimejitter_ammo)
-    )
-))
-
-REGISTER_ITEM(ExtraLife, Pickup, APPLY(UNWORDS
-    ,APPLY(CONFIGURE
-    ,   model               =   "models/items/g_h100.md3"
-    ,   sound               =   "misc/megahealth.wav"
-    ,   name                =   "Extralife"
-    )
-    ,IF(SV, CONFIGURE
-    ,   botvalue            =   BOT_PICKUP_RATING_HIGH
-    ,   itemflags           =   FL_POWERUP
-    ,   itemid              =   IT_NAILS
-    ,   respawntime         =         GET(g_pickup_respawntime_powerup)
-    ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_powerup)
-    )
-))
-
-#undef WITH
-#undef CONFIGURE
+#include "../../common/items/all.qc"
 
 void spawnfunc_item_minst_cells (void)
 {
diff --git a/qcsrc/server/mutators/mutator_instagib_items.qc b/qcsrc/server/mutators/mutator_instagib_items.qc
new file mode 100644 (file)
index 0000000..40340b1
--- /dev/null
@@ -0,0 +1,41 @@
+#include "../../common/items/item.qh"
+
+#define WITH(it) this.m_##it;
+#define CONFIGURE(...) MAP(WITH, __VA_ARGS__)
+
+float instagib_respawntime_ammo = 45;
+float instagib_respawntimejitter_ammo = 0;
+GETTER(float, instagib_respawntime_ammo)
+GETTER(float, instagib_respawntimejitter_ammo)
+
+REGISTER_ITEM(VaporizerCells, Pickup, APPLY(UNWORDS
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/a_cells.md3"
+    ,   sound               =   "misc/itempickup.wav"
+    ,   name                =   "Vaporizer Ammo"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   100
+    ,   itemid              =   IT_CELLS
+    ,   respawntime         =         GET(instagib_respawntime_ammo)
+    ,   respawntimejitter   =   GET(instagib_respawntimejitter_ammo)
+    )
+))
+
+REGISTER_ITEM(ExtraLife, Pickup, APPLY(UNWORDS
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/g_h100.md3"
+    ,   sound               =   "misc/megahealth.wav"
+    ,   name                =   "Extralife"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   BOT_PICKUP_RATING_HIGH
+    ,   itemflags           =   FL_POWERUP
+    ,   itemid              =   IT_NAILS
+    ,   respawntime         =         GET(g_pickup_respawntime_powerup)
+    ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_powerup)
+    )
+))
+
+#undef WITH
+#undef CONFIGURE
index 37c759a..1364b61 100644 (file)
@@ -12,12 +12,14 @@ Zac "Mario" Jardine
 **Extended Team
 Antonio "terencehill" Piu
 Archer
+BuddyFriendGuy
 Debugger
 GATTS
 Halogene
 IDWMaster
 Jan "zykure" Behrens
 JH0nny
+Luigi
 Łukasz "kuniu the frogg" Polek
 Matthias "matthiaskrgr" Krüger
 Mattia "Melanosuchus" Basaglia
@@ -57,6 +59,7 @@ Sahil "DiaboliK" Singhal
 nifrek
 
 *Level Design
+Amadeusz "amade/proraide" Sławiński
 Ben "MooKow" Banker
 Calinou
 Cortez
@@ -64,6 +67,8 @@ Cuinn "Cuinnton" Herrick
 Debugger
 Jakob "tZork" Markström Gröhn
 Konrad "Justin" Slawinski
+Maddin
+L0
 Łukasz "kuniu the frogg" Polek
 Maik "SavageX" Merten
 Marvin "Mirio" Beck
@@ -73,6 +78,7 @@ Pearce "theShadow" Michal
 Rasmus "FruitieX" Eskola
 Ruszkai "CuBe0wL" Ákos
 Severin "sev" Meyer
+ShadoW
 
 *Music / Sound FX
 AquaNova (Archer)
@@ -123,11 +129,8 @@ Dale "graphitemaster" Weiler
 
 
 **Other Active Contributors
-BuddyFriendGuy
 Erik "Ablu" Schilling
-Jope "Sless" Withers
 Mircea "Taoki" Kitsune
-Robert "ai" Kuroto
 
 
 **Translators
@@ -279,6 +282,7 @@ Henning "Tymo" Janssen
 Innovati
 Jitspoe
 Jody Gallagher
+Jope "Sless" Withers
 Juergen "LowDragon" Timm
 KadaverJack
 Kevin "Tyrann" Shanahan
@@ -312,6 +316,7 @@ Q1 Retexturing Project
 Qantourisc
 Oleh "BlaXpirit" Prypin
 Rick "Rat" Kelley
+Robert "ai" Kuroto
 Ronan
 Sajt
 Saulo "mand1nga" Gil