void ArenasScreen::init()
{
    Screen::init();
    buildTrackList();
    DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("tracks");
    // select something by default for the game master
    assert( w != NULL );
    w->setSelection(w->getItems()[0].m_code_name, PLAYER_ID_GAME_MASTER, true);
}   // init
Beispiel #2
0
/**
 * Callback handling events from the kart selection menu
 */
void KartSelectionScreen::eventCallback(Widget* widget,
                                        const std::string& name,
                                        const int player_id)
{
    // don't allow changing group after someone confirmed
    if (name == "kartgroups" && !m_game_master_confirmed)
    {
        RibbonWidget* tabs = getWidget<RibbonWidget>("kartgroups");
        assert(tabs != NULL);
        DynamicRibbonWidget* w = getWidget<DynamicRibbonWidget>("karts");
        assert(w != NULL);

        setKartsFromCurrentGroup();

        const std::string &selected_kart_group =
            tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER);

        UserConfigParams::m_last_used_kart_group = selected_kart_group;

        RandomGenerator random;

        const int num_players = m_kart_widgets.size();
        for (int n=0; n<num_players; n++)
        {
            // The game master is the one that can change the groups, leave
            // his focus on the tabs for others, remove focus from kart that
            // might no more exist in this tab.
            if (n != PLAYER_ID_GAME_MASTER)
                GUIEngine::focusNothingForPlayer(n);

            if (!m_kart_widgets[n].isReady())
            {
                // try to preserve the same kart for each player (except for
                // game master, since it's the one  that can change the
                // groups, so focus for this player must remain on the tabs)
                const std::string& selected_kart =
                    m_kart_widgets[n].getKartInternalName();
                if (!w->setSelection( selected_kart, n,
                                      n != PLAYER_ID_GAME_MASTER))
                {
                    // if we get here, it means one player "lost" his kart in
                    // the tab switch
                    if (UserConfigParams::logGUI())
                        Log::info("KartSelectionScreen", "Player %u"
                                  " lost their selection when switching tabs!!!",n);

                    // Select a random kart in this case
                    const int count = (int) w->getItems().size();
                    if (count > 0)
                    {
                        // FIXME: two players may be given the same kart by
                        // the use of random
                        const int random_id = random.get( count );

                        // select kart for players > 0 (player 0 is the one
                        // that can change the groups, so focus for player 0
                        // must remain on the tabs)
                        const bool success =
                            w->setSelection( random_id, n,
                                             n != PLAYER_ID_GAME_MASTER );
                        if (!success)
                            Log::warn("KartSelectionScreen",
                                      "setting kart of player %u failed");
                    }
                    else
                    {
                        Log::warn("KartSelectionScreen",  " 0 items "
                                  "in the ribbon");
                    }
                }
            }
        } // end for
    }
    else if (name == "karts")
    {
        if (m_kart_widgets.size() > unsigned(player_id))
            playerConfirm(player_id);
    }
    else if (name == "back")
    {
        StateManager::get()->escapePressed();
    }
    else
    {
        // Transmit to all subwidgets, maybe *they* care about this event
        const int amount = m_kart_widgets.size();
        for (int n=0; n<amount; n++)
        {
            m_kart_widgets[n].transmitEvent(widget, name, player_id);
        }

        // those events may mean that a player selection changed, so
        // validate again
        validateIdentChoices();
        validateKartChoices();
    }
}   // eventCallback
Beispiel #3
0
void KartSelectionScreen::playerConfirm(const int player_id)
{
    DynamicRibbonWidget* w = getWidget<DynamicRibbonWidget>("karts");
    assert(w != NULL);
    const std::string selection = w->getSelectionIDString(player_id);
    if (StringUtils::startsWith(selection, ID_LOCKED) && !m_multiplayer)
    {
        unlock_manager->playLockSound();
        return;
    }

    if (player_id == PLAYER_ID_GAME_MASTER)
    {
        UserConfigParams::m_default_kart = selection;
    }

    if (m_kart_widgets[player_id].getKartInternalName().size() == 0 ||
        m_kart_widgets[player_id].getKartInternalName() == RibbonWidget::NO_ITEM_ID)
    {
        SFXManager::get()->quickSound( "anvil" );
        return;
    }

    const int amount = m_kart_widgets.size();

    // Check if we have enough karts for everybody. If there are more players
    // than karts then just allow duplicates
    const int available_kart_count = (int) w->getItems().size();
    const bool will_need_duplicates = (amount > available_kart_count);

    // make sure no other player selected the same identity or kart
    for (int n=0; n<amount; n++)
    {
        if (n == player_id) continue; // don't check a kart against itself

        const bool player_ready   = m_kart_widgets[n].isReady();
        const bool ident_conflict =
            !m_kart_widgets[n].getAssociatedPlayer()->getProfile()
            ->isGuestAccount() &&
            m_kart_widgets[n].getAssociatedPlayer()->getProfile() ==
            m_kart_widgets[player_id].getAssociatedPlayer()->getProfile();
        const bool kart_conflict  = sameKart(m_kart_widgets[n],
                                             m_kart_widgets[player_id]);

        if (player_ready && (ident_conflict || kart_conflict) &&
                !will_need_duplicates)
        {
            if (UserConfigParams::logGUI())
                Log::warn("KartSelectionScreen", "You can't select this identity "
                       "or kart, someone already took it!!");

            SFXManager::get()->quickSound( "anvil" );
            return;
        }

        // If two PlayerKart entries are associated to the same ActivePlayer,
        // something went wrong
        assert(m_kart_widgets[n].getAssociatedPlayer() !=
               m_kart_widgets[player_id].getAssociatedPlayer());
    }

    // Mark this player as ready to start
    m_kart_widgets[player_id].markAsReady();

    if (player_id == PLAYER_ID_GAME_MASTER)
    {
        m_game_master_confirmed = true;
        RibbonWidget* tabs = getWidget<RibbonWidget>("kartgroups");
        assert( tabs != NULL );
        tabs->setActive(false);
    }

    // validate choices to notify player of duplicates
    const bool names_ok = validateIdentChoices();
    const bool karts_ok = validateKartChoices();

    if (!names_ok || !karts_ok) return;

    // check if all players are ready
    bool allPlayersReady = true;
    for (int n=0; n<amount; n++)
    {
        if (!m_kart_widgets[n].isReady())
        {
            allPlayersReady = false;
            break;
        }
    }

    if (allPlayersReady && (!m_multiplayer || amount > 1)) allPlayersDone();
}   // playerConfirm
Beispiel #4
0
bool KartSelectionScreen::validateKartChoices()
{
    bool ok = true;

    const unsigned int amount = m_kart_widgets.size();

    // reset all marks, we'll re-add them next if errors are still there
    for (unsigned int n=0; n<amount; n++)
    {
        m_kart_widgets[n].m_model_view->unsetBadge(BAD_BADGE);
    }

    // Check if we have enough karts for everybody. If there are more
    // players than karts then just allow duplicates
    DynamicRibbonWidget* w = getWidget<DynamicRibbonWidget>("karts");
    assert( w != NULL );
    const unsigned int availableKartCount = (unsigned int)w->getItems().size();
    if (amount > availableKartCount) return true;

    // Check everyone for duplicates
    for (unsigned int n=0; n<amount; n++)
    {
        for (unsigned int m=n+1; m<amount; m++)
        {
            // check if 2 players took the same name
            if (sameKart(m_kart_widgets[n], m_kart_widgets[m]))
            {
                if (UserConfigParams::logGUI())
                {
                    Log::warn("KartSelectionScreen", "Kart conflict!!");
                    Log::warn("KartSelectionScreen", "    Player %u chose %s",n,
                              m_kart_widgets[n].getKartInternalName().c_str());
                    Log::warn("KartSelectionScreen", "    Player %u chose %s",m,
                              m_kart_widgets[m].getKartInternalName().c_str());
                }

                // two players took the same kart. check if one is ready
                if (!m_kart_widgets[n].isReady() &&
                        m_kart_widgets[m].isReady())
                {
                    if (UserConfigParams::logGUI())
                       Log::info("KartSelectionScreen", "    --> Setting red badge on player %u", n);

                    // player m is ready, so player n should not choose
                    // this name
                    m_kart_widgets[n].m_model_view->setBadge(BAD_BADGE);
                }
                else if (m_kart_widgets[n].isReady() &&
                         !m_kart_widgets[m].isReady())
                {
                    if (UserConfigParams::logGUI())
                        Log::info("KartSelectionScreen", "    --> Setting red badge on player %u",m);

                    // player n is ready, so player m should not
                    // choose this name
                    m_kart_widgets[m].m_model_view->setBadge(BAD_BADGE);
                }
                else if (m_kart_widgets[n].isReady() &&
                         m_kart_widgets[m].isReady())
                {
                    // it should be impossible for two players to confirm
                    // they're ready with the same kart
                    assert(false);
                }

                // we know it's not ok (but don't stop right now, all bad
                // ones need red badges)
                ok = false;
            }
        } // end for
    }

    return ok;

}   // validateKartChoices
Beispiel #5
0
void KartSelectionScreen::allPlayersDone()
{
    input_manager->setMasterPlayerOnly(true);

    RibbonWidget* tabs = getWidget<RibbonWidget>("kartgroups");
    assert(tabs != NULL);

    std::string selected_kart_group =
        tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER);

    UserConfigParams::m_last_used_kart_group = selected_kart_group;

    DynamicRibbonWidget* w = getWidget<DynamicRibbonWidget>("karts");
    assert( w != NULL );

    const PtrVector< StateManager::ActivePlayer, HOLD >& players =
        StateManager::get()->getActivePlayers();

    // ---- Print selection (for debugging purposes)
    if(UserConfigParams::logGUI())
    {
        Log::info("KartSelectionScreen", "players : %d",players.size());

        for (unsigned int n=0; n<players.size(); n++)
        {
            Log::info("KartSelectionScreen", "     Player %u is %s on %s",n,
                    core::stringc(
                          players[n].getConstProfile()->getName().c_str()).c_str(),
                    players[n].getDevice()->getName().c_str());
        }
    }

    for (unsigned int n=0; n<players.size(); n++)
    {
        StateManager::get()->getActivePlayer(n)->getProfile()
            ->incrementUseFrequency();
    }
    // ---- Give player info to race manager
    race_manager->setNumPlayers(players.size());

    // ---- Manage 'random kart' selection(s)
    RandomGenerator random;

    std::vector<ItemDescription> items = w->getItems();

    // remove the 'random' item itself
    const int item_count = (int) items.size();
    for (int n=0; n<item_count; n++)
    {
        if (items[n].m_code_name == RANDOM_KART_ID)
        {
            items[n].m_code_name = ID_DONT_USE;
            break;
        }
    }

    // pick random karts
    const int kart_count = m_kart_widgets.size();
    for (int n = 0; n < kart_count; n++)
    {
        std::string selected_kart = m_kart_widgets[n].m_kartInternalName;

        if (selected_kart == RANDOM_KART_ID)
        {
            // don't select an already selected kart
            int random_id;
            // to prevent infinite loop in case they are all locked
            int count = 0;
            bool done = false;
            do
            {
                random_id = random.get(item_count);
                // valid kart if it can bt used, and is either not locked,
                // or it's a multiplayer race.
                if (items[random_id].m_code_name != ID_DONT_USE &&
                    (!StringUtils::startsWith(items[random_id].m_code_name, ID_LOCKED)
                    || m_multiplayer)                                                 )
                {
                    selected_kart = items[random_id].m_code_name;
                    done = true;
                }
                items[random_id].m_code_name = ID_DONT_USE;
                count++;
                if (count > 100) return;
            }
            while (!done);
        }
        else
        {
            // mark the item as taken
            for (int i=0; i<item_count; i++)
            {
                if (items[i].m_code_name ==
                        m_kart_widgets[n].m_kartInternalName)
                {
                    items[i].m_code_name = ID_DONT_USE;
                    break;
                }
            }
        }

        race_manager->setPlayerKart(n, selected_kart);

        // Set per player difficulty if needed
        if (m_multiplayer && UserConfigParams::m_per_player_difficulty &&
            m_kart_widgets[n].isHandicapped())
            race_manager->setPlayerDifficulty(n, PLAYER_DIFFICULTY_HANDICAP);
    }

    // ---- Switch to assign mode
    input_manager->getDeviceManager()->setAssignMode(ASSIGN);

    StateManager::ActivePlayer *ap = m_multiplayer 
                                   ? NULL 
                                   : StateManager::get()->getActivePlayer(0);
    input_manager->getDeviceManager()->setSinglePlayer(ap);

    // ---- Go to next screen or return to overworld
    if (m_from_overworld || m_go_to_overworld_next)
    {
        m_from_overworld = false; // valid once
        m_go_to_overworld_next = false;
        OverWorld::enterOverWorld();
    }
    else
    {
        RaceSetupScreen::getInstance()->push();
    }
}   // allPlayersDone
void ArenasScreen::buildTrackList()
{
    DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("tracks");
    assert( w != NULL );

    // Re-build track list everytime (accounts for locking changes, etc.)
    w->clearItems();

    RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups");
    assert( tabs != NULL );
    const std::string curr_group_name = tabs->getSelectionIDString(0);

    bool soccer_mode = race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER;

    if (curr_group_name == ALL_ARENA_GROUPS_ID)
    {
        const int trackAmount = track_manager->getNumberOfTracks();

        for (int n=0; n<trackAmount; n++)
        {
            Track* curr = track_manager->getTrack(n);
            if (soccer_mode)
            {
                if(!curr->isSoccer()) continue;
            }
            else
            {
                if(!curr->isArena()) continue;
            }

            if (PlayerManager::get()->getCurrentPlayer()->isLocked(curr->getIdent()))
            {
                w->addItem( _("Locked : solve active challenges to gain access to more!"),
                           "locked", curr->getScreenshotFile(), LOCKED_BADGE );
            }
            else
            {
                w->addItem( curr->getName(), curr->getIdent(), curr->getScreenshotFile(), 0,
                           IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
            }
        }

    }
    else
    {
        const std::vector<int>& currArenas = track_manager->getArenasInGroup(curr_group_name, soccer_mode);
        const int trackAmount = currArenas.size();

        for (int n=0; n<trackAmount; n++)
        {
            Track* curr = track_manager->getTrack(currArenas[n]);
            if (soccer_mode)
            {
                if(!curr->isSoccer()) continue;
            }
            else
            {
                if(!curr->isArena()) continue;
            }

            if (PlayerManager::get()->getCurrentPlayer()->isLocked(curr->getIdent()))
            {
                w->addItem( _("Locked : solve active challenges to gain access to more!"),
                           "locked", curr->getScreenshotFile(), LOCKED_BADGE );
            }
            else
            {
                w->addItem( curr->getName(), curr->getIdent(), curr->getScreenshotFile(), 0,
                           IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
            }
        }
    }
    w->addItem(_("Random Arena"), "random_track", "/gui/track_random.png");
    w->updateItemDisplay();

    assert(w->getItems().size() > 0);
}