]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/hud/panel/spect.qc
c9511504309458dea1b342b8a80438b07f5e6679
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud / panel / spect.qc
1 #include "spect.qh"
2
3 #include <client/hud/hud.qh>
4 #include <client/view.qh>
5
6 vector teamscore_size;
7 vector teamscore_fontsize;
8 vector teamname_fontsize;
9
10 void HUD_SpectHUD_Export(int fh)
11 {
12         // allow saving cvars that aesthetically change the panel into hud skin files
13 }
14
15 void HUD_SpectHUD_drawCurrentName(vector pos)
16 {
17         string s = entcs_GetName(current_player);
18         pos.x -= stringwidth_colors(s, hud_fontsize * 2) / 2;
19         drawcolorcodedstring(pos, s, hud_fontsize * 2, panel_fg_alpha, DRAWFLAG_NORMAL);
20 }
21         
22 void HUD_SpectHUD_drawTeamPlayers(vector pos, entity tm, vector rgb, bool invert)
23 {
24         vector tmp_over;
25         vector line_sz = vec2((vid_conwidth - 1) / 7, hud_fontsize.y * 1.5);
26         vector line_sz_sub = vec2((vid_conwidth - 1) / 7, hud_fontsize.y);
27         
28         string playername;
29         float a = panel_fg_alpha * 0.8;
30         entity pl;
31         
32         if(invert)
33                 pos.x -= line_sz.x + hud_fontsize.x;
34         else
35                 pos.x += hud_fontsize.x;        
36         
37         for(pl = players.sort_next; pl; pl = pl.sort_next)
38         {
39                 if(pl.team != tm.team)
40                         continue;
41                 
42                 float health = 0;
43                 float armor = 0;
44                 string icon = "";
45                 vector icon_size = '0 0 0';
46                 vector icon_rgb = '1 1 1';
47                 
48                 // Position and size calculation vectors
49                 tmp_over = pos;
50                 vector total_sz = vec2(line_sz.x, line_sz.y + line_sz_sub.y);
51                 
52                 if(pl.eliminated) {
53                         // z411 TODO : Unhardcode luma
54                         icon = "gfx/hud/luma/notify_death.tga";
55                         icon_rgb = rgb;
56                 } else {
57                         entity entcs = entcs_receiver(pl.sv_entnum);
58                         if(entcs.m_entcs_private) {
59                                 health = (entcs.healthvalue / autocvar_hud_panel_healtharmor_maxhealth) * line_sz.x;
60                                 armor = (GetResource(entcs, RES_ARMOR) / autocvar_hud_panel_healtharmor_maxarmor) * line_sz_sub.x;
61                                         
62                                 Weapon wep = REGISTRY_GET(Weapons, entcs.activewepid);
63                                 icon = strcat("gfx/hud/luma/", wep.model2);
64                         } else {
65                                 if(tm.team == NUM_TEAM_1)
66                                         icon = "gfx/hud/luma/player_red";
67                                 else if(tm.team == NUM_TEAM_2)
68                                         icon = "gfx/hud/luma/player_blue";
69                                 else if(tm.team == NUM_TEAM_3)
70                                         icon = "gfx/hud/luma/player_yellow";
71                                 else if(tm.team == NUM_TEAM_4)
72                                         icon = "gfx/hud/luma/player_pink";
73                                 else
74                                         icon = "gfx/hud/luma/player_neutral";
75                         }
76                 }
77                 
78                 // Draw weapon
79                 if(icon != "")  {
80                         vector tmp_sz = draw_getimagesize(icon);
81                         icon_size = vec2(total_sz.y*(tmp_sz.x/tmp_sz.y), total_sz.y);
82                         total_sz.x += icon_size.x;
83                                 
84                         if(invert) {
85                                 pos.x -= icon_size.x;
86                                 tmp_over.x -= icon_size.x;
87                         }
88                         drawpic(pos, icon, icon_size, icon_rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
89                         pos.x += icon_size.x;
90                 }
91                 
92                 // Get player's name
93                 playername = textShortenToWidth(entcs_GetName(pl.sv_entnum), line_sz.x * 0.8, hud_fontsize, stringwidth_colors);
94                 
95                 // Draw health and name
96                 drawfill(pos, line_sz, rgb * 0.7, a * 0.3, DRAWFLAG_NORMAL);
97                 if(health)
98                         drawfill(pos, vec2(health, line_sz.y), rgb * 0.7, a, DRAWFLAG_NORMAL);
99                 drawcolorcodedstring(pos + eY * ((line_sz.y - hud_fontsize.y) / 2) + eX * (hud_fontsize.x * 0.5), playername, hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
100                 pos.y += line_sz.y;
101                 
102                 // Draw armor
103                 if(armor)
104                         drawfill(pos, vec2(armor, line_sz_sub.y), rgb, a, DRAWFLAG_NORMAL);
105                 
106                 // Highlight current player
107                 if(pl.sv_entnum == current_player && spectatee_status != -1)
108                         drawfill(tmp_over, total_sz, '1 1 1', 0.3, DRAWFLAG_NORMAL);
109                 if(pl.eliminated)
110                         drawfill(tmp_over, total_sz, '0 0 0', 0.4, DRAWFLAG_NORMAL);
111                 
112                 if(!invert)
113                         pos.x -= icon_size.x;
114                 pos.y += line_sz_sub.y * 2;
115         }
116 }
117
118
119 void HUD_SpectHUD_drawTeamScore(vector pos, entity tm, vector rgb, bool invert)
120 {
121         if(!tm) return;
122         
123         vector tmp;
124         string tmp_str;
125         
126         // Team score
127         tmp_str = ftos(tm.(teamscores(ts_primary)));
128         
129         if(invert)
130                 pos.x -= teamscore_size.x;
131         
132         drawfill(pos, teamscore_size, rgb * 0.8, 0.3, DRAWFLAG_NORMAL);
133         
134         tmp = pos;
135         tmp.x += (teamscore_size.x - stringwidth(tmp_str, true, teamscore_fontsize)) / 2;
136         tmp.y += (teamscore_size.y - teamscore_fontsize.y) / 2;
137                 
138         draw_beginBoldFont();
139         drawstring(tmp, tmp_str, teamscore_fontsize, rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
140         draw_endBoldFont();
141         
142         // Team name
143         tmp_str = Team_CustomName(tm.team);
144         
145         tmp = pos;
146         if(invert)
147                 tmp.x -= stringwidth_colors(tmp_str, teamname_fontsize) + teamname_fontsize.x * 0.5;
148         else
149                 tmp.x += teamscore_size.x + teamname_fontsize.x * 0.5;
150         tmp.y += (teamscore_size.y - teamname_fontsize.y) / 2;
151         
152         drawcolorcodedstring(tmp, tmp_str, teamname_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
153 }
154
155 void HUD_SpectHUD_drawDuelScore(vector pos, entity pl, bool invert)
156 {
157         if(!pl) return;
158         
159         vector tmp, tmp_in;
160         string tmp_str;
161         vector health_sz = vec2((vid_conwidth - 1) / 6, teamscore_size.y * 0.4);
162         vector armor_sz = vec2(health_sz.x, health_sz.y / 4);
163         
164         float health = 0;
165         float armor = 0;
166         
167         entity entcs = entcs_receiver(pl.sv_entnum);
168         if(entcs.m_entcs_private) {
169                 health = (entcs.healthvalue / autocvar_hud_panel_healtharmor_maxhealth) * health_sz.x;
170                 armor = (GetResource(entcs, RES_ARMOR) / autocvar_hud_panel_healtharmor_maxarmor) * armor_sz.x;
171         }
172         
173         // Player score
174         tmp_str = ftos(pl.(scores(ps_primary)));
175         
176         if(invert)
177                 pos.x -= teamscore_size.x;
178         
179         drawfill(pos, teamscore_size, '0 0 0', 0.3, DRAWFLAG_NORMAL);
180         
181         tmp = pos;
182         tmp.x += (teamscore_size.x - stringwidth(tmp_str, true, teamscore_fontsize)) / 2;
183         tmp.y += (teamscore_size.y - teamscore_fontsize.y) / 2;
184                 
185         draw_beginBoldFont();
186         drawstring(tmp, tmp_str, teamscore_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
187         draw_endBoldFont();
188         
189         // Player health/armor
190         tmp_in = pos;
191         tmp_in.y += ((teamscore_size.y / 2) - health_sz.y) / 2;
192         
193         // Background
194         tmp = tmp_in;
195         if(invert)
196                 tmp.x -= health_sz.x;
197         else
198                 tmp.x += teamscore_size.x;
199         
200         drawfill(tmp, health_sz, '0 0 0', 0.3, DRAWFLAG_NORMAL);
201         
202         // Bars
203         if(health) {
204                 tmp = tmp_in;
205                 if(invert)
206                         tmp.x -= health;
207                 else
208                         tmp.x += teamscore_size.x;
209         
210                 drawfill(tmp, vec2(health, health_sz.y), '1 0 0', 0.7, DRAWFLAG_NORMAL);
211         }
212         
213         if(armor) {
214                 tmp = tmp_in;
215                 tmp.y += health_sz.y - armor_sz.y;
216                 
217                 if(invert)
218                         tmp.x -= armor;
219                 else
220                         tmp.x += teamscore_size.x;
221                 
222                 drawfill(tmp, vec2(armor, armor_sz.y), '0 1 0', 0.7, DRAWFLAG_NORMAL);
223         }
224         
225         // Player name
226         tmp_str = entcs_GetName(pl.sv_entnum);
227         
228         tmp = pos;
229         if(invert)
230                 tmp.x -= stringwidth_colors(tmp_str, teamname_fontsize) + teamname_fontsize.x * 0.5;
231         else
232                 tmp.x += teamscore_size.x + teamname_fontsize.x * 0.5;
233         tmp.y += ((teamscore_size.y / 2) - teamname_fontsize.y) / 2;
234         tmp.y += teamscore_size.y / 2;
235         
236         drawcolorcodedstring(tmp, tmp_str, teamname_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
237 }
238
239 void HUD_SpectHUD()
240 {
241         if(!spectatee_status) return;
242         
243         vector pos, rgb;
244         float ammo_y, timer_width;
245         entity tm;
246         
247         // Set main vars
248         HUD_Panel_LoadCvars();
249         HUD_Scale_Enable();
250         hud_fontsize = HUD_GetFontsize("hud_fontsize");
251         
252         // Spectator name
253         if (autocvar_hud_spectatorplayernamedisplay)
254         {
255                 if(spectatee_status != -1) {
256                         ammo_y = stov(cvar_string("hud_panel_ammo_pos")).y * vid_conheight;
257                         pos = panel_pos + vec2((vid_conwidth - 1) / 2, (ammo_y - (hud_fontsize.y * 2)));
258                         HUD_SpectHUD_drawCurrentName(pos);
259                 }
260         }
261         
262         if (teamplay && autocvar_hud_spectatorteamdisplay)
263         {
264                 // Set vars
265                 teamscore_fontsize = hud_fontsize * 3;
266                 teamname_fontsize = hud_fontsize * 2;
267                 teamscore_size = vec2(teamscore_fontsize.x * 1.5, teamscore_fontsize.y * 1.25);
268                 timer_width = stov(cvar_string("hud_panel_timer_size")).x * vid_conwidth;
269                 
270                 // Team 1
271                 pos = panel_pos + vec2((vid_conwidth - 1) / 2, 0);
272                 tm = GetTeam(NUM_TEAM_1, false);
273                 rgb = Team_ColorRGB(tm.team);
274                 pos.x -= (timer_width * 1.3) / 2;
275                 HUD_SpectHUD_drawTeamScore(pos, tm, rgb, true);
276                 
277                 pos = panel_pos + vec2(0, (vid_conheight - 1) / 4 + hud_fontsize.y);
278                 HUD_SpectHUD_drawTeamPlayers(pos, tm, rgb, false);
279                 
280                 // Team 2
281                 pos = panel_pos + vec2((vid_conwidth - 1) / 2, 0);
282                 tm = GetTeam(NUM_TEAM_2, false);
283                 rgb = Team_ColorRGB(tm.team);
284                 pos.x += (timer_width * 1.3) / 2;
285                 HUD_SpectHUD_drawTeamScore(pos, tm, rgb, false);
286                 
287                 pos = panel_pos + vec2(vid_conwidth - 1, (vid_conheight - 1) / 4 + hud_fontsize.y);
288                 HUD_SpectHUD_drawTeamPlayers(pos, tm, rgb, true);
289
290                 // Team 3
291                 pos = panel_pos + vec2((vid_conwidth - 1) / 2, 41);
292                 tm = GetTeam(NUM_TEAM_3, false);
293                 rgb = Team_ColorRGB(tm.team);
294                 pos.x -= (timer_width * 1.3) / 2;
295                 HUD_SpectHUD_drawTeamScore(pos, tm, rgb, true);
296                 
297                 pos = panel_pos + vec2(0, (vid_conheight + 450) / 4 + hud_fontsize.y);
298                 HUD_SpectHUD_drawTeamPlayers(pos, tm, rgb, false);
299
300                 // Team 4
301                 pos = panel_pos + vec2((vid_conwidth - 1) / 2, 41);
302                 tm = GetTeam(NUM_TEAM_4, false);
303                 rgb = Team_ColorRGB(tm.team);
304                 pos.x += (timer_width * 1.3) / 2;
305                 HUD_SpectHUD_drawTeamScore(pos, tm, rgb, false);
306                 
307                 pos = panel_pos + vec2(vid_conwidth - 1, (vid_conheight + 450) / 4 + hud_fontsize.y);
308                 HUD_SpectHUD_drawTeamPlayers(pos, tm, rgb, true);
309         } else if(gametype == MAPINFO_TYPE_DUEL && autocvar_hud_spectatordueldisplay) {
310                 // Set vars
311                 teamscore_fontsize = hud_fontsize * 3;
312                 teamname_fontsize = hud_fontsize * 1.5;
313                 teamscore_size = vec2(teamscore_fontsize.x * 1.5, teamscore_fontsize.y * 1.25);
314                 timer_width = stov(cvar_string("hud_panel_timer_size")).x * vid_conwidth;
315                 
316                 entity pl_left = players.sort_next;
317                 entity pl_right = pl_left.sort_next;
318         
319                 // Left player
320                 pos = panel_pos + vec2((vid_conwidth - 1) / 2, 0);
321                 pos.x -= (timer_width * 1.3) / 2;
322                 HUD_SpectHUD_drawDuelScore(pos, pl_left, true);
323                 
324                 // Right player
325                 pos = panel_pos + vec2((vid_conwidth - 1) / 2, 0);
326                 pos.x += (timer_width * 1.3) / 2;
327                 HUD_SpectHUD_drawDuelScore(pos, pl_right, false);
328         }
329 }