vegastrike  0.5.1.r1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
universe_util_generic.cpp
Go to the documentation of this file.
1 #include <math.h>
2 #include <sys/stat.h>
3 #include "lin_time.h"
4 #include "cmd/script/mission.h"
5 #include "universe_util.h"
6 #include "universe_generic.h"
7 #include "cmd/unit_generic.h"
8 #include "cmd/unit_factory.h" //for UnitFactory::getMasterPartList()
9 #include "cmd/collection.h"
10 #include "star_system_generic.h"
11 #include <string>
12 #include <set>
13 #include "savegame.h"
14 #include "save_util.h"
15 #include "cmd/unit_csv.h"
16 #include "gfx/cockpit_generic.h"
17 #include "lin_time.h"
18 #include "load_mission.h"
19 #include "configxml.h"
20 #include "vs_globals.h"
21 #include "vsfilesystem.h"
22 #include "cmd/unit_util.h"
23 #include "networking/netserver.h"
24 #include "cmd/csv.h"
25 #include "linecollide.h"
26 #include "cmd/unit_collide.h"
27 #include "cmd/unit_find.h"
28 
29 #include "python/init.h"
30 #include "cs_python.h"
31 #include "options.h"
32 
34 
35 extern Unit& GetUnitMasterPartList();
36 extern int num_delayed_missions();
37 using std::string;
38 using std::set;
39 
40 //less to write
41 #define activeSys _Universe->activeStarSystem()
42 using namespace VSFileSystem;
43 
44 namespace UniverseUtil
45 {
46 Unit* PythonUnitIter::current()
47 {
48  Unit *ret = NULL;
49  while ( (ret = **this) ) {
50  if (ret->hull > 0)
51  return ret;
52  advance();
53  }
54  return ret;
55 }
56 
57 void PythonUnitIter::advanceSignificant()
58 {
59  advance();
60  while ( notDone() && !UnitUtil::isSignificant( **this ) )
61  advance();
62 }
63 
64 void PythonUnitIter::advanceInsignificant()
65 {
66  advance();
67  while ( notDone() && UnitUtil::isSignificant( **this ) )
68  advance();
69 }
70 
71 void PythonUnitIter::advancePlanet()
72 {
73  advance();
74  while ( notDone() && !(**this)->isPlanet() )
75  advance();
76 }
77 
78 void PythonUnitIter::advanceJumppoint()
79 {
80  advance();
81  while ( notDone() && !(**this)->isJumppoint() )
82  advance();
83 }
84 
85 void PythonUnitIter::advanceN( int n )
86 {
87  while (notDone() && n > 0) {
88  advance();
89  --n;
90  }
91 }
92 
93 void PythonUnitIter::advanceNSignificant( int n )
94 {
95  if ( notDone() && !UnitUtil::isSignificant( **this ) )
96  advanceSignificant();
97  while ( notDone() && (n > 0) ) {
98  advanceSignificant();
99  --n;
100  }
101 }
102 
103 void PythonUnitIter::advanceNInsignificant( int n )
104 {
105  if ( notDone() && UnitUtil::isSignificant( **this ) )
106  advanceInsignificant();
107  while ( notDone() && (n > 0) ) {
108  advanceInsignificant();
109  --n;
110  }
111 }
112 
113 void PythonUnitIter::advanceNPlanet( int n )
114 {
115  if ( notDone() && !(**this)->isPlanet() )
116  advancePlanet();
117  while (notDone() && n > 0) {
118  advancePlanet();
119  --n;
120  }
121 }
122 
123 void PythonUnitIter::advanceNJumppoint( int n )
124 {
125  if ( notDone() && !(**this)->isJumppoint() )
126  advanceJumppoint();
127  while (notDone() && n > 0) {
128  advanceJumppoint();
129  --n;
130  }
131 }
132 
133 Unit * GetUnitFromSerial( ObjSerial serial )
134 {
135  Unit *un;
136  if (serial == 0)
137  return NULL;
138  //Find the unit
139  for (un_iter it = UniverseUtil::getUnitList(); (un = *it); ++it)
140  if ( (*it)->GetSerial() == serial )
141  break;
142  if (un == NULL)
143  cout<<"ERROR --> no unit for serial "<<serial<<endl;
144  return un;
145 }
146 std::string vsConfig( std::string category, std::string option, std::string def )
147 {
148  return vs_config->getVariable( category, option, def );
149 }
150 
151 Unit * launchJumppoint( string name_string,
152  string faction_string,
153  string type_string,
154  string unittype_string,
155  string ai_string,
156  int nr_of_ships,
157  int nr_of_waves,
158  QVector pos,
159  string squadlogo,
160  string destinations )
161 {
162  if (Network) return NULL;
163  int clstype = UNITPTR;
164  if (unittype_string == "planet")
165  clstype = PLANETPTR;
166  else if (unittype_string == "asteroid")
167  clstype = ASTEROIDPTR;
168  else if (unittype_string == "nebula")
169  clstype = NEBULAPTR;
170  CreateFlightgroup cf;
171  cf.fg = Flightgroup::newFlightgroup( name_string,
172  type_string,
173  faction_string,
174  ai_string,
175  nr_of_ships,
176  nr_of_waves,
177  squadlogo,
178  "",
179  mission );
180  cf.unittype = CreateFlightgroup::UNIT;
181  cf.terrain_nr = -1;
182  cf.waves = nr_of_waves;
183  cf.nr_ships = nr_of_ships;
184  cf.fg->pos = pos;
185  cf.rot[0] = cf.rot[1] = cf.rot[2] = 0.0f;
186  Unit *tmp = mission->call_unit_launch( &cf, clstype, destinations );
187  mission->number_of_ships += nr_of_ships;
188 
189  return tmp;
190 }
191 Cargo getRandCargo( int quantity, string category )
192 {
193  Cargo *ret = NULL;
194  Unit *mpl = &GetUnitMasterPartList();
195  unsigned int max = mpl->numCargo();
196  if ( !category.empty() ) {
197  size_t Begin, End;
198  mpl->GetSortedCargoCat( category, Begin, End );
199  if (Begin < End) {
200  unsigned int i = Begin+( rand()%(End-Begin) );
201  ret = &mpl->GetCargo( i );
202  }
203  } else if ( mpl->numCargo() ) {
204  for (unsigned int i = 0; i < 500; ++i) {
205  ret = &mpl->GetCargo( rand()%max );
206  if (ret->GetContent().find( "mission" ) == string::npos)
207  break;
208  }
209  }
210  if (ret) {
211  Cargo tempret = *ret;
212  tempret.quantity = quantity;
213  return tempret; //uses copy
214  } else {
215  Cargo newret;
216  newret.quantity = 0;
217  return newret;
218  }
219 }
220 float GetGameTime()
221 {
222  return mission->gametime;
223 }
224 
225 float getStarTime()
226 {
228 }
229 
230 string getStarDate()
231 {
233 }
234 
236 {
237  setTimeCompression( 1.0 );
238 }
239 static UnitContainer scratch_unit;
240 static QVector scratch_vector;
241 
243 {
244  return UnitFactory::getMasterPartList();
245 }
247 {
248  return scratch_unit.GetUnit();
249 }
250 void setScratchUnit( Unit *un )
251 {
252  scratch_unit.SetUnit( un );
253 }
254 
256 {
257  return scratch_vector;
258 }
259 void setScratchVector( QVector un )
260 {
261  scratch_vector = un;
262 }
263 
264 void pushSystem( string name )
265 {
266  StarSystem *ss = _Universe->GenerateStarSystem( name.c_str(), "", Vector( 0, 0, 0 ) );
268 }
269 void popSystem()
270 {
272 }
274 {
275  if (!activeSys) return "";
276  return activeSys->getFileName();
277 }
278 
280 {
281  if (!activeSys) return "";
282  return activeSys->getName();
283 }
285 void TargetEachOther( string fgname, string faction, string enfgname, string enfaction )
286 {
287  int fac = FactionUtil::GetFactionIndex( faction );
288  int enfac = FactionUtil::GetFactionIndex( enfaction );
289  Unit *un;
290  Unit *en = NULL;
291  Unit *al = NULL;
292  for (un_iter i = _Universe->activeStarSystem()->getUnitList().createIterator(); (un = *i) && ( (!en) || (!al) ); ++i) {
293  if (un->faction == enfac && UnitUtil::getFlightgroupName( un ) == enfgname)
294  if ( (NULL == en) || (rand()%3 == 0) )
295  en = un;
296  if (un->faction == fac && UnitUtil::getFlightgroupName( un ) == fgname)
297  al = un;
298  }
299  if (en && al) {
300  UnitUtil::setFlightgroupLeader( al, al );
301  al->Target( en );
302  //attack target, darent change target!
303  UnitUtil::setFgDirective( al, "A." );
304  UnitUtil::setFlightgroupLeader( en, en );
305  en->Target( al );
306  //help me out here!
307  UnitUtil::setFgDirective( en, "h" );
308  }
309 }
310 
312 void StopTargettingEachOther( string fgname, string faction, string enfgname, string enfaction )
313 {
314  int fac = FactionUtil::GetFactionIndex( faction );
315  int enfac = FactionUtil::GetFactionIndex( enfaction );
316  Unit *un;
317  int clear = 0;
318  for (un_iter i = _Universe->activeStarSystem()->getUnitList().createIterator(); (un = *i) && clear != 3; ++i) {
319  if ( (un->faction == enfac && UnitUtil::getFlightgroupName( un ) == enfgname) ) {
320  clear |= 1;
321  UnitUtil::setFgDirective( un, "b" );
322  } else if (un->faction == fac && UnitUtil::getFlightgroupName( un ) == fgname) {
323  clear |= 2;
324  UnitUtil::setFgDirective( un, "b" );
325  //check to see that its' in this flightgroup or something :-)
326  }
327  }
328 }
329 
330 bool systemInMemory( string nam )
331 {
332  unsigned int nass = _Universe->star_system.size();
333  for (unsigned int i = 0; i < nass; ++i)
334  if (_Universe->star_system[i]->getFileName() == nam)
335  return true;
336  return false;
337 }
338 
339 float GetRelation( std::string myfaction, std::string theirfaction )
340 {
341  int myfac = FactionUtil::GetFactionIndex( myfaction );
342  int theirfac = FactionUtil::GetFactionIndex( theirfaction );
343  int cp = _Universe->CurrentCockpit();
344  Unit *un = _Universe->AccessCockpit()->GetParent();
345  if (!un) return FactionUtil::GetIntRelation( myfac, theirfac );
346  if (myfac == theirfac)
347  return 0;
348  else if (myfac == un->faction)
349  return getRelationModifierInt( cp, theirfac );
350  else if (theirfac == un->faction)
351  return getRelationModifierInt( cp, myfac );
352  else
353  return FactionUtil::GetIntRelation( myfac, theirfac );
354 }
355 void AdjustRelation( std::string myfaction, std::string theirfaction, float factor, float rank )
356 {
357  int myfac = FactionUtil::GetFactionIndex( myfaction );
358  int theirfac = FactionUtil::GetFactionIndex( theirfaction );
359  float realfactor = factor*rank;
360  int cp = _Universe->CurrentCockpit();
361  Unit *un = _Universe->AccessCockpit()->GetParent();
362  if (!un) return;
363  if (myfac == theirfac)
364  return;
365  else if (myfac == un->faction)
366  return adjustRelationModifierInt( cp, theirfac, realfactor );
367  else if (theirfac == un->faction)
368  return adjustRelationModifierInt( cp, myfac, realfactor );
369 }
370 
371 float getRelationModifierInt( int which_cp, int faction )
372 {
373  string saveVar = "Relation_to_"+FactionUtil::GetFactionName( faction );
374  if (getSaveDataLength( which_cp, saveVar ) == 0)
375  return 0.;
376  float val = getSaveData( which_cp, saveVar, 0 );
377  if (val > 1) val = 1;
378  return val;
379 }
380 float getRelationModifier( int which_cp, string faction )
381 {
382  return getRelationModifierInt( which_cp, FactionUtil::GetFactionIndex( faction ) );
383 }
384 float getFGRelationModifier( int which_cp, string fg )
385 {
386  fg = "FG_Relation_"+fg;
387  if (getSaveDataLength( which_cp, fg ) == 0)
388  return 0.;
389  return getSaveData( which_cp, fg, 0 );
390 }
391 void adjustRelationModifierInt( int which_cp, int faction, float delta )
392 {
393  if (delta > 1) delta = 1;
394  string saveVar = "Relation_to_"+FactionUtil::GetFactionName( faction );
395  if (getSaveDataLength( which_cp, saveVar ) == 0)
396  pushSaveData( which_cp, saveVar, delta );
397  float val = getSaveData( which_cp, saveVar, 0 )+delta;
398  if (val > 1) val = 1;
399  return putSaveData( which_cp, saveVar, 0, val );
400 }
401 void adjustRelationModifier( int which_cp, string faction, float delta )
402 {
403  adjustRelationModifierInt( which_cp, FactionUtil::GetFactionIndex( faction ), delta );
404 }
405 void adjustFGRelationModifier( int which_cp, string fg, float delta )
406 {
407  fg = "FG_Relation_"+fg;
408  if (getSaveDataLength( which_cp, fg ) == 0) {
409  pushSaveData( which_cp, fg, delta );
410  return;
411  }
412  putSaveData( which_cp, fg, 0, getSaveData( which_cp, fg, 0 )+delta );
413 }
414 
415 void setMissionOwner( int whichplayer )
416 {
417  mission->player_num = whichplayer;
418 }
420 {
421  return mission->player_num;
422 }
424 {
425  return activeSys->getUnitList().createIterator();
426 }
427 Unit * getUnit( int index )
428 {
429  un_iter iter = activeSys->getUnitList().createIterator();
430  Unit *un = NULL;
431  for (int i = -1; (un = *iter) && i < index; ++iter) {
432  if (un->GetHull() > 0)
433  ++i;
434  if (i == index)
435  break;
436  }
437  return un;
438 }
439 Unit * getUnitByPtr( void *ptr, Unit *finder, bool allowslowness )
440 {
441  if (finder) {
442  UnitPtrLocator unitLocator( ptr );
443  findObjects( activeSys->collidemap[Unit::UNIT_ONLY], finder->location[Unit::UNIT_ONLY], &unitLocator );
444  if (unitLocator.retval)
445  return reinterpret_cast< Unit* > (ptr);
446 
447  else if ( !finder->isSubUnit() )
448  return 0;
449  }
450  if (!allowslowness)
451  return 0;
452  un_iter it = activeSys->getUnitList().createIterator();
453  while ( it.notDone() && ( (void*) (*it) != ptr ) )
454  ++it;
455  return ( (void*) (*it) == ptr ) ? reinterpret_cast< Unit* > (ptr) : 0;
456 }
457 Unit * getUnitByName( std::string name )
458 {
459  un_iter iter = activeSys->getUnitList().createIterator();
460  while (iter.notDone() && UnitUtil::getName( *iter ) != name)
461  ++iter;
462  return iter.notDone() ? (*iter) : NULL;
463 }
465 {
466 #ifdef USE_STL_COLLECTION
467  return activeSys->getUnitList().size();
468 
469 #else
470  //Implentation-safe getNumUnits().
471  int count = 0;
472  un_iter iter = activeSys->getUnitList().createIterator();
473  while ( iter.current() ) {
474  iter.advance();
475  count++;
476  }
477  return count;
478 #endif
479 }
480 //NOTEXPORTEDYET
481 /*
482  * float GetGameTime () {
483  * return mission->gametime;
484  * }
485  * void SetTimeCompression () {
486  * setTimeCompression(1.0);
487  * }
488  */
489 string GetAdjacentSystem( string str, int which )
490 {
491  return _Universe->getAdjacentStarSystems( str )[which];
492 }
493 string GetGalaxyProperty( string sys, string prop )
494 {
495  return _Universe->getGalaxyProperty( sys, prop );
496 }
497 string GetGalaxyPropertyDefault( string sys, string prop, string def )
498 {
499  return _Universe->getGalaxyPropertyDefault( sys, prop, def );
500 }
501 #define DEFAULT_FACTION_SAVENAME "FactionTookOver_"
502 
503 string GetGalaxyFaction( string sys )
504 {
505  string fac = _Universe->getGalaxyProperty( sys, "faction" );
506  vector< std::string > *ans =
507  &( _Universe->AccessCockpit( 0 )->savegame->getMissionStringData( string( DEFAULT_FACTION_SAVENAME )+sys ) );
508  if ( ans->size() )
509  fac = (*ans)[0];
510  return fac;
511 }
512 void SetGalaxyFaction( string sys, string fac )
513 {
514  vector< std::string > *ans =
515  &( _Universe->AccessCockpit( 0 )->savegame->getMissionStringData( string( DEFAULT_FACTION_SAVENAME )+sys ) );
516  if ( ans->size() )
517  (*ans)[0] = fac;
518  else
519  ans->push_back( std::string( fac ) );
520 }
521 int GetNumAdjacentSystems( string sysname )
522 {
523  return _Universe->getAdjacentStarSystems( sysname ).size();
524 }
526 {
527  return g_game.difficulty;
528 }
529 void SetDifficulty( float diff )
530 {
531  g_game.difficulty = diff;
532 }
533 extern void playVictoryTune();
534 void terminateMission( bool Win )
535 {
536  if (Win)
537  playVictoryTune();
538  mission->terminateMission();
539 }
540 static string dontBlankOut( string objective )
541 {
542  while (1) {
543  std::string::size_type where = objective.find( ".blank" );
544  if (where != string::npos)
545  objective = objective.substr( 0, where )+objective.substr( where+strlen( ".blank" ) );
546  else return objective;
547  }
548  return objective;
549 }
550 int addObjective( string objective )
551 {
552  float status = 0;
553  if (SERVER)
554  VSServer->sendSaveData( mission->player_num, Subcmd::Objective|Subcmd::SetValue,
555  mission->objectives.size(), NULL, mission, &objective, &status );
556  mission->objectives.push_back( Mission::Objective( status, dontBlankOut( objective ) ) );
557  return mission->objectives.size()-1;
558 }
559 void setObjective( int which, string newobjective )
560 {
561  if (which < (int) mission->objectives.size() && which >= 0) {
562  if (SERVER)
563  VSServer->sendSaveData( mission->player_num, Subcmd::Objective|Subcmd::SetValue,
564  which, NULL, mission, &newobjective, &mission->objectives[which].completeness );
565  mission->objectives[which].objective = dontBlankOut( newobjective );
566  }
567 }
568 void setCompleteness( int which, float completeNess )
569 {
570  if (which < (int) mission->objectives.size() && which >= 0) {
571  if (SERVER)
572  VSServer->sendSaveData( mission->player_num, Subcmd::Objective|Subcmd::SetValue,
573  which, NULL, mission, &mission->objectives[which].objective, &completeNess );
574  mission->objectives[which].completeness = completeNess;
575  }
576 }
577 float getCompleteness( int which )
578 {
579  if (which < (int) mission->objectives.size() && which >= 0)
580  return mission->objectives[which].completeness;
581  else
582  return 0;
583 }
584 void setTargetLabel( std::string label )
585 {
586  _Universe->AccessCockpit()->setTargetLabel( label );
587 }
588 std::string getTargetLabel()
589 {
590  return _Universe->AccessCockpit()->getTargetLabel();
591 }
592 void eraseObjective( int which )
593 {
594  if (which < (int) mission->objectives.size() && which >= 0) {
595  if (SERVER)
596  VSServer->sendSaveData( mission->player_num, Subcmd::Objective|Subcmd::EraseValue,
597  which, NULL, mission, NULL, NULL );
598  mission->objectives.erase( mission->objectives.begin()+which );
599  }
600 }
602 {
603  if ( mission->objectives.size() ) {
604  mission->objectives.clear();
605  if (SERVER)
606  VSServer->sendSaveData( mission->player_num, Subcmd::Objective|Subcmd::EraseValue,
607  -1, NULL, mission, NULL, NULL );
608  }
609 }
610 void setOwnerII( int which, Unit *owner )
611 {
612  if ( which < (int) mission->objectives.size() )
613  mission->objectives[which].setOwner( owner );
614 }
615 Unit * getOwner( int which )
616 {
617  if ( which < (int) mission->objectives.size() )
618  return mission->objectives[which].getOwner();
619  else
620  return 0;
621 }
623 {
624  int num = 0;
625  unsigned int cp = _Universe->CurrentCockpit();
626  for (unsigned int i = 0; i < active_missions.size(); ++i)
627  if (active_missions[i]->player_num == cp)
628  num++;
629  return num+::num_delayed_missions();
630 }
631 void IOmessage( int delay, string from, string to, string message )
632 {
633  if ( to == "news" && (!game_options.news_from_cargolist) )
634  for (unsigned int i = 0; i < _Universe->numPlayers(); i++)
635  pushSaveString( i, "news", string( "#" )+message );
636  else
637  mission->msgcenter->add( from, to, message, delay );
638 }
639 Unit * GetContrabandList( string faction )
640 {
642 }
643 void LoadMission( string missionname )
644 {
645  ::LoadMission( missionname.c_str(), "", false );
646 }
647 
648 void LoadNamedMissionScript( string title, string missionscript )
649 {
650  ::LoadMission( ("#"+title).c_str(), missionscript, false );
651 }
652 
653 void LoadMissionScript( string missionscript )
654 {
655  ::LoadMission( "nothing.mission", missionscript, false );
656 }
657 
658 void SetAutoStatus( int global_auto, int player_auto )
659 {
660  if (global_auto == 1)
661  mission->global_autopilot = Mission::AUTO_ON;
662  else if (global_auto == -1)
663  mission->global_autopilot = Mission::AUTO_OFF;
664  else
665  mission->global_autopilot = Mission::AUTO_NORMAL;
666  if (player_auto == 1)
667  mission->player_autopilot = Mission::AUTO_ON;
668  else if (player_auto == -1)
669  mission->player_autopilot = Mission::AUTO_OFF;
670  else
671  mission->player_autopilot = Mission::AUTO_NORMAL;
672 }
673 QVector SafeStarSystemEntrancePoint( StarSystem *sts, QVector pos, float radial_size )
674 {
675  if (radial_size < 0)
676  radial_size = game_options.respawn_unit_size;
677  for (unsigned int k = 0; k < 10; ++k) {
678  Unit *un;
679  bool collision = false;
680  {
681  //fixme, make me faster, use collide map
682  for (un_iter i = sts->getUnitList().createIterator(); (un = *i) != NULL; ++i) {
683  if (UnitUtil::isAsteroid( un ) || un->isUnit() == NEBULAPTR)
684  continue;
685  double dist = ( pos-un->LocalPosition() ).Magnitude()-un->rSize()-/*def_un_size-*/ radial_size;
686  if (dist < 0) {
687  QVector delta = pos-un->LocalPosition();
688  double mag = delta.Magnitude();
689  if (mag > .01)
690  delta = delta/mag;
691  else
692  delta.Set( 0, 0, 1 );
693  delta = delta.Scale( dist+un->rSize()+radial_size );
694  if (k < 5) {
695  pos = pos+delta;
696  collision = true;
697  } else {
698  QVector r( .5, .5, .5 );
699  pos += ( radial_size+un->rSize() )*r;
700  collision = true;
701  }
702  }
703  }
704  if (collision == false)
705  break;
706  }
707  }
708  return pos;
709 }
710 QVector SafeEntrancePoint( QVector pos, float radial_size )
711 {
712  return SafeStarSystemEntrancePoint( _Universe->activeStarSystem(), pos, radial_size );
713 }
714 Unit * launch( string name_string,
715  string type_string,
716  string faction_string,
717  string unittype,
718  string ai_string,
719  int nr_of_ships,
720  int nr_of_waves,
721  QVector pos,
722  string sqadlogo )
723 {
724  if (Network) return NULL;
725  return launchJumppoint( name_string,
726  faction_string,
727  type_string,
728  unittype,
729  ai_string,
730  nr_of_ships,
731  nr_of_waves,
732  pos,
733  sqadlogo,
734  "" );
735 }
736 
737 string LookupUnitStat( const string &unitname, const string &faction, const string &statname )
738 {
739  CSVRow tmp( LookupUnitRow( unitname, faction ) );
740  if ( tmp.success() )
741  return tmp[statname];
742 
743  else
744  return string();
745 }
746 
747 static std::vector< Unit* >cachedUnits;
748 void precacheUnit( string type_string, string faction_string )
749 {
750  cachedUnits.push_back( UnitFactory::createUnit( type_string.c_str(), true, FactionUtil::GetFactionIndex( faction_string ) ) );
751 }
752 Unit * getPlayer()
753 {
754  return _Universe->AccessCockpit()->GetParent();
755 }
756 bool networked()
757 {
758  return Network != NULL;
759 }
760 bool isserver()
761 {
762  return SERVER;
763 }
764 void securepythonstr( string &message )
765 {
766  std::replace( message.begin(), message.end(), '\'', '\"' );
767  std::replace( message.begin(), message.end(), '\\', '/' );
768  std::replace( message.begin(), message.end(), '\n', ' ' );
769  std::replace( message.begin(), message.end(), '\r', ' ' );
770 }
771 void receivedCustom( int cp, bool trusted, string cmd, string args, string id )
772 {
773  int cp_orig = _Universe->CurrentCockpit();
775  _Universe->pushActiveStarSystem( _Universe->AccessCockpit()->activeStarSystem );
776  securepythonstr( cmd );
777  securepythonstr( args );
778  securepythonstr( id );
779  string pythonCode = game_options.custompython+"("+(trusted ? "True" : "False")
780  +", r\'"+cmd+"\', r\'"+args+"\', r\'"+id+"\')\n";
781  COUT<<"Executing python command: "<<endl;
782  cout<<" "<<pythonCode;
783  const char *cpycode = pythonCode.c_str();
784  ::Python::reseterrors();
785  PyRun_SimpleString( const_cast< char* > (cpycode) );
786  ::Python::reseterrors();
788  _Universe->SetActiveCockpit( cp_orig );
789 }
791 {
792  return _Universe->numPlayers();
793 }
794 Unit * getPlayerX( int which )
795 {
796  if ( which >= getNumPlayers() )
797  return NULL;
798  return _Universe->AccessCockpit( which )->GetParent();
799 }
801 {
802  return game_options.auto_pilot_planet_radius_percent;
803 }
804 std::string getVariable( std::string section, std::string name, std::string def )
805 {
806  return vs_config->getVariable( section, name, def );
807 }
808 std::string getSubVariable( std::string section, std::string subsection, std::string name, std::string def )
809 {
810  return vs_config->getVariable( section, subsection, name, def );
811 }
812 double timeofday()
813 {
814  return getNewTime();
815 }
816 double sqrt( double x )
817 {
818  return ::sqrt( x );
819 }
820 double log( double x )
821 {
822  return ::log( x );
823 }
824 double exp( double x )
825 {
826  return ::exp( x );
827 }
828 double cos( double x )
829 {
830  return ::cos( x );
831 }
832 double sin( double x )
833 {
834  return ::sin( x );
835 }
836 double acos( double x )
837 {
838  return ::acos( x );
839 }
840 double asin( double x )
841 {
842  return ::asin( x );
843 }
844 double atan( double x )
845 {
846  return ::atan( x );
847 }
848 double tan( double x )
849 {
850  return ::tan( x );
851 }
852 void micro_sleep( int n )
853 {
854  ::micro_sleep( n );
855 }
856 
857 void ComputeSystemSerials( std::string &systempath )
858 {
859  using namespace VSFileSystem;
860  //Read the file
861  VSFile f;
862  VSError err = f.OpenReadOnly( systempath, SystemFile );
863  if (err <= Ok) {
864  cout<<"\t\tcomputing serials for "<<systempath<<"...";
865  std::string system = f.ReadFull();
866 
867  //Now looking for "<planet ", "<Planet ", "<PLANET ", "<unit ", "<Unit ", "<UNIT ", same for nebulas
868  std::vector< std::string >search_patterns;
869 
870  bool newserials = true;
871  if (system.find( "serial=", 0 ) != std::string::npos) {
872  newserials = false;
873  cout<<"Found serial in system file : replacing serials..."<<endl;
874  } else {
875  cout<<"Found no serial in system file : generating..."<<endl;
876  }
877  search_patterns.push_back( "<planet " );
878  search_patterns.push_back( "<Planet " );
879  search_patterns.push_back( "<PLANET " );
880  search_patterns.push_back( "<unit " );
881  search_patterns.push_back( "<Unit " );
882  search_patterns.push_back( "<UNIT " );
883  search_patterns.push_back( "<nebula " );
884  search_patterns.push_back( "<Nebula " );
885  search_patterns.push_back( "<NEBULA " );
886  search_patterns.push_back( "<jump " );
887  search_patterns.push_back( "<Jump " );
888  search_patterns.push_back( "<JUMP " );
889  for (std::vector< std::string >::iterator ti = search_patterns.begin(); ti != search_patterns.end(); ++ti) {
890  std::string search( (*ti) );
891  std::string::size_type search_length = (*ti).length();
892  std::string::size_type curpos = 0;
893  int nboc = 0;
894  while ( ( curpos = system.find( search, curpos ) ) != std::string::npos ) {
895  ObjSerial new_serial = getUniqueSerial();
896  std::string serial_str( (*ti)+"serial=\""+XMLSupport::tostring5( new_serial )+"\" " );
897  //If there are already serial in the file we replace that kind of string : <planet serial="XXXXX"
898  //of length search_length + 14 (length of serial="XXXXX")
899  if (newserials)
900  system.replace( curpos, search_length, serial_str );
901  else
902  system.replace( curpos, search_length+15, serial_str );
903  ++nboc;
904  curpos += search_length;
905  }
906  cerr<<"\t\tFound "<<nboc<<" occurences of "<<search<<endl;
907  }
908  //Add the system xml string to the server
909  if (SERVER) VSServer->addSystem( systempath, system );
910  //Overwrite the system files with the buffer containing serials
911  f.Close();
912  //Should generate the modified system file in homedir
913  err = f.OpenCreateWrite( systempath, SystemFile );
914  if (err > Ok) {
915  cerr<<"!!! ERROR : opening "<<systempath<<" for writing"<<endl;
916  VSExit( 1 );
917  }
918  if ( f.Write( system ) != system.length() ) {
919  cerr<<"!!! ERROR : writing system file"<<endl;
920  VSExit( 1 );
921  }
922  f.Close();
923 
924  cout<<" OK !"<<endl;
925  } else {
926  cerr<<"ERROR cannot open system file : "<<systempath<<endl;
927  VSExit( 1 );
928  }
929 }
930 
931 void ComputeGalaxySerials( std::vector< std::string > &stak )
932 {
933  cout<<"Going through "<<stak.size()<<" sectors"<<endl;
934  cout<<"Generating random serial numbers :"<<endl;
935  for (; !stak.empty();) {
936  string sys( stak.back()+".system" );
937  stak.pop_back();
938  ComputeSystemSerials( sys );
939  }
940  cout<<"Computing done."<<endl;
941 }
942 
943 string getSaveDir()
944 {
945  return GetSaveDir();
946 }
947 
948 static std::string simplePrettySystem( std::string system )
949 {
950  std::string::size_type where = system.find_first_of( '/' );
951  std::string::size_type basewhere = system.find_first_of( '@', where );
952  return std::string( "Sec:" )+system.substr( 0, where )
953  +" Sys:"+( where == string::npos ? std::string("") : system.substr( where+1, (basewhere!=string::npos) ? basewhere-where-1 : string::npos ) )
954  +( basewhere == string::npos ? std::string("") : std::string(" ")+system.substr( basewhere+1 ) );
955 }
956 static std::string simplePrettyShip( std::string ship )
957 {
958  if (ship.length() > 0)
959  ship[0] = toupper( ship[0] );
960  std::string::size_type where = ship.find( "." );
961  if (where != string::npos) {
962  ship = ship.substr( 0, where );
963  ship = "Refurbished "+ship;
964  }
965  return ship;
966 }
967 
968 string getSaveInfo( const std::string &filename, bool formatForTextbox )
969 {
970  static SaveGame savegame( "" );
971  static set< string >campaign_score_vars;
972  static bool campaign_score_vars_init = false;
973  if (!campaign_score_vars_init) {
974  string campaign_score = vs_config->getVariable( "physics", "campaigns", "privateer_campaign vegastrike_campaign" );
975 
976  string::size_type where = 0, when = game_options.campaigns.find( ' ' );
977  while (where != string::npos) {
978  campaign_score_vars.insert( game_options.campaigns.substr( where, ( (when == string::npos) ? when : when-where ) ) );
979  where = (when == string::npos) ? when : when+1;
980  when = game_options.campaigns.find( ' ', where );
981  }
982  campaign_score_vars_init = true;
983  }
984  std::string system;
985  std::string lf = (formatForTextbox ? "#n#" : "\n");
986  QVector pos( 0, 0, 0 );
987  bool updatepos = false;
988  float creds;
989  vector< std::string >Ships;
990  std::string sillytemp = UniverseUtil::setCurrentSaveGame( filename );
991  savegame.SetStarSystem( "" );
992  savegame.ParseSaveGame( filename, system, "", pos, updatepos, creds, Ships,
993  _Universe->CurrentCockpit(), "", true, false, game_options.quick_savegame_summaries, true, true,
994  campaign_score_vars );
996  string text;
997  text += filename;
998  text = "Savegame: "+text+lf+"_________________"+lf;
999  {
1000  struct stat attrib;
1001  if ( 0 == stat( (getSaveDir()+filename).c_str(), &attrib ) ) {
1002  text += "Saved on: ";
1003  text += ctime( &attrib.st_mtime )+lf;
1004  }
1005  }
1006  text += "Credits: "+XMLSupport::tostring( (unsigned int) creds )+"."+XMLSupport::tostring(
1007  ( (unsigned int) (creds*100) )%100 )+lf;
1008  text += simplePrettySystem( system )+lf;
1009  if ( Ships.size() ) {
1010  text += "Starship: "+simplePrettyShip( Ships[0] )+lf;
1011  if (Ships.size() > 2) {
1012  text += "Fleet:"+lf;
1013  for (unsigned int i = 2; i < Ships.size(); i += 2)
1014  text += " "+simplePrettyShip( Ships[i-1] )+lf+" Located At:"+lf+" "+simplePrettySystem( Ships[i] )+lf;
1015  }
1016  }
1017  if (!game_options.quick_savegame_summaries) {
1018  bool hit = false;
1019  for (set< string >::const_iterator it = campaign_score_vars.begin(); it != campaign_score_vars.end(); ++it) {
1020  string var = *it;
1021  unsigned int curscore = savegame.getMissionData( var ).size()+savegame.getMissionStringData( var ).size();
1022  if (curscore > 0) {
1023  hit = true;
1024  if (var.length() > 0)
1025  var[0] = toupper( var[0] );
1026  text += var.substr( 0, var.find( "_" ) )+" Campaign Score: "+XMLSupport::tostring( curscore )+lf;
1027  }
1028  }
1029  if (!hit)
1030  text += "Campaign Score: 0"+lf;
1031  }
1032  return text;
1033 }
1034 
1036 {
1037  return GetCurrentSaveGame();
1038 }
1039 
1040 string setCurrentSaveGame( const string &newsave )
1041 {
1042  return SetCurrentSaveGame( newsave );
1043 }
1044 
1046 {
1047  static string ngsn( "New_Game" );
1048  return ngsn;
1049 }
1050 
1051 vector< string > GetJumpPath( string from, string to )
1052 {
1053  vector< string > path;
1054  _Universe->getJumpPath(from, to, path);
1055  return path;
1056 }
1057 
1058 }
1059 
1060 #undef activeSys
1061