예제 #1
0
파일: app.cpp 프로젝트: BITINT/DEFCON2
void App::ShutdownCurrentGame()
{
    //
    // Stop the MetaServer registration

    if( MetaServer_IsRegisteringOverLAN() )
    {
        MetaServer_StopRegisteringOverLAN();
    }

    if( MetaServer_IsRegisteringOverWAN() )
    {
        MetaServer_StopRegisteringOverWAN();
    }
    
	if( m_gameRunning )
    {
        EclRemoveAllWindows();
    }

    //
    // If there is a client, shut it down now

    if( m_world )
    {
        delete m_world;
        m_world = NULL;
    }

    if( m_clientToServer->IsConnected() )
    {
        m_clientToServer->ClientLeave(true);
    }
    else
    {
        m_clientToServer->ClientLeave(false);
    }
    

    //
    // If there is a server, shut it down now
    
    if( m_server )
    {
        m_server->Shutdown();
        delete m_server;
        m_server = NULL;
    }

    if( m_tutorial )
    {
        delete m_tutorial;
        m_tutorial = NULL;
    }

    m_gameRunning = false;
    delete m_game;
    m_game = new Game();


    g_startTime = FLT_MAX;
    g_gameTime = 0.0f;
    g_advanceTime = 0.0f;
    g_lastServerAdvance = 0.0f;
    g_predictionTime = 0.0f;
    g_lastProcessedSequenceId = -2;                         // -2=not yet ready to begin. -1=ready for first update (id=0)

    g_soundSystem->StopAllSounds( SoundObjectId(), "StartMusic StartMusic" );

    g_app->GetMapRenderer()->m_renderEverything = false;
    m_gameStartTimer = -1.0f;
	GetInterface()->SetMouseCursor();
	SetMousePointerVisible(true);
}
예제 #2
0
파일: nuke.cpp 프로젝트: cahocachi/DEFCON
bool Nuke::Update()
{
    //
    // Are we disarmed?

    if( m_currentState == 1 && m_stateTimer <= 0 )
    {
        if( m_teamId == g_app->GetWorld()->m_myTeamId )
        {
            char message[64];
            sprintf( message, LANGUAGEPHRASE("message_disarmed") );
            g_app->GetWorld()->AddWorldMessage( m_longitude, m_latitude, m_teamId, message, WorldMessage::TypeObjectState );
        }
        return true;
    }


    //
    // Is our waypoint changing?

    Fixed timePerUpdate = SERVER_ADVANCE_PERIOD * g_app->GetWorld()->GetTimeScaleFactor();
    
    if( m_newLongitude != 0 || m_newLatitude != 0 )
    {
        Fixed factor1 = m_turnRate * timePerUpdate * 2;
        Fixed factor2 = 1 - factor1;
        m_targetLongitude = ( m_newLongitude * factor1 ) + ( m_targetLongitude * factor2 );
        m_targetLatitude = ( m_newLatitude * factor1 ) + ( m_targetLatitude * factor2 );

        if( ( m_targetLongitude - m_newLongitude ).abs() < 1 &&
			( m_targetLatitude - m_newLatitude ).abs() < 1 )
        {
            SetWaypoint( m_newLongitude, m_newLatitude );
            m_newLongitude = 0;
            m_newLatitude = 0;
        }
    }


    //
    // Move towards target

    Vector3<Fixed> target( m_targetLongitude, m_targetLatitude, 0 );
    Vector3<Fixed> pos( m_longitude, m_latitude, 0 );
    Fixed remainingDistance = (target - pos).Mag();
    Fixed fractionDistance = 1 - remainingDistance / m_totalDistance;

    Vector3<Fixed> front = (target - pos).Normalise();  
    Fixed fractionNorth = 5 * m_latitude.abs() / ( 200 / 2 );
    fractionNorth = max( fractionNorth, 3 );
    
    front.RotateAroundZ( Fixed::PI / (fractionNorth * m_curveDirection) );
    front.RotateAroundZ( fractionDistance * (-m_curveDirection * Fixed::PI/fractionNorth) );

    if( pos.y > 85 )
    {
        // We are dangerously far north
        // Make sure we dont go off the top of the world
        Fixed extremeFractionNorth = (pos.y - 85) / 15;
        Clamp( extremeFractionNorth, Fixed(0), Fixed(1) );
        front.y *= ( 1 - extremeFractionNorth );
        front.Normalise();
    }

    m_vel = Vector3<Fixed>(front * (m_speed/2 + m_speed/2 * fractionDistance * fractionDistance));
       
    Fixed newLongitude = m_longitude + m_vel.x * timePerUpdate;
    Fixed newLatitude = m_latitude + m_vel.y * timePerUpdate;
    Fixed newDistance = g_app->GetWorld()->GetDistance( newLongitude, newLatitude, m_targetLongitude, m_targetLatitude);

    if( newLongitude <= -180 ||
        newLongitude >= 180 )
    {
        m_longitude = newLongitude;
        CrossSeam();

        newLongitude = m_longitude;
        newDistance = g_app->GetWorld()->GetDistance( newLongitude, newLatitude, m_targetLongitude, m_targetLatitude );
    }

    if( newDistance < 2 &&
        newDistance >= remainingDistance )
    {
        m_targetLongitude = 0;
        m_targetLatitude = 0;
        m_vel.Zero();
        g_app->GetWorld()->CreateExplosion( m_teamId, m_longitude, m_latitude, 100 );
        g_soundSystem->TriggerEvent( SoundObjectId(m_objectId), "Detonate" );
        return true;
    }
    else
    {
        m_range -= Vector3<Fixed>( m_vel.x * Fixed(timePerUpdate), m_vel.y * Fixed(timePerUpdate), 0 ).Mag();
        if( m_range <= 0 )
        {
            m_life = 0;
			m_lastHitByTeamId = -1;
            g_app->GetWorld()->AddOutOfFueldMessage( m_objectId );
        }
        m_longitude = newLongitude;
        m_latitude = newLatitude;
    }

    return MovingObject::Update();
}
예제 #3
0
파일: game.cpp 프로젝트: cahocachi/DEFCON
void Game::Update()
{
    //
    // If there is a real-world timer, update it

    if( m_winner == -1 && m_maxGameTime > 0 )
    {
        m_maxGameTime -= SERVER_ADVANCE_PERIOD;
        m_maxGameTime = max( m_maxGameTime, 0 );

        if( !m_gameTimeWarning && 
            m_maxGameTime <= (10 * 60) &&
            g_app->GetGame()->GetOptionValue("MaxGameRealTime") >= 10 )
        {
            g_app->GetInterface()->ShowMessage( 0, 0, -1, LANGUAGEPHRASE("message_ten_minute_warning"), true );
            m_gameTimeWarning = true;

            if( g_app->m_hidden )
            {
                g_app->GetStatusIcon()->SetSubIcon( STATUS_ICON_TIMER );
                g_app->GetStatusIcon()->SetCaption( LANGUAGEPHRASE("tray_icon_ten_minute_warning") );
            }
        }
    }


    // Remove all remaining units and calculate total nukes when Defcon 3 hits

    int defcon = g_app->GetWorld()->GetDefcon();
    if( defcon != m_lastKnownDefcon )
    {
        if( !g_app->GetTutorial() ||
            g_app->GetTutorial()->GetCurrentLevel() == 7 )
        {
            if( defcon == 3 )
            {
                for( int i = 0; i < g_app->GetWorld()->m_teams.Size(); ++i )
                {
                    Team *team = g_app->GetWorld()->m_teams[i];
                    team->m_unitCredits = 0;
                    for( int j = 0; j < WorldObject::NumObjectTypes; ++j )
                    {
                        team->m_unitsAvailable[j] = 0;
                    }
                
                }

                CountNukes();
                for( int i = 0; i < g_app->GetWorld()->m_teams.Size(); ++i )
                {
                    Team *team = g_app->GetWorld()->m_teams[i];
                    m_totalNukes[team->m_teamId] = m_nukeCount[team->m_teamId];
                }

                EclRemoveWindow( "Side Panel" );
                EclRemoveWindow( "Placement" );                
            }
        }
        m_lastKnownDefcon = defcon;
    }


    //
    // Has somebody won?

    if( m_winner == -1 )
    {
        //
        // If the game is counting down...

        if( m_victoryTimer > 0 )
        {
            m_victoryTimer -= SERVER_ADVANCE_PERIOD * g_app->GetWorld()->GetTimeScaleFactor();
            m_victoryTimer = max( m_victoryTimer, 0 );
        }

        m_recalcTimer -= SERVER_ADVANCE_PERIOD;
        if( m_recalcTimer <= 0 )
        {
            m_recalcTimer = 3;

            //
            // Recalculate the scores

            CountNukes();
            CalculateScores();
    
    
            //
            // Look at nukes remaining
            // If there are few enough nukes, start the timer
            if( !m_lockVictoryTimer &&
                 m_victoryTimer < 0 )
            {            
                int totalNukeCount = 0;
                int totalMaxNukeCount = 0;
                int numTeams = g_app->GetWorld()->m_teams.Size();
                for( int t = 0; t < numTeams; ++t )
                {
                    Team *team = g_app->GetWorld()->m_teams[t];
                    totalNukeCount += m_nukeCount[team->m_teamId];
                    totalMaxNukeCount += m_totalNukes[team->m_teamId];
                }

                float averageNukeCount = totalNukeCount / (float) numTeams;
                float averageTotalCount = totalMaxNukeCount / (float) numTeams;
                float victoryNukeCount = averageTotalCount * GetOptionValue("VictoryTrigger") / 100.0f;

                if( averageNukeCount <= victoryNukeCount )
                {
                    m_victoryTimer = GetOptionValue("VictoryTimer");
                    m_victoryTimer *= 60;       //to get it into minutes

                    if( m_victoryTimer > 0 )
                    {
                        g_app->GetInterface()->ShowMessage( 0, 0, -1, LANGUAGEPHRASE("message_victory_timer"), true );
                        g_soundSystem->TriggerEvent( "Interface", "DefconChange" );

                        if( g_app->m_hidden )
                        {
                            g_app->GetStatusIcon()->SetSubIcon( STATUS_ICON_TIMER );
                            g_app->GetStatusIcon()->SetCaption( LANGUAGEPHRASE("tray_icon_victory_timer") );
                        }
                    }
                }
            }

            //
            // If the countdown has finished
            // Declare the winner now!

            if( m_victoryTimer == 0 || m_maxGameTime == 0 )
            {
                CalculateScores();
    
                m_winner = -1;
                int winningScore = 0;
                for( int t = 0; t < g_app->GetWorld()->m_teams.Size(); ++t )
                {
                    Team *team = g_app->GetWorld()->m_teams[t];
                    int score = GetScore(team->m_teamId);
                    g_app->GetClientToServer()->SendTeamScore( team->m_teamId, score );
                    if( score > winningScore )
                    {
                        winningScore = score;
                        m_winner = team->m_teamId;
                    }
                }

                int numPlayers = g_app->GetWorld()->m_teams.Size();

                char msg[128];
                if( m_winner != -1 )
                {
                    strcpy(msg, LANGUAGEPHRASE("message_victory"));
                    LPREPLACESTRINGFLAG( 'T', g_app->GetWorld()->GetTeam(m_winner)->GetTeamName(), msg );
                    
                    if( m_winner == g_app->GetWorld()->m_myTeamId &&
                        numPlayers > 1 )
                    {
                    }
                }
                else
                {
                    strcpy(msg, LANGUAGEPHRASE("message_stalemate"));
                    m_winner = 999;
                }
                strupr(msg);
                g_app->GetInterface()->ShowMessage( 0, 0, m_winner, msg, true );

                g_app->GetMapRenderer()->m_renderEverything = true;
                for( int i = 0; i < g_app->GetWorld()->m_teams.Size(); ++i )
                {
                    g_app->GetWorld()->m_teams[i]->m_desiredGameSpeed = 0;
                }

                if( !EclGetWindow( "Stats" ) )
                {
                    EclRegisterWindow( new StatsWindow()  );
                }

                g_soundSystem->StopAllSounds( SoundObjectId(), "StartMusic StartMusic" );
                g_soundSystem->TriggerEvent( "Interface", "GameOver" );

                int specVisible = g_app->GetGame()->GetOptionValue("SpectatorChatChannel");
                if( specVisible == 0 &&
                    g_app->GetWorld()->m_spectators.Size() )
                {
                    g_app->GetWorld()->AddChatMessage( -1, CHATCHANNEL_PUBLIC, LANGUAGEPHRASE("message_spectators_chat_players"), -1, false );
                }
            }
        }
    }
}