]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/hud/panel/physics.qc
Header police
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud / panel / physics.qc
1 #include "physics.qh"
2 // Physics panel (#15)
3
4 vector acc_prevspeed;
5 float acc_prevtime, acc_avg, top_speed, top_speed_time;
6 float physics_update_time, discrete_speed, discrete_acceleration;
7 void HUD_Physics()
8 {
9         if(!autocvar__hud_configure)
10         {
11                 if(!autocvar_hud_panel_physics) return;
12                 if(spectatee_status == -1 && (autocvar_hud_panel_physics == 1 || autocvar_hud_panel_physics == 3)) return;
13                 if(autocvar_hud_panel_physics == 3 && !(gametype == MAPINFO_TYPE_RACE || gametype == MAPINFO_TYPE_CTS)) return;
14         }
15
16         HUD_Panel_UpdateCvars();
17
18         draw_beginBoldFont();
19
20         HUD_Panel_DrawBg(1);
21         if(panel_bg_padding)
22         {
23                 panel_pos += '1 1 0' * panel_bg_padding;
24                 panel_size -= '2 2 0' * panel_bg_padding;
25         }
26
27         float acceleration_progressbar_scale = 0;
28         if(autocvar_hud_panel_physics_progressbar && autocvar_hud_panel_physics_acceleration_progressbar_scale > 1)
29                 acceleration_progressbar_scale = autocvar_hud_panel_physics_acceleration_progressbar_scale;
30
31         float text_scale;
32         if (autocvar_hud_panel_physics_text_scale <= 0)
33                 text_scale = 1;
34         else
35                 text_scale = min(autocvar_hud_panel_physics_text_scale, 1);
36
37         //compute speed
38         float speed, conversion_factor;
39         string unit;
40
41         switch(autocvar_hud_panel_physics_speed_unit)
42         {
43                 default:
44                 case 1:
45                         unit = _(" qu/s");
46                         conversion_factor = 1.0;
47                         break;
48                 case 2:
49                         unit = _(" m/s");
50                         conversion_factor = 0.0254;
51                         break;
52                 case 3:
53                         unit = _(" km/h");
54                         conversion_factor = 0.0254 * 3.6;
55                         break;
56                 case 4:
57                         unit = _(" mph");
58                         conversion_factor = 0.0254 * 3.6 * 0.6213711922;
59                         break;
60                 case 5:
61                         unit = _(" knots");
62                         conversion_factor = 0.0254 * 1.943844492; // 1 m/s = 1.943844492 knots, because 1 knot = 1.852 km/h
63                         break;
64         }
65
66         vector vel = (csqcplayer ? csqcplayer.velocity : pmove_vel);
67
68         float max_speed = floor( autocvar_hud_panel_physics_speed_max * conversion_factor + 0.5 );
69         if (autocvar__hud_configure)
70                 speed = floor( max_speed * 0.65 + 0.5 );
71         else if(autocvar_hud_panel_physics_speed_vertical)
72                 speed = floor( vlen(vel) * conversion_factor + 0.5 );
73         else
74                 speed = floor( vlen(vel - vel.z * '0 0 1') * conversion_factor + 0.5 );
75
76         //compute acceleration
77         float acceleration, f;
78         if (autocvar__hud_configure)
79                 acceleration = autocvar_hud_panel_physics_acceleration_max * 0.3;
80         else
81         {
82                 // 1 m/s = 0.0254 qu/s; 1 g = 9.80665 m/s^2
83                 f = time - acc_prevtime;
84                 if(autocvar_hud_panel_physics_acceleration_vertical)
85                         acceleration = (vlen(vel) - vlen(acc_prevspeed));
86                 else
87                         acceleration = (vlen(vel - '0 0 1' * vel.z) - vlen(acc_prevspeed - '0 0 1' * acc_prevspeed.z));
88
89                 acceleration = acceleration * (1 / max(0.0001, f)) * (0.0254 / 9.80665);
90
91                 acc_prevspeed = vel;
92                 acc_prevtime = time;
93
94                 if(autocvar_hud_panel_physics_acceleration_movingaverage)
95                 {
96                         f = bound(0, f * 10, 1);
97                         acc_avg = acc_avg * (1 - f) + acceleration * f;
98                         acceleration = acc_avg;
99                 }
100         }
101
102         int acc_decimals = 2;
103         if(time > physics_update_time)
104         {
105                 // workaround for ftos_decimals returning a negative 0
106                 if(discrete_acceleration > -1 / pow(10, acc_decimals) && discrete_acceleration < 0)
107                         discrete_acceleration = 0;
108                 discrete_acceleration = acceleration;
109                 discrete_speed = speed;
110                 physics_update_time += autocvar_hud_panel_physics_update_interval;
111         }
112
113         //compute layout
114         float panel_ar = panel_size.x/panel_size.y;
115         vector speed_offset = '0 0 0', acceleration_offset = '0 0 0';
116         if (panel_ar >= 5 && !acceleration_progressbar_scale)
117         {
118                 panel_size.x *= 0.5;
119                 if (autocvar_hud_panel_physics_flip)
120                         speed_offset.x = panel_size.x;
121                 else
122                         acceleration_offset.x = panel_size.x;
123         }
124         else
125         {
126                 panel_size.y *= 0.5;
127                 if (autocvar_hud_panel_physics_flip)
128                         speed_offset.y = panel_size.y;
129                 else
130                         acceleration_offset.y = panel_size.y;
131         }
132         int speed_baralign, acceleration_baralign;
133         if (autocvar_hud_panel_physics_baralign == 1)
134                 acceleration_baralign = speed_baralign = 1;
135     else if(autocvar_hud_panel_physics_baralign == 4)
136                 acceleration_baralign = speed_baralign = 2;
137         else if (autocvar_hud_panel_physics_flip)
138         {
139                 acceleration_baralign = (autocvar_hud_panel_physics_baralign == 2);
140                 speed_baralign = (autocvar_hud_panel_physics_baralign == 3);
141         }
142         else
143         {
144                 speed_baralign = (autocvar_hud_panel_physics_baralign == 2);
145                 acceleration_baralign = (autocvar_hud_panel_physics_baralign == 3);
146         }
147         if (autocvar_hud_panel_physics_acceleration_progressbar_mode == 0)
148                 acceleration_baralign = 3; //override hud_panel_physics_baralign value for acceleration
149
150         //draw speed
151         if(speed)
152         if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 2)
153                 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);
154         vector tmp_offset = '0 0 0', tmp_size = '0 0 0';
155         if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 2)
156         {
157                 tmp_size.x = panel_size.x * 0.75;
158                 tmp_size.y = panel_size.y * text_scale;
159                 if (speed_baralign)
160                         tmp_offset.x = panel_size.x - tmp_size.x;
161                 //else
162                         //tmp_offset_x = 0;
163                 tmp_offset.y = (panel_size.y - tmp_size.y) / 2;
164                 drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(discrete_speed), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
165
166                 //draw speed unit
167                 if (speed_baralign)
168                         tmp_offset.x = 0;
169                 else
170                         tmp_offset.x = tmp_size.x;
171                 if (autocvar_hud_panel_physics_speed_unit_show)
172                 {
173                         //tmp_offset_y = 0;
174                         tmp_size.x = panel_size.x * (1 - 0.75);
175                         tmp_size.y = panel_size.y * 0.4 * text_scale;
176                         tmp_offset.y = (panel_size.y * 0.4 - tmp_size.y) / 2;
177                         drawstring_aspect(panel_pos + speed_offset + tmp_offset, unit, tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
178                 }
179         }
180
181         //compute and draw top speed
182         if (autocvar_hud_panel_physics_topspeed)
183         if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 2)
184         {
185                 if (autocvar__hud_configure)
186                 {
187                         top_speed = floor( max_speed * 0.75 + 0.5 );
188                         f = 1;
189                 }
190                 else
191                 {
192                         if (speed >= top_speed)
193                         {
194                                 top_speed = speed;
195                                 top_speed_time = time;
196                         }
197                         if (top_speed != 0)
198                         {
199                                 f = max(1, autocvar_hud_panel_physics_topspeed_time);
200                                 // divide by f to make it start from 1
201                                 f = cos( ((time - top_speed_time) / f) * PI/2 );
202                         }
203             else //hide top speed 0, it would be stupid
204                                 f = 0;
205                 }
206                 if (f > 0)
207                 {
208                         //top speed progressbar peak
209                         if(speed < top_speed)
210                         if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 2)
211                         {
212                                 float peak_offsetX;
213                                 vector peak_size = '0 0 0';
214                                 if (speed_baralign == 0)
215                                         peak_offsetX = min(top_speed, max_speed)/max_speed * panel_size.x;
216                 else if (speed_baralign == 1)
217                                         peak_offsetX = (1 - min(top_speed, max_speed)/max_speed) * panel_size.x;
218                 else // if (speed_baralign == 2)
219                     peak_offsetX = min(top_speed, max_speed)/max_speed * panel_size.x * 0.5;
220                                 peak_size.x = floor(panel_size.x * 0.01 + 1.5);
221                 peak_size.y = panel_size.y;
222                 if (speed_baralign == 2) // draw two peaks, on both sides
223                 {
224                     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);
225                     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);
226                 }
227                 else
228                     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);
229                         }
230
231                         //top speed
232                         tmp_offset.y = panel_size.y * 0.4;
233                         tmp_size.x = panel_size.x * (1 - 0.75);
234                         tmp_size.y = (panel_size.y - tmp_offset.y) * text_scale;
235                         tmp_offset.y += (panel_size.y - tmp_offset.y - tmp_size.y) / 2;
236                         drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(top_speed), tmp_size, '1 0 0', f * panel_fg_alpha, DRAWFLAG_NORMAL);
237                 }
238                 else
239                         top_speed = 0;
240         }
241
242         //draw acceleration
243         if(acceleration)
244         if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 3)
245         {
246                 vector progressbar_color;
247                 if(acceleration < 0)
248                         progressbar_color = autocvar_hud_progressbar_acceleration_neg_color;
249                 else
250                         progressbar_color = autocvar_hud_progressbar_acceleration_color;
251
252                 f = acceleration/autocvar_hud_panel_physics_acceleration_max;
253                 if (autocvar_hud_panel_physics_acceleration_progressbar_nonlinear)
254                         f = (f >= 0 ? sqrt(f) : -sqrt(-f));
255
256                 if (acceleration_progressbar_scale) // allow progressbar to go out of panel bounds
257                 {
258                         tmp_size = acceleration_progressbar_scale * panel_size.x * eX + panel_size.y * eY;
259
260                         if (acceleration_baralign == 1)
261                                 tmp_offset.x = panel_size.x - tmp_size.x;
262                         else if (acceleration_baralign == 2 || acceleration_baralign == 3)
263                                 tmp_offset.x = (panel_size.x - tmp_size.x) / 2;
264                         else
265                                 tmp_offset.x = 0;
266                         tmp_offset.y = 0;
267                 }
268                 else
269                 {
270                         tmp_size = panel_size;
271                         tmp_offset = '0 0 0';
272                 }
273
274                 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);
275         }
276
277         if(autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 3)
278         {
279                 tmp_size.x = panel_size.x;
280                 tmp_size.y = panel_size.y * text_scale;
281                 tmp_offset.x = 0;
282                 tmp_offset.y = (panel_size.y - tmp_size.y) / 2;
283
284                 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);
285         }
286
287         draw_endBoldFont();
288 }