void GameUniverse::StartDraw() { #ifndef WIN32 RESETTIME(); #endif GFXBeginScene(); unsigned int i; StarSystem * lastStarSystem = NULL; for (i=0;i<cockpit.size();++i) { SetActiveCockpit (i); float x,y,w,h; CalculateCoords (i,cockpit.size(),x,y,w,h); AccessCamera()->SetSubwindow (x,y,w,h); if (cockpit.size()>1&&AccessCockpit(i)->activeStarSystem!=lastStarSystem) { active_star_system[0]->SwapOut(); lastStarSystem=AccessCockpit()->activeStarSystem; active_star_system[0]=lastStarSystem; lastStarSystem->SwapIn(); } AccessCockpit()->SelectProperCamera(); if (cockpit.size()>0) AccessCamera()->UpdateGFX(); if (!RefreshGUI() && !UniverseUtil::isSplashScreenShowing()) { activeStarSystem()->Draw(); } AccessCamera()->SetSubwindow (0,0,1,1); } UpdateTime(); UpdateTimeCompressionSounds(); _Universe->SetActiveCockpit (((int)(rand01()*cockpit.size()))%cockpit.size()); for (i=0;i<star_system.size()&&i<game_options.NumRunningSystems;++i) { star_system[i]->Update((i==0)?1:game_options.InactiveSystemTime/i,true); } StarSystem::ProcessPendingJumps(); for (i=0;i<cockpit.size();++i) { SetActiveCockpit(i); pushActiveStarSystem(AccessCockpit(i)->activeStarSystem); ProcessInput(i); //input neesd to be taken care of; popActiveStarSystem(); } if (screenshotkey) { KBData b; Screenshot(b,PRESS); screenshotkey=false; } GFXEndScene(); //so we don't starve the audio thread micro_sleep (getmicrosleep()); //remove systems not recently visited? static int sorttime=0; if (game_options.garbagecollectfrequency!=0) { //don't want to delete something when there is something pending to jump therexo if (PendingJumpsEmpty()) { if ((++sorttime)%game_options.garbagecollectfrequency==1) { SortStarSystems(star_system,active_star_system.back()); if (star_system.size() > game_options.numoldsystems && game_options.deleteoldsystems) { if (std::find (active_star_system.begin(),active_star_system.end(),star_system.back())==active_star_system.end()) { delete star_system.back(); star_system.pop_back(); } else { VSFileSystem::vs_fprintf (stderr,"error with active star system list\n"); } } } } } }
bool Cockpit::Update() { if (retry_dock && !SERVER && Network == NULL) { QVector vec; DockToSavedBases( _Universe->CurrentCockpit(), vec ); } if (jumpok) jumpok++; if (jumpok > 5) jumpok = 0; UpdAutoPilot(); Unit *par = GetParent(); if (par != NULL) { static float minEnergyForShieldDownpower = XMLSupport::parse_float( vs_config->getVariable( "physics", "shield_energy_downpower", "-.125" ) ); static float minEnergyShieldTime = XMLSupport::parse_float( vs_config->getVariable( "physics", "shield_energy_downpower_time", "5" ) ); static float minEnergyShieldPercent = XMLSupport::parse_float( vs_config->getVariable( "physics", "shield_energy_downpower_percent", ".66666666666666" ) ); bool toolittleenergy = (par->EnergyData() <= minEnergyForShieldDownpower); if (toolittleenergy) { secondsWithZeroEnergy += SIMULATION_ATOM; if (secondsWithZeroEnergy > minEnergyShieldTime) { secondsWithZeroEnergy = 0; PowerDownShield( &par->shield, minEnergyShieldPercent ); } } else { secondsWithZeroEnergy = 0; } } if ( turretcontrol.size() > _Universe->CurrentCockpit() ) { if (turretcontrol[_Universe->CurrentCockpit()]) { turretcontrol[_Universe->CurrentCockpit()] = 0; Unit *par = GetParent(); //this being here, it will require poking the turret from the undock script if (par) { if (par->name == "return_to_cockpit") { //if (par->owner->isUnit()==UNITPTR ) this->SetParent(par->owner,GetUnitFileName().c_str(),this->unitmodname.c_str(),savegame->GetPlayerLocation()); // this warps back to the parent unit if we're eject-docking. in this position it also causes badness upon loading a game. Unit *temp = findUnitInStarsystem( par->owner ); if (temp) { SwitchUnits( NULL, temp ); this->SetParent( temp, GetUnitFileName().c_str(), this->unitmodname.c_str(), temp->Position() ); //this warps back to the parent unit if we're eject-docking. causes badness upon loading a game. } par->Kill(); } } if (par) { static int index = 0; int i = 0; bool tmp = false; bool tmpgot = false; if (parentturret.GetUnit() == NULL) { tmpgot = true; Unit *un; for (un_iter ui = par->getSubUnits(); (un = *ui);) { if ( _Universe->isPlayerStarship( un ) ) { ++ui; continue; } if (i++ == index) { //NOTE : this may have been a correction to the conditional bug ++index; if (un->name.get().find( "accessory" ) == string::npos) { tmp = true; SwitchUnitsTurret( par, un ); parentturret.SetUnit( par ); Unit *finalunit = GetFinalTurret( un ); this->SetParent( finalunit, GetUnitFileName().c_str(), this->unitmodname.c_str(), savegame->GetPlayerLocation() ); break; } } ++ui; } } if (tmp == false) { if (tmpgot) index = 0; Unit *un = parentturret.GetUnit(); if ( un && ( !_Universe->isPlayerStarship( un ) ) ) { SetParent( un, GetUnitFileName().c_str(), this->unitmodname.c_str(), savegame->GetPlayerLocation() ); SwitchUnits( NULL, un ); parentturret.SetUnit( NULL ); un->SetTurretAI(); un->DisableTurretAI(); } } } } } static bool autoclear = XMLSupport::parse_bool( vs_config->getVariable( "AI", "autodock", "false" ) ); if (autoclear && par) { Unit *targ = par->Target(); if (targ) { static float autopilot_term_distance = XMLSupport::parse_float( vs_config->getVariable( "physics", "auto_pilot_termination_distance", "6000" ) ); float doubled = dockingdistance( targ, par ); if ( ( (targ->isUnit() != PLANETPTR && doubled < autopilot_term_distance) || (UnitUtil::getSignificantDistance( targ, par ) <= 0) ) && ( !( par->IsCleared( targ ) || targ->IsCleared( par ) || par->isDocked( targ ) || targ->isDocked( par ) ) ) && (par->getRelation( targ ) >= 0) && (targ->getRelation( par ) >= 0) ) { if ( targ->isUnit() != PLANETPTR || targ->GetDestinations().empty() ) RequestClearence( par, targ, 0 ); //sex is always 0... don't know how to get it. } else if ( ( par->IsCleared( targ ) || targ->IsCleared( par ) ) && ( !( par->isDocked( targ ) ) || targ->isDocked( par ) ) && ( (targ->isUnit() == PLANETPTR && UnitUtil::getSignificantDistance( par, targ ) > 0) || ( ( targ->isUnit() != PLANETPTR && UnitUtil::getSignificantDistance( par, targ ) > ( targ->rSize()+par->rSize() ) ) && (doubled >= autopilot_term_distance) ) ) ) { if ( targ->isUnit() != PLANETPTR || targ->GetDestinations().empty() ) { par->EndRequestClearance( targ ); targ->EndRequestClearance( par ); } } } } if ( switchunit.size() > _Universe->CurrentCockpit() ) { if (switchunit[_Universe->CurrentCockpit()]) { parentturret.SetUnit( NULL ); static float initialzoom = XMLSupport::parse_float( vs_config->getVariable( "graphics", "inital_zoom_factor", "2.25" ) ); zoomfactor = initialzoom; static int index = 0; switchunit[_Universe->CurrentCockpit()] = 0; static bool switch_nonowned_units = XMLSupport::parse_bool( vs_config->getVariable( "AI", "switch_nonowned_units", "true" ) ); //switch_nonowned_units = true; //static bool switch_to_fac=XMLSupport::parse_bool(vs_config->getVariable("AI","switch_to_whole_faction","true")); Unit *un; bool found = false; int i = 0; for (un_iter ui = _Universe->activeStarSystem()->getUnitList().createIterator(); (un = *ui); ++ui) if (un->faction == this->unitfaction) { //this switches units UNLESS we're an ejected pilot. Instead, if we are an ejected //pilot, switch only if we're close enough. //the trigger is to allow switching only between ships that are actually owned by you, this prevents //stealing a ship from a hired wingman. if ( ( ( (par != NULL) && (i++) >= index ) || par == NULL ) && ( !_Universe->isPlayerStarship( un ) ) && ( switch_nonowned_units || (par != NULL && un->owner == par->owner) || (par != NULL && un == par->owner) || (par != NULL && un->owner == par) || (par == NULL && un->owner) ) && (un->name != "eject") && (un->name != "Pilot") && (un->isUnit() != MISSILEPTR) ) { found = true; ++index; Unit *k = GetParent(); bool proceed = true; if (k) if (k->name == "eject" || k->name == "Pilot" || k->name == "return_to_cockpit") proceed = false; //we are an ejected pilot, so, if we can get close enough to the related unit, jump into it and remove the seat. This said, always allow //switching from the "fake" ejection seat (ejectdock). if ( !proceed && k && ( k->Position()-un->Position() ).Magnitude() < ( un->rSize()+5*k->rSize() ) ) { if ( !(k->name == "return_to_cockpit") ) SwitchUnits( k, un ); //this refers to cockpit if ( !(k->name == "return_to_cockpit") ) this->SetParent( un, GetUnitFileName().c_str(), this->unitmodname.c_str(), savegame->GetPlayerLocation() ); if ( !(k->name == "return_to_cockpit") ) k->Kill(); //un->SetAI(new FireKeyboard ()) } if (proceed) { //k->PrimeOrdersLaunched(); //k->SetAI (new Orders::AggressiveAI ("interceptor.agg.xml")); //k->SetTurretAI(); //Flightgroup * fg = k->getFlightgroup(); //if (fg!=NULL) { // //un->SetFg (fg,fg->nr_ships++); //fg->nr_ships_left++; //fg->leader.SetUnit(un); //fg->directive="b"; //} SwitchUnits( k, un ); this->SetParent( un, GetUnitFileName().c_str(), this->unitmodname.c_str(), savegame->GetPlayerLocation() ); //un->SetAI(new FireKeyboard ()) } break; } } if (!found) index = 0; } } //this causes the physical ejecting. Check going_to_dock_screen in here, also. if (ejecting) { ejecting = false; //going_to_dock_screen=true; // NO, clear this only after we've UNDOCKED that way we know we don't have issues. Unit *un = GetParent(); if (un) { if (going_to_dock_screen == false) un->EjectCargo( (unsigned int) -1 ); if (going_to_dock_screen == true) { un->EjectCargo( (unsigned int) -2 ); going_to_dock_screen = false; } } } if (!par) { if ( respawnunit.size() > _Universe->CurrentCockpit() ) { if (respawnunit[_Universe->CurrentCockpit()]) { static float initialzoom = XMLSupport::parse_float( vs_config->getVariable( "graphics", "inital_zoom_factor", "2.25" ) ); zoomfactor = initialzoom; if (Network != NULL) { Network[_Universe->CurrentCockpit()].respawnRequest(); respawnunit[_Universe->CurrentCockpit()] = 0; } else { parentturret.SetUnit( NULL ); respawnunit[_Universe->CurrentCockpit()] = 0; std::string savegamefile = mission->getVariable( "savegame", "" ); unsigned int k; for (k = 0; k < _Universe->numPlayers(); ++k) if (_Universe->AccessCockpit( k ) == this) break; if ( k == _Universe->numPlayers() ) k = 0; if (active_missions.size() > 1) { for (int i = active_missions.size()-1; i > 0; --i) //don't terminate zeroth mission if (active_missions[i]->player_num == k) active_missions[i]->terminateMission(); } unsigned int whichcp = k; string newsystem; QVector pos; bool setplayerXloc; savegame->SetStarSystem( "" ); QVector tmpoldpos = savegame->GetPlayerLocation(); savegame->SetPlayerLocation( QVector( FLT_MAX, FLT_MAX, FLT_MAX ) ); vector< string > packedInfo; savegame->ParseSaveGame( savegamefile, newsystem, newsystem, pos, setplayerXloc, this->credits, packedInfo, k ); UnpackUnitInfo(packedInfo); if (pos.i == FLT_MAX && pos.j == FLT_MAX && pos.k == FLT_MAX) pos = tmpoldpos; savegame->SetPlayerLocation( pos ); CopySavedShips( savegame->GetCallsign(), whichcp, packedInfo, true ); bool actually_have_save = false; static bool persistent_on_load = XMLSupport::parse_bool( vs_config->getVariable( "physics", "persistent_on_load", "true" ) ); if (savegame->GetStarSystem() != "") { actually_have_save = true; newsystem = savegame->GetStarSystem()+".system"; } else { newsystem = _Universe->activeStarSystem()->getFileName(); if (newsystem.find( ".system" ) == string::npos) newsystem += ".system"; } Background::BackgroundClone savedtextures = { {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }; if (persistent_on_load) { _Universe->getActiveStarSystem( 0 )->SwapOut(); } else { Background *tmp = _Universe->activeStarSystem()->getBackground(); savedtextures = tmp->Cache(); _Universe->clearAllSystems(); } StarSystem *ss = _Universe->GenerateStarSystem( newsystem.c_str(), "", Vector( 0, 0, 0 ) ); if (!persistent_on_load) savedtextures.FreeClone(); this->activeStarSystem = ss; _Universe->pushActiveStarSystem( ss ); vector< StarSystem* >saved; while ( _Universe->getNumActiveStarSystem() ) { saved.push_back( _Universe->activeStarSystem() ); _Universe->popActiveStarSystem(); } if ( !saved.empty() ) saved.back() = ss; unsigned int mysize = saved.size(); for (unsigned int i = 0; i < mysize; i++) { _Universe->pushActiveStarSystem( saved.back() ); saved.pop_back(); } ss->SwapIn(); int fgsnumber = 0; if (fg) { fgsnumber = fg->flightgroup_nr++; fg->nr_ships++; fg->nr_ships_left++; } Unit *un = UnitFactory::createUnit( GetUnitFileName().c_str(), false, this->unitfaction, unitmodname, fg, fgsnumber ); un->SetCurPosition( UniverseUtil::SafeEntrancePoint( savegame->GetPlayerLocation() ) ); ss->AddUnit( un ); this->SetParent( un, GetUnitFileName().c_str(), unitmodname.c_str(), savegame->GetPlayerLocation() ); SwitchUnits( NULL, un ); this->credits = savegame->GetSavedCredits(); DoCockpitKeys(); _Universe->popActiveStarSystem(); _Universe->pushActiveStarSystem( ss ); savegame->ReloadPickledData(); savegame->LoadSavedMissions(); if (actually_have_save && !SERVER && Network == NULL) { QVector vec; DockToSavedBases( whichcp, vec ); } UniverseUtil::hideSplashScreen(); _Universe->popActiveStarSystem(); if (!persistent_on_load) _Universe->pushActiveStarSystem( ss ); return true; } } } } return false; }