stk-code_catmod/src/states_screens/network_kart_selection.cpp

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