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