]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/client/miscfunctions.qc
reduce tuba bandwidth even more
[divverent/nexuiz.git] / data / qcsrc / client / miscfunctions.qc
1 var float(string text, float handleColors) stringwidth;
2
3 entity players;
4 entity teams;
5
6 void restartAnnouncer_Think() {
7         float countdown_rounded, countdown;
8         countdown = getstatf(STAT_GAMESTARTTIME) - time;
9         countdown_rounded = floor(0.5 + countdown);
10         if(countdown <= 0) {
11                 if (!spectatee_status) //do cprint only for players
12                         centerprint("^1Begin!");
13
14                 sound(self, CHAN_VOICE, "announcer/robotic/begin.wav", VOL_BASEVOICE, ATTN_NONE);
15                 //reset maptime announcers now as well
16                 announcer_5min = announcer_1min = FALSE;
17
18                 remove(self);
19                 return;
20         }
21         else {
22                 if (!spectatee_status) //do cprint only for players
23                         centerprint(strcat("^1Game starts in ", ftos(countdown_rounded), " seconds"));
24
25                 if(countdown_rounded <= 3 && countdown_rounded >= 1) {
26                         sound(self, CHAN_VOICE, strcat("announcer/robotic/", ftos(countdown_rounded), ".wav"), VOL_BASEVOICE, ATTN_NONE);
27                 }
28
29                 self.nextthink = getstatf(STAT_GAMESTARTTIME) - (countdown - 1);
30         }
31 }
32
33 /**
34  * Plays the 1minute or 5 minutes (of maptime) remaining sound, if client wants it
35  */
36 void maptimeAnnouncer() {
37     float timelimit;
38     timelimit = getstatf(STAT_TIMELIMIT);
39     float timeleft;
40     timeleft = max(0, timelimit * 60 + getstatf(STAT_GAMESTARTTIME) - time);
41
42     //5 minute check
43     if (cvar("cl_sound_maptime_warning") >= 2) {
44         //make sure that after connect (and e.g. 4 minutes left) we will not get a wrong sound
45         if(announcer_5min)
46         {
47                         if(timeleft > 300)
48                                 announcer_5min = FALSE;
49         }
50         else if (timelimit > 0 && timeleft < 300 && timeleft > 299) {
51                         announcer_5min = TRUE;
52                         //dprint("i will play the sound, I promise!\n");
53                         sound(self, CHAN_VOICE, "announcer/robotic/5minutesremain.wav", VOL_BASEVOICE, ATTN_NONE);
54                 }
55     }
56
57     //1 minute check
58     if (cvar("cl_sound_maptime_warning") == 1 || cvar("cl_sound_maptime_warning") == 3) {
59         if (announcer_1min)
60         {
61                         if(timeleft > 60)
62                                 announcer_1min = FALSE;
63         }
64         else if (timelimit > 0 && timeleft < 60) {
65                         announcer_1min = TRUE;
66                         sound(self, CHAN_VOICE, "announcer/robotic/1minuteremains.wav", VOL_BASEVOICE, ATTN_NONE);
67         }
68         }
69 }
70
71 /**
72  * Add all future announcer sounds precaches here.
73  * TODO: make all announcer sound() calls client-side in the end, to allow queues etc.
74  */
75 void Announcer_Precache () {
76     precache_sound ("announcer/robotic/1minuteremains.wav");
77         precache_sound ("announcer/robotic/5minutesremain.wav");
78 }
79
80 void AuditLists()
81 {
82         entity e;
83         entity prev;
84
85         prev = players;
86         for(e = prev.sort_next; e; prev = e, e = e.sort_next)
87         {
88                 if(prev != e.sort_prev)
89                         error(strcat("sort list chain error\nplease submit the output of 'prvm_edicts client' to the developers"));
90         }
91
92         prev = teams;
93         for(e = prev.sort_next; e; prev = e, e = e.sort_next)
94         {
95                 if(prev != e.sort_prev)
96                         error(strcat("sort list chain error\nplease submit the output of 'prvm_edicts client' to the developers"));
97         }
98 }
99
100
101 float RegisterPlayer(entity player)
102 {
103         entity pl;
104         AuditLists();
105         for(pl = players.sort_next; pl; pl = pl.sort_next)
106                 if(pl == player)
107                         error("Player already registered!");
108         player.sort_next = players.sort_next;
109         player.sort_prev = players;
110         if(players.sort_next)
111                 players.sort_next.sort_prev = player;
112         players.sort_next = player;
113         AuditLists();
114         return true;
115 }
116
117 void RemovePlayer(entity player)
118 {
119         entity pl, parent;
120         AuditLists();
121         parent = players;
122         for(pl = players.sort_next; pl && pl != player; pl = pl.sort_next)
123                 parent = pl;
124
125         if(!pl)
126         {
127                 error("Trying to remove a player which is not in the playerlist!");
128                 return;
129         }
130         parent.sort_next = player.sort_next;
131         if(player.sort_next)
132                 player.sort_next.sort_prev = parent;
133         AuditLists();
134 }
135
136 void MoveToLast(entity e)
137 {
138         AuditLists();
139         other = e.sort_next;
140         while(other)
141         {
142                 SORT_SWAP(other, e);
143                 other = e.sort_next;
144         }
145         AuditLists();
146 }
147
148 float RegisterTeam(entity Team)
149 {
150         entity tm;
151         AuditLists();
152         for(tm = teams.sort_next; tm; tm = tm.sort_next)
153                 if(tm == Team)
154                         error("Team already registered!");
155         Team.sort_next = teams.sort_next;
156         Team.sort_prev = teams;
157         if(teams.sort_next)
158                 teams.sort_next.sort_prev = Team;
159         teams.sort_next = Team;
160         AuditLists();
161         return true;
162 }
163
164 void RemoveTeam(entity Team)
165 {
166         entity tm, parent;
167         AuditLists();
168         parent = teams;
169         for(tm = teams.sort_next; tm && tm != Team; tm = tm.sort_next)
170                 parent = tm;
171
172         if(!tm)
173         {
174                 print("Trying to remove a team which is not in the teamlist!");
175                 return;
176         }
177         parent.sort_next = Team.sort_next;
178         if(Team.sort_next)
179                 Team.sort_next.sort_prev = parent;
180         AuditLists();
181 }
182
183 entity GetTeam(float Team, float add)
184 {
185         float num;
186         entity tm;
187         num = (Team == COLOR_SPECTATOR) ? 16 : Team;
188         if(teamslots[num])
189                 return teamslots[num];
190         if not(add)
191                 return NULL;
192         tm = spawn();
193         tm.team = Team;
194         teamslots[num] = tm;
195         RegisterTeam(tm);
196         return tm;
197 }
198
199 void CSQC_CheckEngine()
200 {
201         sbar_font = FONT_USER+1;
202         sbar_bigfont = FONT_USER+2;
203 }
204
205 vector Sbar_GetFontsize(string cvarname)
206 {
207         vector v;
208         v = stov(cvar_string(cvarname));
209         if(v_x == 0)
210                 v = '8 8 0';
211         if(v_y == 0)
212                 v_y = v_x;
213         v_z = 0;
214         return v;
215 }
216
217 float Sbar_GetWidth(float teamcolumnwidth)
218 {
219         float f;
220         f = cvar("sbar_width");
221         if(f == 0)
222                 f = 640;
223         if(f < 320)
224                 f = 320;
225         if(f > vid_conwidth - 2 * teamcolumnwidth)
226                 f = vid_conwidth - 2 * teamcolumnwidth;
227         return f;
228 }
229
230 float PreviewExists(string name)
231 {
232         float f;
233         string file;
234
235         if(cvar("cl_readpicture_force"))
236                 return false;
237
238         file = strcat(name, ".tga");
239         f = fopen(file, FILE_READ);
240         if(f >= 0)
241         {
242                 fclose(f);
243                 return true;
244         }
245         file = strcat(name, ".png");
246         f = fopen(file, FILE_READ);
247         if(f >= 0)
248         {
249                 fclose(f);
250                 return true;
251         }
252         file = strcat(name, ".jpg");
253         f = fopen(file, FILE_READ);
254         if(f >= 0)
255         {
256                 fclose(f);
257                 return true;
258         }
259         file = strcat(name, ".pcx");
260         f = fopen(file, FILE_READ);
261         if(f >= 0)
262         {
263                 fclose(f);
264                 return true;
265         }
266         return false;
267 }
268
269 vector rotate(vector v, float a)
270 {
271         vector w;
272         // FTEQCC SUCKS AGAIN
273         w_x =      v_x * cos(a) + v_y * sin(a);
274         w_y = -1 * v_x * sin(a) + v_y * cos(a);
275         return w;
276 }
277
278 float ColorTranslateMode;
279
280 string ColorTranslateRGB(string s)
281 {
282         if(ColorTranslateMode & 1)
283                 return strdecolorize(s);
284         else
285                 return s;
286 }
287
288 float cvar_or(string cv, float v)
289 {
290         string s;
291         s = cvar_string(cv);
292         if(s == "")
293                 return v;
294         else
295                 return stof(s);
296 }
297
298 vector project_3d_to_2d(vector vec)
299 {
300         vec = cs_project(vec);
301         if(cs_project_is_b0rked > 0)
302         {
303                 vec_x *= vid_conwidth / vid_width;
304                 vec_y *= vid_conheight / vid_height;
305         }
306         return vec;
307 }
308
309 void dummyfunction(float a1, float a2, float a3, float a4, float a5, float a6, float a7, float a8)
310 {
311 }
312
313 float expandingbox_sizefactor_from_fadelerp(float fadelerp)
314 {
315         return 1.2 / (1.2 - fadelerp);
316 }
317
318 vector expandingbox_resize_centered_box_offset(float sz, vector boxsize, float boxxsizefactor)
319 {
320         boxsize_x *= boxxsizefactor; // easier interface for text
321         return boxsize * (0.5 * (1 - sz));
322 }
323
324 void drawborderlines(float thickness, vector pos, vector dim, vector color, float alpha, float drawflag)
325 {
326         vector line_dim;
327
328         // left and right lines
329         pos_x -= thickness;
330         line_dim_x = thickness;
331         line_dim_y = dim_y;
332         drawfill(pos, line_dim, color, alpha, drawflag);
333         drawfill(pos + (dim_x + thickness) * '1 0 0', line_dim, color, alpha, drawflag);
334
335         // upper and lower lines
336         pos_y -= thickness;
337         line_dim_x = dim_x + thickness * 2; // make upper and lower lines longer
338         line_dim_y = thickness;
339         drawfill(pos, line_dim, color, alpha, drawflag);
340         drawfill(pos + (dim_y + thickness) * '0 1 0', line_dim, color, alpha, drawflag);
341 }
342
343 void drawpic_tiled(vector pos, string pic, vector sz, vector area, vector color, float alpha, float drawflag)
344 {
345         vector current_pos, end_pos, new_size, ratio;
346         end_pos = pos + area;
347
348         current_pos_y = pos_y;
349         while (current_pos_y < end_pos_y)
350         {
351                 current_pos_x = pos_x;
352                 while (current_pos_x < end_pos_x)
353                 {
354                         new_size_x = min(sz_x, end_pos_x - current_pos_x);
355                         new_size_y = min(sz_y, end_pos_y - current_pos_y);
356                         ratio_x = new_size_x / sz_x;
357                         ratio_y = new_size_y / sz_y;
358                         drawsubpic(current_pos, new_size, pic, '0 0 0', ratio, color, alpha, drawflag);
359                         current_pos_x += sz_x;
360                 }
361                 current_pos_y += sz_y;
362         }
363 }
364
365 void drawpic_expanding(vector position, string pic, vector scale, vector rgb, float alpha, float flag, float fadelerp)
366 {
367         float sz;
368         sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
369
370         drawpic(position + expandingbox_resize_centered_box_offset(sz, scale, 1), pic, scale * sz, rgb, alpha * (1 - fadelerp), flag);
371 }
372
373 void drawpic_expanding_two(vector position, string pic, vector scale, vector rgb, float alpha, float flag, float fadelerp)
374 {
375         drawpic_expanding(position, pic, scale, rgb, alpha, flag, fadelerp);
376         drawpic(position, pic, scale, rgb, alpha * fadelerp, flag);
377 }
378
379 void drawstring_expanding(vector position, string text, vector scale, vector rgb, float alpha, float flag, float fadelerp)
380 {
381         float sz;
382         sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
383
384         dummyfunction(0, 0, 0, 0, 0, 0, 0, 0);
385         drawstring(position + expandingbox_resize_centered_box_offset(sz, scale, stringwidth(text, FALSE)), text, scale * sz, rgb, alpha * (1 - fadelerp), flag);
386 }
387
388 void drawcolorcodedstring_expanding(vector position, string text, vector scale, float alpha, float flag, float fadelerp)
389 {
390         float sz;
391         sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
392
393         dummyfunction(0, 0, 0, 0, 0, 0, 0, 0);
394         drawcolorcodedstring(position + expandingbox_resize_centered_box_offset(sz, scale, stringwidth(text, TRUE)), text, scale * sz, alpha * (1 - fadelerp), flag);
395 }