Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
script_callbacks.cpp
Go to the documentation of this file.
1 /*
4  * Vega Strike
5  * Copyright (C) 2001-2002 Daniel Horn
6  *
7  * http://vegastrike.sourceforge.net/
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22  */
23 
24 /*
25  * xml Mission Scripting written by Alexander Rawass <alexannika@users.sourceforge.net>
26  */
27 #include <algorithm>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <errno.h>
31 #include <time.h>
32 #include <ctype.h>
33 #include <assert.h>
34 #ifndef WIN32
35 //this file isn't available on my system (all win32 machines?) i dun even know what it has or if we need it as I can compile without it
36 #include <unistd.h>
37 #endif
38 
39 #include <expat.h>
40 #include "xml_support.h"
41 #include "vegastrike.h"
42 #include "lin_time.h"
43 
44 #include "cmd/unit_generic.h"
45 #include "mission.h"
46 #include "easydom.h"
47 
48 #include "msgcenter.h"
49 #include "pythonmission.h"
50 
51 using std::cout;
52 using std::cerr;
53 using std::endl;
54 
55 string varToString( varInst *vi )
56 {
57  switch (vi->type)
58  {
59  case VAR_FLOAT:
60  return XMLSupport::tostring( (float) vi->float_val );
61  case VAR_INT:
62  return XMLSupport::tostring( vi->int_val );
63  case VAR_BOOL:
64  return XMLSupport::tostring( vi->bool_val );
65  case VAR_OBJECT:
66  default:
67  if (vi->objectname == "string")
68  return *( (string*) vi->object );
69  else
70  return XMLSupport::tostring( (long) vi->object );
71  }
72 }
73 
74 void Mission::doCall_toxml( string module, varInst *ovi )
75 {
76  if (module == "_olist")
77  call_olist_toxml( NULL, SCRIPT_RUN, ovi );
78  else if (module == "_unit")
79  call_unit_toxml( NULL, SCRIPT_RUN, ovi );
80 }
81 
82 varInst* Mission::doCall( missionNode *node, int mode, string module, string method )
83 {
84  varInst *vi = NULL;
86  if (module_id == CMT_UNIT) {
87  vi = call_unit( node, mode );
88  } else if (module_id == CMT_STD) {
89  if (mode == SCRIPT_PARSE)
90  node->script.method_id = module_std_map[method];
92  if (method_id == CMT_STD_Rnd) {
93  vi = callRnd( node, mode );
94  } else if (method_id == CMT_STD_getGameTime) {
95  vi = callGetGameTime( node, mode );
96  } else if (method_id == CMT_STD_ResetTimeCompression) {
97  vi = callResetTimeCompression( node, mode );
98  } else if (0) {
99  vi = callGetSystemName( node, mode );
100  } else if (method_id == CMT_STD_getSystemFile) {
101  vi = callGetSystemFile( node, mode );
102  } else if (method_id == CMT_STD_getCurrentAIUnit) {
103  vi = callGetCurrentAIUnit( node, mode );
104  } else if (method_id == CMT_STD_getCurrentAIOrder) {
105  vi = callGetCurrentAIOrder( node, mode );
106  } else if (method_id == CMT_STD_isNull) {
107  vi = call_isNull( node, mode );
108  } else if (method_id == CMT_STD_setNull) {
109  vi = call_setNull( node, mode );
110  } else if (method_id == CMT_STD_equal) {
111  vi = call_isequal( node, mode );
112  } else if (method_id == CMT_STD_Float) {
113  vi = call_float_cast( node, mode );
114  } else if (method_id == CMT_STD_Int) {
115  vi = call_int_cast( node, mode );
116  } else if (method_id == CMT_STD_getGalaxyProperty) {
117  vi = callGetGalaxyProperty( node, mode );
118  } else if (method_id == CMT_STD_musicAddList) {
119  vi = call_musicAddList( node, mode );
120  } else if (method_id == CMT_STD_musicPlaySong) {
121  vi = call_musicPlaySong( node, mode );
122  } else if (method_id == CMT_STD_musicPlayList) {
123  vi = call_musicPlayList( node, mode );
124  } else if (method_id == CMT_STD_getDifficulty) {
125  vi = newVarInst( VI_TEMP );
126  vi->type = VAR_FLOAT;
128  } else if (method_id == CMT_STD_setDifficulty) {
129  float diff = getFloatArg( node, mode, 0 );
130  if (mode == SCRIPT_RUN)
131  g_game.difficulty = diff;
132  vi = newVarInst( VI_TEMP );
133  vi->type = VAR_VOID;
134  } else if (method_id == CMT_STD_getNumAdjacentSystems) {
135  vi = callGetNumAdjacentSystems( node, mode );
136  } else if (method_id == CMT_STD_getAdjacentSystem) {
137  vi = callGetAdjacentSystem( node, mode );
138  } else if (method_id == CMT_STD_terminateMission) {
139  vi = call_terminateMission( node, mode );
140  } else if (method_id == CMT_STD_playSound) {
141  std::string soundName = getStringArgument( node, mode, 0 );
142  QVector loc;
143  loc.i = getFloatArg( node, mode, 1 );
144  loc.j = getFloatArg( node, mode, 2 );
145  loc.k = getFloatArg( node, mode, 3 );
146  Vector speed( 0, 0, 0 );
147  if (node->subnodes.size() > 6) {
148  speed.i = getFloatArg( node, mode, 4 );
149  speed.j = getFloatArg( node, mode, 5 );
150  speed.k = getFloatArg( node, mode, 6 );
151  }
152  vi = newVarInst( VI_TEMP );
153  vi->type = VAR_VOID;
154  } else if (method_id == CMT_STD_playSoundCockpit) {
155  std::string soundName = getStringArgument( node, mode, 0 );
156  } else if (method_id == CMT_STD_playAnimation) {
157  std::string aniName = getStringArgument( node, mode, 0 );
158  QVector loc( 0, 0, 0 );
159  loc.i = getFloatArg( node, mode, 1 );
160  loc.j = getFloatArg( node, mode, 2 );
161  loc.k = getFloatArg( node, mode, 3 );
162  vi = newVarInst( VI_TEMP );
163  vi->type = VAR_VOID;
164  }
165  } else if (module_id == CMT_OLIST) {
166  vi = call_olist( node, mode );
167  } else if (module_id == CMT_OMAP) {
168  vi = call_omap( node, mode );
169  } else if (module_id == CMT_ORDER) {
170  vi = call_order( node, mode );
171  } else if (module_id == CMT_STRING) {
172  vi = call_string( node, mode );
173  } else if (module_id == CMT_IO) {
174  if (method == "PrintFloats")
175  vi = callPrintFloats( node, mode );
176  else if (method == "printf")
177  vi = call_io_printf( node, mode );
178  else if (method == "sprintf")
179  vi = call_io_sprintf( node, mode );
180  else if (method == "message")
181  vi = call_io_message( node, mode );
182  else if (method == "printMsgList")
183  vi = call_io_printmsglist( node, mode );
184  } else if (module_id == CMT_BRIEFING) {
185  vi = call_briefing( node, mode );
186  }
187  return vi;
188 }
189 
190 varInst* Mission::doCall( missionNode *node, int mode )
191 {
192  trace( node, mode );
193  if (mode == SCRIPT_PARSE) {
194  string name = node->attr_value( "name" );
195  string module = node->attr_value( "module" );
196  string object = node->attr_value( "object" );
197  if ( object.empty() && module.empty() ) {
198  fatalError( node, mode, "you have to give a callback object or module" );
199  assert( 0 );
200  }
201  if ( name.empty() ) {
202  fatalError( node, mode, "you have to give a callback name" );
203  assert( 0 );
204  }
205  node->script.name = name;
206  callback_module_type module_id = module_map[module];
207  node->script.callback_module_id = module_id;
208  }
209  //RUNTIME && PARSE
210  string module = node->attr_value( "module" );
211  if ( module.empty() ) {
212  //does not work yet
213  string object = node->attr_value( "object" );
214  assert( 0 );
215  varInst *ovi = NULL;
216  if (ovi == NULL) {
217  fatalError( node, mode, "no object found with name "+object );
218  assert( 0 );
219  }
220  if (ovi->type != VAR_OBJECT) {
221  fatalError( node, mode, "given variable"+object+" is not an object" );
222  assert( 0 );
223  }
224  module = ovi->objectname;
225  if ( module.empty() ) {
226  fatalError( node, mode, "object "+object+" not yet initialized" );
227  assert( 0 );
228  }
229  module = "_"+module;
230  }
231  string method = node->script.name;
232  varInst *vi = NULL;
233  vi = doCall( node, mode, module, method );
234  if (vi == NULL) {
235  fatalError( node, mode, "no such callback named "+module+"."+node->script.name );
236  assert( 0 );
237  }
238  return vi;
239 }
240 
241 
242 varInst* Mission::call_isNull( missionNode *node, int mode )
243 {
244  varInst *ovi = getObjectArg( node, mode );
245  varInst *viret = newVarInst( VI_TEMP );
246  viret->type = VAR_BOOL;
247  viret->bool_val = (ovi->object == NULL);
248  deleteVarInst( ovi );
249  return viret;
250 }
251 
252 varInst* Mission::call_setNull( missionNode *node, int mode )
253 {
254  varInst *ovi = getObjectArg( node, mode );
255  ovi->object = NULL;
256  varInst *viret = newVarInst( VI_TEMP );
257  viret->type = VAR_VOID;
258  deleteVarInst( ovi );
259  return viret;
260 }
261 
262 varInst* Mission::call_terminateMission( missionNode *node, int mode )
263 {
264  getBoolArg( node, mode, 0 );
265  if (mode == SCRIPT_RUN)
267  varInst *viret = newVarInst( VI_TEMP );
268  viret->type = VAR_VOID;
269  return viret;
270 }
271 
272 varInst* Mission::call_float_cast( missionNode *node, int mode )
273 {
274  missionNode *snode = getArgument( node, mode, 0 );
275  int intval = checkIntExpr( snode, mode );
276  varInst *viret = newVarInst( VI_TEMP );
277  viret->type = VAR_FLOAT;
278  viret->float_val = (float) intval;
279  return viret;
280 }
281 
282 varInst* Mission::call_int_cast( missionNode *node, int mode )
283 {
284  missionNode *snode = getArgument( node, mode, 0 );
285  double floatval = checkFloatExpr( snode, mode );
286  varInst *viret = newVarInst( VI_TEMP );
287  viret->type = VAR_INT;
288  viret->int_val = (int) floatval;
289  return viret;
290 }
291 
292 varInst* Mission::call_isequal( missionNode *node, int mode )
293 {
294  varInst *ovi = getObjectArg( node, mode );
295  missionNode *other_node = getArgument( node, mode, 1 );
296  varInst *other_vi = checkObjectExpr( other_node, mode );
297  varInst *viret = newVarInst( VI_TEMP );
298  viret->type = VAR_BOOL;
299  bool res = false;
300  if (mode == SCRIPT_RUN) {
301  if (other_vi->objectname == ovi->objectname)
302  if (other_vi->object == ovi->object)
303  res = true;
304  }
305  deleteVarInst( ovi );
306  deleteVarInst( other_vi );
307  viret->bool_val = res;
308  return viret;
309 }
310 
311 varInst* Mission::callGetGameTime( missionNode *node, int mode )
312 {
313  varInst *vi = newVarInst( VI_TEMP );
314  vi->type = VAR_FLOAT;
315  if (mode == SCRIPT_RUN)
316  vi->float_val = gametime;
317  return vi;
318 }
319 
320 varInst* Mission::callResetTimeCompression( missionNode *node, int mode )
321 {
322  varInst *vi = newVarInst( VI_TEMP );
323  vi->type = VAR_VOID;
324  if (mode == SCRIPT_RUN)
325  setTimeCompression( 1.0 );
326  return vi;
327 }
328 
329 varInst* Mission::callGetSystemName( missionNode *node, int mode )
330 {
331  varInst *vi = newVarInst( VI_TEMP );
332  vi->type = VAR_OBJECT;
333  vi->objectname = "string";
334  if (mode == SCRIPT_RUN) {
335  deleteVarInst( vi );
336  StarSystem *ssystem = _Universe->activeStarSystem();
337  string sysname = ssystem->getName();
338  vi = call_string_new( node, mode, sysname );
339  }
340  return vi;
341 }
342 
343 varInst* Mission::callGetSystemFile( missionNode *node, int mode, StarSystem *ss )
344 {
345  varInst *vi = newVarInst( VI_TEMP );
346  vi->type = VAR_OBJECT;
347  vi->objectname = "string";
348  if (mode == SCRIPT_RUN) {
349  deleteVarInst( vi );
350  if (ss == NULL)
351  ss = _Universe->activeStarSystem();
352  string sysname = ss->getFileName();
353  vi = call_string_new( node, mode, sysname );
354  }
355  return vi;
356 }
357 
358 varInst* Mission::callGetAdjacentSystem( missionNode *node, int mode )
359 {
360  varInst *vi = newVarInst( VI_TEMP );
361  vi->type = VAR_OBJECT;
362  vi->objectname = "string";
363  string str = getStringArgument( node, mode, 0 );
364  int which = (int) getIntArg( node, mode, 1 );
365  if (mode == SCRIPT_RUN) {
366  deleteVarInst( vi );
367  const string &sysname = _Universe->getAdjacentStarSystems( str )[which];
368  vi = call_string_new( node, mode, sysname );
369  }
370  return vi;
371 }
372 
373 varInst* Mission::callGetGalaxyProperty( missionNode *node, int mode )
374 {
375  varInst *vi = newVarInst( VI_TEMP );
376  vi->type = VAR_OBJECT;
377  vi->objectname = "string";
378  string sys = getStringArgument( node, mode, 0 );
379  string prop = getStringArgument( node, mode, 1 );
380  if (mode == SCRIPT_RUN) {
381  deleteVarInst( vi );
382  string sysname = _Universe->getGalaxyProperty( sys, prop );
383  vi = call_string_new( node, mode, sysname );
384  }
385  return vi;
386 }
387 
388 varInst* Mission::callGetNumAdjacentSystems( missionNode *node, int mode )
389 {
390  string sysname = getStringArgument( node, mode, 0 );
391  int ret = 0;
392  if (mode == SCRIPT_RUN)
393  ret = _Universe->getAdjacentStarSystems( sysname ).size();
394  varInst *vi = newVarInst( VI_TEMP );
395  vi->type = VAR_INT;
396  vi->int_val = ret;
397  return vi;
398 }
399 
400 varInst* Mission::call_io_printmsglist( missionNode *node, int mode )
401 {
402  int i = 0;
403  if (mode == SCRIPT_RUN) {
404  gameMessage msg;
405  while (msgcenter->last( i, msg, std::vector< std::string > () ) && i < 7.0) {
406  cout<<"MESSAGE"<<msg.message<<endl;
407  i++;
408  }
409  }
410  varInst *viret = newVarInst( VI_TEMP );
411  viret->type = VAR_VOID;
412  return viret;
413 }
414 
415 varInst* Mission::call_io_message( missionNode *node, int mode )
416 {
417  missionNode *args[3];
418  varInst *args_vi[3];
419  string args_str[3];
420  int delay = (int) getIntArg( node, mode, 0 );
421  for (int i = 0; i < 3; i++) {
422  args[i] = getArgument( node, mode, i+1 );
423  args_vi[i] = checkObjectExpr( args[i], mode );
424  if (mode == SCRIPT_RUN)
425  args_str[i] = call_string_getstring( node, mode, args_vi[i] );
426  deleteVarInst( args_vi[i] );
427  }
428  if (mode == SCRIPT_RUN)
429  msgcenter->add( args_str[0], args_str[1], args_str[2], delay );
430  varInst *viret = newVarInst( VI_TEMP );
431  viret->type = VAR_VOID;
432  return viret;
433 }
434 
435 #if 1
436 string Mission::replaceNewline( string origstr )
437 {
438  string ostr = origstr;
439  int breakpos = ostr.find( "\\n", 0 );
440  if (breakpos >= 0) {
441  string newstr = ostr.replace( breakpos, 2, "\n" );
442  return replaceNewline( newstr );
443  } else {
444  return ostr;
445  }
446 }
447 #endif
448 
449 varInst* Mission::call_io_sprintf( missionNode *node, int mode )
450 {
451  missionNode *outstr_node = getArgument( node, mode, 0 );
452  varInst *outstr_vi = checkObjectExpr( outstr_node, mode );
453  string *outstrptr = getStringObject( outstr_node, mode, outstr_vi );
454  char outbuffer[1024];
455  string outstring;
456  missionNode *stringnode = getArgument( node, mode, 1 );
457  if (stringnode->tag != DTAG_CONST) {
458  fatalError( node, mode, "only const string allowed for second arg of sprintf" );
459  assert( 0 );
460  }
461  varInst *str_vi = checkObjectExpr( stringnode, mode );
462  if ( str_vi->type != VAR_OBJECT || (str_vi->type == VAR_OBJECT && str_vi->objectname != "string") ) {
463  fatalError( node, mode, "io.sprintf needs string object as second arg" );
464  assert( 0 );
465  }
466  int nr_of_args = node->subnodes.size();
467  int current_arg = 2;
468  string *fullstringptr;
469  string fullstring;
470  fullstringptr = (string*) str_vi->object;
471  fullstring = *fullstringptr;
472  fullstring = replaceNewline( fullstring );
473  string endstring = fullstring;
474  while (current_arg < nr_of_args) {
475  int breakpos = endstring.find( "%", 0 );
476  string beforestring = endstring.substr( 0, breakpos );
477  string breakstring = endstring.substr( breakpos, 2 );
478  if (breakstring[1] == 'f') {
479  missionNode *anode = getArgument( node, mode, current_arg );
480  double res = checkFloatExpr( anode, mode );
481  if (mode == SCRIPT_RUN) {
482  sprintf( outbuffer, "%s", beforestring.c_str() );
483  outstring += outbuffer;
484  sprintf( outbuffer, "%f", res );
485  outstring += outbuffer;
486  }
487  } else if (breakstring[1] == 'd') {
488  missionNode *anode = getArgument( node, mode, current_arg );
489  int res = checkIntExpr( anode, mode );
490  if (mode == SCRIPT_RUN) {
491  sprintf( outbuffer, "%s", beforestring.c_str() );
492  outstring += outbuffer;
493  sprintf( outbuffer, "%d", res );
494  outstring += outbuffer;
495  }
496  } else if (breakstring[1] == 's') {
497  missionNode *anode = getArgument( node, mode, current_arg );
498  varInst *res_vi = doObjectVar( anode, mode );
499  if (mode == SCRIPT_RUN) {
500  if ( res_vi->type != VAR_OBJECT || (res_vi->type == VAR_OBJECT && res_vi->objectname != "string") ) {
501  fatalError( node, mode, "io.printf needs string object as some arg" );
502  assert( 0 );
503  }
504  string *strptr = (string*) res_vi->object;
505  sprintf( outbuffer, "%s", beforestring.c_str() );
506  outstring += outbuffer;
507  sprintf( outbuffer, "%s", strptr->c_str() );
508  outstring += outbuffer;
509  }
510  deleteVarInst( res_vi );
511  }
512  endstring = endstring.substr( breakpos+2, endstring.size()-(breakpos+2) );
513  current_arg++;
514  }
515  if (mode == SCRIPT_RUN) {
516  sprintf( outbuffer, "%s", endstring.c_str() );
517  outstring += outbuffer;
518  (*outstrptr) = outstring;
519  }
520  varInst *viret = newVarInst( VI_TEMP );
521  viret->type = VAR_VOID;
522  deleteVarInst( str_vi );
523  deleteVarInst( outstr_vi );
524 
525  return viret;
526 }
527 
528 varInst* Mission::call_io_printf( missionNode *node, int mode )
529 {
530  missionNode *stringnode = getArgument( node, mode, 0 );
531  if (stringnode->tag != DTAG_CONST) {
532  fatalError( node, mode, "only const string allowed for first arg of printf" );
533  assert( 0 );
534  }
535  varInst *str_vi = checkObjectExpr( stringnode, mode );
536  if ( str_vi->type != VAR_OBJECT || (str_vi->type == VAR_OBJECT && str_vi->objectname != "string") ) {
537  fatalError( node, mode, "io.printf needs string object as first arg" );
538  assert( 0 );
539  }
540  int nr_of_args = node->subnodes.size();
541  int current_arg = 1;
542  string *fullstringptr;
543  string fullstring;
544  fullstringptr = (string*) str_vi->object;
545  fullstring = *fullstringptr;
546  fullstring = replaceNewline( fullstring );
547  string endstring = fullstring;
548  while (current_arg < nr_of_args) {
549  int breakpos = endstring.find( "%", 0 );
550  string beforestring = endstring.substr( 0, breakpos );
551  string breakstring = endstring.substr( breakpos, 2 );
552  if (breakstring[1] == 'f') {
553  missionNode *anode = getArgument( node, mode, current_arg );
554  double res = checkFloatExpr( anode, mode );
555  if (mode == SCRIPT_RUN) {
556  printf( "%s", beforestring.c_str() );
557  printf( "%f", res );
558  }
559  } else if (breakstring[1] == 'd') {
560  missionNode *anode = getArgument( node, mode, current_arg );
561  int res = checkIntExpr( anode, mode );
562  if (mode == SCRIPT_RUN) {
563  printf( "%s", beforestring.c_str() );
564  printf( "%d", res );
565  }
566  } else if (breakstring[1] == 'b') {
567  missionNode *anode = getArgument( node, mode, current_arg );
568  bool res = checkBoolExpr( anode, mode );
569  if (mode == SCRIPT_RUN) {
570  printf( "%s", beforestring.c_str() );
571  if (res == true)
572  printf( "true" );
573  else
574  printf( "false" );
575  }
576  } else if (breakstring[1] == 's') {
577  missionNode *anode = getArgument( node, mode, current_arg );
578  varInst *res_vi = doObjectVar( anode, mode );
579  if (mode == SCRIPT_RUN) {
580  if ( res_vi->type != VAR_OBJECT || (res_vi->type == VAR_OBJECT && res_vi->objectname != "string") ) {
581  fatalError( node, mode, "io.printf needs string object as some arg" );
582  assert( 0 );
583  }
584  string *strptr = (string*) res_vi->object;
585 
586  printf( "%s", beforestring.c_str() );
587  printf( "%s", strptr->c_str() );
588  }
589  deleteVarInst( res_vi );
590  }
591  endstring = endstring.substr( breakpos+2, endstring.size()-(breakpos+2) );
592  current_arg++;
593  }
594  if (mode == SCRIPT_RUN)
595  printf( "%s", endstring.c_str() );
596  varInst *viret = newVarInst( VI_TEMP );
597  viret->type = VAR_VOID;
598  deleteVarInst( str_vi );
599  fflush( stdout );
600  return viret;
601 }
602 
603 varInst* Mission::call_musicAddList( missionNode *node, int mode )
604 {
605  varInst *vi = newVarInst( VI_TEMP );
606  vi->type = VAR_INT;
607  vi->int_val = 0;
608  return vi;
609 }
610 
611 varInst* Mission::call_musicPlaySong( missionNode *node, int mode )
612 {
613  varInst *vi = newVarInst( VI_TEMP );
614  vi->type = VAR_VOID;
615  return vi;
616 }
617 
618 varInst* Mission::call_musicPlayList( missionNode *node, int mode )
619 {
620  varInst *vi = newVarInst( VI_TEMP );
621  vi->type = VAR_VOID;
622  return vi;
623 }
624 
625 varInst* Mission::callPrintFloats( missionNode *node, int mode )
626 {
627  string s1 = node->attr_value( "s1" );
628  string s2 = node->attr_value( "s2" );
629  if (mode == SCRIPT_RUN)
630  cout<<"print: "<<s1;
631  int len = node->subnodes.size();
632  for (int i = 0; i < len; i++) {
633  double res = checkFloatExpr( (missionNode*) node->subnodes[i], mode );
634  if (mode == SCRIPT_RUN)
635  cout<<" "<<res<<" ,";
636  }
637  if (mode == SCRIPT_RUN)
638  cout<<" "<<s2<<endl;
639  varInst *vi = newVarInst( VI_TEMP );
640  vi->type = VAR_VOID;
641 
642  return vi;
643 }
644 
645 varInst* Mission::callGetCurrentAIUnit( missionNode *node, int mode )
646 {
647  varInst *vi = newVarInst( VI_TEMP );
648  vi->type = VAR_OBJECT;
649  vi->objectname = "unit";
650  vi->object = (void*) current_ai_unit;
651 
652  return vi;
653 }
654 
655 varInst* Mission::callGetCurrentAIOrder( missionNode *node, int mode )
656 {
657  varInst *vi = newVarInst( VI_TEMP );
658  vi->type = VAR_OBJECT;
659  vi->objectname = "order";
660  vi->object = (void*) current_ai_order;
661 
662  return vi;
663 }
664 
665 varInst* Mission::callRnd( missionNode *node, int mode )
666 {
667  varInst *vi = newVarInst( VI_TEMP );
668  vi->type = VAR_FLOAT;
669  vi->float_val = ( (float) rand() )/( ( (float) RAND_MAX )+1 );
670 
671  char buffer[100];
672  sprintf( buffer, "rnd returning %f", (vi->float_val) );
673  debug( 7, node, mode, buffer );
674 
675  return vi;
676 }
677 
678 varInst* Mission::getObjectArg( missionNode *node, int mode )
679 {
680  if (node->subnodes.size() < 1) {
681  fatalError( node, mode, method_str( node )+" needs an object as first argument" );
682  assert( 0 );
683  }
684  missionNode *snode = (missionNode*) node->subnodes[0];
685  varInst *ovi = doObjectVar( snode, mode );
686 
687  debug( 3, node, mode, node->attr_value( "module" )+"."+node->attr_value( "name" )+" object: " );
688  printVarInst( 3, ovi );
689 
690  return ovi;
691 }
692 
693 string Mission::method_str( missionNode *node )
694 {
695  return node->attr_value( "module" )+"."+node->attr_value( "name" );
696 }
697 
698 bool Mission::getBoolArg( missionNode *node, int mode, int arg_nr )
699 {
700  missionNode *val_node = getArgument( node, mode, arg_nr );
701  bool res = checkBoolExpr( val_node, mode );
702  return res;
703 }
704 
705 double Mission::getFloatArg( missionNode *node, int mode, int arg_nr )
706 {
707  missionNode *val_node = getArgument( node, mode, arg_nr );
708  return checkFloatExpr( val_node, mode );
709 }
710 
711 int Mission::getIntArg( missionNode *node, int mode, int arg_nr )
712 {
713  missionNode *val_node = getArgument( node, mode, arg_nr );
714  int res = checkIntExpr( val_node, mode );
715  return res;
716 }
717 
718 Unit* Mission::getUnitArg( missionNode *node, int mode, int arg_nr )
719 {
720  Unit *ret = NULL;
721 
722  missionNode *unit_node = getArgument( node, mode, arg_nr );
723  varInst *unit_vi = checkObjectExpr( unit_node, mode );
724  if (mode == SCRIPT_RUN) {
725  if (unit_vi->type == VAR_OBJECT && unit_vi->objectname == "unit") {
726  ret = getUnitObject( unit_node, mode, unit_vi );
727  } else {
728  printf( "Error: Unit died prematurely\n" );
729  return NULL; //never reach
730  }
731  }
732  deleteVarInst( unit_vi );
733  return ret;
734 }
735 
736 QVector Mission::getVec3Arg( missionNode *node, int mode, int arg_nr )
737 {
738  missionNode *pos_node = getArgument( node, mode, arg_nr );
739  varInst *pos_vi = checkObjectExpr( pos_node, mode );
740 
741  QVector vec3;
742  if (mode == SCRIPT_RUN)
743  vec3 = call_olist_tovector( pos_node, mode, pos_vi );
744  deleteVarInst( pos_vi );
745  return vec3;
746 }
747 
748 missionNode* Mission::getArgument( missionNode *node, int mode, int arg_nr )
749 {
750  if ( node->subnodes.size() < (unsigned int) (arg_nr+1) ) {
751  char buf[200];
752  sprintf( buf, " needs at least %d arguments", arg_nr+1 );
753  fatalError( node, mode, method_str( node )+buf );
754  assert( 0 );
755  }
756  missionNode *snode = (missionNode*) node->subnodes[arg_nr];
757 
758  return snode;
759 }
760 
761 void Mission::initCallbackMaps()
762 {
763  module_map["_io"] = CMT_IO;
764  module_map["_std"] = CMT_STD;
765  module_map["_string"] = CMT_STRING;
766  module_map["_olist"] = CMT_OLIST;
767  module_map["_omap"] = CMT_OMAP;
768  module_map["_order"] = CMT_ORDER;
769  module_map["_unit"] = CMT_UNIT;
770  module_map["_briefing"] = CMT_BRIEFING;
771  module_briefing_map["addShip"] = CMT_BRIEFING_addShip;
772  module_briefing_map["removeShip"] = CMT_BRIEFING_removeShip;
773  module_briefing_map["enqueueOrder"] = CMT_BRIEFING_enqueueOrder;
774  module_briefing_map["replaceOrder"] = CMT_BRIEFING_replaceOrder;
775  module_briefing_map["setShipPosition"] = CMT_BRIEFING_setShipPosition;
776  module_briefing_map["getShipPosition"] = CMT_BRIEFING_getShipPosition;
777  module_briefing_map["setCamPosition"] = CMT_BRIEFING_setCamPosition;
778  module_briefing_map["setCamOrientation"] = CMT_BRIEFING_setCamOrientation;
779  module_briefing_map["setCloak"] = CMT_BRIEFING_setCloak;
780  module_briefing_map["terminate"] = CMT_BRIEFING_terminate;
781 
782  module_std_map["Rnd"] = CMT_STD_Rnd;
783  module_std_map["getGameTime"] = CMT_STD_getGameTime;
784  module_std_map["ResetTimeCompression"] = CMT_STD_ResetTimeCompression;
785  module_std_map["GetSystemName"] = CMT_STD_getSystemFile;
786  module_std_map["getNumAdjacentSystems"] = CMT_STD_getNumAdjacentSystems;
787  module_std_map["getGalaxyProperty"] = CMT_STD_getGalaxyProperty;
788  module_std_map["getAdjacentSystem"] = CMT_STD_getAdjacentSystem;
789  module_std_map["GetSystemFile"] = CMT_STD_getSystemFile;
790  module_std_map["getSystemFile"] = CMT_STD_getSystemFile;
791  module_std_map["getCurrentAIUnit"] = CMT_STD_getCurrentAIUnit;
792  module_std_map["getCurrentAIOrder"] = CMT_STD_getCurrentAIOrder;
793  module_std_map["isNull"] = CMT_STD_isNull;
794  module_std_map["setNull"] = CMT_STD_setNull;
795  module_std_map["equal"] = CMT_STD_equal;
796  module_std_map["Int"] = CMT_STD_Int;
797  module_std_map["Float"] = CMT_STD_Float;
798  module_std_map["getDifficulty"] = CMT_STD_getDifficulty;
799  module_std_map["setDifficulty"] = CMT_STD_setDifficulty;
800  module_std_map["playSound"] = CMT_STD_playSound;
801  module_std_map["playSoundCockpit"] = CMT_STD_playSoundCockpit;
802  module_std_map["terminateMission"] = CMT_STD_terminateMission;
803  module_std_map["playAnimation"] = CMT_STD_playAnimation;
804  module_std_map["musicAddList"] = CMT_STD_musicAddList;
805  module_std_map["musicPlaySong"] = CMT_STD_musicPlaySong;
806  module_std_map["musicPlayList"] = CMT_STD_musicPlayList;
807 
808  module_order_map["newAggressiveAI"] = CMT_ORDER_newAggressiveAI;
809  module_order_map["newMoveTo"] = CMT_ORDER_newMoveTo;
810  module_order_map["newChangeHeading"] = CMT_ORDER_newChangeHeading;
811  module_order_map["newFaceTarget"] = CMT_ORDER_newFaceTarget;
812  module_order_map["newFireAt"] = CMT_ORDER_newFireAt;
813  module_order_map["newExecuteFor"] = CMT_ORDER_newExecuteFor;
814  module_order_map["newCloakFor"] = CMT_ORDER_newCloakFor;
815  module_order_map["newMatchVelocity"] = CMT_ORDER_newMatchVelocity;
816  module_order_map["newMatchAngularVelocity"] = CMT_ORDER_newMatchAngularVelocity;
817  module_order_map["newMatchLinearVelocity"] = CMT_ORDER_newMatchLinearVelocity;
818  module_order_map["newFlyToWaypoint"] = CMT_ORDER_newFlyToWaypoint;
819  module_order_map["newFlyToWaypointDefend"] = CMT_ORDER_newFlyToWaypointDefend;
820  module_order_map["newFlyToJumppoint"] = CMT_ORDER_newFlyToJumppoint;
821  module_order_map["newPatrol"] = CMT_ORDER_newPatrol;
822  module_order_map["newOrderList"] = CMT_ORDER_newOrderList;
823  module_order_map["newSuperiority"] = CMT_ORDER_newSuperiority;
824 
825  module_order_map["enqueueOrder"] = CMT_ORDER_enqueueOrder;
826  module_order_map["enqueueOrderFirst"] = CMT_ORDER_enqueueOrderFirst;
827  module_order_map["eraseOrder"] = CMT_ORDER_eraseOrder;
828  module_order_map["findOrder"] = CMT_ORDER_findOrder;
829  module_order_map["SteerUp"] = CMT_ORDER_SteerUp;
830  module_order_map["SteerRight"] = CMT_ORDER_SteerRight;
831  module_order_map["SteerRollRight"] = CMT_ORDER_SteerRollRight;
832  module_order_map["SteerStop"] = CMT_ORDER_SteerStop;
833  module_order_map["SteerAccel"] = CMT_ORDER_SteerAccel;
834  module_order_map["SteerAfterburn"] = CMT_ORDER_SteerAfterburn;
835  module_order_map["SteerSheltonSlide"] = CMT_ORDER_SteerSheltonSlide;
836  module_order_map["print"] = CMT_ORDER_print;
837  module_order_map["setActionString"] = CMT_ORDER_setActionString;
838 
839  module_olist_map["new"] = CMT_OLIST_new;
840  module_olist_map["delete"] = CMT_OLIST_delete;
841  module_olist_map["push_back"] = CMT_OLIST_push_back;
842  module_olist_map["pop_back"] = CMT_OLIST_pop_back;
843  module_olist_map["back"] = CMT_OLIST_back;
844  module_olist_map["at"] = CMT_OLIST_at;
845  module_olist_map["erase"] = CMT_OLIST_erase;
846  module_olist_map["set"] = CMT_OLIST_set;
847  module_olist_map["toxml"] = CMT_OLIST_toxml;
848  module_olist_map["size"] = CMT_OLIST_size;
849  module_omap_map["new"] = CMT_OMAP_new;
850  module_omap_map["delete"] = CMT_OMAP_delete;
851  module_omap_map["set"] = CMT_OMAP_set;
852  module_omap_map["get"] = CMT_OMAP_get;
853  module_omap_map["toxml"] = CMT_OMAP_toxml;
854  module_omap_map["size"] = CMT_OMAP_size;
855 
856  module_string_map["new"] = CMT_STRING_new;
857  module_string_map["delete"] = CMT_STRING_delete;
858  module_string_map["print"] = CMT_STRING_print;
859  module_string_map["equal"] = CMT_STRING_equal;
860  module_string_map["begins"] = CMT_STRING_begins;
861 
862  module_unit_map["getContainer"] = CMT_UNIT_getContainer;
863  module_unit_map["getUnitFromContainer"] = CMT_UNIT_getUnitFromContainer;
864  module_unit_map["deleteContainer"] = CMT_UNIT_deleteContainer;
865  module_unit_map["getUnit"] = CMT_UNIT_getUnit;
866  module_unit_map["getTurret"] = CMT_UNIT_getTurret;
867  module_unit_map["getCredits"] = CMT_UNIT_getCredits;
868  module_unit_map["getRandCargo"] = CMT_UNIT_getRandCargo;
869  module_unit_map["addCredits"] = CMT_UNIT_addCredits;
870  module_unit_map["getPlayer"] = CMT_UNIT_getPlayer;
871  module_unit_map["getPlayerX"] = CMT_UNIT_getPlayerX;
872  module_unit_map["launch"] = CMT_UNIT_launch;
873  module_unit_map["launchNebula"] = CMT_UNIT_launchPlanet;
874  module_unit_map["launchPlanet"] = CMT_UNIT_launchNebula;
875  module_unit_map["launchJumppoint"] = CMT_UNIT_launchJumppoint;
876  module_unit_map["getPosition"] = CMT_UNIT_getPosition;
877  module_unit_map["getFaction"] = CMT_UNIT_getFaction;
878  module_unit_map["getVelocity"] = CMT_UNIT_getVelocity;
879  module_unit_map["getTarget"] = CMT_UNIT_getTarget;
880  module_unit_map["getName"] = CMT_UNIT_getName;
881  module_unit_map["setName"] = CMT_UNIT_setName;
882  module_unit_map["equal"] = CMT_UNIT_equal;
883  module_unit_map["getThreat"] = CMT_UNIT_getThreat;
884  module_unit_map["setTarget"] = CMT_UNIT_setTarget;
885  module_unit_map["setPosition"] = CMT_UNIT_setPosition;
886  module_unit_map["addCargo"] = CMT_UNIT_addCargo;
887  module_unit_map["removeCargo"] = CMT_UNIT_removeCargo;
888  module_unit_map["incrementCargo"] = CMT_UNIT_incrementCargo;
889  module_unit_map["decrementCargo"] = CMT_UNIT_decrementCargo;
890  module_unit_map["getThreat"] = CMT_UNIT_getThreat;
891  module_unit_map["getDistance"] = CMT_UNIT_getDistance;
892  module_unit_map["getMinDis"] = CMT_UNIT_getMinDis;
893  module_unit_map["getAngle"] = CMT_UNIT_getAngle;
894  module_unit_map["getAngleToPos"] = CMT_UNIT_getAngleToPos;
895  module_unit_map["getFShieldData"] = CMT_UNIT_getFShieldData;
896  module_unit_map["getRShieldDat"] = CMT_UNIT_getRShieldData;
897  module_unit_map["getLShieldData"] = CMT_UNIT_getLShieldData;
898  module_unit_map["getBShieldData"] = CMT_UNIT_getBShieldData;
899  module_unit_map["getEnergyData"] = CMT_UNIT_getEnergyData;
900  module_unit_map["getHullData"] = CMT_UNIT_getHullData;
901  module_unit_map["getRSize"] = CMT_UNIT_getRSize;
902  module_unit_map["isStarShip"] = CMT_UNIT_isStarShip;
903  module_unit_map["isPlanet"] = CMT_UNIT_isPlanet;
904  module_unit_map["isSun"] = CMT_UNIT_isSun;
905  module_unit_map["isSignificant"] = CMT_UNIT_isSignificant;
906  module_unit_map["isJumppoint"] = CMT_UNIT_isJumppoint;
907  module_unit_map["getRelation"] = CMT_UNIT_getRelation;
908  module_unit_map["Jump"] = CMT_UNIT_Jump;
909  module_unit_map["getOrientationP"] = CMT_UNIT_getOrientationP;
910  module_unit_map["getOrder"] = CMT_UNIT_getOrder;
911  module_unit_map["removeFromGame"] = CMT_UNIT_removeFromGame;
912  module_unit_map["getFgDirective"] = CMT_UNIT_getFgDirective;
913  module_unit_map["setFgDirective"] = CMT_UNIT_setFgDirective;
914  module_unit_map["getFgLeader"] = CMT_UNIT_getFgLeader;
915  module_unit_map["setFgLeader"] = CMT_UNIT_setFgLeader;
916  module_unit_map["getFgID"] = CMT_UNIT_getFgId;
917  module_unit_map["getFgId"] = CMT_UNIT_getFgId;
918  module_unit_map["getFgName"] = CMT_UNIT_getFgName;
919  module_unit_map["getFgSubnumber"] = CMT_UNIT_getFgSubnumber;
920  module_unit_map["scanSystem"] = CMT_UNIT_scanSystem;
921  module_unit_map["scannerNearestEnemy"] = CMT_UNIT_scannerNearestEnemy;
922  module_unit_map["scannerNearestFriend"] = CMT_UNIT_scannerNearestFriend;
923  module_unit_map["scannerNearestShip"] = CMT_UNIT_scannerNearestShip;
924  module_unit_map["scannerLeader"] = CMT_UNIT_scannerLeader;
925  module_unit_map["scannerNearestEnemyDist"] = CMT_UNIT_scannerNearestEnemyDist;
926  module_unit_map["scannerNearestFriendDist"] = CMT_UNIT_scannerNearestFriendDist;
927  module_unit_map["scannerNearestShipDist"] = CMT_UNIT_scannerNearestShipDist;
928  module_unit_map["toxml"] = CMT_UNIT_toxml;
929  module_unit_map["getSaveData"] = CMT_UNIT_getSaveData;
930  module_unit_map["upgrade"] = CMT_UNIT_upgrade;
931  module_unit_map["frameOfReference"] = CMT_UNIT_frameOfReference;
932  module_unit_map["communicateTo"] = CMT_UNIT_communicateTo;
933  module_unit_map["commAnimation"] = CMT_UNIT_commAnimation;
934  module_unit_map["correctStarSystem"] = CMT_UNIT_correctStarSystem; //useful when comparing _jumps_
935  module_unit_map["switchFg"] = CMT_UNIT_switchFg;
936 }
937