]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/common/util.qc
map list can now search a map name while you type it
[divverent/nexuiz.git] / data / qcsrc / common / util.qc
1 string wordwrap_buffer;
2
3 void wordwrap_buffer_put(string s)
4 {
5         wordwrap_buffer = strcat(wordwrap_buffer, s);
6 }
7
8 string wordwrap(string s, float l)
9 {
10         wordwrap_buffer = "";
11         wordwrap_cb(s, l, wordwrap_buffer_put);
12         return wordwrap_buffer;
13 }
14
15 #ifndef MENUQC
16 void wordwrap_buffer_sprint(string s)
17 {
18         wordwrap_buffer = strcat(wordwrap_buffer, s);
19         if(s == "\n")
20         {
21                 sprint(self, wordwrap_buffer);
22                 wordwrap_buffer = "";
23         }
24 }
25
26 void wordwrap_sprint(string s, float l)
27 {
28         wordwrap_buffer = "";
29         wordwrap_cb(s, l, wordwrap_buffer_sprint);
30         if(wordwrap_buffer != "")
31                 sprint(self, strcat(wordwrap_buffer, "\n"));
32         return;
33 }
34 #endif
35
36 void wordwrap_cb(string s, float l, void(string) callback)
37 {
38         local string c;
39         local float lleft, i, j, wlen;
40
41         s = strzone(s);
42         lleft = l;
43         for (i = 0;i < strlen(s);i++)
44         {
45                 if (substring(s, i, 2) == "\\n")
46                 {
47                         callback("\n");
48                         lleft = l;
49                         i++;
50                 }
51                 else if (substring(s, i, 1) == "\n")
52                 {
53                         callback("\n");
54                         lleft = l;
55                 }
56                 else if (substring(s, i, 1) == " ")
57                 {
58                         if (lleft > 0)
59                         {
60                                 callback(" ");
61                                 lleft = lleft - 1;
62                         }
63                 }
64                 else
65                 {
66                         for (j = i+1;j < strlen(s);j++)
67                                 //    ^^ this skips over the first character of a word, which
68                                 //       is ALWAYS part of the word
69                                 //       this is safe since if i+1 == strlen(s), i will become
70                                 //       strlen(s)-1 at the end of this block and the function
71                                 //       will terminate. A space can't be the first character we
72                                 //       read here, and neither can a \n be the start, since these
73                                 //       two cases have been handled above.
74                         {
75                                 c = substring(s, j, 1);
76                                 if (c == " ")
77                                         break;
78                                 if (c == "\\")
79                                         break;
80                                 if (c == "\n")
81                                         break;
82                                 // we need to keep this tempstring alive even if substring is
83                                 // called repeatedly, so call strcat even though we're not
84                                 // doing anything
85                                 callback("");
86                         }
87                         wlen = j - i;
88                         if (lleft < wlen)
89                         {
90                                 callback("\n");
91                                 lleft = l;
92                         }
93                         callback(substring(s, i, wlen));
94                         lleft = lleft - wlen;
95                         i = j - 1;
96                 }
97         }
98         strunzone(s);
99 }
100
101 float dist_point_line(vector p, vector l0, vector ldir)
102 {
103         ldir = normalize(ldir);
104         
105         // remove the component in line direction
106         p = p - (p * ldir) * ldir;
107
108         // vlen of the remaining vector
109         return vlen(p);
110 }
111
112 void depthfirst(entity start, .entity up, .entity downleft, .entity right, void(entity, entity) funcPre, void(entity, entity) funcPost, entity pass)
113 {
114         entity e;
115         e = start;
116         funcPre(pass, e);
117         while(e.downleft)
118         {
119                 e = e.downleft;
120                 funcPre(pass, e);
121         }
122         funcPost(pass, e);
123         while(e != start)
124         {
125                 if(e.right)
126                 {
127                         e = e.right;
128                         funcPre(pass, e);
129                         while(e.downleft)
130                         {
131                                 e = e.downleft;
132                                 funcPre(pass, e);
133                         }
134                 }
135                 else
136                         e = e.up;
137                 funcPost(pass, e);
138         }
139 }
140
141 float median(float a, float b, float c)
142 {
143         if(a < c)
144                 return bound(a, b, c);
145         return bound(c, b, a);
146 }
147
148 // converts a number to a string with the indicated number of decimals
149 // works for up to 10 decimals!
150 string ftos_decimals(float number, float decimals)
151 {
152         string result;
153         string tmp;
154         float len;
155
156         // if negative, cut off the sign first
157         if(number < 0)
158                 return strcat("-", ftos_decimals(-number, decimals));
159         // it now is always positive!
160
161         // 3.516 -> 352
162         number = floor(number * pow(10, decimals) + 0.5);
163
164         // 352 -> "352"
165         result = ftos(number);
166         len = strlen(result);
167         // does it have a decimal point (should not happen)? If there is one, it is always at len-7)
168                 // if ftos had fucked it up, which should never happen: "34278.000000"
169         if(len >= 7)
170                 if(substring(result, len - 7, 1) == ".")
171                 {
172                         dprint("ftos(integer) has comma? Can't be. Affected result: ", result, "\n");
173                         result = substring(result, 0, len - 7);
174                         len -= 7;
175                 }
176                 // "34278"
177         if(decimals == 0)
178                 return result; // don't insert a point for zero decimals
179         // is it too short? If yes, insert leading zeroes
180         if(len <= decimals)
181         {
182                 result = strcat(substring("0000000000", 0, decimals - len + 1), result);
183                 len = decimals + 1;
184         }
185         // and now... INSERT THE POINT!
186         tmp = substring(result, len - decimals, decimals);
187         result = strcat(substring(result, 0, len - decimals), ".", tmp);
188         return result;
189 }
190
191 float time;
192 vector colormapPaletteColor(float c, float isPants)
193 {
194         switch(c)
195         {
196                 case  0: return '0.733 0.733 0.733';
197                 case  1: return '0.451 0.341 0.122';
198                 case  2: return '0.000 0.733 0.733';
199                 case  3: return '0.000 1.000 0.000';
200                 case  4: return '1.000 0.000 0.000';
201                 case  5: return '0.000 0.502 1.000';
202                 case  6: return '0.812 0.561 0.169';
203                 case  7: return '0.718 0.529 0.420';
204                 case  8: return '0.765 0.545 0.667';
205                 case  9: return '1.000 0.000 1.000';
206                 case 10: return '0.639 0.529 0.482';
207                 case 11: return '0.310 0.388 0.341';
208                 case 12: return '1.000 1.000 0.000';
209                 case 13: return '0.000 0.000 1.000';
210                 case 14: return '1.000 0.502 0.000';
211                 case 15:
212                         if(isPants)
213                                 return
214                                           '1 0 0' * (0.502 + 0.498 * sin(time / 2.7182818285 + 0.0000000000))
215                                         + '0 1 0' * (0.502 + 0.498 * sin(time / 2.7182818285 + 2.0943951024))
216                                         + '0 0 1' * (0.502 + 0.498 * sin(time / 2.7182818285 + 4.1887902048));
217                         else
218                                 return
219                                           '1 0 0' * (0.502 + 0.498 * sin(time / 3.1415926536 + 5.2359877560))
220                                         + '0 1 0' * (0.502 + 0.498 * sin(time / 3.1415926536 + 3.1415926536))
221                                         + '0 0 1' * (0.502 + 0.498 * sin(time / 3.1415926536 + 1.0471975512));
222                 default: return '0.000 0.000 0.000';
223         }
224 }
225
226 // unzone the string, and return it as tempstring. Safe to be called on string_null
227 string fstrunzone(string s)
228 {
229         string sc;
230         if not(s)
231                 return s;
232         sc = strcat(s, "");
233         strunzone(s);
234         return sc;
235 }