]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/gamec/miscfunctions.c
a piece of code I forgot to commit... but it's ifdeffed out anyway (variable
[divverent/nexuiz.git] / data / qcsrc / server / gamec / miscfunctions.c
1 string W_Name(float weaponid);
2 float(float index) weapon_translateindextoflag;
3
4 float logfile_open;
5 float logfile;
6
7 void(string s) bcenterprint
8 {
9         entity head;
10         head = find(world, classname, "player");
11         while(head)
12         {
13                 if(clienttype(head) == CLIENTTYPE_REAL)
14                         centerprint(head, s);
15                 head = find(head, classname, "player");
16         }
17 }
18
19 void(string s, float check_dangerous) ServerConsoleEcho =
20 {
21         local string ch;
22         localcmd("echo \"");
23         if(check_dangerous)
24         {
25                 while(strlen(s))
26                 {
27                         ch = substring(s, 0, 1);
28                         if(ch != "\"" && ch != "\r" && ch != "\n")
29                                 localcmd(ch);
30                         s = substring(s, 1, strlen(s) - 1);
31                 }
32         }
33         else
34         {
35                 localcmd(s);
36         }
37         localcmd("\"\n");
38 }
39
40 void(string s, float check_dangerous) GameLogEcho =
41 {
42         string fn;
43         float matches;
44
45         if(cvar("sv_eventlog_files"))
46         {
47                 if(!logfile_open)
48                 {
49                         logfile_open = TRUE;
50                         matches = cvar("sv_eventlog_files_counter") + 1;
51                         cvar_set("sv_eventlog_files_counter", ftos(matches));
52                         fn = ftos(matches);
53                         if(strlen(fn) < 8)
54                                 fn = strcat(substring("00000000", 0, 8 - strlen(fn)), fn);
55                         fn = strcat(cvar_string("sv_eventlog_files_nameprefix"), fn, cvar_string("sv_eventlog_files_namesuffix"));
56                         logfile = fopen(fn, FILE_APPEND);
57                 }
58                 if(logfile >= 0)
59                         fputs(logfile, strcat(s, "\n"));
60         }
61         if(cvar("sv_eventlog_console"))
62         {
63                 ServerConsoleEcho(s, check_dangerous);
64         }
65 }
66
67 void() GameLogInit =
68 {
69         logfile_open = 0;
70         // will be opened later
71 }
72
73 void() GameLogClose =
74 {
75         if(logfile_open && logfile >= 0)
76         {
77                 fclose(logfile);
78                 logfile = -1;
79         }
80 }
81
82 float math_mod(float a, float b)
83 {
84         return a - (floor(a / b) * b);
85 }
86
87 string linewrap(string s, float l)
88 {
89         string t;
90
91         t = "";
92         while(l < strlen(s))
93         {
94                 t = strcat(t, substring(s, 0, l), "\n");
95                 s = substring(s, l+1, strlen(s));
96         }
97         return strcat(t, s);
98 }
99
100 vector find_floor(vector org)
101 {
102         traceline(org + '0 0 5', org - '0 0 255', TRUE, self);
103         if (trace_fraction < 1)
104                 return trace_endpos;
105         else
106                 return org;
107 }
108
109 void relocate_spawnpoint()
110 {
111         vector org, loc;
112         string error_msg;
113
114         error_msg = "spawn point too close to a wall";
115         
116         org = find_floor(self.origin) + '0 0 30';
117
118         traceline(org, org - '18 0 0', TRUE, world);
119         if(trace_fraction < 1)
120         {
121                 loc = trace_endpos;
122                 traceline(loc, loc + '36 0 0', TRUE, world);
123                 if(trace_fraction >= 1 && !self.noalign)
124                         org = loc + '18 0 0';
125                 else
126                 {
127                         objerror(error_msg);
128                         return;
129                 }
130         }
131
132         traceline (org, org - '-18 0 0', TRUE, world);
133         if (trace_fraction < 1)
134         {
135                 loc = trace_endpos;
136                 traceline (loc, loc + '-36 0 0', TRUE, world);
137                 if(trace_fraction >= 1 && !self.noalign)
138                         org = loc + '-18 0 0';
139                 else
140                 {
141                         objerror(error_msg);
142                         return;
143                 }
144         }
145
146         traceline (org, org - '0 18 0' , TRUE, world);
147         if (trace_fraction < 1)
148         {
149                 loc = trace_endpos;
150                 traceline (loc, loc + '0 36 0', TRUE, world);
151                 if(trace_fraction >= 1 && !self.noalign)
152                         org = loc + '0 18 0';
153                 else
154                 {                       
155                         objerror(error_msg);
156                         return;
157                 }
158         }
159
160         traceline (org, org - '0 -18 0', TRUE, world);
161         if (trace_fraction < 1)
162         {
163                 loc = trace_endpos;
164                 traceline (loc, loc + '0 -36 0', TRUE, world);
165                 if(trace_fraction >= 1 && !self.noalign)
166                         org = loc + '0 -18 0';
167                 else
168                 {
169                         objerror(error_msg);
170                         return;
171                 }
172         }
173         
174         if(!self.noalign)
175                 setorigin(self, org);
176 }
177
178 // NOTE: DO NOT USE THIS FUNCTION TOO OFTEN.
179 // IT WILL MOST PROBABLY DESTROY _ALL_ OTHER TEMP
180 // STRINGS AND TAKE QUITE LONG. haystack and needle MUST
181 // BE CONSTANT OR strzoneD!
182 float(string haystack, string needle, float offset) strstr =
183 {
184         float len, endpos;
185         string found;
186         len = strlen(needle);
187         endpos = strlen(haystack) - len;
188         while(offset < endpos)
189         {
190                 found = substring(haystack, offset, len);
191                 if(found == needle)
192                         return offset;
193                 offset = offset + 1;
194         }
195         return -1;
196 }
197
198 float NUM_NEAREST_ENTITIES = 4;
199 entity nearest_entity[NUM_NEAREST_ENTITIES];
200 float nearest_length[NUM_NEAREST_ENTITIES];
201 entity(vector point, .string field, string value, vector axismod) findnearest =
202 {
203         entity localhead;
204         float i;
205         float j;
206         float len;
207         vector dist;
208
209         float num_nearest;
210         num_nearest = 0;
211
212         localhead = find(world, field, value);
213         while(localhead)
214         {
215                 if((localhead.items == IT_KEY1 || localhead.items == IT_KEY2) && localhead.target == "###item###")
216                         dist = localhead.oldorigin;
217                 else
218                         dist = localhead.origin;
219                 dist = dist - point;
220                 dist = dist_x * axismod_x * '1 0 0' + dist_y * axismod_y * '0 1 0' + dist_z * axismod_z * '0 0 1';
221                 len = vlen(dist);
222
223                 for(i = 0; i < num_nearest; ++i)
224                 {
225                         if(len < nearest_length[i])
226                                 break;
227                 }
228
229                 // now i tells us where to insert at
230                 //   INSERTION SORT! YOU'VE SEEN IT! RUN!
231                 if(i < NUM_NEAREST_ENTITIES)
232                 {
233                         for(j = NUM_NEAREST_ENTITIES - 1; j >= i; --j)
234                         {
235                                 nearest_length[j + 1] = nearest_length[j];
236                                 nearest_entity[j + 1] = nearest_entity[j];
237                         }
238                         nearest_length[i] = len;
239                         nearest_entity[i] = localhead;
240                         if(num_nearest < NUM_NEAREST_ENTITIES)
241                                 num_nearest = num_nearest + 1;
242                 }
243                 
244                 localhead = find(localhead, field, value);
245         }
246
247         // now use the first one from our list that we can see
248         for(i = 0; i < num_nearest; ++i)
249         {
250                 traceline(point, nearest_entity[i].origin, TRUE, world);
251                 if(trace_fraction == 1)
252                 {
253                         if(i != 0)
254                         {
255                                 dprint("Nearest point (");
256                                 dprint(nearest_entity[0].netname);
257                                 dprint(") is not visible, using a visible one.\n");
258                         }
259                         return nearest_entity[i];
260                 }
261         }
262
263         if(num_nearest == 0)
264                 return world;
265
266         dprint("Not seeing any location point, using nearest as fallback.\n");
267         /* DEBUGGING CODE:
268         dprint("Candidates were: ");
269         for(j = 0; j < num_nearest; ++j)
270         {
271                 if(j != 0)
272                         dprint(", ");
273                 dprint(nearest_entity[j].netname);
274         }
275         dprint("\n");
276         */
277
278         return nearest_entity[0];
279 }
280
281 void() target_location =
282 {   
283         self.classname = "target_location";
284         // location name in netname
285         // eventually support: count, teamgame selectors, line of sight?
286 };  
287
288 void() info_location =
289 {   
290         self.classname = "target_location";
291         self.message = self.netname;
292 };  
293
294 string NearestLocation(vector p)
295 {
296         entity loc;
297         string ret;
298         ret = "somewhere";
299         loc = findnearest(p, classname, "target_location", '1 1 1');
300         if(loc)
301         {
302                 ret = loc.message;
303         }
304         else
305         {
306                 loc = findnearest(p, target, "###item###", '1 1 4');
307                 if(loc)
308                         ret = loc.netname;
309         }
310         return ret;
311 }
312
313 string(string msg) formatmessage =
314 {
315         float p;
316         float n;
317         string msg_save;
318         string escape;
319         string replacement;
320         msg_save = strzone(msg);
321         p = 0;
322         n = 7;
323         while(1)
324         {
325                 if(n < 1)
326                         break; // too many replacements
327                 n = n - 1;
328                 p = strstr(msg_save, "%", p); // NOTE: this destroys msg as it's a tempstring!
329                 if(p < 0)
330                         break;
331                 replacement = substring(msg_save, p, 2);
332                 escape = substring(msg_save, p + 1, 1);
333                 if(escape == "%")
334                         replacement = "%";
335                 else if(escape == "a")
336                         replacement = ftos(floor(self.armorvalue));
337                 else if(escape == "h")
338                         replacement = ftos(floor(self.health));
339                 else if(escape == "l")
340                         replacement = NearestLocation(self.origin);
341                 else if(escape == "y")
342                         replacement = NearestLocation(self.cursor_trace_endpos);
343                 else if(escape == "d")
344                         replacement = NearestLocation(self.death_origin);
345                 else if(escape == "w")
346                 {
347                         float wep;
348                         wep = self.weapon;
349                         if(!wep)
350                                 wep = self.switchweapon;
351                         if(!wep)
352                                 wep = self.cnt;
353                         replacement = W_Name(wep);
354                 }
355                 else if(escape == "W")
356                 {
357                         if(self.items & IT_SHELLS) replacement = "shells";
358                         else if(self.items & IT_NAILS) replacement = "bullets";
359                         else if(self.items & IT_ROCKETS) replacement = "rockets";
360                         else if(self.items & IT_CELLS) replacement = "cells";
361                         else replacement = "batteries"; // ;)
362                 }
363                 else if(escape == "x")
364                 {
365                         replacement = self.cursor_trace_ent.netname;
366                         if(!replacement || !self.cursor_trace_ent)
367                                 replacement = "nothing";
368                 }
369                 msg = strcat(substring(msg_save, 0, p), replacement);
370                 msg = strcat(msg, substring(msg_save, p+2, strlen(msg_save) - (p+2)));
371                 strunzone(msg_save);
372                 msg_save = strzone(msg);
373                 p = p + 2;
374         }
375         msg = strcat(msg_save);
376         strunzone(msg_save);
377         return msg;
378 }
379
380 /*
381 =============
382 GetCvars
383 =============
384 Called with:
385   0:  sends the request
386   >0: receives a cvar from name=argv(f) value=argv(f+1)
387 */
388 void GetCvars_handleString(float f, .string field, string name)
389 {
390         if(f)
391         {
392                 if(argv(f) == name)
393                         self.field = argv(f + 1);
394         }
395         else
396                 stuffcmd(self, strcat("cmd reportcvar ", name, " $", name, "\n"));
397 }
398 void GetCvars_handleFloat(float f, .float field, string name)
399 {
400         if(f)
401         {
402                 if(argv(f) == name)
403                         self.field = stof(argv(f + 1));
404         }
405         else
406                 stuffcmd(self, strcat("cmd reportcvar ", name, " $", name, "\n"));
407 }
408 void GetCvars(float f)
409 {
410         GetCvars_handleFloat(f, cvar_cl_playerdetailreduction, "cl_playerdetailreduction");
411         GetCvars_handleFloat(f, cvar_cl_nogibs, "cl_nogibs");
412 }
413
414 float fexists(string f)
415 {
416         float fh;
417         fh = fopen(f, FILE_READ);
418         if(fh < 0)
419                 return FALSE;
420         fclose(fh);
421         return TRUE;
422 }