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