コード例 #1
0
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");
					}
				}
			}
		}
	}

}
コード例 #2
0
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;
}