3 #include <client/autocvars.qh>
4 #include <client/defs.qh>
5 #include <client/miscfunctions.qh>
6 #include <client/main.qh>
7 #include <common/gamemodes/_mod.qh>
8 #include <common/mapinfo.qh>
9 #include <lib/csqcmodel/cl_player.qh>
13 void HUD_Physics_Export(int fh)
15 // allow saving cvars that aesthetically change the panel into hud skin files
16 HUD_Write_Cvar("hud_panel_physics_speed_unit_show");
17 HUD_Write_Cvar("hud_panel_physics_speed_max");
18 HUD_Write_Cvar("hud_panel_physics_speed_vertical");
19 HUD_Write_Cvar("hud_panel_physics_topspeed");
20 HUD_Write_Cvar("hud_panel_physics_topspeed_time");
21 HUD_Write_Cvar("hud_panel_physics_acceleration_max");
22 HUD_Write_Cvar("hud_panel_physics_acceleration_vertical");
23 HUD_Write_Cvar("hud_panel_physics_flip");
24 HUD_Write_Cvar("hud_panel_physics_baralign");
25 HUD_Write_Cvar("hud_panel_physics_progressbar");
26 HUD_Write_Cvar("hud_panel_physics_acceleration_progressbar_mode");
27 HUD_Write_Cvar("hud_panel_physics_acceleration_progressbar_scale");
28 HUD_Write_Cvar("hud_panel_physics_acceleration_progressbar_nonlinear");
29 HUD_Write_Cvar("hud_panel_physics_text");
30 HUD_Write_Cvar("hud_panel_physics_text_scale");
34 float acc_prevtime, acc_avg, top_speed, top_speed_time;
35 float physics_update_time, discrete_speed, discrete_acceleration;
38 if(!autocvar__hud_configure)
40 if(!autocvar_hud_panel_physics) return;
41 if(spectatee_status == -1 && (autocvar_hud_panel_physics == 1 || autocvar_hud_panel_physics == 3)) return;
42 if(autocvar_hud_panel_physics == 3 && !MUTATOR_CALLHOOK(HUD_Physics_showoptional)) return;
45 HUD_Panel_LoadCvars();
49 if (autocvar_hud_panel_physics_dynamichud)
56 panel_pos += '1 1 0' * panel_bg_padding;
57 panel_size -= '2 2 0' * panel_bg_padding;
60 float acceleration_progressbar_scale = 0;
61 if(autocvar_hud_panel_physics_progressbar && autocvar_hud_panel_physics_acceleration_progressbar_scale > 1)
62 acceleration_progressbar_scale = autocvar_hud_panel_physics_acceleration_progressbar_scale;
65 if (autocvar_hud_panel_physics_text_scale <= 0)
68 text_scale = min(autocvar_hud_panel_physics_text_scale, 1);
71 float speed, conversion_factor = GetSpeedUnitFactor(autocvar_hud_panel_physics_speed_unit);
72 string unit = GetSpeedUnit(autocvar_hud_panel_physics_speed_unit);
73 vector vel = (csqcplayer ? csqcplayer.velocity : pmove_vel);
75 float max_speed = floor( autocvar_hud_panel_physics_speed_max * conversion_factor + 0.5 );
76 if (autocvar__hud_configure)
77 speed = floor( max_speed * 0.65 + 0.5 );
78 else if(autocvar_hud_panel_physics_speed_vertical)
79 speed = floor( vlen(vel) * conversion_factor + 0.5 );
81 speed = floor( vlen(vel - vel.z * '0 0 1') * conversion_factor + 0.5 );
83 //compute acceleration
84 float acceleration, f;
85 if (autocvar__hud_configure)
86 acceleration = autocvar_hud_panel_physics_acceleration_max * 0.3;
89 // 1 m/s = 0.0254 qu/s; 1 g = 9.80665 m/s^2
90 f = time - acc_prevtime;
91 if(autocvar_hud_panel_physics_acceleration_vertical)
92 acceleration = (vlen(vel) - vlen(acc_prevspeed));
94 acceleration = (vlen(vel - '0 0 1' * vel.z) - vlen(acc_prevspeed - '0 0 1' * acc_prevspeed.z));
96 acceleration = acceleration * (1 / max(0.0001, f)) * (0.0254 / 9.80665);
101 if(autocvar_hud_panel_physics_acceleration_movingaverage)
103 f = bound(0, f * 10, 1);
104 acc_avg = acc_avg * (1 - f) + acceleration * f;
105 acceleration = acc_avg;
109 const int acc_decimals = 2;
110 if(time > physics_update_time)
112 discrete_acceleration = acceleration;
113 // workaround for ftos_decimals returning a negative 0
114 if(discrete_acceleration > -1 / (10 ** acc_decimals) && discrete_acceleration < 0)
115 discrete_acceleration = 0;
116 discrete_speed = speed;
117 physics_update_time += autocvar_hud_panel_physics_update_interval;
118 if(physics_update_time < time)
119 physics_update_time = time + autocvar_hud_panel_physics_update_interval;
123 float panel_ar = panel_size.x/panel_size.y;
124 vector speed_offset = '0 0 0', acceleration_offset = '0 0 0';
125 if (panel_ar >= 5 && !acceleration_progressbar_scale)
128 if (autocvar_hud_panel_physics_flip)
129 speed_offset.x = panel_size.x;
131 acceleration_offset.x = panel_size.x;
136 if (autocvar_hud_panel_physics_flip)
137 speed_offset.y = panel_size.y;
139 acceleration_offset.y = panel_size.y;
141 int speed_baralign, acceleration_baralign;
142 if (autocvar_hud_panel_physics_baralign == 1)
143 acceleration_baralign = speed_baralign = 1;
144 else if(autocvar_hud_panel_physics_baralign == 4)
145 acceleration_baralign = speed_baralign = 2;
146 else if (autocvar_hud_panel_physics_flip)
148 acceleration_baralign = (autocvar_hud_panel_physics_baralign == 2);
149 speed_baralign = (autocvar_hud_panel_physics_baralign == 3);
153 speed_baralign = (autocvar_hud_panel_physics_baralign == 2);
154 acceleration_baralign = (autocvar_hud_panel_physics_baralign == 3);
156 if (autocvar_hud_panel_physics_acceleration_progressbar_mode == 0)
157 acceleration_baralign = 3; //override hud_panel_physics_baralign value for acceleration
161 if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 2)
162 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);
163 vector tmp_offset = '0 0 0', tmp_size = '0 0 0';
164 if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 2)
166 tmp_size.x = panel_size.x * 0.75;
167 tmp_size.y = panel_size.y * text_scale;
169 tmp_offset.x = panel_size.x - tmp_size.x;
172 tmp_offset.y = (panel_size.y - tmp_size.y) / 2;
173 drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(discrete_speed), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
179 tmp_offset.x = tmp_size.x;
180 if (autocvar_hud_panel_physics_speed_unit_show)
183 tmp_size.x = panel_size.x * (1 - 0.75);
184 tmp_size.y = panel_size.y * 0.4 * text_scale;
185 tmp_offset.y = (panel_size.y * 0.4 - tmp_size.y) / 2;
186 drawstring_aspect(panel_pos + speed_offset + tmp_offset, unit, tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
190 //compute and draw top speed
191 if (autocvar_hud_panel_physics_topspeed)
192 if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 2)
194 if (autocvar__hud_configure)
196 top_speed = floor( max_speed * 0.75 + 0.5 );
201 if (speed >= top_speed)
204 top_speed_time = time;
208 f = max(1, autocvar_hud_panel_physics_topspeed_time);
209 // divide by f to make it start from 1
210 f = cos( ((time - top_speed_time) / f) * PI/2 );
212 else //hide top speed 0, it would be stupid
217 //top speed progressbar peak
218 if(speed < top_speed)
219 if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 2)
222 vector peak_size = '0 0 0';
223 if (speed_baralign == 0)
224 peak_offsetX = min(top_speed, max_speed)/max_speed * panel_size.x;
225 else if (speed_baralign == 1)
226 peak_offsetX = (1 - min(top_speed, max_speed)/max_speed) * panel_size.x;
227 else // if (speed_baralign == 2)
228 peak_offsetX = min(top_speed, max_speed)/max_speed * panel_size.x * 0.5;
229 peak_size.x = floor(panel_size.x * 0.01 + 1.5);
230 peak_size.y = panel_size.y;
231 if (speed_baralign == 2) // draw two peaks, on both sides
233 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);
234 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);
237 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);
241 tmp_offset.y = panel_size.y * 0.4;
242 tmp_size.x = panel_size.x * (1 - 0.75);
243 tmp_size.y = (panel_size.y - tmp_offset.y) * text_scale;
244 tmp_offset.y += (panel_size.y - tmp_offset.y - tmp_size.y) / 2;
245 drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(top_speed), tmp_size, '1 0 0', f * panel_fg_alpha, DRAWFLAG_NORMAL);
253 if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 3)
255 vector progressbar_color;
257 progressbar_color = autocvar_hud_progressbar_acceleration_neg_color;
259 progressbar_color = autocvar_hud_progressbar_acceleration_color;
261 f = acceleration/autocvar_hud_panel_physics_acceleration_max;
262 if (autocvar_hud_panel_physics_acceleration_progressbar_nonlinear)
263 f = (f >= 0 ? sqrt(f) : -sqrt(-f));
265 if (acceleration_progressbar_scale) // allow progressbar to go out of panel bounds
267 tmp_size = acceleration_progressbar_scale * panel_size.x * eX + panel_size.y * eY;
269 if (acceleration_baralign == 1)
270 tmp_offset.x = panel_size.x - tmp_size.x;
271 else if (acceleration_baralign == 2 || acceleration_baralign == 3)
272 tmp_offset.x = (panel_size.x - tmp_size.x) / 2;
279 tmp_size = panel_size;
280 tmp_offset = '0 0 0';
283 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);
286 if(autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 3)
288 tmp_size.x = panel_size.x;
289 tmp_size.y = panel_size.y * text_scale;
291 tmp_offset.y = (panel_size.y - tmp_size.y) / 2;
293 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);