From: k9er Date: Mon, 10 Feb 2025 17:45:23 +0000 (+0000) Subject: Physics hud: add jump speed text, more config options, code refactoring X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=15895f14bcbb9977350bf3f0338d853ff7bc70b2;p=xonotic%2Fxonotic-data.pk3dir.git Physics hud: add jump speed text, more config options, code refactoring --- diff --git a/_hud_common.cfg b/_hud_common.cfg index 05992fce3..d574fcb0c 100644 --- a/_hud_common.cfg +++ b/_hud_common.cfg @@ -106,8 +106,12 @@ seta hud_panel_engineinfo_framecounter_exponentialmovingaverage_instantupdate_ch seta hud_panel_engineinfo_framecounter_decimals "0" "amount of decimals to show" seta hud_panel_engineinfo_framecounter_time "0.1" "time between framerate display updates" -seta hud_panel_physics_acceleration_movingaverage 1 "use an averaging method for calculating acceleration instead of the real value" -seta hud_panel_physics_update_interval 0.016 "how often (in seconds) numeric values get updated on screen" +seta hud_panel_physics_acceleration_movingaverage "1" "use an averaging method for calculating acceleration instead of the real value. lower (positive) values update the acceleration quicker" +seta hud_panel_physics_acceleration_max_slick "-1" "acceleration progressbar gets completely filled up by this value (in g) while on slick; \"-1\" = same as the normal max" +seta hud_panel_physics_update_interval "0.015625" "how often (in seconds) numeric values get updated on screen" +seta hud_panel_physics_jumpspeed "0" "also show jump speed, replacing the speed unit text (NOTE: ignores vertical speed)" +seta hud_panel_physics_jumpspeed_time "1" "how many seconds the jumpspeed text takes to fade out" +seta hud_panel_physics_force_layout "0" "\"1\" = force speed and acceleration to be side-by-side, \"2\" = force them to be above one another" seta hud_panel_itemstime_progressbar_maxtime "30" "when left time is at least this amount, the status bar is full" seta hud_panel_itemstime_hidespawned "1" "\"1\" = hide an item from the panel when all the occurrences of it are available again, \"2\" = hide it when at least one occurrence is available again" diff --git a/_hud_descriptions.cfg b/_hud_descriptions.cfg index 5432875e4..56c1e9d7c 100644 --- a/_hud_descriptions.cfg +++ b/_hud_descriptions.cfg @@ -252,15 +252,16 @@ seta hud_panel_physics_progressbar "" "enable progress bar in panel; \"2\" = onl seta hud_panel_physics_acceleration_max "" "acceleration progress bar gets completely filled up by this value (in g)" seta hud_panel_physics_acceleration_progressbar_mode "" "\"0\" = progress bar increases from the center to the right if the acceleration is positive, to the left if it's negative, \"1\" = progress bar increases from the border in the same direction for both positive and negative accelerations" seta hud_panel_physics_acceleration_progressbar_scale "" "multiply acceleration progress bar values by this factor (allow progress bar to go out of panel bounds)" -seta hud_panel_physics_acceleration_progressbar_nonlinear "" "use a non linear function to display acceleration progress bar values (amplify more smaller values)" +seta hud_panel_physics_acceleration_progressbar_nonlinear "" "use a nonlinear function to display acceleration progress bar values (amplifies smaller values)" seta hud_panel_physics_acceleration_vertical "" "include the acceleration on the Z-axis" seta hud_panel_physics_text "" "show text in panel; \"2\" = only for speed, \"3\" = only for acceleration" seta hud_panel_physics_text_scale "" "scale text height by this factor" -seta hud_panel_physics_speed_unit_show "" "also show speed unit" +seta hud_panel_physics_speed_unit_show "" "also show speed unit (NOTE: overridden if both topspeed and jumpspeed text are shown)" seta hud_panel_physics_speed_max "" "speed progress bar gets filled up completely by this value (in qu/s)" seta hud_panel_physics_speed_vertical "" "include the speed on the Z-axis" +seta hud_panel_physics_speed_colored "" "draw the speed text as the same color as your current acceleration (hud_progressbar_acceleration_color when accelerating, hud_progressbar_acceleration_neg_color when decelerating)" seta hud_panel_physics_topspeed "" "also show top speed" -seta hud_panel_physics_topspeed_time "" "how many seconds the top speed takes to fade out" +seta hud_panel_physics_topspeed_time "" "how many seconds the topspeed text takes to fade out" seta hud_panel_centerprint_pos "" "position of this base of the panel" seta hud_panel_centerprint_size "" "size of this panel" diff --git a/hud_luma.cfg b/hud_luma.cfg index 9aaaac6f7..579a5bd7a 100644 --- a/hud_luma.cfg +++ b/hud_luma.cfg @@ -250,6 +250,7 @@ seta hud_panel_physics_bg_padding "" seta hud_panel_physics_speed_unit_show "1" seta hud_panel_physics_speed_max "1800" seta hud_panel_physics_speed_vertical "0" +seta hud_panel_physics_speed_colored "0" seta hud_panel_physics_topspeed "1" seta hud_panel_physics_topspeed_time "4" seta hud_panel_physics_acceleration_max "1.5" diff --git a/hud_luminos.cfg b/hud_luminos.cfg index 6bc988364..362dbf5e5 100644 --- a/hud_luminos.cfg +++ b/hud_luminos.cfg @@ -250,6 +250,7 @@ seta hud_panel_physics_bg_padding "" seta hud_panel_physics_speed_unit_show "1" seta hud_panel_physics_speed_max "1800" seta hud_panel_physics_speed_vertical "0" +seta hud_panel_physics_speed_colored "0" seta hud_panel_physics_topspeed "1" seta hud_panel_physics_topspeed_time "4" seta hud_panel_physics_acceleration_max "1.5" diff --git a/hud_luminos_minimal.cfg b/hud_luminos_minimal.cfg index c798b7564..8fd1d6892 100644 --- a/hud_luminos_minimal.cfg +++ b/hud_luminos_minimal.cfg @@ -250,6 +250,7 @@ seta hud_panel_physics_bg_padding "" seta hud_panel_physics_speed_unit_show "1" seta hud_panel_physics_speed_max "1800" seta hud_panel_physics_speed_vertical "0" +seta hud_panel_physics_speed_colored "0" seta hud_panel_physics_topspeed "1" seta hud_panel_physics_topspeed_time "4" seta hud_panel_physics_acceleration_max "1.5" diff --git a/hud_luminos_minimal_xhair.cfg b/hud_luminos_minimal_xhair.cfg index 7532b807f..ff7c94328 100644 --- a/hud_luminos_minimal_xhair.cfg +++ b/hud_luminos_minimal_xhair.cfg @@ -250,6 +250,7 @@ seta hud_panel_physics_bg_padding "" seta hud_panel_physics_speed_unit_show "1" seta hud_panel_physics_speed_max "1800" seta hud_panel_physics_speed_vertical "0" +seta hud_panel_physics_speed_colored "0" seta hud_panel_physics_topspeed "1" seta hud_panel_physics_topspeed_time "4" seta hud_panel_physics_acceleration_max "1.5" diff --git a/hud_luminos_old.cfg b/hud_luminos_old.cfg index 80ab470df..ff9661362 100644 --- a/hud_luminos_old.cfg +++ b/hud_luminos_old.cfg @@ -250,6 +250,7 @@ seta hud_panel_physics_bg_padding "" seta hud_panel_physics_speed_unit_show "1" seta hud_panel_physics_speed_max "1800" seta hud_panel_physics_speed_vertical "0" +seta hud_panel_physics_speed_colored "0" seta hud_panel_physics_topspeed "1" seta hud_panel_physics_topspeed_time "4" seta hud_panel_physics_acceleration_max "1.5" diff --git a/hud_nexuiz.cfg b/hud_nexuiz.cfg index 2b8fe1465..5c50c9adf 100644 --- a/hud_nexuiz.cfg +++ b/hud_nexuiz.cfg @@ -250,6 +250,7 @@ seta hud_panel_physics_bg_padding "" seta hud_panel_physics_speed_unit_show "0" seta hud_panel_physics_speed_max "1800" seta hud_panel_physics_speed_vertical "0" +seta hud_panel_physics_speed_colored "0" seta hud_panel_physics_topspeed "0" seta hud_panel_physics_topspeed_time "4" seta hud_panel_physics_acceleration_max "1.5" diff --git a/qcsrc/client/hud/panel/physics.qc b/qcsrc/client/hud/panel/physics.qc index efbf045cd..292bc004d 100644 --- a/qcsrc/client/hud/panel/physics.qc +++ b/qcsrc/client/hud/panel/physics.qc @@ -2,6 +2,8 @@ #include #include +#include +#include "strafehud.qh" // Physics (#15) @@ -13,7 +15,10 @@ void HUD_Physics_Export(int fh) HUD_Write_Cvar("hud_panel_physics_speed_vertical"); HUD_Write_Cvar("hud_panel_physics_topspeed"); HUD_Write_Cvar("hud_panel_physics_topspeed_time"); + HUD_Write_Cvar("hud_panel_physics_jumpspeed"); + HUD_Write_Cvar("hud_panel_physics_jumpspeed_time"); HUD_Write_Cvar("hud_panel_physics_acceleration_max"); + HUD_Write_Cvar("hud_panel_physics_acceleration_max_slick"); HUD_Write_Cvar("hud_panel_physics_acceleration_vertical"); HUD_Write_Cvar("hud_panel_physics_flip"); HUD_Write_Cvar("hud_panel_physics_baralign"); @@ -23,38 +28,49 @@ void HUD_Physics_Export(int fh) HUD_Write_Cvar("hud_panel_physics_acceleration_progressbar_nonlinear"); HUD_Write_Cvar("hud_panel_physics_text"); HUD_Write_Cvar("hud_panel_physics_text_scale"); + HUD_Write_Cvar("hud_panel_physics_force_layout"); } -vector acc_prevspeed; -float acc_prevtime, acc_avg, top_speed, top_speed_time; -float physics_update_time, discrete_speed, discrete_acceleration; +vector acc_prev_vel; +float acc_prev_time, acc_avg, top_speed, top_speed_time, jump_speed, jump_speed_time; +float prev_vel_z = 0, prev_speed2d = 0; +float physics_update_time, discrete_speed, discrete_top_speed, discrete_accel; // not done for jumpspeed void HUD_Physics() { - if(!autocvar__hud_configure) + if (!autocvar__hud_configure) { - if(!autocvar_hud_panel_physics) return; - if(spectatee_status == -1 && (autocvar_hud_panel_physics == 1 || autocvar_hud_panel_physics == 3)) return; - if(autocvar_hud_panel_physics == 3 && !MUTATOR_CALLHOOK(HUD_Physics_showoptional)) return; + if (!autocvar_hud_panel_physics) return; + if (spectatee_status == -1 && (autocvar_hud_panel_physics == 1 || autocvar_hud_panel_physics == 3)) return; + if (autocvar_hud_panel_physics == 3 && !MUTATOR_CALLHOOK(HUD_Physics_showoptional)) return; } HUD_Panel_LoadCvars(); - draw_beginBoldFont(); - if (autocvar_hud_panel_physics_dynamichud) HUD_Scale_Enable(); else HUD_Scale_Disable(); HUD_Panel_DrawBg(); - if(panel_bg_padding) + if (panel_bg_padding) { - panel_pos += '1 1 0' * panel_bg_padding; + panel_pos += '1 1 0' * panel_bg_padding; panel_size -= '2 2 0' * panel_bg_padding; } - float acceleration_progressbar_scale = 0; - if(autocvar_hud_panel_physics_progressbar && autocvar_hud_panel_physics_acceleration_progressbar_scale > 1) - acceleration_progressbar_scale = autocvar_hud_panel_physics_acceleration_progressbar_scale; + // NOTE: this is copied from strafehud.qc + bool is_local = !(spectatee_status > 0 || isdemo()); + entity strafeplayer = StrafeHUD_GetStrafeplayer(is_local); + + if (!csqcplayer || !strafeplayer) + return; + + // draw physics hud + + draw_beginBoldFont(); + + float accel_progressbar_scale = 0; + if (autocvar_hud_panel_physics_progressbar && autocvar_hud_panel_physics_acceleration_progressbar_scale > 1) + accel_progressbar_scale = autocvar_hud_panel_physics_acceleration_progressbar_scale; float text_scale; if (autocvar_hud_panel_physics_text_scale <= 0) @@ -62,134 +78,179 @@ void HUD_Physics() else text_scale = min(autocvar_hud_panel_physics_text_scale, 1); - //compute speed - float speed, conversion_factor = GetSpeedUnitFactor(autocvar_hud_speed_unit); - vector vel = (csqcplayer ? csqcplayer.velocity : pmove_vel); - - float max_speed = floor( autocvar_hud_panel_physics_speed_max * conversion_factor + 0.5 ); + // compute speed + vector strafevelocity = csqcplayer.velocity; + float conversion_factor = GetSpeedUnitFactor(autocvar_hud_speed_unit); + float speed, speed2d; + float max_speed = floor(autocvar_hud_panel_physics_speed_max * conversion_factor + 0.5); if (autocvar__hud_configure) - speed = floor( max_speed * 0.65 + 0.5 ); - else if(autocvar_hud_panel_physics_speed_vertical) - speed = floor( vlen(vel) * conversion_factor + 0.5 ); + { + speed2d = floor(max_speed * 0.65 + 0.5); + speed = speed2d; // just ignore vertical speed in hud configure + } else - speed = floor( vlen(vel - vel.z * '0 0 1') * conversion_factor + 0.5 ); + { + speed2d = floor(vlen(vec2(strafevelocity)) * conversion_factor + 0.5); + if (autocvar_hud_panel_physics_speed_vertical) + speed = floor(vlen(strafevelocity) * conversion_factor + 0.5); + else + speed = speed2d; + } - //compute acceleration - float acceleration, f; + // compute acceleration + float accel; if (autocvar__hud_configure) - acceleration = autocvar_hud_panel_physics_acceleration_max * 0.3; + accel = 0.45; // use a hardcoded value so that the hud responds to hud_panel_physics_acceleration_max changing else { - // 1 m/s = 0.0254 qu/s; 1 g = 9.80665 m/s^2 - f = time - acc_prevtime; - if(autocvar_hud_panel_physics_acceleration_vertical) - acceleration = (vlen(vel) - vlen(acc_prevspeed)); + float f = time - acc_prev_time; + if (autocvar_hud_panel_physics_acceleration_vertical) + accel = (vlen(strafevelocity) - vlen(acc_prev_vel)); else - acceleration = (vlen(vel - '0 0 1' * vel.z) - vlen(acc_prevspeed - '0 0 1' * acc_prevspeed.z)); + accel = (vlen(vec2(strafevelocity)) - vlen(vec2(acc_prev_vel))); - acceleration = acceleration * (1 / max(0.0001, f)) * (0.0254 / 9.80665); + accel *= (1 / max(0.0001, f)) * ACCEL2GRAV; // now a fraction of gravity - acc_prevspeed = vel; - acc_prevtime = time; + acc_prev_vel = strafevelocity; + acc_prev_time = time; - if(autocvar_hud_panel_physics_acceleration_movingaverage) + if (autocvar_hud_panel_physics_acceleration_movingaverage > 0) { - f = bound(0, f * 10, 1); - acc_avg = acc_avg * (1 - f) + acceleration * f; - acceleration = acc_avg; + f = bound(0, f * 10 / autocvar_hud_panel_physics_acceleration_movingaverage, 1); + acc_avg = acc_avg * (1 - f) + accel * f; + accel = acc_avg; } } - const int acc_decimals = 2; - if(time > physics_update_time) - { - discrete_acceleration = acceleration; - // workaround for ftos_decimals returning a negative 0 - if(discrete_acceleration > -1 / (10 ** acc_decimals) && discrete_acceleration < 0) - discrete_acceleration = 0; - discrete_speed = speed; - physics_update_time += autocvar_hud_panel_physics_update_interval; - if(physics_update_time < time) - physics_update_time = time + autocvar_hud_panel_physics_update_interval; - } - - //compute layout - float panel_ar = panel_size.x/panel_size.y; - vector speed_offset = '0 0 0', acceleration_offset = '0 0 0'; - if (panel_ar >= 5 && !acceleration_progressbar_scale) + // compute layout + float panel_ar = panel_size.x / panel_size.y; + vector speed_offset = '0 0 0', accel_offset = '0 0 0'; + if (autocvar_hud_panel_physics_force_layout == PHYSICS_LAYOUT_HORIZONTAL + || (autocvar_hud_panel_physics_force_layout != PHYSICS_LAYOUT_VERTICAL && panel_ar >= 5 && !accel_progressbar_scale)) { panel_size.x *= 0.5; if (autocvar_hud_panel_physics_flip) speed_offset.x = panel_size.x; else - acceleration_offset.x = panel_size.x; + accel_offset.x = panel_size.x; } - else + else // speed and accel are drawn on top of one another (vvv), rather than side by side (^^^) { panel_size.y *= 0.5; if (autocvar_hud_panel_physics_flip) speed_offset.y = panel_size.y; else - acceleration_offset.y = panel_size.y; + accel_offset.y = panel_size.y; } - int speed_baralign, acceleration_baralign; - if (autocvar_hud_panel_physics_baralign == 1) - acceleration_baralign = speed_baralign = 1; - else if(autocvar_hud_panel_physics_baralign == 4) - acceleration_baralign = speed_baralign = 2; + int speed_baralign, accel_baralign; + if (autocvar_hud_panel_physics_baralign == PHYSICS_BARALIGN_RIGHT) + accel_baralign = speed_baralign = 1; + else if (autocvar_hud_panel_physics_baralign == PHYSICS_BARALIGN_CENTER) + accel_baralign = speed_baralign = 2; else if (autocvar_hud_panel_physics_flip) { - acceleration_baralign = (autocvar_hud_panel_physics_baralign == 2); - speed_baralign = (autocvar_hud_panel_physics_baralign == 3); + accel_baralign = (autocvar_hud_panel_physics_baralign == PHYSICS_BARALIGN_ONLY_LEFT); + speed_baralign = (autocvar_hud_panel_physics_baralign == PHYSICS_BARALIGN_ONLY_RIGHT); } else { - speed_baralign = (autocvar_hud_panel_physics_baralign == 2); - acceleration_baralign = (autocvar_hud_panel_physics_baralign == 3); + speed_baralign = (autocvar_hud_panel_physics_baralign == PHYSICS_BARALIGN_ONLY_LEFT); + accel_baralign = (autocvar_hud_panel_physics_baralign == PHYSICS_BARALIGN_ONLY_RIGHT); } if (autocvar_hud_panel_physics_acceleration_progressbar_mode == 0) - acceleration_baralign = 3; //override hud_panel_physics_baralign value for acceleration + accel_baralign = 3; // override hud_panel_physics_baralign value for acceleration - //draw speed - if(speed) - if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 2) - HUD_Panel_DrawProgressBar(panel_pos + speed_offset, panel_size, "progressbar", speed/max_speed, 0, speed_baralign, autocvar_hud_progressbar_speed_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); vector tmp_offset = '0 0 0', tmp_size = '0 0 0'; - if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 2) + float speed_size = 0.75; + int text_bits = BITS(0); // describes which texts may be drawn. BIT(0) = topspeed, BIT(1) = jumpspeed, BIT(2) = speed unit + // ordered by decreasing priority -- speed unit isn't drawn if the other two are, + // ... and topspeed takes priority over jumpspeed in the lower spot + + // draw speed + if (speed > 0) + if (autocvar_hud_panel_physics_progressbar == PHYSICS_PROGRESSBAR_BOTH + || autocvar_hud_panel_physics_progressbar == PHYSICS_PROGRESSBAR_SPEED) + HUD_Panel_DrawProgressBar(panel_pos + speed_offset, panel_size, "progressbar", speed / max_speed, 0, speed_baralign, + autocvar_hud_progressbar_speed_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); + + float accel_max; + if (autocvar__hud_configure) + accel_max = autocvar_hud_panel_physics_acceleration_max; + else { - tmp_size.x = panel_size.x * 0.75; - tmp_size.y = panel_size.y * text_scale; - if (speed_baralign) - tmp_offset.x = panel_size.x - tmp_size.x; - //else - //tmp_offset_x = 0; - tmp_offset.y = (panel_size.y - tmp_size.y) / 2; - 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) - tmp_offset.x = 0; + // NOTE: this code is similar to the logic in strafehud.qc + int keys = STAT(PRESSED_KEYS); + bool jumpheld = StrafeHUD_DetermineJumpHeld(strafeplayer, keys, is_local); + bool real_onground = StrafeHUD_DetermineOnGround(strafeplayer, is_local); + bool onground = real_onground && !jumpheld; + bool real_onslick = onground && StrafeHUD_DetermineOnSlick(strafeplayer); + bool all_slick = PHYS_FRICTION(strafeplayer) == 0; + + accel_max = (autocvar_hud_panel_physics_acceleration_max_slick != -1 && ((all_slick && real_onground) || real_onslick)) + ? autocvar_hud_panel_physics_acceleration_max_slick + : autocvar_hud_panel_physics_acceleration_max; + } + + // compute speed text color + vector speed_text_color = '1 1 1'; + if (autocvar_hud_panel_physics_text == PHYSICS_TEXT_BOTH + || autocvar_hud_panel_physics_text == PHYSICS_TEXT_SPEED) + { + if (autocvar__hud_configure) + speed_text_color = autocvar_hud_progressbar_acceleration_color; + else if (autocvar_hud_panel_physics_speed_colored) + { + float accel_pixels_drawn = accel / accel_max * accel_progressbar_scale * panel_size.x; + // this calculates how wide the accel/decel bar would be (if it were drawn), so that the text is only colored if something shows on the bar + // this workaround prevents tiny floating point errors that would otherwise cause the color to flicker + // positive means accel, negative means decel + if (accel_pixels_drawn > 1) + speed_text_color = autocvar_hud_progressbar_acceleration_color; + else if (accel_pixels_drawn < -1) + speed_text_color = autocvar_hud_progressbar_acceleration_neg_color; + } + } + + // compute jumpspeed text + float jump_speed_f = 0; + if (autocvar_hud_panel_physics_jumpspeed) + if (autocvar_hud_panel_physics_text == PHYSICS_TEXT_BOTH + || autocvar_hud_panel_physics_text == PHYSICS_TEXT_SPEED) + { + text_bits |= BIT(1); + if (autocvar__hud_configure) + { + jump_speed = floor(max_speed * 0.59 + 0.5); // slightly less than current speed text + jump_speed_f = 1; + } else - tmp_offset.x = tmp_size.x; - if (autocvar_hud_panel_physics_speed_unit_show) { - //tmp_offset_y = 0; - tmp_size.x = panel_size.x * (1 - 0.75); - tmp_size.y = panel_size.y * 0.4 * text_scale; - tmp_offset.y = (panel_size.y * 0.4 - tmp_size.y) / 2; - string unit = GetSpeedUnit(autocvar_hud_speed_unit); - drawstring_aspect(panel_pos + speed_offset + tmp_offset, unit, tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + if (rint(strafevelocity.z) > rint(prev_vel_z)) + { + // NOTE: this includes some situations where the player doesn't explicitly jump + // e.g. landing, swimming in water, walking up/down ramps, using jetpack, bouncepads + jump_speed = prev_speed2d; + jump_speed_time = time; + } + prev_vel_z = strafevelocity.z; + float time_frac = (time - jump_speed_time) / max(1, autocvar_hud_panel_physics_jumpspeed_time); + jump_speed_f = time_frac > 1 ? 0 : cos(time_frac * M_PI_2); } } - //compute and draw top speed + prev_speed2d = speed2d; + + // compute and draw topspeed + float top_speed_f = 0; if (autocvar_hud_panel_physics_topspeed) - if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 2) + if (autocvar_hud_panel_physics_text == PHYSICS_TEXT_BOTH + || autocvar_hud_panel_physics_text == PHYSICS_TEXT_SPEED) { + text_bits |= BIT(0); if (autocvar__hud_configure) { - top_speed = floor( max_speed * 0.75 + 0.5 ); - f = 1; + top_speed = floor(max_speed * 0.73 + 0.5); + top_speed_f = 1; } else { @@ -198,73 +259,98 @@ void HUD_Physics() top_speed = speed; top_speed_time = time; } - if (top_speed != 0) + if (top_speed == 0) // hide topspeed 0 + top_speed_f = 0; + else { - f = max(1, autocvar_hud_panel_physics_topspeed_time); - // divide by f to make it start from 1 - f = cos( ((time - top_speed_time) / f) * PI/2 ); + float time_frac = (time - top_speed_time) / max(1, autocvar_hud_panel_physics_topspeed_time); + top_speed_f = time_frac > 1 ? 0 : cos(time_frac * M_PI_2); } - else // hide top speed 0 - f = 0; } - if (f > 0) + // topspeed progressbar peak + if (top_speed_f > 0) { - //top speed progressbar peak - if(speed < top_speed) - if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 2) + if (speed < top_speed) + if (autocvar_hud_panel_physics_progressbar == PHYSICS_PROGRESSBAR_BOTH + || autocvar_hud_panel_physics_progressbar == PHYSICS_PROGRESSBAR_SPEED) { float peak_offsetX; vector peak_size = '0 0 0'; if (speed_baralign == 0) - peak_offsetX = min(top_speed, max_speed)/max_speed * panel_size.x; + peak_offsetX = min(top_speed, max_speed) / max_speed * panel_size.x; else if (speed_baralign == 1) - peak_offsetX = (1 - min(top_speed, max_speed)/max_speed) * panel_size.x; - else // if (speed_baralign == 2) - peak_offsetX = min(top_speed, max_speed)/max_speed * panel_size.x * 0.5; + peak_offsetX = (1 - min(top_speed, max_speed) / max_speed) * panel_size.x; + else //if (speed_baralign == 2) + peak_offsetX = min(top_speed, max_speed) / max_speed * panel_size.x * 0.5; peak_size.x = floor(panel_size.x * 0.01 + 1.5); peak_size.y = panel_size.y; if (speed_baralign == 2) // draw two peaks, on both sides { - drawfill(panel_pos + speed_offset + eX * (0.5 * panel_size.x + peak_offsetX - peak_size.x), peak_size, autocvar_hud_progressbar_speed_color, f * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); - drawfill(panel_pos + speed_offset + eX * (0.5 * panel_size.x - peak_offsetX + peak_size.x), peak_size, autocvar_hud_progressbar_speed_color, f * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); + drawfill(panel_pos + speed_offset + eX * (0.5 * panel_size.x + peak_offsetX - peak_size.x), peak_size, + autocvar_hud_progressbar_speed_color, top_speed_f * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); + drawfill(panel_pos + speed_offset + eX * (0.5 * panel_size.x - peak_offsetX + peak_size.x), peak_size, + autocvar_hud_progressbar_speed_color, top_speed_f * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); } else - drawfill(panel_pos + speed_offset + eX * (peak_offsetX - peak_size.x), peak_size, autocvar_hud_progressbar_speed_color, f * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); + drawfill(panel_pos + speed_offset + eX * (peak_offsetX - peak_size.x), peak_size, + autocvar_hud_progressbar_speed_color, top_speed_f * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); } - - //top speed - tmp_offset.y = panel_size.y * 0.4; - tmp_size.x = panel_size.x * (1 - 0.75); - tmp_size.y = (panel_size.y - tmp_offset.y) * text_scale; - tmp_offset.y += (panel_size.y - tmp_offset.y - tmp_size.y) / 2; - drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(top_speed), tmp_size, '1 0 0', f * panel_fg_alpha, DRAWFLAG_NORMAL); } else top_speed = 0; } - //draw acceleration - if(acceleration) - if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 3) + const int acc_decimals = 2; + if (time > physics_update_time) + { + discrete_speed = speed; + discrete_top_speed = top_speed; + discrete_accel = accel; + // workaround for ftos_decimals returning a negative 0 + if (discrete_accel > -1 / (10 ** acc_decimals) && discrete_accel < 0) + discrete_accel = 0; + physics_update_time += autocvar_hud_panel_physics_update_interval; + if (physics_update_time < time) + physics_update_time = time + autocvar_hud_panel_physics_update_interval; + } + + // draw speed text + if (autocvar_hud_panel_physics_text == PHYSICS_TEXT_BOTH + || autocvar_hud_panel_physics_text == PHYSICS_TEXT_SPEED) + { + tmp_size.x = panel_size.x * speed_size; + tmp_size.y = panel_size.y * text_scale; + tmp_offset.x = speed_baralign ? panel_size.x * (1 - speed_size) : 0; + tmp_offset.y = (panel_size.y - tmp_size.y) * 0.5; + drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(discrete_speed), tmp_size, speed_text_color, panel_fg_alpha, DRAWFLAG_NORMAL); + + if (autocvar_hud_panel_physics_speed_unit_show) + text_bits |= BIT(2); + } + + // draw acceleration + if (accel) + if (autocvar_hud_panel_physics_progressbar == PHYSICS_PROGRESSBAR_BOTH + || autocvar_hud_panel_physics_progressbar == PHYSICS_PROGRESSBAR_ACCEL) { vector progressbar_color; - if(acceleration < 0) + if (accel < 0) progressbar_color = autocvar_hud_progressbar_acceleration_neg_color; else progressbar_color = autocvar_hud_progressbar_acceleration_color; - f = acceleration/autocvar_hud_panel_physics_acceleration_max; + float f = accel / accel_max; if (autocvar_hud_panel_physics_acceleration_progressbar_nonlinear) f = (f >= 0 ? sqrt(f) : -sqrt(-f)); - if (acceleration_progressbar_scale) // allow progressbar to go out of panel bounds + if (accel_progressbar_scale) // allow progressbar to go out of panel bounds { - tmp_size = acceleration_progressbar_scale * panel_size.x * eX + panel_size.y * eY; + tmp_size = accel_progressbar_scale * panel_size.x * eX + panel_size.y * eY; - if (acceleration_baralign == 1) + if (accel_baralign == 1) tmp_offset.x = panel_size.x - tmp_size.x; - else if (acceleration_baralign == 2 || acceleration_baralign == 3) - tmp_offset.x = (panel_size.x - tmp_size.x) / 2; + else if (accel_baralign == 2 || accel_baralign == 3) + tmp_offset.x = (panel_size.x - tmp_size.x) * 0.5; else tmp_offset.x = 0; tmp_offset.y = 0; @@ -275,17 +361,71 @@ void HUD_Physics() tmp_offset = '0 0 0'; } - 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); + HUD_Panel_DrawProgressBar(panel_pos + accel_offset + tmp_offset, tmp_size, "accelbar", f, 0, accel_baralign, + progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); } - if(autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 3) + // draw acceleration text + if (autocvar_hud_panel_physics_text == PHYSICS_TEXT_BOTH + || autocvar_hud_panel_physics_text == PHYSICS_TEXT_ACCEL) { 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; + tmp_offset.y = (panel_size.y - tmp_size.y) * 0.5; + drawstring_aspect(panel_pos + accel_offset + tmp_offset, strcat(ftos_decimals(discrete_accel, acc_decimals), "g"), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + } + + tmp_size.x = panel_size.x * (1 - speed_size); + tmp_offset.x = speed_baralign ? 0 : panel_size.x * speed_size; + float top_speed_y = 0, jump_speed_y = 0, main_text_size; // speed unit is not main text + + // draw speed unit text + if ((text_bits & BIT(2)) && text_bits != BITS(3)) // can't draw all 3 texts at once, speed unit has the lowest priority + { + if (text_bits == BIT(2)) // it's the only text drawn, so make it large and centered + { + main_text_size = 1 - 0.8; // make the main text small, so the non-main text (speed unit) is large + tmp_offset.y = panel_size.y * main_text_size * 0.5; // offset halved to center text + } + else + { + main_text_size = 0.6; // make the main text slightly larger, since it's more important + tmp_offset.y = 0; + top_speed_y = panel_size.y * (1 - main_text_size); + jump_speed_y = top_speed_y; + } + tmp_size.y = panel_size.y * (1 - main_text_size) * text_scale; + tmp_offset.y += (panel_size.y * (1 - main_text_size) - tmp_size.y) * 0.5; + drawstring_aspect(panel_pos + speed_offset + tmp_offset, GetSpeedUnit(autocvar_hud_speed_unit), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + } + else if (text_bits == BIT(0) || text_bits == BIT(1)) // only one text is drawn, make it large and centered + { + main_text_size = 0.8; + top_speed_y = panel_size.y * (1 - main_text_size) * 0.5; // offset halved to center text + jump_speed_y = top_speed_y; + } + else // both topspeed and jumpspeed are drawn + { + main_text_size = 0.5; // make them equal size + top_speed_y = panel_size.y * (1 - main_text_size); // put topspeed in the lower slot + jump_speed_y = 0; // put jumpspeed in the upper slot + } - 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 jumpspeed text + tmp_size.y = panel_size.y * main_text_size * text_scale; + if ((text_bits & BIT(1)) && jump_speed_f > 0) + { + jump_speed_y += (panel_size.y * main_text_size - tmp_size.y) * 0.5; + tmp_offset.y = jump_speed_y; + drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(jump_speed), tmp_size, '0 1 0', jump_speed_f * panel_fg_alpha, DRAWFLAG_NORMAL); + } + // draw topspeed text + if ((text_bits & BIT(0)) && top_speed_f > 0) + { + top_speed_y += (panel_size.y * main_text_size - tmp_size.y) * 0.5; + tmp_offset.y = top_speed_y; + drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(discrete_top_speed), tmp_size, '1 0 0', top_speed_f * panel_fg_alpha, DRAWFLAG_NORMAL); } draw_endBoldFont(); diff --git a/qcsrc/client/hud/panel/physics.qh b/qcsrc/client/hud/panel/physics.qh index 353a970cd..8b0cb57d9 100644 --- a/qcsrc/client/hud/panel/physics.qh +++ b/qcsrc/client/hud/panel/physics.qh @@ -3,10 +3,11 @@ bool autocvar_hud_panel_physics; float autocvar_hud_panel_physics_acceleration_movingaverage = 1; -float autocvar_hud_panel_physics_acceleration_progressbar_mode; +int autocvar_hud_panel_physics_acceleration_progressbar_mode; float autocvar_hud_panel_physics_acceleration_progressbar_scale; -float autocvar_hud_panel_physics_acceleration_progressbar_nonlinear; +bool autocvar_hud_panel_physics_acceleration_progressbar_nonlinear; float autocvar_hud_panel_physics_acceleration_max; +float autocvar_hud_panel_physics_acceleration_max_slick = -1; float autocvar_hud_panel_physics_update_interval; int autocvar_hud_panel_physics_progressbar; bool autocvar_hud_panel_physics_acceleration_vertical; @@ -16,11 +17,39 @@ bool autocvar_hud_panel_physics_dynamichud = true; float autocvar_hud_panel_physics_speed_max; bool autocvar_hud_panel_physics_speed_unit_show; bool autocvar_hud_panel_physics_speed_vertical; +bool autocvar_hud_panel_physics_speed_colored; int autocvar_hud_panel_physics_text; float autocvar_hud_panel_physics_text_scale; bool autocvar_hud_panel_physics_topspeed; float autocvar_hud_panel_physics_topspeed_time; +bool autocvar_hud_panel_physics_jumpspeed; +float autocvar_hud_panel_physics_jumpspeed_time = 1; +int autocvar_hud_panel_physics_force_layout; vector autocvar_hud_progressbar_acceleration_color; vector autocvar_hud_progressbar_acceleration_neg_color; vector autocvar_hud_progressbar_speed_color; + +const int PHYSICS_BARALIGN_LEFT = 0; +const int PHYSICS_BARALIGN_RIGHT = 1; +const int PHYSICS_BARALIGN_ONLY_LEFT = 2; +const int PHYSICS_BARALIGN_ONLY_RIGHT = 3; +const int PHYSICS_BARALIGN_CENTER = 4; + +const int PHYSICS_PROGRESSBAR_NONE = 0; +const int PHYSICS_PROGRESSBAR_BOTH = 1; +const int PHYSICS_PROGRESSBAR_SPEED = 2; +const int PHYSICS_PROGRESSBAR_ACCEL = 3; + +const int PHYSICS_TEXT_NONE = 0; +const int PHYSICS_TEXT_BOTH = 1; +const int PHYSICS_TEXT_SPEED = 2; +const int PHYSICS_TEXT_ACCEL = 3; + +const int PHYSICS_LAYOUT_AUTOMATIC = 0; +const int PHYSICS_LAYOUT_HORIZONTAL = 1; +const int PHYSICS_LAYOUT_VERTICAL = 2; + +// 1 m/s^2 = 0.0254 qu/s^2; 1 g = 9.80665 m/s^2 +const float ACCEL2GRAV = 0.00259007918096393775; // converts qu/s^2 acceleration to m/s^2, relative to real-world gravity +// equivalent to 0.0254 / 9.80665 diff --git a/qcsrc/client/hud/panel/strafehud.qc b/qcsrc/client/hud/panel/strafehud.qc index 6601f3814..d77d6d927 100644 --- a/qcsrc/client/hud/panel/strafehud.qc +++ b/qcsrc/client/hud/panel/strafehud.qc @@ -11,10 +11,6 @@ // non-essential #include // for v_flipped state -// non-local players -#include // anim_implicit_state -#include // CSQCModel_server2csqc() - // StrafeHUD (#25) void HUD_StrafeHUD_Export(int fh) @@ -25,8 +21,6 @@ void HUD_StrafeHUD_Export(int fh) void HUD_StrafeHUD() { static float hud_lasttime = 0; - entity strafeplayer; - bool is_local; // generic hud routines if(!autocvar__hud_configure) @@ -55,17 +49,8 @@ void HUD_StrafeHUD() panel_size -= '2 2 0' * panel_bg_padding; } - // find out whether the local csqcmodel entity is valid - if(spectatee_status > 0 || isdemo()) - { - is_local = false; - strafeplayer = CSQCModel_server2csqc(player_localentnum - 1); - } - else - { - is_local = true; - strafeplayer = csqcplayer; - } + bool is_local = !(spectatee_status > 0 || isdemo()); + entity strafeplayer = StrafeHUD_GetStrafeplayer(is_local); if(!csqcplayer || !strafeplayer) { @@ -79,7 +64,7 @@ void HUD_StrafeHUD() bool jumpheld = StrafeHUD_DetermineJumpHeld(strafeplayer, keys, is_local); // does not get changed by ground timeout and is not affected by jump input - bool real_onground = is_local ? IS_ONGROUND(strafeplayer) : !(strafeplayer.anim_implicit_state & ANIMIMPLICITSTATE_INAIR); + bool real_onground = StrafeHUD_DetermineOnGround(strafeplayer, is_local); // does not get changed by ground timeout bool real_onslick = false; @@ -96,10 +81,7 @@ void HUD_StrafeHUD() static bool onslick_last = false; if(onground) { - // do not use IS_ONSLICK(), it only works for the local player and only if client prediction is enabled - trace_dphitq3surfaceflags = 0; - tracebox(strafeplayer.origin, strafeplayer.mins, strafeplayer.maxs, strafeplayer.origin - '0 0 1', MOVE_NOMONSTERS, strafeplayer); - real_onslick = onslick = trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK; + real_onslick = onslick = StrafeHUD_DetermineOnSlick(strafeplayer); onground_lasttime = time; onslick_last = onslick; @@ -557,7 +539,7 @@ void HUD_StrafeHUD() float text_offset_top; float text_offset_bottom; bool all_slick = PHYS_FRICTION(strafeplayer) == 0; - text_offset_top = text_offset_bottom = StrafeHUD_DrawSlickDetector(strafeplayer, all_slick && real_onground ? true : real_onslick); + text_offset_top = text_offset_bottom = StrafeHUD_DrawSlickDetector(strafeplayer, (all_slick && real_onground) || real_onslick); if(autocvar_hud_panel_strafehud_direction) StrafeHUD_DrawDirectionIndicator(direction, opposite_direction, fwd); @@ -574,13 +556,13 @@ void HUD_StrafeHUD() if(moveangle >= absolute_overturnangle) { if(moveangle == absolute_overturnangle && absolute_overturnangle == 180) - ; // everywhere gives acceleration, keep strafe_ratio as 0 + {} // everywhere gives acceleration, keep strafe_ratio as 0 else { - currentangle_color = autocvar_hud_panel_strafehud_angle_overturn_color; - strafe_ratio = (moveangle - absolute_overturnangle) / (180 - absolute_overturnangle); - // moveangle is always <= 180, so this code won't run if absolute_overturnangle == 180 - strafe_ratio *= -1; + currentangle_color = autocvar_hud_panel_strafehud_angle_overturn_color; + strafe_ratio = (moveangle - absolute_overturnangle) / (180 - absolute_overturnangle); + // moveangle is always <= 180, so this code won't run if absolute_overturnangle == 180 + strafe_ratio *= -1; } } // player gains speed by strafing diff --git a/qcsrc/client/hud/panel/strafehud.qh b/qcsrc/client/hud/panel/strafehud.qh index a84d8abf5..05e4496c0 100644 --- a/qcsrc/client/hud/panel/strafehud.qh +++ b/qcsrc/client/hud/panel/strafehud.qh @@ -152,5 +152,3 @@ const int STRAFEHUD_PROJECTION_PERSPECTIVE = 1; const int STRAFEHUD_PROJECTION_PANORAMIC = 2; const float ACOS_SQRT2_3_DEG = 35.2643896827546543153; /* acos(sqrt(2/3)) * RAD2DEG */ - -float GeomLerp(float a, float _lerp, float b); // declare GeomLerp here since there's no header file for it diff --git a/qcsrc/client/hud/panel/strafehud/util.qc b/qcsrc/client/hud/panel/strafehud/util.qc index c3786e1a5..2d9f60a9d 100644 --- a/qcsrc/client/hud/panel/strafehud/util.qc +++ b/qcsrc/client/hud/panel/strafehud/util.qc @@ -4,6 +4,10 @@ #include #include +// non-local players +#include // CSQCModel_server2csqc() +#include // anim_implicit_state + // convert a strafe angle into a HUD width value float StrafeHUD_AngleToWidth(float angle, float range) { @@ -102,6 +106,14 @@ string StrafeHUD_GetLengthUnit(int length_unit) } } +entity StrafeHUD_GetStrafeplayer(bool is_local) +{ + // use the local csqcmodel entity if it's valid (i.e. is_local == true) + return is_local + ? csqcplayer + : CSQCModel_server2csqc(player_localentnum - 1); +} + // check the player waterlevel without affecting the player entity, this way we can fetch waterlevel even if client prediction is disabled float StrafeHUD_DetermineWaterLevel(entity e) { @@ -317,6 +329,23 @@ bool StrafeHUD_DetermineJumpHeld(entity e, int keys, bool is_local) return false; } +// determine whether the player is on ground +// this return value is used in real_onground, not onground +bool StrafeHUD_DetermineOnGround(entity e, bool is_local) +{ + return is_local ? IS_ONGROUND(e) : !(e.anim_implicit_state & ANIMIMPLICITSTATE_INAIR); +} + +// determine whether the player is standing on a slick surface +// NOTE: this isn't the only condition for the slick detector being drawn +bool StrafeHUD_DetermineOnSlick(entity e) +{ + // do not use IS_ONSLICK(), it only works for the local player and only if client prediction is enabled + trace_dphitq3surfaceflags = 0; + tracebox(e.origin, e.mins, e.maxs, e.origin - '0 0 1', MOVE_NOMONSTERS, e); + return boolean(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK); +} + // mix two colors based on a ratio // TODO: move mixing colors out of the HUD, this could be useful for other code vector StrafeHUD_MixColors(vector color1, vector color2, float ratio) diff --git a/qcsrc/client/hud/panel/strafehud/util.qh b/qcsrc/client/hud/panel/strafehud/util.qh index 11d8064c0..1345f4948 100644 --- a/qcsrc/client/hud/panel/strafehud/util.qh +++ b/qcsrc/client/hud/panel/strafehud/util.qh @@ -10,6 +10,8 @@ float StrafeHUD_ProjectWidth(float, float, float); float StrafeHUD_GetLengthUnitFactor(int); string StrafeHUD_GetLengthUnit(int); +entity StrafeHUD_GetStrafeplayer(bool); + float StrafeHUD_DetermineWaterLevel(entity); float StrafeHUD_DetermineFrameTime(); float StrafeHUD_DetermineWishAngle(vector, int, bool); @@ -17,6 +19,8 @@ int StrafeHUD_DetermineForwardKeys(vector, int, bool); float StrafeHUD_DetermineHudAngle(float, float, float); float StrafeHUD_DetermineDirection(float, float, float); bool StrafeHUD_DetermineJumpHeld(entity, int, bool); +bool StrafeHUD_DetermineOnGround(entity, bool); +bool StrafeHUD_DetermineOnSlick(entity); vector StrafeHUD_MixColors(vector, vector, float); diff --git a/qcsrc/common/ent_cs.qh b/qcsrc/common/ent_cs.qh index 3c96661e6..2834c0e57 100644 --- a/qcsrc/common/ent_cs.qh +++ b/qcsrc/common/ent_cs.qh @@ -1,7 +1,8 @@ #pragma once #ifdef CSQC -#include + #include + #include // for playerslots #endif REGISTER_NET_LINKED(ENT_CLIENT_ENTCS) diff --git a/qcsrc/common/physics/player.qh b/qcsrc/common/physics/player.qh index 976bef7c1..e2e907767 100644 --- a/qcsrc/common/physics/player.qh +++ b/qcsrc/common/physics/player.qh @@ -2,6 +2,12 @@ // Client/server mappings +#ifdef CSQC + #include // for .isplayermodel, .csqcmodel_isdead + #include // for GetResource + #include // for ISPLAYER_CLIENT, ISPLAYER_PLAYER +#endif + #ifdef SVQC // TODO: get rid of this random dumb include! #include @@ -365,3 +371,6 @@ NET_HANDLE(setpause, bool) return true; } #endif + +// used elsewhere, like in strafehud +float GeomLerp(float, float, float); diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc b/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc index dcc1a1207..11d54be21 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc +++ b/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc @@ -66,6 +66,11 @@ void XonoticHUDPhysicsDialog_fill(entity me) me.TD(me, 1, 3.8/2, e = makeXonoticCheckBox(0, "hud_panel_physics_topspeed", _("Top speed"))); me.TD(me, 1, 3.8/2, e = makeXonoticSlider(1, 10, 1, "hud_panel_physics_topspeed_time")); setDependent(e, "hud_panel_physics_topspeed", 1, 1); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 3.8/2, e = makeXonoticCheckBox(0, "hud_panel_physics_jumpspeed", _("Jump speed"))); + me.TD(me, 1, 3.8/2, e = makeXonoticSlider(1, 10, 1, "hud_panel_physics_jumpspeed_time")); + setDependent(e, "hud_panel_physics_jumpspeed", 1, 1); //acceleration me.TR(me); diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_physics.qh b/qcsrc/menu/xonotic/dialog_hudpanel_physics.qh index b0d036390..a2f8380a9 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_physics.qh +++ b/qcsrc/menu/xonotic/dialog_hudpanel_physics.qh @@ -6,9 +6,8 @@ CLASS(XonoticHUDPhysicsDialog, XonoticRootDialog) ATTRIB(XonoticHUDPhysicsDialog, title, string, _("Physics Panel")); ATTRIB(XonoticHUDPhysicsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT); ATTRIB(XonoticHUDPhysicsDialog, intendedWidth, float, 0.4); - ATTRIB(XonoticHUDPhysicsDialog, rows, float, 18); + ATTRIB(XonoticHUDPhysicsDialog, rows, float, 19); ATTRIB(XonoticHUDPhysicsDialog, columns, float, 4); ATTRIB(XonoticHUDPhysicsDialog, name, string, "HUDphysics"); - ATTRIB(XonoticHUDPhysicsDialog, sliderTopspeedTime, entity); ATTRIB(XonoticHUDPhysicsDialog, requiresConnection, float, true); ENDCLASS(XonoticHUDPhysicsDialog)