223 lines
8.4 KiB
C++
223 lines
8.4 KiB
C++
// SuperTuxKart - a fun racing game with go-kart
|
|
// Copyright (C) 2014-2015 SuperTuxKart-Team
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 3
|
|
// of the License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
#include "states_screens/network_kart_selection.hpp"
|
|
|
|
#include "audio/sfx_manager.hpp"
|
|
#include "challenges/unlock_manager.hpp"
|
|
#include "config/player_manager.hpp"
|
|
#include "config/user_config.hpp"
|
|
#include "graphics/irr_driver.hpp"
|
|
#include "guiengine/widgets/player_kart_widget.hpp"
|
|
#include "items/item_manager.hpp"
|
|
#include "karts/kart_properties.hpp"
|
|
#include "karts/kart_properties_manager.hpp"
|
|
#include "network/network_player_profile.hpp"
|
|
#include "network/protocol_manager.hpp"
|
|
#include "network/protocols/client_lobby.hpp"
|
|
#include "network/stk_host.hpp"
|
|
#include "states_screens/server_selection.hpp"
|
|
#include "states_screens/state_manager.hpp"
|
|
#include "states_screens/tracks_screen.hpp"
|
|
#include "states_screens/waiting_for_others.hpp"
|
|
|
|
static const char ID_LOCKED[] = "locked/";
|
|
|
|
using namespace GUIEngine;
|
|
|
|
DEFINE_SCREEN_SINGLETON( NetworkKartSelectionScreen );
|
|
|
|
NetworkKartSelectionScreen::NetworkKartSelectionScreen()
|
|
: KartSelectionScreen("karts_online.stkgui")
|
|
{
|
|
} // NetworkKartSelectionScreen
|
|
|
|
// ----------------------------------------------------------------------------
|
|
NetworkKartSelectionScreen::~NetworkKartSelectionScreen()
|
|
{
|
|
} // ~NetworkKartSelectionScreen
|
|
|
|
// ----------------------------------------------------------------------------
|
|
void NetworkKartSelectionScreen::init()
|
|
{
|
|
m_multiplayer = false;
|
|
KartSelectionScreen::init();
|
|
|
|
RibbonWidget* tabs = getWidget<RibbonWidget>("kartgroups");
|
|
assert( tabs != NULL );
|
|
// Select standard kart group
|
|
tabs->select( "standard", PLAYER_ID_GAME_MASTER);
|
|
tabs->setActive(false);
|
|
tabs->setVisible(false);
|
|
|
|
// change the back button image (because it makes the game quit)
|
|
IconButtonWidget* back_button = getWidget<IconButtonWidget>("back");
|
|
back_button->setImage("gui/main_quit.png");
|
|
|
|
// add a widget for each player except self (already exists):
|
|
GameSetup* setup = STKHost::get()->getGameSetup();
|
|
if (!setup)
|
|
{
|
|
Log::error("NetworkKartSelectionScreen",
|
|
"No network game setup registered.");
|
|
return;
|
|
}
|
|
std::vector<NetworkPlayerProfile*> players = setup->getPlayers();
|
|
|
|
Log::info("NKSS", "There are %d players", players.size());
|
|
// ---- Get available area for karts
|
|
// make a copy of the area, ands move it to be outside the screen
|
|
Widget* kartsAreaWidget = getWidget("playerskarts");
|
|
// start at the rightmost of the screen
|
|
const int shift = irr_driver->getFrameSize().Width;
|
|
core::recti kartsArea(kartsAreaWidget->m_x + shift,
|
|
kartsAreaWidget->m_y,
|
|
kartsAreaWidget->m_x + shift + kartsAreaWidget->m_w,
|
|
kartsAreaWidget->m_y + kartsAreaWidget->m_h);
|
|
GameSetup *game_setup = STKHost::get()->getGameSetup();
|
|
|
|
// FIXME: atm only adds the local master, split screen supports
|
|
// needs to be added
|
|
int player_id = game_setup->getLocalMasterID();
|
|
m_id_mapping.clear();
|
|
m_id_mapping.insert(m_id_mapping.begin(), player_id);
|
|
|
|
const int amount = m_kart_widgets.size();
|
|
Widget* fullarea = getWidget("playerskarts");
|
|
|
|
const int splitWidth = fullarea->m_w / amount;
|
|
|
|
for (int n=0; n<amount; n++)
|
|
{
|
|
m_kart_widgets[n].move( fullarea->m_x + splitWidth*n,
|
|
fullarea->m_y, splitWidth, fullarea->m_h);
|
|
}
|
|
|
|
} // init
|
|
|
|
// ----------------------------------------------------------------------------
|
|
void NetworkKartSelectionScreen::playerConfirm(const int playerID)
|
|
{
|
|
DynamicRibbonWidget* w = getWidget<DynamicRibbonWidget>("karts");
|
|
assert(w != NULL);
|
|
const std::string selection = w->getSelectionIDString(playerID);
|
|
if (StringUtils::startsWith(selection, ID_LOCKED))
|
|
{
|
|
unlock_manager->playLockSound();
|
|
return;
|
|
}
|
|
|
|
if (playerID == PLAYER_ID_GAME_MASTER)
|
|
{
|
|
UserConfigParams::m_default_kart = selection;
|
|
}
|
|
|
|
if (m_kart_widgets[playerID].getKartInternalName().size() == 0)
|
|
{
|
|
SFXManager::get()->quickSound( "anvil" );
|
|
return;
|
|
}
|
|
if(playerID == PLAYER_ID_GAME_MASTER) // self
|
|
{
|
|
|
|
LobbyProtocol* protocol = LobbyProtocol::get();
|
|
ClientLobby *clrp = dynamic_cast<ClientLobby*>(protocol);
|
|
assert(clrp);
|
|
// FIXME SPLITSCREEN: we need to supply the global player id of the
|
|
// player selecting the kart here. For now ... just vote the same kart
|
|
// for each local player.
|
|
std::vector<NetworkPlayerProfile*> players =
|
|
STKHost::get()->getMyPlayerProfiles();
|
|
for(unsigned int i=0; i<players.size(); i++)
|
|
{
|
|
clrp->requestKartSelection(players[i]->getGlobalPlayerId(),
|
|
selection);
|
|
}
|
|
}
|
|
} // playerConfirm
|
|
|
|
// ----------------------------------------------------------------------------
|
|
void NetworkKartSelectionScreen::playerSelected(uint8_t player_id,
|
|
const std::string &kart_name)
|
|
{
|
|
int widget_id = -1;
|
|
for (unsigned int i = 0; i < m_id_mapping.size(); i++)
|
|
{
|
|
Log::info("NKSS", "Checking race id %d : mapped of %d is %d",
|
|
player_id, i, m_id_mapping[i]);
|
|
if (m_id_mapping[i] == player_id)
|
|
widget_id = i;
|
|
}
|
|
|
|
// This selection was for a remote kart, which is not shown
|
|
// Just ignore it.
|
|
if(widget_id==-1)
|
|
return;
|
|
|
|
KartSelectionScreen::updateKartWidgetModel(widget_id, kart_name,
|
|
irr::core::stringw(kart_name.c_str()),
|
|
/*Todo get color*/0.0f);
|
|
KartSelectionScreen::updateKartStats(widget_id, kart_name);
|
|
m_kart_widgets[widget_id].setKartInternalName(kart_name);
|
|
m_kart_widgets[widget_id].markAsReady(); // mark player ready
|
|
|
|
// If this is the authorised client, send the currently set race config
|
|
// to the server.
|
|
if(STKHost::get()->isAuthorisedToControl())
|
|
{
|
|
Protocol* protocol = ProtocolManager::getInstance()
|
|
->getProtocol(PROTOCOL_LOBBY_ROOM);
|
|
ClientLobby* clrp =
|
|
dynamic_cast<ClientLobby*>(protocol);
|
|
assert(clrp);
|
|
// FIXME: for now we submit a vote from the authorised user
|
|
// for the various modes based on the settings in the race manager.
|
|
// This needs more/better gui elements (and some should be set when
|
|
// defining the server).
|
|
std::vector<NetworkPlayerProfile*> players =
|
|
STKHost::get()->getMyPlayerProfiles();
|
|
for(unsigned int i=0; i<players.size(); i++)
|
|
{
|
|
uint8_t id = players[i]->getGlobalPlayerId();
|
|
clrp->voteMajor(id, race_manager->getMajorMode());
|
|
clrp->voteMinor(id, race_manager->getMinorMode());
|
|
clrp->voteReversed(id, race_manager->getReverseTrack());
|
|
clrp->voteRaceCount(id, 1);
|
|
clrp->voteLaps(id, 3);
|
|
}
|
|
//WaitingForOthersScreen::getInstance()->push();
|
|
//return;
|
|
}
|
|
TracksScreen::getInstance()->setOfficalTrack(true);
|
|
TracksScreen::getInstance()->push();
|
|
} // playerSelected
|
|
|
|
// ----------------------------------------------------------------------------
|
|
bool NetworkKartSelectionScreen::onEscapePressed()
|
|
{
|
|
// then remove the lobby screen (you left the server)
|
|
StateManager::get()->popMenu();
|
|
ServerSelection::getInstance()->refresh();
|
|
Protocol *lobby = LobbyProtocol::get();
|
|
// notify the server that we left
|
|
ClientLobby* clrp =
|
|
dynamic_cast<ClientLobby*>(lobby);
|
|
if (clrp)
|
|
clrp->leave();
|
|
return true; // remove the screen
|
|
} // onEscapePressed
|