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