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_call_order.cpp
Go to the documentation of this file.
1 /*
2  * Vega Strike
3  * Copyright (C) 2001-2002 Daniel Horn
4  *
5  * http://vegastrike.sourceforge.net/
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 /*
23  * xml Mission Scripting written by Alexander Rawass <alexannika@users.sourceforge.net>
24  */
25 
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include <time.h>
30 #include <ctype.h>
31 #include <assert.h>
32 #ifndef WIN32
33 //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
34 #include <unistd.h>
35 #endif
36 
37 #include <expat.h>
38 #include "xml_support.h"
39 
40 #include "vegastrike.h"
41 #include "cmd/collection.h"
42 #include "cmd/unit_generic.h"
43 #include "cmd/ai/order.h"
44 #include "cmd/ai/aggressive.h"
45 #include "cmd/ai/navigation.h"
46 #include "cmd/ai/flybywire.h"
47 #include "cmd/ai/tactics.h"
48 #include "cmd/ai/missionscript.h"
49 #include "gfx/cockpit_generic.h"
50 #include "mission.h"
51 #include "easydom.h"
52 
53 #include "vs_globals.h"
54 #include "configxml.h"
55 
56 
57 /* *********************************************************** */
58 
59 varInst* Mission::call_order( missionNode *node, int mode )
60 {
61  varInst *viret = NULL;
62  if (mode == SCRIPT_PARSE) {
63  string cmd = node->attr_value( "name" );
64  node->script.method_id = module_order_map[cmd];
65  }
67  if (method_id == CMT_ORDER_newAggressiveAI) {
68  string filestr = getStringArgument( node, mode, 0 );
69  string intstr = getStringArgument( node, mode, 1 );
70  Order *my_order = NULL;
71  if (mode == SCRIPT_RUN)
72  my_order = new Orders::AggressiveAI( filestr.c_str() );
73  viret = newVarInst( VI_TEMP );
74  viret->type = VAR_OBJECT;
75  viret->objectname = "order";
76  viret->object = (void*) my_order;
77  return viret;
78  } else if (method_id == CMT_ORDER_newMoveTo) {
79  missionNode *pos_node = getArgument( node, mode, 0 );
80  varInst *pos_vi = checkObjectExpr( pos_node, mode );
81  missionNode *ab_node = getArgument( node, mode, 1 );
82  bool afterburn = checkBoolExpr( ab_node, mode );
83  missionNode *sw_node = getArgument( node, mode, 2 );
84  int nr_switchbacks = checkIntExpr( sw_node, mode );
85  Order *my_order = NULL;
86  if (mode == SCRIPT_RUN) {
87  QVector vec3 = call_olist_tovector( pos_node, mode, pos_vi );
88  my_order = new Orders::MoveTo( vec3, afterburn, nr_switchbacks );
89  }
90  viret = newVarInst( VI_TEMP );
91  viret->type = VAR_OBJECT;
92  viret->objectname = "order";
93  viret->object = (void*) my_order;
94  deleteVarInst( pos_vi );
95  return viret;
96  } else if (method_id == CMT_ORDER_newChangeHeading) {
97  missionNode *pos_node = getArgument( node, mode, 0 );
98  varInst *pos_vi = checkObjectExpr( pos_node, mode );
99  missionNode *sw_node = getArgument( node, mode, 1 );
100  int nr_switchbacks = checkIntExpr( sw_node, mode );
101  Order *my_order = NULL;
102  if (mode == SCRIPT_RUN) {
103  QVector vec3 = call_olist_tovector( pos_node, mode, pos_vi );
104  my_order = new Orders::ChangeHeading( vec3, nr_switchbacks );
105  }
106  viret = newVarInst( VI_TEMP );
107  viret->type = VAR_OBJECT;
108  viret->objectname = "order";
109  viret->object = (void*) my_order;
110  deleteVarInst( pos_vi );
111  return viret;
112  } else if (method_id == CMT_ORDER_newFaceTarget) {
113  missionNode *itts_node = getArgument( node, mode, 0 );
114  bool itts = checkBoolExpr( itts_node, mode );
115  missionNode *fini_node = getArgument( node, mode, 1 );
116  bool fini = checkBoolExpr( fini_node, mode );
117  missionNode *acc_node = getArgument( node, mode, 2 );
118  int acc = checkIntExpr( acc_node, mode );
119  Order *my_order = NULL;
120  if (mode == SCRIPT_RUN) {
121  if (itts)
122  my_order = new Orders::FaceTargetITTS( fini, acc );
123  else
124  my_order = new Orders::FaceTarget( fini, acc );
125  }
126  viret = newVarInst( VI_TEMP );
127  viret->type = VAR_OBJECT;
128  viret->objectname = "order";
129  viret->object = (void*) my_order;
130  return viret;
131  } else if (method_id == CMT_ORDER_newFireAt) {
132  missionNode *aggr_node = getArgument( node, mode, 1 );
133  float aggr = checkFloatExpr( aggr_node, mode );
134  Order *my_order = NULL;
135  if (mode == SCRIPT_RUN)
136  my_order = new Orders::FireAt( aggr );
137  viret = newVarInst( VI_TEMP );
138  viret->type = VAR_OBJECT;
139  viret->objectname = "order";
140  viret->object = (void*) my_order;
141  return viret;
142  } else if (method_id == CMT_ORDER_newExecuteFor) {
143  missionNode *enq_node = getArgument( node, mode, 0 );
144  varInst *enq_vi = checkObjectExpr( enq_node, mode );
145  Order *enq_order = getOrderObject( enq_node, mode, enq_vi );
146  missionNode *time_node = getArgument( node, mode, 1 );
147  float fortime = checkFloatExpr( time_node, mode );
148  Order *my_order = NULL;
149  if (mode == SCRIPT_RUN)
150  my_order = new Orders::ExecuteFor( enq_order, fortime );
151  viret = newVarInst( VI_TEMP );
152  viret->type = VAR_OBJECT;
153  viret->objectname = "order";
154  viret->object = (void*) my_order;
155  deleteVarInst( enq_vi );
156  return viret;
157  } else if (method_id == CMT_ORDER_newCloakFor) {
158  missionNode *val_node = getArgument( node, mode, 0 );
159  bool res = checkBoolExpr( val_node, mode );
160  missionNode *time_node = getArgument( node, mode, 1 );
161  float fortime = checkFloatExpr( time_node, mode );
162  Order *my_order = NULL;
163  if (mode == SCRIPT_RUN)
164  my_order = new CloakFor( res, fortime );
165  viret = newVarInst( VI_TEMP );
166  viret->type = VAR_OBJECT;
167  viret->objectname = "order";
168  viret->object = (void*) my_order;
169  return viret;
170  } else if (method_id == CMT_ORDER_newMatchVelocity) {
171  missionNode *des_node = getArgument( node, mode, 0 );
172  varInst *des_vi = checkObjectExpr( des_node, mode );
173  missionNode *desa_node = getArgument( node, mode, 1 );
174  varInst *desa_vi = checkObjectExpr( desa_node, mode );
175  missionNode *local_node = getArgument( node, mode, 2 );
176  bool local = checkBoolExpr( local_node, mode );
177  missionNode *afburn_node = getArgument( node, mode, 3 );
178  bool afburn = checkBoolExpr( afburn_node, mode );
179  missionNode *fini_node = getArgument( node, mode, 4 );
180  bool fini = checkBoolExpr( fini_node, mode );
181  Order *my_order = NULL;
182  if (mode == SCRIPT_RUN) {
183  Vector des3 = call_olist_tovector( des_node, mode, des_vi ).Cast();
184  Vector desa3 = call_olist_tovector( desa_node, mode, desa_vi ).Cast();
185  my_order = new Orders::MatchVelocity( des3, desa3, local, afburn, fini );
186  }
187  viret = newVarInst( VI_TEMP );
188  viret->type = VAR_OBJECT;
189  viret->objectname = "order";
190  viret->object = (void*) my_order;
191  deleteVarInst( des_vi );
192  deleteVarInst( desa_vi );
193  return viret;
194  } else if (method_id == CMT_ORDER_newMatchAngularVelocity) {
195  missionNode *des_node = getArgument( node, mode, 0 );
196  varInst *des_vi = checkObjectExpr( des_node, mode );
197  missionNode *local_node = getArgument( node, mode, 1 );
198  bool local = checkBoolExpr( local_node, mode );
199  missionNode *fini_node = getArgument( node, mode, 2 );
200  bool fini = checkBoolExpr( fini_node, mode );
201  Order *my_order = NULL;
202  if (mode == SCRIPT_RUN) {
203  Vector des3 = call_olist_tovector( des_node, mode, des_vi ).Cast();
204  my_order = new Orders::MatchAngularVelocity( des3, local, fini );
205  }
206  viret = newVarInst( VI_TEMP );
207  viret->type = VAR_OBJECT;
208  viret->objectname = "order";
209  viret->object = (void*) my_order;
210  deleteVarInst( des_vi );
211  return viret;
212  } else if (method_id == CMT_ORDER_newMatchLinearVelocity) {
213  missionNode *des_node = getArgument( node, mode, 0 );
214  varInst *des_vi = checkObjectExpr( des_node, mode );
215  missionNode *local_node = getArgument( node, mode, 1 );
216  bool local = checkBoolExpr( local_node, mode );
217  missionNode *afburn_node = getArgument( node, mode, 2 );
218  bool afburn = checkBoolExpr( afburn_node, mode );
219  missionNode *fini_node = getArgument( node, mode, 3 );
220  bool fini = checkBoolExpr( fini_node, mode );
221  Order *my_order = NULL;
222  if (mode == SCRIPT_RUN) {
223  Vector des3 = call_olist_tovector( des_node, mode, des_vi ).Cast();
224  my_order = new Orders::MatchLinearVelocity( des3, local, afburn, fini );
225  }
226  viret = newVarInst( VI_TEMP );
227  viret->type = VAR_OBJECT;
228  viret->objectname = "order";
229  viret->object = (void*) my_order;
230  deleteVarInst( des_vi );
231  return viret;
232  } else if (method_id == CMT_ORDER_newFlyToWaypoint) {
233  missionNode *des_node = getArgument( node, mode, 0 );
234  varInst *des_vi = checkObjectExpr( des_node, mode );
235  float vel = getFloatArg( node, mode, 1 );
236  bool afburn = getBoolArg( node, mode, 2 );
237  float range = getFloatArg( node, mode, 3 );
238  Order *my_order = NULL;
239  if (mode == SCRIPT_RUN) {
240  QVector des3 = call_olist_tovector( des_node, mode, des_vi );
241  my_order = new AIFlyToWaypoint( des3, vel, afburn, range );
242  }
243  viret = newVarInst( VI_TEMP );
244  viret->type = VAR_OBJECT;
245  viret->objectname = "order";
246  viret->object = (void*) my_order;
247  deleteVarInst( des_vi );
248  return viret;
249  } else if (method_id == CMT_ORDER_newFlyToWaypointDefend) {
250  missionNode *des_node = getArgument( node, mode, 0 );
251  varInst *des_vi = checkObjectExpr( des_node, mode );
252  float vel = getFloatArg( node, mode, 1 );
253  bool afburn = getBoolArg( node, mode, 2 );
254  float range = getFloatArg( node, mode, 3 );
255  float defend_range = getFloatArg( node, mode, 4 );
256  Order *my_order = NULL;
257  if (mode == SCRIPT_RUN) {
258  QVector des3 = call_olist_tovector( des_node, mode, des_vi );
259  my_order = new AIFlyToWaypointDefend( des3, vel, afburn, range, defend_range );
260  }
261  viret = newVarInst( VI_TEMP );
262  viret->type = VAR_OBJECT;
263  viret->objectname = "order";
264  viret->object = (void*) my_order;
265  deleteVarInst( des_vi );
266  return viret;
267  } else if (method_id == CMT_ORDER_newFlyToJumppoint) {
268  missionNode *des_node = getArgument( node, mode, 0 );
269  varInst *des_vi = checkObjectExpr( des_node, mode );
270  Unit *des_unit = getUnitObject( des_node, mode, des_vi );
271  float vel = getFloatArg( node, mode, 1 );
272  bool afburn = getBoolArg( node, mode, 2 );
273  Order *my_order = NULL;
274  if (mode == SCRIPT_RUN)
275  my_order = new AIFlyToJumppoint( des_unit, vel, afburn );
276  viret = newVarInst( VI_TEMP );
277  viret->type = VAR_OBJECT;
278  viret->objectname = "order";
279  viret->object = (void*) my_order;
280  deleteVarInst( des_vi );
281  return viret;
282  } else if (method_id == CMT_ORDER_newPatrol) {
283  int patrol_mode = getIntArg( node, mode, 0 );
284  missionNode *des_node = getArgument( node, mode, 1 );
285  varInst *des_vi = checkObjectExpr( des_node, mode );
286  double range = getFloatArg( node, mode, 2 );
287  missionNode *unit_node = getArgument( node, mode, 3 );
288  varInst *unit_vi = checkObjectExpr( unit_node, mode );
289  Unit *around_unit = getUnitObject( unit_node, mode, unit_vi );
290  float patrol_speed = getFloatArg( node, mode, 4 );
291  Order *my_order = NULL;
292  if (mode == SCRIPT_RUN) {
293  QVector des3 = call_olist_tovector( des_node, mode, des_vi );
294  my_order = new AIPatrol( patrol_mode, des3, range, around_unit, patrol_speed );
295  }
296  viret = newVarInst( VI_TEMP );
297  viret->type = VAR_OBJECT;
298  viret->objectname = "order";
299  viret->object = (void*) my_order;
300  deleteVarInst( des_vi );
301  deleteVarInst( unit_vi );
302  return viret;
303  } else if (method_id == CMT_ORDER_newOrderList) {
304  missionNode *unit_node = getArgument( node, mode, 0 );
305  varInst *unit_vi = checkObjectExpr( unit_node, mode );
306  olist_t *orderlist = getOListObject( unit_node, mode, unit_vi );
307  Order *my_order = NULL;
308  if (mode == SCRIPT_RUN)
309  my_order = new AIOrderList( orderlist );
310  viret = newVarInst( VI_TEMP );
311  viret->type = VAR_OBJECT;
312  viret->objectname = "order";
313  viret->object = (void*) my_order;
314  deleteVarInst( unit_vi );
315  return viret;
316  } else if (method_id == CMT_ORDER_newSuperiority) {
317  Order *my_order = NULL;
318  if (mode == SCRIPT_RUN)
319  my_order = new AISuperiority();
320  viret = newVarInst( VI_TEMP );
321  viret->type = VAR_OBJECT;
322  viret->objectname = "order";
323  viret->object = (void*) my_order;
324  return viret;
325  } else {
326  varInst *ovi = getObjectArg( node, mode );
327  Order *my_order = getOrderObject( node, mode, ovi );
328  if (mode == SCRIPT_RUN) {
329  Unit *player = _Universe->AccessCockpit()->GetParent();
330  if (player) {
331  if ( my_order == player->getAIState() ) {
332  printf( "IGNOREING order for player\n" );
333  viret = newVarInst( VI_TEMP );
334  viret->type = VAR_VOID;
335  return viret;
336  }
337  }
338  }
339  if (method_id == CMT_ORDER_enqueueOrder) {
340  missionNode *enq_node = getArgument( node, mode, 1 );
341  varInst *enq_vi = checkObjectExpr( enq_node, mode );
342  if (mode == SCRIPT_RUN) {
343  debug( 3, node, mode, "enqueueing order" );
344  }
345  deleteVarInst( enq_vi );
346  viret = newVarInst( VI_TEMP );
347  viret->type = VAR_VOID;
348  } else if (method_id == CMT_ORDER_enqueueOrderFirst) {
349  missionNode *enq_node = getArgument( node, mode, 1 );
350  varInst *enq_vi = checkObjectExpr( enq_node, mode );
351  if (mode == SCRIPT_RUN) {
352  debug( 3, node, mode, "enqueueing order as first" );
353  }
354  deleteVarInst( enq_vi );
355  viret = newVarInst( VI_TEMP );
356  viret->type = VAR_VOID;
357  } else if (method_id == CMT_ORDER_eraseOrder) {
358  missionNode *enq_node = getArgument( node, mode, 1 );
359  varInst *enq_vi = checkObjectExpr( enq_node, mode );
360  Order *enq_order = getOrderObject( enq_node, mode, enq_vi );
361  if (mode == SCRIPT_RUN) {
362  my_order->eraseOrder( enq_order );
363  debug( 3, node, mode, "erasing order" );
364  }
365  deleteVarInst( enq_vi );
366  viret = newVarInst( VI_TEMP );
367  viret->type = VAR_VOID;
368  } else if (method_id == CMT_ORDER_findOrder) {
369  missionNode *enq_node = getArgument( node, mode, 1 );
370  varInst *enq_vi = checkObjectExpr( enq_node, mode );
371  Order *enq_order = getOrderObject( enq_node, mode, enq_vi );
372  Order *res_order = NULL;
373  if (mode == SCRIPT_RUN)
374  res_order = my_order->findOrder( enq_order );
375  viret = newVarInst( VI_TEMP );
376  viret->type = VAR_OBJECT;
377  viret->objectname = "order";
378  viret->object = (void*) res_order;
379  deleteVarInst( enq_vi );
380  } else if (method_id == CMT_ORDER_SteerUp) {
381  missionNode *val_node = getArgument( node, mode, 1 );
382  float val = checkFloatExpr( val_node, mode );
383  if (mode == SCRIPT_RUN) {
384  //this will crash if order is no FlyByWire
385  //is there a way to check that?
386  ( (FlyByWire*) my_order )->Up( val );
387  }
388  viret = newVarInst( VI_TEMP );
389  viret->type = VAR_VOID;
390  } else if (method_id == CMT_ORDER_SteerRight) {
391  missionNode *val_node = getArgument( node, mode, 1 );
392  float val = checkFloatExpr( val_node, mode );
393  if (mode == SCRIPT_RUN) {
394  //this will crash if order is no FlyByWire
395  //is there a way to check that?
396  ( (FlyByWire*) my_order )->Right( val );
397  }
398  viret = newVarInst( VI_TEMP );
399  viret->type = VAR_VOID;
400  } else if (method_id == CMT_ORDER_SteerRollRight) {
401  missionNode *val_node = getArgument( node, mode, 1 );
402  float val = checkFloatExpr( val_node, mode );
403  if (mode == SCRIPT_RUN) {
404  //this will crash if order is no FlyByWire
405  //is there a way to check that?
406  ( (FlyByWire*) my_order )->RollRight( val );
407  }
408  viret = newVarInst( VI_TEMP );
409  viret->type = VAR_VOID;
410  } else if (method_id == CMT_ORDER_SteerStop) {
411  missionNode *val_node = getArgument( node, mode, 1 );
412  float val = checkFloatExpr( val_node, mode );
413  if (mode == SCRIPT_RUN) {
414  //this will crash if order is no FlyByWire
415  //is there a way to check that?
416  ( (FlyByWire*) my_order )->Stop( val );
417  }
418  viret = newVarInst( VI_TEMP );
419  viret->type = VAR_VOID;
420  } else if (method_id == CMT_ORDER_SteerAccel) {
421  missionNode *val_node = getArgument( node, mode, 1 );
422  float val = checkFloatExpr( val_node, mode );
423  if (mode == SCRIPT_RUN) {
424  //this will crash if order is no FlyByWire
425  //is there a way to check that?
426  ( (FlyByWire*) my_order )->Accel( val );
427  }
428  viret = newVarInst( VI_TEMP );
429  viret->type = VAR_VOID;
430  } else if (method_id == CMT_ORDER_SteerAfterburn) {
431  missionNode *val_node = getArgument( node, mode, 1 );
432  float val = checkFloatExpr( val_node, mode );
433  if (mode == SCRIPT_RUN) {
434  //this will crash if order is no FlyByWire
435  //is there a way to check that?
436  ( (FlyByWire*) my_order )->Afterburn( val );
437  }
438  viret = newVarInst( VI_TEMP );
439  viret->type = VAR_VOID;
440  } else if (method_id == CMT_ORDER_SteerSheltonSlide) {
441  missionNode *val_node = getArgument( node, mode, 1 );
442  bool res = checkBoolExpr( val_node, mode );
443  if (mode == SCRIPT_RUN) {
444  //this will crash if order is no FlyByWire
445  //is there a way to check that?
446  ( (FlyByWire*) my_order )->SheltonSlide( res );
447  }
448  viret = newVarInst( VI_TEMP );
449  viret->type = VAR_VOID;
450  } else if (method_id == CMT_ORDER_print) {
451  if (mode == SCRIPT_RUN)
452  printf( "print: order=%s\n", my_order->getOrderDescription().c_str() );
453  viret = newVarInst( VI_TEMP );
454  viret->type = VAR_VOID;
455  } else if (method_id == CMT_ORDER_setActionString) {
456  string astring = getStringArgument( node, mode, 1 );
457  if (mode == SCRIPT_RUN)
458  my_order->setActionString( astring );
459  viret = newVarInst( VI_TEMP );
460  viret->type = VAR_VOID;
461  } else {
462  fatalError( node, mode, "no such method in orders "+node->script.name );
463  assert( 0 );
464  }
465  deleteVarInst( ovi );
466  return viret;
467  }
468  return NULL; //never reach
469 }
470 
471 Order* Mission::getOrderObject( missionNode *node, int mode, varInst *ovi )
472 {
473  Order *my_object = NULL;
474  if (mode == SCRIPT_RUN) {
475  my_object = (Order*) ovi->object;
476  if (my_object == NULL) {
477  fatalError( node, mode, "order: no object" );
478  assert( 0 );
479  }
480  }
481  return my_object;
482 }
483