vegastrike  0.5.1.r1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
load_mission.cpp
Go to the documentation of this file.
1 #include "configxml.h"
2 #include "cmd/script/mission.h"
3 #include "cmd/script/pythonmission.h"
4 #include "vs_globals.h"
5 #include "networking/netserver.h"
6 #include "star_system_generic.h"
7 #include "vs_globals.h"
8 #include "cmd/unit_generic.h"
9 #include "cmd/unit_factory.h"
10 #include "gfx/cockpit_generic.h"
11 #include "cmd/ai/aggressive.h"
12 #include "cmd/ai/script.h"
13 #include "cmd/ai/missionscript.h"
14 #include "cmd/script/flightgroup.h"
15 #include "python/python_class.h"
16 #include "savegame.h"
17 #include "save_util.h"
18 #include "load_mission.h"
19 
20 #include "options.h"
21 
23 std::string PickledDataSansMissionName( std::string pickled )
24 {
25  string::size_type newline = pickled.find( "\n" );
26  if (newline != string::npos)
27  return pickled.substr( newline+1, pickled.length()-(newline+1) );
28  else
29  return pickled;
30 }
31 std::string PickledDataOnlyMissionName( std::string pickled )
32 {
33  string::size_type newline = pickled.find( "\n" );
34  return pickled.substr( 0, newline );
35 }
36 int ReadIntSpace( std::string &str )
37 {
38  std::string myint;
39  bool toggle = false;
40  int i = 0;
41  while ( i < (int) str.length() ) {
42  char c[2] = {0, 0};
43  c[0] = str[i++];
44  if (c[0] != ' ') {
45  toggle = true;
46  myint += c;
47  } else if (toggle) {
48  break;
49  }
50  }
51  str = str.substr( i, str.length()-i );
52  return XMLSupport::parse_int( myint );
53 }
55 {
56  std::string str;
57  std::string script;
58  unsigned int player;
59  delayed_mission( std::string str, std::string script )
60  {
61  this->str = str;
62  this->script = script;
64  }
65 };
66 vector< delayed_mission >delayed_missions;
68 {
69  unsigned int cp = _Universe->CurrentCockpit();
70  int number = 0;
71  for (unsigned int i = 0; i < delayed_missions.size(); ++i)
72  if (delayed_missions[i].player == cp)
73  ++number;
74  return number;
75 }
76 
78 {
79  while ( !delayed_missions.empty() )
80  if ( delayed_missions.back().player < (unsigned int) _Universe->numPlayers() ) {
81  int i = _Universe->CurrentCockpit();
83  StarSystem *ss = _Universe->AccessCockpit()->activeStarSystem;
84  if (ss == NULL)
87  LoadMission( delayed_missions.back().str.c_str(), delayed_missions.back().script, false );
88  delayed_missions.pop_back();
91  }
92 }
93 void delayLoadMission( std::string str )
94 {
95  delayed_missions.push_back( delayed_mission( str, string( "" ) ) );
96 }
97 void delayLoadMission( std::string str, std::string script )
98 {
99  delayed_missions.push_back( delayed_mission( str, script ) );
100 }
102 {
103  std::string lpd = last_pickled_data;
104  if (_Universe->numPlayers() == 1) {
105  if ( !lpd.empty() ) {
106  unsigned int nummis = ReadIntSpace( lpd );
107  for (unsigned int i = 0; i < nummis; i++) {
108  int len = ReadIntSpace( lpd );
109  std::string pickled = lpd.substr( 0, len );
110  lpd = lpd.substr( len, lpd.length()-len );
111  if ( i < active_missions.size() )
112  active_missions[i]->UnPickle( PickledDataSansMissionName( pickled ) );
113  else
114  UnpickleMission( lpd );
115  }
116  }
117  }
118 }
119 void UnpickleMission( std::string pickled )
120 {
121  std::string file = PickledDataOnlyMissionName( pickled );
122  pickled = PickledDataSansMissionName( pickled );
123  if ( pickled.length() ) {
124  active_missions.push_back( new Mission( file.c_str() ) );
125  active_missions.back()->initMission();
126  active_missions.back()->SetUnpickleData( pickled );
127  }
128 }
129 std::string lengthify( std::string tp )
130 {
131  int len = tp.length();
132  tp = XMLSupport::tostring( len )+" "+tp;
133  return tp;
134 }
135 std::string PickleAllMissions()
136 {
137  std::string res;
138  int count = 0;
139  for (unsigned int i = 0; i < active_missions.size(); i++) {
140  string tmp = active_missions[i]->Pickle();
141  if (tmp.length() || i == 0) {
142  count++;
143  res += lengthify( tmp );
144  }
145  }
146  return XMLSupport::tostring( count )+" "+res;
147 }
148 int ReadIntSpace( FILE *fp )
149 {
150  std::string myint;
151  bool toggle = false;
152  while ( !VSFileSystem::vs_feof( fp ) ) {
153  char c[2] = {0, 0};
154  if ( 1 == VSFileSystem::vs_read( &c[0], sizeof (char), 1, fp ) ) {
155  if (c[0] != ' ') {
156  toggle = true;
157  myint += c;
158  } else if (toggle) {
159  break;
160  }
161  }
162  }
163  return XMLSupport::parse_int( myint );
164 }
165 int ReadIntSpace( char* &buf )
166 {
167  std::string myint;
168  bool toggle = false;
169  while (*buf != 0) {
170  char c[2] = {0, 0};
171  if ( (c[0] = *buf) ) {
172  if (c[0] != ' ') {
173  toggle = true;
174  myint += c;
175  } else if (toggle) {
176  break;
177  }
178  buf++;
179  }
180  }
181  return XMLSupport::parse_int( myint );
182 }
183 std::string UnpickleAllMissions( FILE *fp )
184 {
185  std::string retval;
186  unsigned int nummissions = ReadIntSpace( fp );
187  retval += XMLSupport::tostring( (int) nummissions )+" ";
188  for (unsigned int i = 0; i < nummissions; i++) {
189  unsigned int picklelength = ReadIntSpace( fp );
190  retval += XMLSupport::tostring( (int) picklelength )+" ";
191  char *temp = (char*) malloc( sizeof (char)*(1+picklelength) );
192  temp[0] = 0;
193  temp[picklelength] = 0;
194  VSFileSystem::vs_read( temp, picklelength, 1, fp );
195  retval += temp;
196  if ( i < active_missions.size() )
197  active_missions[i]->SetUnpickleData( PickledDataSansMissionName( temp ) );
198  else
199  UnpickleMission( temp );
200  free( temp );
201  }
202  return retval;
203 }
204 std::string UnpickleAllMissions( char* &buf )
205 {
206  std::string retval;
207  unsigned int nummissions = ReadIntSpace( buf );
208  retval += XMLSupport::tostring( (int) nummissions )+" ";
209  for (unsigned int i = 0; i < nummissions; i++) {
210  unsigned int picklelength = ReadIntSpace( buf );
211  retval += XMLSupport::tostring( (int) picklelength )+" ";
212  char *temp = (char*) malloc( sizeof (char)*(1+picklelength) );
213  temp[0] = 0;
214  temp[picklelength] = 0;
215  memcpy( temp, buf, picklelength );
216  buf += picklelength;
217  //VSFileSystem::vs_read (temp,picklelength,1,fp);
218  retval += temp;
219  if ( i < active_missions.size() )
220  active_missions[i]->SetUnpickleData( PickledDataSansMissionName( temp ) );
221  else
222  UnpickleMission( temp );
223  free( temp );
224  }
225  return retval;
226 }
227 void LoadMission( const char *mn, bool loadFirstUnit )
228 {
229  LoadMission( mn, string( "" ), loadFirstUnit );
230 }
231 void LoadMission( const char *nission_name, const std::string &script, bool loadFirstUnit )
232 {
233  using namespace VSFileSystem;
234  string mission_name( nission_name );
235  const char *friendly_mission_name = nission_name;
236  if (nission_name[0] == '#') {
237  //Allows you to title a mission without loading that file.
238  mission_name = string();
239  friendly_mission_name++;
240  }
241  if ( mission_name.empty() )
242  mission_name = game_options.empty_mission;
243  printf( "%s", script.c_str() );
244  VSFile f;
245  VSError err = f.OpenReadOnly( mission_name, MissionFile );
246  if (err > Ok)
247  return;
248  f.Close();
249  if (Mission::getNthPlayerMission( _Universe->CurrentCockpit(), 0 ) != NULL) {
250  pushSaveString( _Universe->CurrentCockpit(), "active_scripts", script );
251  pushSaveString( _Universe->CurrentCockpit(), "active_missions", nission_name );
252  }
253  active_missions.push_back( new Mission( mission_name.c_str(), script ) );
254 
255  mission = active_missions.back();
256  active_missions.back()->initMission();
257 
258  char fightername[1024];
259  vector< Flightgroup* >::const_iterator siter;
260  vector< Flightgroup* >fg = active_missions.back()->flightgroups;
261  Unit *fighter;
262  if (Network != NULL) {
263  for (siter = fg.begin(); siter != fg.end(); siter++) {
264  Flightgroup *fg = *siter;
265  string fg_name = fg->name;
266  string fullname = fg->type;
267  strncpy( fightername, fullname.c_str(), 1023 );
268  fightername[1023] = '\0';
269  int a = 0;
270  int tmptarget = 0;
271  string ainame = fg->ainame;
272  float fg_radius = 0.0;
273  for (int s = 0; s < fg->nr_ships; s++) {
274  QVector pox;
275 
276  pox.i = fg->pos.i+s*fg_radius*3;
277  pox.j = fg->pos.i+s*fg_radius*3;
278  pox.k = fg->pos.i+s*fg_radius*3;
279  if (pox.i == pox.j && pox.j == pox.k && pox.k == 0) {
280  pox.i = rand()*10000./RAND_MAX-5000;
281  pox.j = rand()*10000./RAND_MAX-5000;
282  pox.k = rand()*10000./RAND_MAX-5000;
283  }
284  if ( _Universe->AccessCockpit()->GetParent() ) {
285  QVector fposs = _Universe->AccessCockpit()->GetParent()->Position();
286  pox = pox+fposs; //adds our own position onto this
287  }
288  tmptarget = FactionUtil::GetFactionIndex( fg->faction ); //that should not be in xml?
289  string modifications( "" );
290  if (a != 0 || loadFirstUnit)
291  fighter = UnitFactory::createUnit( fightername, false, tmptarget, modifications, fg, s );
292  else
293  continue;
294  fighter->SetPosAndCumPos( pox );
295 
296  fg_radius = fighter->rSize();
297  if (benchmark > 0.0 || a != 0) {
298  fighter->LoadAIScript( ainame );
299  fighter->SetTurretAI();
300  }
302  a++;
303  } //for nr_ships
304  } //end of for flightgroups
305  }
306  if (active_missions.size() > 0)
307  //Give the mission a name.
308  active_missions.back()->mission_name = friendly_mission_name;
309  active_missions.back()->player_num = _Universe->CurrentCockpit();
310  if (SERVER) {
311  int num = active_missions.back()->getPlayerMissionNumber();
312  if (num > 0)
313  VSServer->sendMission( _Universe->CurrentCockpit(), Subcmd::AcceptMission,
314  friendly_mission_name, num-1 );
315  }
316  active_missions.back()->DirectorInitgame();
318  //return true;
319 }
320