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