Started to support split screen by fixing and improving the handling

of local plauyer ids.
This commit is contained in:
hiker
2016-01-14 08:20:14 +11:00
parent e70017a1a6
commit 846fd3f059
3 changed files with 60 additions and 42 deletions

View File

@@ -413,12 +413,9 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
profile->setHostId(my_host_id);
STKHost::get()->getGameSetup()->setLocalMaster(my_player_id);
m_setup->setNumLocalPlayers(1);
m_setup->addPlayer(profile);
// connection token
uint32_t token = data.gui32(3);
peer->setClientServerToken(token);
NetworkingLobby::getInstance()->addPlayer(profile);
// Add all players
// ===============
@@ -436,6 +433,7 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
NetworkPlayerProfile* profile2 =
new NetworkPlayerProfile(player_id, name);
profile2->setHostId(host_id);
m_setup->addPlayer(profile2);
n += bytes_read+3;
// Inform the network lobby of all players so that the GUI can
@@ -443,7 +441,10 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
NetworkingLobby::getInstance()->addPlayer(profile2);
}
// add self
// Add self after other players so that player order is identical
// on server and all clients.
m_setup->addPlayer(profile);
NetworkingLobby::getInstance()->addPlayer(profile);
m_server = event->getPeer();
m_state = CONNECTED;
} // connectionAccepted

View File

@@ -74,50 +74,51 @@ void StartGameProtocol::setup()
for (unsigned int i = 0; i < players.size(); i++)
{
NetworkPlayerProfile* profile = players[i];
bool is_local = profile->getHostId()
== STKHost::get()->getMyHostId();
RemoteKartInfo rki(profile->getGlobalPlayerId(),
bool is_local = profile->isLocalPlayer();
// A server does not create a NetworkingLobby (where clients
// create the ActivePlayers for local players, in order to bind the
// correct input device to the players). All non-local players (esp.
// all karts on the server) are created here.
if(NetworkConfig::get()->isServer() || !is_local)
{
// On the server no device or player profile is needed.
StateManager::get()->createActivePlayer(NULL, NULL);
}
// Adjust the local player id so that local players have the numbers
// 0 to num-1; and all other karts start with num. This way the local
// players get the first ActivePlayers assigned (which have the
// corresponding device associated with it).
RemoteKartInfo rki(is_local ? local_player_id
: i-local_player_id+STKHost::get()->getGameSetup()->getNumLocalPlayers(),
profile->getKartName(),
profile->getName(),
profile->getHostId(),
!is_local);
rki.setGlobalPlayerId(profile->getGlobalPlayerId());
rki.setPerPlayerDifficulty(profile->getPerPlayerDifficulty());
rki.setLocalPlayerId(local_player_id);
if(is_local) local_player_id++;
if(is_local)
{
// Set the local player kart
if(local_player_id==0)
NetworkWorld::getInstance()->setSelfKart(profile->getKartName());
rki.setLocalPlayerId(local_player_id);
local_player_id++;
}
// Inform the race manager about the data for this kart.
race_manager->setPlayerKart(i, rki);
if(is_local)
{
PlayerProfile* profile_to_use = PlayerManager::getCurrentPlayer();
assert(profile_to_use);
InputDevice* device = input_manager->getDeviceManager()
->getLatestUsedDevice();
int new_player_id = 0;
// more than one player, we're the first
if (StateManager::get()->getActivePlayers().size() >= 1)
new_player_id = 0;
else
new_player_id = StateManager::get()
->createActivePlayer(profile_to_use, device);
StateManager::ActivePlayer *ap =
StateManager::get()->getActivePlayer(new_player_id);
device->setPlayer(ap);
input_manager->getDeviceManager()->setSinglePlayer(ap);
race_manager->setPlayerKart(new_player_id,
profile->getKartName());
NetworkWorld::getInstance()->setSelfKart(profile->getKartName());
} // if is_local
else
{
StateManager::get()->createActivePlayer( NULL, NULL );
race_manager->setPlayerKart(i, rki);
}
} // for i in players
race_manager->computeRandomKartList();
// Make sure that if there is only a single local player this player can
// use all input devices.
StateManager::ActivePlayer *ap = race_manager->getNumLocalPlayers()>1
? NULL
: StateManager::get()->getActivePlayer(0);
input_manager->getDeviceManager()->setSinglePlayer(ap);
Log::info("StartGameProtocol", "Player configuration ready.");
m_state = SYNCHRONIZATION_WAIT;

View File

@@ -47,8 +47,18 @@ using namespace GUIEngine;
DEFINE_SCREEN_SINGLETON( NetworkingLobby );
/** This is the lobby screen that is shown on all clients, but not on the
* server. It shows currently connected clients, and allows the 'master'
* client (i.e. the stk instance that created the server) to control the
* server. This especially means that it can initialise the actual start
* of the racing.
* This class is responsible for creating the ActivePlayers data structure
* for all local players (the ActivePlayer maps device to player, i.e.
* controls which device is used by which player). Note that a server
* does not create an instance of this class and will create the ActivePlayer
* data structure in the StartGameProtocol.
*/
// ----------------------------------------------------------------------------
NetworkingLobby::NetworkingLobby() : Screen("online/networking_lobby.stkgui")
{
m_server = NULL;
@@ -88,9 +98,11 @@ void NetworkingLobby::beforeAddingWidget()
} // beforeAddingWidget
// ----------------------------------------------------------------------------
/** This function is a callback from the parent class, and is called each time
* this screen is shown to initialise the screen. This class is responsible
* for creating the active players and binding them to the right device.
*/
void NetworkingLobby::init()
{
Screen::init();
@@ -98,9 +110,13 @@ void NetworkingLobby::init()
m_server = ServersManager::get()->getJoinedServer();
if(m_server)
m_server_name_widget->setText(m_server->getName(), false);
m_start_button->setVisible(STKHost::get()->isAuthorisedToControl());
// For now create the active player and bind it to the right
// input device.
InputDevice *device = input_manager->getDeviceManager()->getLatestUsedDevice();
PlayerProfile* profile = PlayerManager::getCurrentPlayer();
StateManager::get()->createActivePlayer(profile, device);
} // init
// ----------------------------------------------------------------------------