vegastrike  0.5.1.r1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
universe_generic.cpp
Go to the documentation of this file.
1 
4 #include <stdio.h>
5 #include <fcntl.h>
6 #include <algorithm>
7 #include "universe_generic.h"
8 #include "galaxy_xml.h"
9 #include "galaxy_gen.h"
10 #include "gfx/cockpit_generic.h"
11 #include "cmd/unit_generic.h"
12 #include "vs_globals.h"
13 #include "xml_support.h"
14 #include "cmd/script/mission.h"
15 #include "vsfilesystem.h"
16 #include "save_util.h"
17 #include "cmd/unit_util.h"
18 #include "universe_util.h"
19 #include "cmd/csv.h"
20 #include "cmd/role_bitmask.h"
21 
22 using namespace GalaxyXML;
23 
24 extern StarSystem * GetLoadedStarSystem( const char *file );
25 vector< StarSystem* >deleteQueue;
27 {
28  while ( star_system.size() ) {
29  star_system.back()->RemoveStarsystemFromUniverse();
30  delete star_system.back();
31  star_system.pop_back();
32  }
33  active_star_system.clear();
34  script_system = NULL;
35 }
36 
37 Cockpit* Universe::createCockpit( std::string player )
38 {
39  Cockpit *cp = new Cockpit( "", NULL, player );
40  cockpit.push_back( cp );
41  return cp;
42 }
43 
44 Unit * DockToSavedBases( int playernum, QVector &safevec )
45 {
46  static string _str = vs_config->getVariable( "AI", "startDockedTo", "MiningBase" );
47  string str = _str;
48  Unit *plr = _Universe->AccessCockpit( playernum )->GetParent();
49  if ( !plr || !plr->getStarSystem() ) {
50  safevec = QVector( 0, 0, 0 );
51  return NULL;
52  }
53  vector< string >strs = loadStringList( playernum, mission_key );
54  if ( strs.size() )
55  str = strs[0];
56  Unit *closestUnit = NULL;
57  float lastdist = 0;
58  float dist = 0;
59  Unit *un;
60  QVector dock_position( plr->curr_physical_state.position );
61  for (un_iter iter = plr->getStarSystem()->getUnitList().createIterator(); (un = *iter); ++iter)
62  if (un->name == str || un->getFullname() == str) {
63  dist = UnitUtil::getSignificantDistance( plr, un );
64  if (closestUnit == NULL || dist < lastdist) {
65  lastdist = dist;
66  closestUnit = un;
67  }
68  }
69  if (closestUnit) {
70  if (UnitUtil::getSignificantDistance( plr, closestUnit ) > 0 && closestUnit->isUnit() != PLANETPTR)
71  dock_position = closestUnit->Position();
72  dock_position = UniverseUtil::SafeEntrancePoint( dock_position, plr->rSize() );
73  plr->SetPosAndCumPos( dock_position );
74 
75  vector< DockingPorts >dprt = closestUnit->pImage->dockingports;
76  unsigned int i;
77  for (i = 0;; i++) {
78  if ( i >= dprt.size() ) {
79  safevec = QVector( 0, 0, 0 );
80  return NULL;
81  }
82  if (!dprt[i].IsOccupied())
83  break;
84  }
85  plr->ForceDock( closestUnit, i );
86  closestUnit->pImage->clearedunits.push_back( plr );
87  closestUnit->RequestPhysics();
88  _Universe->AccessCockpit( playernum )->retry_dock = 0;
89  } else {
90  if (_Universe->AccessCockpit( playernum )->retry_dock == 0)
91  _Universe->AccessCockpit( playernum )->retry_dock = 128;
92  else _Universe->AccessCockpit( playernum )->retry_dock -= 1;
93  }
94  safevec = dock_position;
95  return ( closestUnit && closestUnit->isDocked( plr ) ) ? closestUnit : NULL;
96 }
97 
98 
99 Cockpit* Universe::isPlayerStarship( const Unit *doNotDereference )
100 {
101  using std::vector;
102  if (!doNotDereference)
103  return NULL;
104  for (std::vector< Cockpit* >::iterator iter = cockpit.begin(); iter < cockpit.end(); iter++)
105  if ( doNotDereference == ( *(iter) )->GetParent() )
106  return *(iter);
107  return NULL;
108 }
109 
110 int Universe::whichPlayerStarship( const Unit *doNotDereference )
111 {
112  if (!doNotDereference)
113  return -1;
114  for (unsigned int i = 0; i < cockpit.size(); i++)
115  if ( doNotDereference == cockpit[i]->GetParent() )
116  return i;
117  return -1;
118 }
119 
121 {
122 #ifdef VS_DEBUG
123  if ( i < 0 || i >= cockpit.size() )
124  VSFileSystem::vs_fprintf( stderr, "ouch invalid cockpit %d", i );
125 #endif
126  current_cockpit = i;
127 }
128 
129 void Universe::SetActiveCockpit( Cockpit *cp )
130 {
131  for (unsigned int i = 0; i < cockpit.size(); i++)
132  if (cockpit[i] == cp) {
133  SetActiveCockpit( i );
134  return;
135  }
136 }
137 
138 void Universe::SetupCockpits( vector< string >playerNames )
139 {
140  for (unsigned int i = 0; i < playerNames.size(); i++)
141  cockpit.push_back( new Cockpit( "", NULL, playerNames[i] ) );
142 }
143 
144 void SortStarSystems( std::vector< StarSystem* > &ss, StarSystem *drawn )
145 {
146  if ( ( *ss.begin() ) == drawn )
147  return;
148  vector< StarSystem* >::iterator drw = std::find( ss.begin(), ss.end(), drawn );
149  if ( drw != ss.end() ) {
150  StarSystem *tmp = drawn;
151  vector< StarSystem* >::iterator i = ss.begin();
152  while (i <= drw) {
153  StarSystem *t = *i;
154  *i = tmp;
155  tmp = t;
156  i++;
157  }
158  }
159 }
160 
161 void Universe::Init( const char *gal )
162 {
163  ROLES::getAllRolePriorities();
164  LoadWeapons( VSFileSystem::weapon_list.c_str() );
165  galaxy.reset(new GalaxyXML::Galaxy( gal ));
166  static bool firsttime = false;
167  if (!firsttime) {
168  LoadFactionXML( "factions.xml" );
169  firsttime = true;
170  }
171  script_system = NULL;
172 }
173 
174 Universe::Universe( int argc, char **argv, const char *galaxy_str, bool server )
175  : current_cockpit( 0 )
176  , script_system( NULL )
177 {
178  this->Init( galaxy_str );
179  network_lock = false;
180  is_server = server;
181 }
182 
184  : current_cockpit( 0 )
185  , script_system( NULL )
186 {
187  is_server = false;
188 }
189 
191 {
192  factions.clear();
193  cockpit.clear();
194 }
195 
197 {
198  std::cerr<<"Loading a starsystem"<<std::endl;
199  star_system.push_back( s );
200  SortStarSystems( star_system, s ); //dont' want instadie
201 }
202 
204 {
205  return std::find( star_system.begin(), star_system.end(), s ) != star_system.end();
206 }
207 
209 {
210  return (Network || SERVER) && network_lock;
211 }
212 
213 void Universe::netLock( bool enable )
214 {
215  network_lock = false;
216  if (Network || SERVER)
217  network_lock = enable;
218 }
219 
221 {
222  //not sure what to do here? serialize?
223 }
224 
225 StarSystem* Universe::Init( string systemfile, const Vector &centr, const string planetname )
226 {
227  string fullname = systemfile+".system";
228  return GenerateStarSystem( (char*) fullname.c_str(), "", centr );
229 }
230 
232 {
233  vector< StarSystem* >::iterator iter;
234  for (iter = star_system.begin(); iter != star_system.end(); iter++) {
235  StarSystem *ss = *iter;
236  if (ss->getName() == name)
237  return ss;
238  }
239  return NULL;
240 }
241 
242 extern void MakeStarSystem( string file, Galaxy *galaxy, string origin, int forcerandom );
243 extern string RemoveDotSystem( const char *input );
244 using namespace VSFileSystem;
245 
246 static void ss_generating( bool enable )
247 {
248  static bool ss_generating_active = false;
249  if (enable) {
251  static const std::string empty;
253  ss_generating_active = true;
254  }
255  } else if (ss_generating_active) {
257  ss_generating_active = false;
258  }
259 }
260 
261 void Universe::Generate1( const char *file, const char *jumpback )
262 {
263  int count = 0;
264  static bool show_loading = XMLSupport::parse_bool( vs_config->getVariable( "splash", "while_loading_starsystem", "false" ) );
265  if (show_loading)
266  ss_generating( true );
267  VSFile f;
268  VSError err = f.OpenReadOnly( file, SystemFile );
269  //If the file is not found we generate a system
270  if (err > Ok)
271  MakeStarSystem( file, galaxy.get(), RemoveDotSystem( jumpback ), count );
272  if (SERVER) {
273  string filestr( file );
275  }
276 }
277 
279 {
280  static bool firsttime = true;
281  LoadStarSystem( ss );
282  pushActiveStarSystem( ss );
283  static int num_times_to_simulate_new_star_system =
284  XMLSupport::parse_int( vs_config->getVariable( "physics", "num_times_to_simulate_new_star_system", "20" ) );
285  for (unsigned int tume = 0; tume <= num_times_to_simulate_new_star_system*SIM_QUEUE_SIZE+1; ++tume)
286  ss->UpdateUnitPhysics( true );
287  //notify the director that a new system is loaded (gotta have at least one active star system)
288  StarSystem *old_script_system = script_system;
289  script_system = ss;
290  VSFileSystem::vs_fprintf( stderr, "Loading Star System %s\n", ss->getFileName().c_str() );
291  const vector< std::string > &adjacent = getAdjacentStarSystems( ss->getFileName() );
292  for (unsigned int i = 0; i < adjacent.size(); i++) {
293  VSFileSystem::vs_fprintf( stderr, " Next To: %s\n", adjacent[i].c_str() );
294  }
295  static bool first = true;
296  if (!first)
297  mission->DirectorStartStarSystem( ss );
298  first = false;
299  script_system = old_script_system;
300  popActiveStarSystem();
301  if ( active_star_system.empty() ) {
302  pushActiveStarSystem( ss );
303  } else {
304  ss->SwapOut();
305  activeStarSystem()->SwapIn();
306  }
307  if (firsttime) {
308  firsttime = false;
309  } else {}
310  ss_generating( false );
311 }
312 
313 StarSystem* Universe::GenerateStarSystem( const char *file, const char *jumpback, Vector center )
314 {
315  StarSystem *tmpcache;
316  if ( ( tmpcache = GetLoadedStarSystem( file ) ) )
317  return tmpcache;
318  this->Generate1( file, jumpback );
319  StarSystem *ss = new StarSystem( file, center );
320  this->Generate2( ss );
321  return ss;
322 }
323 
325 {
326  static float nonactivesystemtime = XMLSupport::parse_floatf( vs_config->getVariable( "physics", "InactiveSystemTime", ".3" ) );
327  float systime = nonactivesystemtime;
328  for (unsigned int i = 0; i < star_system.size(); ++i)
329  //Calls the update function for server
330  star_system[i]->Update( (i == 0) ? 1 : systime/i );
331 }
332 
334 {
335  for (unsigned int i = 0; i < star_system.size(); i++)
336  if (star_system[i] == ss)
337  return i;
338  return -1;
339 }
340 
342 {
343  VSFile allUnits;
344  VSError err;
345  static string unitdata = vs_config->getVariable( "data", "UnitCSV", "modunits.csv" );
346  while (unitdata.length() != 0) {
347  string::size_type where = unitdata.find( " " ), where2 = where;
348  if (where == string::npos)
349  where = unitdata.length();
350  string tmp = unitdata.substr( 0, where );
351  err = allUnits.OpenReadOnly( tmp, UnitFile );
352  if (err <= Ok) {
353  unitTables.push_back( new CSVTable( allUnits, allUnits.GetRoot() ) );
354  allUnits.Close();
355  }
356  if (where2 == string::npos) break;
357  unitdata = unitdata.substr( where+1, unitdata.length() );
358  }
359  //Now include units.csv at the end.
360  err = allUnits.OpenReadOnly( "units.csv", UnitFile );
361  if (err <= Ok) {
362  unitTables.push_back( new CSVTable( allUnits, allUnits.GetRoot() ) );
363  allUnits.Close();
364  }
365 }
366 
368 {
369  for (std::vector<CSVTable*>::iterator it = unitTables.begin(); it != unitTables.end(); ++it)
370  {
371  delete *it;
372  }
373  unitTables.clear();
374 }