]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/common/gamecommand.qc
Nothing sets flashblend, so remove it.
[divverent/nexuiz.git] / data / qcsrc / common / gamecommand.qc
1 #define MAX_RPN_STACK 8
2 float rpn_error;
3 float rpn_sp;
4 string rpn_stack[MAX_RPN_STACK];
5 string rpn_pop() {
6         if(rpn_sp > 0) {
7                 --rpn_sp;
8                 return rpn_stack[rpn_sp];
9         } else {
10                 print("rpn: stack underflow\n");
11                 rpn_error = TRUE;
12                 return "";
13         }
14 }
15 void rpn_push(string s) {
16         if(rpn_sp < MAX_RPN_STACK) {
17                 rpn_stack[rpn_sp] = s;
18                 ++rpn_sp;
19         } else {
20                 print("rpn: stack overflow\n");
21                 rpn_error = TRUE;
22         }
23 }
24 string rpn_get() {
25         if(rpn_sp > 0) {
26                 return rpn_stack[rpn_sp - 1];
27         } else {
28                 print("rpn: empty stack\n");
29                 rpn_error = TRUE;
30                 return "";
31         }
32 }
33 void rpn_set(string s) {
34         if(rpn_sp > 0) {
35                 rpn_stack[rpn_sp - 1] = s;
36         } else {
37                 print("rpn: empty stack\n");
38                 rpn_error = TRUE;
39         }
40 }
41 float rpn_getf() { return stof(rpn_get()); }
42 float rpn_popf() { return stof(rpn_pop()); }
43 void rpn_pushf(float f) { return rpn_push(ftos(f)); }
44 void rpn_setf(float f) { return rpn_set(ftos(f)); }
45
46 float GameCommand_Generic(string command)
47 {
48         float argc;
49         argc = tokenize(command);
50         if(argv(0) == "help")
51         {
52                 print("  rpn EXPRESSION... - a RPN calculator.\n");
53                 print("    Operator description (x: string, s: set, f: float):\n");
54                 print("    x pop ----------------------------->     : removes the top\n");
55                 print("    x dup -----------------------------> x x : duplicates the top\n");
56                 print("    x x exch --------------------------> x x : swap the top two\n");
57                 print("    /cvarname load --------------------> x   : loads a cvar\n");
58                 print("    /cvarname x def ------------------->     : writes to a cvar\n");
59                 print("    f f add|sub|mul|div|mod -----------> f   : adds/... two numbers\n");
60                 print("    f neg|abs|sgn|rand ----------------> f   : negates/... a number\n");
61                 print("    s s union|intersection|difference -> s   : set operations\n");
62                 print("    s shuffle -------------------------> s   : randomly arrange elements\n");
63                 print("    Set operations operate on 'such''strings' like g_maplist.\n");
64                 print("    Unknown tokens insert their cvar value.\n");
65                 return TRUE;
66         }
67         
68         if(argv(0) == "rpn")
69         {
70                 if(argc >= 2)
71                 {
72                         float rpnpos;
73                         string rpncmd;
74                         string s, s2;
75                         float f, f2;
76                         float i, j;
77                         rpn_sp = 0;
78                         rpn_error = FALSE;
79                         for(rpnpos = 1; rpnpos < argc; ++rpnpos)
80                         {
81                                 rpncmd = argv(rpnpos);
82                                 f = strlen(rpncmd);
83                                 if(rpncmd == "") {
84                                 } else if(stof(substring(rpncmd, 0, 1)) > 0) {
85                                         rpn_push(rpncmd);
86                                 } else if(substring(rpncmd, 0, 1) == "0") {
87                                         rpn_push(rpncmd);
88                                 } else if(f >= 2 && substring(rpncmd, 0, 1) == "+") {
89                                         rpn_push(rpncmd);
90                                 } else if(f >= 2 && substring(rpncmd, 0, 1) == "-") {
91                                         rpn_push(rpncmd);
92                                 } else if(f >= 2 && substring(rpncmd, 0, 1) == "/") {
93                                         rpn_push(substring(rpncmd, 1, strlen(rpncmd) - 1));
94                                 } else if(rpncmd == "def" || rpncmd == "=") {
95                                         s = rpn_pop();
96                                         s2 = rpn_pop();
97 #ifdef MENUQC
98                                         registercvar(s2, "", 0);
99 #else
100                                         registercvar(s2, "");
101 #endif
102                                         if(!rpn_error) // don't change cvars if a stack error had happened!
103                                                 cvar_set(s2, s);
104                                 } else if(rpncmd == "load") {
105                                         rpn_set(cvar_string(rpn_get()));
106                                 } else if(rpncmd == "exch") {
107                                         s = rpn_pop();
108                                         s2 = rpn_get();
109                                         rpn_set(s);
110                                         rpn_push(s2);
111                                 } else if(rpncmd == "dup") {
112                                         rpn_push(rpn_get());
113                                 } else if(rpncmd == "pop") {
114                                         rpn_pop();
115                                 } else if(rpncmd == "add" || rpncmd == "+") {
116                                         f = rpn_popf();
117                                         rpn_setf(rpn_getf() + f);
118                                 } else if(rpncmd == "sub" || rpncmd == "-") {
119                                         f = rpn_popf();
120                                         rpn_setf(rpn_getf() - f);
121                                 } else if(rpncmd == "mul" || rpncmd == "*") {
122                                         f = rpn_popf();
123                                         rpn_setf(rpn_getf() * f);
124                                 } else if(rpncmd == "div" || rpncmd == "/") {
125                                         f = rpn_popf();
126                                         rpn_setf(rpn_getf() / f);
127                                 } else if(rpncmd == "mod" || rpncmd == "%") {
128                                         f = rpn_popf();
129                                         f2 = rpn_getf();
130                                         rpn_setf(f2 - f * floor(f2 / f));
131                                 } else if(rpncmd == "abs") {
132                                         rpn_setf(fabs(rpn_getf()));
133                                 } else if(rpncmd == "sgn") {
134                                         f = rpn_getf();
135                                         if(f < 0)
136                                                 rpn_set("-1");
137                                         else if(f > 0)
138                                                 rpn_set("1");
139                                         else
140                                                 rpn_set("0");
141                                 } else if(rpncmd == "neg" || rpncmd == "~") {
142                                         rpn_setf(-rpn_getf());
143                                 } else if(rpncmd == "rand") {
144                                         rpn_setf(ceil(random() * rpn_getf()) - 1);
145                                 } else if(rpncmd == "union") {
146                                         // s s2 union
147                                         s2 = rpn_pop();
148                                         s = rpn_get();
149                                         f = tokenize(s);
150                                         f2 = tokenize(strcat(s, s2));
151                                         // tokens 0..(f-1) represent s
152                                         // tokens f..f2 represent s2
153                                         // UNION: add all tokens to s that are in s2 but not in s
154                                         s = "";
155                                         for(i = 0; i < f; ++i)
156                                                 s = strcat(s, "'", argv(i), "'");
157                                         for(i = f; i < f2; ++i) {
158                                                 for(j = 0; j < f; ++j)
159                                                         if(argv(i) == argv(j))
160                                                                 goto skip_union;
161                                                 s = strcat(s, "'", argv(i), "'");
162 :skip_union
163                                         }
164                                         rpn_set(s);
165                                         tokenize(command);
166                                 } else if(rpncmd == "intersection") {
167                                         // s s2 intersection
168                                         s2 = rpn_pop();
169                                         s = rpn_get();
170                                         f = tokenize(s);
171                                         f2 = tokenize(strcat(s, s2));
172                                         // tokens 0..(f-1) represent s
173                                         // tokens f..f2 represent s2
174                                         // INTERSECTION: keep only the tokens from s that are also in s2
175                                         s = "";
176                                         for(i = 0; i < f; ++i) {
177                                                 for(j = f; j < f2; ++j)
178                                                         if(argv(i) == argv(j))
179                                                         {
180                                                                 s = strcat(s, "'", argv(i), "'");
181                                                                 break;
182                                                         }
183                                         }
184                                         rpn_set(s);
185                                         tokenize(command);
186                                 } else if(rpncmd == "difference") {
187                                         // s s2 difference
188                                         s2 = rpn_pop();
189                                         s = rpn_get();
190                                         f = tokenize(s);
191                                         f2 = tokenize(strcat(s, s2));
192                                         // tokens 0..(f-1) represent s
193                                         // tokens f..f2 represent s2
194                                         // DIFFERENCE: keep only the tokens from s that are not in s2
195                                         s = "";
196                                         for(i = 0; i < f; ++i) {
197                                                 for(j = f; j < f2; ++j)
198                                                         if(argv(i) == argv(j))
199                                                                 goto skip_difference;
200                                                 s = strcat(s, "'", argv(i), "'");
201 :skip_difference
202                                         }
203                                         rpn_set(s);
204                                         tokenize(command);
205                                 } else if(rpncmd == "shuffle") {
206                                         // s shuffle
207                                         s = rpn_get();
208                                         f = tokenize(s);
209
210                                         for(i = 0; i < f - 1; ++i) {
211                                                 // move a random item from i..f-1 to position i
212                                                 s = "";
213                                                 f2 = ceil(random() * (f - i) + i) - 1;
214                                                 for(j = 0; j < i; ++j)
215                                                         s = strcat(s, "'", argv(j), "'");
216                                                 s = strcat(s, "'", argv(f2), "'");
217                                                 for(j = i; j < f; ++j)
218                                                         if(j != f2)
219                                                                 s = strcat(s, "'", argv(j), "'");
220                                                 f = tokenize(s);
221                                         }
222
223                                         rpn_set(s);
224                                         tokenize(command);
225                                 } else if(rpncmd == "fexists_assert") {
226                                         s = rpn_pop();
227                                         if(!rpn_error)
228                                         {
229                                                 f = fopen(s, FILE_READ);
230                                                 if(f != -1)
231                                                         fclose(f);
232                                                 else {
233                                                         print("rpn: ERROR: ", s, " does not exist!\n");
234                                                         rpn_error = TRUE;
235                                                 }
236                                         }
237                                 } else {
238                                         rpn_push(cvar_string(rpncmd));
239                                 }
240                                 if(rpn_error)
241                                         break;
242                         }
243                         while(rpn_sp > 0)
244                         {
245                                 s = rpn_pop();
246                                 print("rpn: still on stack: ", s, "\n");
247                         }
248                         return TRUE;
249                 }
250         }
251
252         return FALSE;
253 }