Exemplo n.º 1
0
std::vector<CDeterministicMNCPtr> CDeterministicMNList::CalculateQuorum(size_t maxSize, const uint256& modifier) const
{
    auto scores = CalculateScores(modifier);

    // sort is descending order
    std::sort(scores.rbegin(), scores.rend(), [](const std::pair<arith_uint256, CDeterministicMNCPtr>& a, std::pair<arith_uint256, CDeterministicMNCPtr>& b) {
        if (a.first == b.first) {
            // this should actually never happen, but we should stay compatible with how the non deterministic MNs did the sorting
            return a.second->collateralOutpoint < b.second->collateralOutpoint;
        }
        return a.first < b.first;
    });

    // take top maxSize entries and return it
    std::vector<CDeterministicMNCPtr> result;
    result.resize(std::min(maxSize, scores.size()));
    for (size_t i = 0; i < result.size(); i++) {
        result[i] = std::move(scores[i].second);
    }
    return result;
}
Exemplo n.º 2
0
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 );
                }
            }
        }
    }
}