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