Add live changing handicap

This commit is contained in:
Benau 2018-12-13 16:36:16 +08:00
parent d1d4ba4422
commit 8f5ee309a8
10 changed files with 113 additions and 20 deletions

View File

@ -143,9 +143,9 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void unsetNetworking(); void unsetNetworking();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
const std::vector<std::tuple<InputDevice*, PlayerProfile*, std::vector<std::tuple<InputDevice*, PlayerProfile*,
PerPlayerDifficulty> >& PerPlayerDifficulty> >&
getNetworkPlayers() const { return m_network_players; } getNetworkPlayers() { return m_network_players; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool isAddingNetworkPlayers() const bool isAddingNetworkPlayers() const
{ return !m_done_adding_network_players; } { return !m_done_adding_network_players; }

View File

@ -106,6 +106,9 @@ public:
PerPlayerDifficulty getPerPlayerDifficulty() const PerPlayerDifficulty getPerPlayerDifficulty() const
{ return m_per_player_difficulty; } { return m_per_player_difficulty; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setPerPlayerDifficulty(PerPlayerDifficulty d)
{ m_per_player_difficulty = d; }
// ------------------------------------------------------------------------
/** Returns the name of this player. */ /** Returns the name of this player. */
const irr::core::stringw& getName() const { return m_player_name; } const irr::core::stringw& getName() const { return m_player_name; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -674,15 +674,18 @@ void ClientLobby::updatePlayerList(Event* event)
m_waiting_for_game = waiting; m_waiting_for_game = waiting;
unsigned player_count = data.getUInt8(); unsigned player_count = data.getUInt8();
std::vector<std::tuple<uint32_t, uint32_t, uint32_t, core::stringw, std::vector<std::tuple<uint32_t, uint32_t, uint32_t, core::stringw,
int, KartTeam> > players; int, KartTeam, PerPlayerDifficulty> > players;
core::stringw total_players; core::stringw total_players;
for (unsigned i = 0; i < player_count; i++) for (unsigned i = 0; i < player_count; i++)
{ {
std::tuple<uint32_t, uint32_t, uint32_t, core::stringw, int, std::tuple<uint32_t, uint32_t, uint32_t, core::stringw, int,
KartTeam> pl; KartTeam, PerPlayerDifficulty> pl;
std::get<0>(pl) = data.getUInt32(); uint32_t host_id = data.getUInt32();
std::get<1>(pl) = data.getUInt32(); uint32_t online_id = data.getUInt32();
std::get<2>(pl) = data.getUInt8(); uint8_t local_id = data.getUInt8();
std::get<0>(pl) = host_id;
std::get<1>(pl) = online_id;
std::get<2>(pl) = local_id;
data.decodeStringW(&std::get<3>(pl)); data.decodeStringW(&std::get<3>(pl));
total_players += std::get<3>(pl); total_players += std::get<3>(pl);
bool is_peer_waiting_for_game = data.getUInt8() == 1; bool is_peer_waiting_for_game = data.getUInt8() == 1;
@ -693,12 +696,18 @@ void ClientLobby::updatePlayerList(Event* event)
if (waiting && !is_peer_waiting_for_game) if (waiting && !is_peer_waiting_for_game)
std::get<4>(pl) = 3; std::get<4>(pl) = 3;
PerPlayerDifficulty d = (PerPlayerDifficulty)data.getUInt8(); PerPlayerDifficulty d = (PerPlayerDifficulty)data.getUInt8();
std::get<6>(pl) = d;
if (d == PLAYER_DIFFICULTY_HANDICAP) if (d == PLAYER_DIFFICULTY_HANDICAP)
std::get<3>(pl) = _("%s (handicapped)", std::get<3>(pl)); std::get<3>(pl) = _("%s (handicapped)", std::get<3>(pl));
std::get<5>(pl) = (KartTeam)data.getUInt8(); std::get<5>(pl) = (KartTeam)data.getUInt8();
bool ready = data.getUInt8() == 1; bool ready = data.getUInt8() == 1;
if (ready) if (ready)
std::get<4>(pl) = 4; std::get<4>(pl) = 4;
if (host_id == STKHost::get()->getMyHostId())
{
auto& local_players = NetworkConfig::get()->getNetworkPlayers();
std::get<2>(local_players.at(local_id)) = d;
}
players.push_back(pl); players.push_back(pl);
} }

View File

@ -63,7 +63,8 @@ public:
LE_CHANGE_TEAM, LE_CHANGE_TEAM,
LE_BAD_TEAM, LE_BAD_TEAM,
LE_BAD_CONNECTION, LE_BAD_CONNECTION,
LE_CONFIG_SERVER LE_CONFIG_SERVER,
LE_CHANGE_HANDICAP
}; };
enum RejectReason : uint8_t enum RejectReason : uint8_t

View File

@ -377,6 +377,7 @@ bool ServerLobby::notifyEventAsynchronous(Event* event)
case LE_REQUEST_BEGIN: startSelection(event); break; case LE_REQUEST_BEGIN: startSelection(event); break;
case LE_CHAT: handleChat(event); break; case LE_CHAT: handleChat(event); break;
case LE_CONFIG_SERVER: handleServerConfiguration(event); break; case LE_CONFIG_SERVER: handleServerConfiguration(event); break;
case LE_CHANGE_HANDICAP: changeHandicap(event); break;
default: break; default: break;
} // switch } // switch
} // if (event->getType() == EVENT_TYPE_MESSAGE) } // if (event->getType() == EVENT_TYPE_MESSAGE)
@ -2730,3 +2731,36 @@ void ServerLobby::handleServerConfiguration(Event* event)
delete server_info; delete server_info;
updatePlayerList(); updatePlayerList();
} // handleServerConfiguration } // handleServerConfiguration
//-----------------------------------------------------------------------------
/*! \brief Called when a player want to change his handicap
* \param event : Event providing the information.
*
* Format of the data :
* Byte 0 1
* ----------------------------------
* Size | 1 | 1 |
* Data | local player id | new handicap |
* ----------------------------------
*/
void ServerLobby::changeHandicap(Event* event)
{
NetworkString& data = event->data();
if (m_state.load() != WAITING_FOR_START_GAME &&
!event->getPeer()->isWaitingForGame())
{
Log::warn("ServerLobby", "Set handicap at wrong time.");
return;
}
uint8_t local_id = data.getUInt8();
auto& player = event->getPeer()->getPlayerProfiles().at(local_id);
uint8_t difficulty_id = data.getUInt8();
if (difficulty_id >= PLAYER_DIFFICULTY_COUNT)
{
Log::warn("ServerLobby", "Wrong handicap %d.", difficulty_id);
return;
}
PerPlayerDifficulty d = (PerPlayerDifficulty)difficulty_id;
player->setPerPlayerDifficulty(d);
updatePlayerList();
} // changeHandicap

View File

@ -263,6 +263,7 @@ private:
void updateWaitingPlayers(); void updateWaitingPlayers();
void resetServer(); void resetServer();
void addWaitingPlayersToGame(); void addWaitingPlayersToGame();
void changeHandicap(Event* event);
public: public:
ServerLobby(); ServerLobby();
virtual ~ServerLobby(); virtual ~ServerLobby();

View File

@ -18,6 +18,7 @@
#include "states_screens/dialogs/network_user_dialog.hpp" #include "states_screens/dialogs/network_user_dialog.hpp"
#include "config/player_manager.hpp" #include "config/player_manager.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/dialog_queue.hpp" #include "guiengine/dialog_queue.hpp"
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/widgets/icon_button_widget.hpp" #include "guiengine/widgets/icon_button_widget.hpp"
@ -101,7 +102,27 @@ void NetworkUserDialog::beforeAddingWidgets()
} }
else else
getWidget<IconButtonWidget>("accept")->setVisible(false); getWidget<IconButtonWidget>("accept")->setVisible(false);
getWidget<IconButtonWidget>("remove")->setVisible(false);
m_handicap_widget = NULL;
if (m_host_id == STKHost::get()->getMyHostId())
{
m_handicap_widget = getWidget<IconButtonWidget>("remove");
m_handicap_widget->setVisible(true);
if (m_per_player_difficulty == PLAYER_DIFFICULTY_NORMAL)
{
//I18N: In the network user dialog
m_handicap_widget->setText(_("Enable handicap"));
}
else
{
//I18N: In the network user dialog
m_handicap_widget->setText(_("Disable handicap"));
}
m_handicap_widget->setImage(irr_driver->getTexture(FileManager::MODEL,
"anchor-icon.png"));
}
else
getWidget<IconButtonWidget>("remove")->setVisible(false);
getWidget<IconButtonWidget>("enter")->setVisible(false); getWidget<IconButtonWidget>("enter")->setVisible(false);
} // beforeAddingWidgets } // beforeAddingWidgets
@ -144,7 +165,7 @@ GUIEngine::EventPropagation
m_self_destroy = true; m_self_destroy = true;
return GUIEngine::EVENT_BLOCK; return GUIEngine::EVENT_BLOCK;
} }
else if(selection == m_friend_widget->m_properties[PROP_ID]) else if (selection == m_friend_widget->m_properties[PROP_ID])
{ {
XMLRequest *request = new XMLRequest(); XMLRequest *request = new XMLRequest();
PlayerManager::setUserDetails(request, "friend-request"); PlayerManager::setUserDetails(request, "friend-request");
@ -153,7 +174,7 @@ GUIEngine::EventPropagation
m_self_destroy = true; m_self_destroy = true;
return GUIEngine::EVENT_BLOCK; return GUIEngine::EVENT_BLOCK;
} }
else if(selection == m_kick_widget->m_properties[PROP_ID]) else if (selection == m_kick_widget->m_properties[PROP_ID])
{ {
NetworkString kick(PROTOCOL_LOBBY_ROOM); NetworkString kick(PROTOCOL_LOBBY_ROOM);
kick.addUInt8(LobbyProtocol::LE_KICK_HOST).addUInt32(m_host_id); kick.addUInt8(LobbyProtocol::LE_KICK_HOST).addUInt32(m_host_id);
@ -161,7 +182,8 @@ GUIEngine::EventPropagation
m_self_destroy = true; m_self_destroy = true;
return GUIEngine::EVENT_BLOCK; return GUIEngine::EVENT_BLOCK;
} }
else if(selection == m_change_team_widget->m_properties[PROP_ID]) else if (m_change_team_widget &&
selection == m_change_team_widget->m_properties[PROP_ID])
{ {
NetworkString change_team(PROTOCOL_LOBBY_ROOM); NetworkString change_team(PROTOCOL_LOBBY_ROOM);
change_team.addUInt8(LobbyProtocol::LE_CHANGE_TEAM) change_team.addUInt8(LobbyProtocol::LE_CHANGE_TEAM)
@ -170,6 +192,21 @@ GUIEngine::EventPropagation
m_self_destroy = true; m_self_destroy = true;
return GUIEngine::EVENT_BLOCK; return GUIEngine::EVENT_BLOCK;
} }
else if (m_handicap_widget &&
selection == m_handicap_widget->m_properties[PROP_ID])
{
PerPlayerDifficulty new_difficulty = PLAYER_DIFFICULTY_NORMAL;
if (m_per_player_difficulty == PLAYER_DIFFICULTY_NORMAL)
{
new_difficulty = PLAYER_DIFFICULTY_HANDICAP;
}
NetworkString change_handicap(PROTOCOL_LOBBY_ROOM);
change_handicap.addUInt8(LobbyProtocol::LE_CHANGE_HANDICAP)
.addUInt8(m_local_id).addUInt8(new_difficulty);
STKHost::get()->sendToServer(&change_handicap, true/*reliable*/);
m_self_destroy = true;
return GUIEngine::EVENT_BLOCK;
}
} }
return GUIEngine::EVENT_LET; return GUIEngine::EVENT_LET;
} // processEvent } // processEvent

View File

@ -47,6 +47,8 @@ private:
const uint8_t m_local_id; const uint8_t m_local_id;
PerPlayerDifficulty m_per_player_difficulty;
const core::stringw m_name; const core::stringw m_name;
const bool m_allow_change_team; const bool m_allow_change_team;
@ -69,11 +71,14 @@ private:
GUIEngine::IconButtonWidget* m_cancel_widget; GUIEngine::IconButtonWidget* m_cancel_widget;
GUIEngine::IconButtonWidget* m_handicap_widget;
public: public:
NetworkUserDialog(uint32_t host_id, uint32_t online_id, uint8_t local_id, NetworkUserDialog(uint32_t host_id, uint32_t online_id, uint8_t local_id,
const core::stringw& name, bool allow_change_team) const core::stringw& name, bool allow_change_team,
PerPlayerDifficulty d)
: ModalDialog(0.8f,0.8f), m_host_id(host_id), m_online_id(online_id), : ModalDialog(0.8f,0.8f), m_host_id(host_id), m_online_id(online_id),
m_local_id(local_id), m_name(name), m_local_id(local_id), m_per_player_difficulty(d), m_name(name),
m_allow_change_team(allow_change_team), m_self_destroy(false), m_allow_change_team(allow_change_team), m_self_destroy(false),
m_fetched_ranking(std::make_shared<bool>(false)) m_fetched_ranking(std::make_shared<bool>(false))
{ {

View File

@ -439,7 +439,9 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name,
host_online_local_ids[1], host_online_local_ids[2], host_online_local_ids[1], host_online_local_ids[2],
std::get<0>(m_player_names.at( std::get<0>(m_player_names.at(
m_player_list->getSelectionInternalName())), m_player_list->getSelectionInternalName())),
m_allow_change_team); m_allow_change_team,
std::get<3>(m_player_names.at(
m_player_list->getSelectionInternalName())));
} // click on a user } // click on a user
else if (name == m_send_button->m_properties[PROP_ID]) else if (name == m_send_button->m_properties[PROP_ID])
{ {
@ -498,7 +500,7 @@ bool NetworkingLobby::onEscapePressed()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void NetworkingLobby::updatePlayers(const std::vector<std::tuple<uint32_t, void NetworkingLobby::updatePlayers(const std::vector<std::tuple<uint32_t,
uint32_t, uint32_t, core::stringw, uint32_t, uint32_t, core::stringw,
int, KartTeam> >& p) int, KartTeam, PerPlayerDifficulty> >& p)
{ {
// In GUI-less server this function will be called without proper // In GUI-less server this function will be called without proper
// initialisation // initialisation
@ -531,7 +533,8 @@ void NetworkingLobby::updatePlayers(const std::vector<std::tuple<uint32_t,
else if (cur_team == KART_TEAM_BLUE) else if (cur_team == KART_TEAM_BLUE)
m_player_list->markItemBlue(i); m_player_list->markItemBlue(i);
m_player_names[internal_name] = m_player_names[internal_name] =
std::make_tuple(std::get<3>(q), std::get<4>(q), cur_team); std::make_tuple(std::get<3>(q), std::get<4>(q), cur_team,
std::get<6>(q));
} }
updatePlayerPings(); updatePlayerPings();
} // updatePlayers } // updatePlayers

View File

@ -66,8 +66,8 @@ private:
NetworkingLobby(); NetworkingLobby();
float m_ping_update_timer; float m_ping_update_timer;
std::map<std::string, std::tuple<core::stringw, /*icon*/int, KartTeam> > std::map<std::string, std::tuple<core::stringw, /*icon*/int, KartTeam,
m_player_names; PerPlayerDifficulty> > m_player_names;
std::shared_ptr<Server> m_joined_server; std::shared_ptr<Server> m_joined_server;
std::vector<core::stringw> m_server_info; std::vector<core::stringw> m_server_info;
int m_server_info_height; int m_server_info_height;
@ -137,7 +137,7 @@ public:
void updatePlayers(const std::vector<std::tuple<uint32_t/*host id*/, void updatePlayers(const std::vector<std::tuple<uint32_t/*host id*/,
uint32_t/*online id*/, uint32_t/*local player id*/, uint32_t/*online id*/, uint32_t/*local player id*/,
core::stringw/*player name*/, int/*icon id*/, core::stringw/*player name*/, int/*icon id*/,
KartTeam> >& p); KartTeam, PerPlayerDifficulty> >& p);
void openSplitscreenDialog(InputDevice* device); void openSplitscreenDialog(InputDevice* device);
void addSplitscreenPlayer(irr::core::stringw name); void addSplitscreenPlayer(irr::core::stringw name);
void cleanAddedPlayers(); void cleanAddedPlayers();