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