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