]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/hud/panel/notify.qc
Merge branch 'master' into Mario/speed_var
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud / panel / notify.qc
1 #include "notify.qh"
2
3 #include <client/autocvars.qh>
4 #include <client/miscfunctions.qh>
5
6 // Notifications (#4)
7
8 void HUD_Notify_Export(int fh)
9 {
10         // allow saving cvars that aesthetically change the panel into hud skin files
11         HUD_Write_Cvar("hud_panel_notify_flip");
12         HUD_Write_Cvar("hud_panel_notify_fontsize");
13         HUD_Write_Cvar("hud_panel_notify_time");
14         HUD_Write_Cvar("hud_panel_notify_fadetime");
15         HUD_Write_Cvar("hud_panel_notify_icon_aspect");
16 }
17
18 void HUD_Notify_Push(string icon, string attacker, string victim)
19 {
20         if (icon == "")
21                 return;
22
23         ++notify_count;
24         --notify_index;
25
26         if (notify_index == -1)
27                 notify_index = NOTIFY_MAX_ENTRIES-1;
28
29         // Free old strings
30         if (notify_attackers[notify_index])
31                 strunzone(notify_attackers[notify_index]);
32
33         if (notify_victims[notify_index])
34                 strunzone(notify_victims[notify_index]);
35
36         if (notify_icons[notify_index])
37                 strunzone(notify_icons[notify_index]);
38
39         // Allocate new strings
40         if (victim != "")
41         {
42                 notify_attackers[notify_index] = strzone(attacker);
43                 notify_victims[notify_index] = strzone(victim);
44         }
45         else
46         {
47                 // In case of a notification without a victim, the attacker
48                 // is displayed on the victim's side. Instead of special
49                 // treatment later on, we can simply switch them here.
50                 notify_attackers[notify_index] = string_null;
51                 notify_victims[notify_index] = strzone(attacker);
52         }
53
54         notify_icons[notify_index] = strzone(icon);
55         notify_times[notify_index] = time;
56 }
57
58 void HUD_Notify()
59 {
60         if (!autocvar__hud_configure)
61                 if (!autocvar_hud_panel_notify)
62                         return;
63
64         HUD_Panel_LoadCvars();
65
66         if (autocvar_hud_panel_notify_dynamichud)
67                 HUD_Scale_Enable();
68         else
69                 HUD_Scale_Disable();
70         HUD_Panel_DrawBg();
71
72         if (!autocvar__hud_configure)
73                 if (notify_count == 0)
74                         return;
75
76         vector pos, size;
77         pos  = panel_pos;
78         size = panel_size;
79
80         if (panel_bg_padding)
81         {
82                 pos  += '1 1 0' * panel_bg_padding;
83                 size -= '2 2 0' * panel_bg_padding;
84         }
85
86         float fade_start = max(0, autocvar_hud_panel_notify_time);
87         float fade_time = max(0, autocvar_hud_panel_notify_fadetime);
88         float icon_aspect = max(1, autocvar_hud_panel_notify_icon_aspect);
89
90         int entry_count = bound(1, floor(NOTIFY_MAX_ENTRIES * size.y / size.x), NOTIFY_MAX_ENTRIES);
91         float entry_height = size.y / entry_count;
92
93         float panel_width_half = size.x * 0.5;
94         float icon_width_half = entry_height * icon_aspect / 2;
95         float name_maxwidth = panel_width_half - icon_width_half - size.x * NOTIFY_ICON_MARGIN;
96
97         vector font_size = '0.5 0.5 0' * entry_height * autocvar_hud_panel_notify_fontsize;
98         vector icon_size = vec2(icon_aspect, 1) * entry_height;
99         vector icon_left = eX * (panel_width_half - icon_width_half);
100         vector attacker_right = eX * name_maxwidth;
101         vector victim_left = eX * (size.x - name_maxwidth);
102
103         vector attacker_pos, victim_pos, icon_pos;
104         string attacker, victim, icon;
105         int i, j, count, step, limit;
106         float alpha;
107
108         if (autocvar_hud_panel_notify_flip)
109         {
110                 // Order items from the top down
111                 i = 0;
112                 step = +1;
113                 limit = entry_count;
114         }
115         else
116         {
117                 // Order items from the bottom up
118                 i = entry_count - 1;
119                 step = -1;
120                 limit = -1;
121         }
122
123         for (j = notify_index, count = 0; i != limit; i += step, ++j, ++count)
124         {
125                 if(autocvar__hud_configure)
126                 {
127                         attacker = sprintf(_("Player %d"), count + 1);
128                         victim = sprintf(_("Player %d"), count + 2);
129                         icon = REGISTRY_GET(Weapons, min(WEP_FIRST + count * 2, WEP_LAST)).model2;
130                         alpha = bound(0, 1.2 - count / entry_count, 1);
131                 }
132                 else
133                 {
134                         if (j == NOTIFY_MAX_ENTRIES)
135                                 j = 0;
136
137                         if (notify_times[j] + fade_start > time)
138                                 alpha = 1;
139                         else if (fade_time != 0)
140                         {
141                                 alpha = bound(0, (notify_times[j] + fade_start + fade_time - time) / fade_time, 1);
142                                 if (alpha == 0)
143                                         break;
144                         }
145                         else
146                                 break;
147
148                         attacker = notify_attackers[j];
149                         victim = notify_victims[j];
150                         icon = notify_icons[j];
151                 }
152
153                 if (icon != "" && victim != "")
154                 {
155                         vector name_top = eY * (i * entry_height + 0.5 * (entry_height - font_size.y));
156
157                         icon_pos = pos + icon_left + eY * i * entry_height;
158                         drawpic_aspect_skin(icon_pos, icon, icon_size, '1 1 1', panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
159
160                         victim = textShortenToWidth(ColorTranslateRGB(victim), name_maxwidth, font_size, stringwidth_colors);
161                         victim_pos = pos + victim_left + name_top;
162                         drawcolorcodedstring(victim_pos, victim, font_size, panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
163
164                         if (attacker != "")
165                         {
166                                 attacker = textShortenToWidth(ColorTranslateRGB(attacker), name_maxwidth, font_size, stringwidth_colors);
167                                 attacker_pos = pos + attacker_right - eX * stringwidth(attacker, true, font_size) + name_top;
168                                 drawcolorcodedstring(attacker_pos, attacker, font_size, panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
169                         }
170                 }
171         }
172
173         notify_count = count;
174 }