Allow player going back to lobby without disconnecting the server
This commit is contained in:
parent
641b16e1c7
commit
bb31d6b226
@ -101,6 +101,9 @@ public:
|
|||||||
void addLiveJoinPeer(std::weak_ptr<STKPeer> peer)
|
void addLiveJoinPeer(std::weak_ptr<STKPeer> peer)
|
||||||
{ m_last_confirmed_item_ticks[peer] = 0; }
|
{ m_last_confirmed_item_ticks[peer] = 0; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
void erasePeerInGame(std::weak_ptr<STKPeer> peer)
|
||||||
|
{ m_last_confirmed_item_ticks.erase(peer); }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
void saveCompleteState(BareNetworkString* buffer) const;
|
void saveCompleteState(BareNetworkString* buffer) const;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void restoreCompleteState(const BareNetworkString& buffer);
|
void restoreCompleteState(const BareNetworkString& buffer);
|
||||||
|
@ -18,8 +18,10 @@
|
|||||||
|
|
||||||
#include "karts/kart_rewinder.hpp"
|
#include "karts/kart_rewinder.hpp"
|
||||||
|
|
||||||
|
#include "audio/sfx_manager.hpp"
|
||||||
#include "items/attachment.hpp"
|
#include "items/attachment.hpp"
|
||||||
#include "items/powerup.hpp"
|
#include "items/powerup.hpp"
|
||||||
|
#include "guiengine/message_queue.hpp"
|
||||||
#include "karts/abstract_kart.hpp"
|
#include "karts/abstract_kart.hpp"
|
||||||
#include "karts/explosion_animation.hpp"
|
#include "karts/explosion_animation.hpp"
|
||||||
#include "karts/rescue_animation.hpp"
|
#include "karts/rescue_animation.hpp"
|
||||||
@ -65,8 +67,6 @@ void KartRewinder::reset()
|
|||||||
m_has_server_state = false;
|
m_has_server_state = false;
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** This function is called immediately before a rewind is done and saves
|
/** This function is called immediately before a rewind is done and saves
|
||||||
* the current transform for the kart. The difference between this saved
|
* the current transform for the kart. The difference between this saved
|
||||||
@ -110,6 +110,13 @@ void KartRewinder::computeError()
|
|||||||
{
|
{
|
||||||
const int kartid = getWorldKartId();
|
const int kartid = getWorldKartId();
|
||||||
Log::debug("KartRewinder", "Kart id %d disconnected.", kartid);
|
Log::debug("KartRewinder", "Kart id %d disconnected.", kartid);
|
||||||
|
|
||||||
|
SFXManager::get()->quickSound("appear");
|
||||||
|
core::stringw player_name = getController()->getName();
|
||||||
|
// I18N: Message shown in game to tell player left the game in network
|
||||||
|
core::stringw msg = _("%s left the game.", player_name);
|
||||||
|
|
||||||
|
MessageQueue::add(MessageQueue::MT_FRIEND, msg);
|
||||||
World::getWorld()->eliminateKart(kartid,
|
World::getWorld()->eliminateKart(kartid,
|
||||||
false/*notify_of_elimination*/);
|
false/*notify_of_elimination*/);
|
||||||
setPosition(World::getWorld()->getCurrentNumKarts() + 1);
|
setPosition(World::getWorld()->getCurrentNumKarts() + 1);
|
||||||
|
@ -508,14 +508,18 @@ void ClientLobby::disconnectedPlayer(Event* event)
|
|||||||
if (!checkDataSize(event, 1)) return;
|
if (!checkDataSize(event, 1)) return;
|
||||||
|
|
||||||
NetworkString &data = event->data();
|
NetworkString &data = event->data();
|
||||||
SFXManager::get()->quickSound("appear");
|
|
||||||
unsigned disconnected_player_count = data.getUInt8();
|
unsigned disconnected_player_count = data.getUInt8();
|
||||||
uint32_t host_id = data.getUInt32();
|
uint32_t host_id = data.getUInt32();
|
||||||
m_peers_votes.erase(host_id);
|
m_peers_votes.erase(host_id);
|
||||||
|
// If world exists the kart rewinder will know which player disconnects
|
||||||
|
if (!World::getWorld())
|
||||||
|
SFXManager::get()->quickSound("appear");
|
||||||
for (unsigned i = 0; i < disconnected_player_count; i++)
|
for (unsigned i = 0; i < disconnected_player_count; i++)
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
data.decodeString(&name);
|
data.decodeString(&name);
|
||||||
|
if (!World::getWorld())
|
||||||
|
continue;
|
||||||
core::stringw player_name = StringUtils::utf8ToWide(name);
|
core::stringw player_name = StringUtils::utf8ToWide(name);
|
||||||
core::stringw msg = _("%s disconnected.", player_name);
|
core::stringw msg = _("%s disconnected.", player_name);
|
||||||
// Use the friend icon to avoid an error-like message
|
// Use the friend icon to avoid an error-like message
|
||||||
@ -961,10 +965,14 @@ void ClientLobby::backToLobby(Event *event)
|
|||||||
m_auto_started = false;
|
m_auto_started = false;
|
||||||
m_state.store(CONNECTED);
|
m_state.store(CONNECTED);
|
||||||
|
|
||||||
RaceEventManager::getInstance()->stop();
|
if (RaceEventManager::getInstance())
|
||||||
auto gep = RaceEventManager::getInstance()->getProtocol();
|
{
|
||||||
if (gep)
|
RaceEventManager::getInstance()->stop();
|
||||||
gep->requestTerminate();
|
auto gep = RaceEventManager::getInstance()->getProtocol();
|
||||||
|
// Game events protocol is main thread event only
|
||||||
|
if (gep)
|
||||||
|
gep->requestTerminate();
|
||||||
|
}
|
||||||
auto gp = GameProtocol::lock();
|
auto gp = GameProtocol::lock();
|
||||||
if (gp)
|
if (gp)
|
||||||
{
|
{
|
||||||
|
@ -46,33 +46,34 @@ public:
|
|||||||
/** Lists all lobby events (LE). */
|
/** Lists all lobby events (LE). */
|
||||||
enum : uint8_t
|
enum : uint8_t
|
||||||
{
|
{
|
||||||
LE_CONNECTION_REQUESTED = 1, // a connection to the server
|
LE_CONNECTION_REQUESTED = 1, // a connection to the server
|
||||||
LE_CONNECTION_REFUSED, // Connection to server refused
|
LE_CONNECTION_REFUSED, // Connection to server refused
|
||||||
LE_CONNECTION_ACCEPTED, // Connection to server accepted
|
LE_CONNECTION_ACCEPTED, // Connection to server accepted
|
||||||
LE_SERVER_INFO, // inform client about server info
|
LE_SERVER_INFO, // inform client about server info
|
||||||
LE_REQUEST_BEGIN, // begin of kart selection
|
LE_REQUEST_BEGIN, // begin of kart selection
|
||||||
LE_UPDATE_PLAYER_LIST, // inform client about player list update
|
LE_UPDATE_PLAYER_LIST, // inform client about player list update
|
||||||
LE_KART_SELECTION, // Player selected kart
|
LE_KART_SELECTION, // Player selected kart
|
||||||
LE_PLAYER_DISCONNECTED, // Client disconnected
|
LE_PLAYER_DISCONNECTED, // Client disconnected
|
||||||
LE_CLIENT_LOADED_WORLD, // Client finished loading world
|
LE_CLIENT_LOADED_WORLD, // Client finished loading world
|
||||||
LE_LOAD_WORLD, // Clients should load world
|
LE_LOAD_WORLD, // Clients should load world
|
||||||
LE_START_RACE, // Server to client to start race
|
LE_START_RACE, // Server to client to start race
|
||||||
LE_START_SELECTION, // inform client to start selection
|
LE_START_SELECTION, // inform client to start selection
|
||||||
LE_RACE_FINISHED, // race has finished, display result
|
LE_RACE_FINISHED, // race has finished, display result
|
||||||
LE_RACE_FINISHED_ACK, // client went back to lobby
|
LE_RACE_FINISHED_ACK, // client went back to lobby
|
||||||
LE_BACK_LOBBY, // Force clients to go back to lobby
|
LE_BACK_LOBBY, // Force clients to go back to lobby
|
||||||
LE_VOTE, // Track vote
|
LE_VOTE, // Track vote
|
||||||
LE_CHAT,
|
LE_CHAT, // Client chat message
|
||||||
LE_SERVER_OWNERSHIP,
|
LE_SERVER_OWNERSHIP, // Tell client he is now the server owner
|
||||||
LE_KICK_HOST,
|
LE_KICK_HOST, // Server owner kicks some other peer in game
|
||||||
LE_CHANGE_TEAM,
|
LE_CHANGE_TEAM, // Client wants to change his team
|
||||||
LE_BAD_TEAM,
|
LE_BAD_TEAM, // Tell server owner that the team is unbalanced
|
||||||
LE_BAD_CONNECTION,
|
LE_BAD_CONNECTION, // High ping or too many packets loss
|
||||||
LE_CONFIG_SERVER,
|
LE_CONFIG_SERVER, // Server owner config server game mode or difficulty
|
||||||
LE_CHANGE_HANDICAP,
|
LE_CHANGE_HANDICAP, // Client changes handicap
|
||||||
LE_LIVE_JOIN,
|
LE_LIVE_JOIN, // Client live join or spectate
|
||||||
LE_LIVE_JOIN_ACK,
|
LE_LIVE_JOIN_ACK, // Server tell client live join or spectate succeed
|
||||||
LE_KART_INFO
|
LE_KART_INFO, // Client or server exchange new kart info
|
||||||
|
LE_CLIENT_BACK_LOBBY // Client tell server to go back lobby
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RejectReason : uint8_t
|
enum RejectReason : uint8_t
|
||||||
|
@ -303,6 +303,7 @@ bool ServerLobby::notifyEvent(Event* event)
|
|||||||
case LE_LIVE_JOIN: liveJoinRequest(event); break;
|
case LE_LIVE_JOIN: liveJoinRequest(event); break;
|
||||||
case LE_CLIENT_LOADED_WORLD: finishedLoadingLiveJoinClient(event); break;
|
case LE_CLIENT_LOADED_WORLD: finishedLoadingLiveJoinClient(event); break;
|
||||||
case LE_KART_INFO: handleKartInfo(event); break;
|
case LE_KART_INFO: handleKartInfo(event); break;
|
||||||
|
case LE_CLIENT_BACK_LOBBY: clientWantsToBackLobby(event); break;
|
||||||
default: Log::error("ServerLobby", "Unknown message type %d - ignored.",
|
default: Log::error("ServerLobby", "Unknown message type %d - ignored.",
|
||||||
message_type);
|
message_type);
|
||||||
break;
|
break;
|
||||||
@ -656,15 +657,25 @@ NetworkString* ServerLobby::getLoadWorldMessage(
|
|||||||
} // getLoadWorldMessage
|
} // getLoadWorldMessage
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Returns true if server can be live joined or spectating
|
||||||
|
*/
|
||||||
bool ServerLobby::canLiveJoinNow() const
|
bool ServerLobby::canLiveJoinNow() const
|
||||||
{
|
{
|
||||||
return ServerConfig::m_live_players &&
|
return ServerConfig::m_live_players &&
|
||||||
race_manager->supportsLiveJoining() &&
|
race_manager->supportsLiveJoining() && worldIsActive();
|
||||||
World::getWorld() && RaceEventManager::getInstance()->isRunning() &&
|
} // canLiveJoinNow
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Returns true if world is active for clients to live join, spectate or
|
||||||
|
* going back to lobby live
|
||||||
|
*/
|
||||||
|
bool ServerLobby::worldIsActive() const
|
||||||
|
{
|
||||||
|
return World::getWorld() && RaceEventManager::getInstance()->isRunning() &&
|
||||||
!RaceEventManager::getInstance()->isRaceOver() &&
|
!RaceEventManager::getInstance()->isRaceOver() &&
|
||||||
(World::getWorld()->getPhase() == WorldStatus::RACE_PHASE ||
|
(World::getWorld()->getPhase() == WorldStatus::RACE_PHASE ||
|
||||||
World::getWorld()->getPhase() == WorldStatus::GOAL_PHASE);
|
World::getWorld()->getPhase() == WorldStatus::GOAL_PHASE);
|
||||||
} // canLiveJoinNow
|
} // worldIsActive
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** \ref STKPeer peer will be reset back to the lobby with reason
|
/** \ref STKPeer peer will be reset back to the lobby with reason
|
||||||
@ -701,6 +712,7 @@ void ServerLobby::liveJoinRequest(Event* event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool spectator = data.getUInt8() == 1;
|
bool spectator = data.getUInt8() == 1;
|
||||||
|
peer->clearAvailableKartIDs();
|
||||||
if (!spectator)
|
if (!spectator)
|
||||||
{
|
{
|
||||||
setPlayerKarts(data, peer);
|
setPlayerKarts(data, peer);
|
||||||
@ -728,7 +740,6 @@ void ServerLobby::liveJoinRequest(Event* event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
peer->clearAvailableKartIDs();
|
|
||||||
for (int id : used_id)
|
for (int id : used_id)
|
||||||
{
|
{
|
||||||
Log::info("ServerLobby", "%s live joining with reserved kart id %d.",
|
Log::info("ServerLobby", "%s live joining with reserved kart id %d.",
|
||||||
@ -3352,6 +3363,9 @@ void ServerLobby::setPlayerKarts(const NetworkString& ns, STKPeer* peer) const
|
|||||||
} // setPlayerKarts
|
} // setPlayerKarts
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Tell the client \ref RemoteKartInfo of a player when some player joining
|
||||||
|
* live.
|
||||||
|
*/
|
||||||
void ServerLobby::handleKartInfo(Event* event)
|
void ServerLobby::handleKartInfo(Event* event)
|
||||||
{
|
{
|
||||||
World* w = World::getWorld();
|
World* w = World::getWorld();
|
||||||
@ -3380,3 +3394,56 @@ void ServerLobby::handleKartInfo(Event* event)
|
|||||||
peer->sendPacket(ns, true/*reliable*/);
|
peer->sendPacket(ns, true/*reliable*/);
|
||||||
delete ns;
|
delete ns;
|
||||||
} // handleKartInfo
|
} // handleKartInfo
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Client if currently in-game (including spectator) wants to go back to
|
||||||
|
* lobby.
|
||||||
|
*/
|
||||||
|
void ServerLobby::clientWantsToBackLobby(Event* event)
|
||||||
|
{
|
||||||
|
World* w = World::getWorld();
|
||||||
|
std::shared_ptr<STKPeer> peer = event->getPeerSP();
|
||||||
|
|
||||||
|
if (!w || !worldIsActive() || peer->isWaitingForGame())
|
||||||
|
{
|
||||||
|
Log::warn("ServerLobby", "%s try to leave the game at wrong time.",
|
||||||
|
peer->getAddress().toString().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const int id : peer->getAvailableKartIDs())
|
||||||
|
{
|
||||||
|
RemoteKartInfo& rki = race_manager->getKartInfo(id);
|
||||||
|
if (rki.getHostId() == peer->getHostId())
|
||||||
|
{
|
||||||
|
Log::info("ServerLobby", "%s left the game with kart id %d.",
|
||||||
|
peer->getAddress().toString().c_str(), id);
|
||||||
|
rki.setNetworkPlayerProfile(
|
||||||
|
std::shared_ptr<NetworkPlayerProfile>());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log::error("ServerLobby", "%s doesn't exist anymore in server.",
|
||||||
|
peer->getAddress().toString().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NetworkItemManager* nim =
|
||||||
|
dynamic_cast<NetworkItemManager*>(ItemManager::get());
|
||||||
|
assert(nim);
|
||||||
|
nim->erasePeerInGame(peer);
|
||||||
|
m_peers_ready.erase(peer);
|
||||||
|
peer->setWaitingForGame(true);
|
||||||
|
|
||||||
|
NetworkString* reset = getNetworkString(2);
|
||||||
|
reset->setSynchronous(true);
|
||||||
|
reset->addUInt8(LE_BACK_LOBBY).addUInt8(BLR_NONE);
|
||||||
|
peer->sendPacket(reset, /*reliable*/true);
|
||||||
|
delete reset;
|
||||||
|
updatePlayerList();
|
||||||
|
NetworkString* server_info = getNetworkString();
|
||||||
|
server_info->setSynchronous(true);
|
||||||
|
server_info->addUInt8(LE_SERVER_INFO);
|
||||||
|
m_game_setup->addServerInfo(server_info);
|
||||||
|
peer->sendPacket(server_info, /*reliable*/true);
|
||||||
|
delete server_info;
|
||||||
|
} // clientWantsToBackLobby
|
||||||
|
@ -279,9 +279,11 @@ private:
|
|||||||
void liveJoinRequest(Event* event);
|
void liveJoinRequest(Event* event);
|
||||||
void rejectLiveJoin(STKPeer* peer, BackLobbyReason blr);
|
void rejectLiveJoin(STKPeer* peer, BackLobbyReason blr);
|
||||||
bool canLiveJoinNow() const;
|
bool canLiveJoinNow() const;
|
||||||
|
bool worldIsActive() const;
|
||||||
int getReservedId(std::shared_ptr<NetworkPlayerProfile>& p,
|
int getReservedId(std::shared_ptr<NetworkPlayerProfile>& p,
|
||||||
unsigned local_id) const;
|
unsigned local_id) const;
|
||||||
void handleKartInfo(Event* event);
|
void handleKartInfo(Event* event);
|
||||||
|
void clientWantsToBackLobby(Event* event);
|
||||||
public:
|
public:
|
||||||
ServerLobby();
|
ServerLobby();
|
||||||
virtual ~ServerLobby();
|
virtual ~ServerLobby();
|
||||||
|
@ -28,7 +28,9 @@
|
|||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "modes/overworld.hpp"
|
#include "modes/overworld.hpp"
|
||||||
#include "modes/world.hpp"
|
#include "modes/world.hpp"
|
||||||
|
#include "network/protocols/lobby_protocol.hpp"
|
||||||
#include "network/network_config.hpp"
|
#include "network/network_config.hpp"
|
||||||
|
#include "network/network_string.hpp"
|
||||||
#include "network/stk_host.hpp"
|
#include "network/stk_host.hpp"
|
||||||
#include "race/race_manager.hpp"
|
#include "race/race_manager.hpp"
|
||||||
#include "states_screens/help_screen_1.hpp"
|
#include "states_screens/help_screen_1.hpp"
|
||||||
@ -155,14 +157,21 @@ GUIEngine::EventPropagation
|
|||||||
}
|
}
|
||||||
race_manager->exitRace();
|
race_manager->exitRace();
|
||||||
race_manager->setAIKartOverride("");
|
race_manager->setAIKartOverride("");
|
||||||
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
|
|
||||||
|
|
||||||
if (race_manager->raceWasStartedFromOverworld())
|
if (NetworkConfig::get()->isNetworking())
|
||||||
{
|
{
|
||||||
OverWorld::enterOverWorld();
|
StateManager::get()->resetAndSetStack(
|
||||||
|
NetworkConfig::get()->getResetScreens().data());
|
||||||
|
NetworkConfig::get()->unsetNetworking();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
|
||||||
|
if (race_manager->raceWasStartedFromOverworld())
|
||||||
|
{
|
||||||
|
OverWorld::enterOverWorld();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkConfig::get()->unsetNetworking();
|
|
||||||
return GUIEngine::EVENT_BLOCK;
|
return GUIEngine::EVENT_BLOCK;
|
||||||
}
|
}
|
||||||
else if (selection == "help")
|
else if (selection == "help")
|
||||||
@ -187,23 +196,26 @@ GUIEngine::EventPropagation
|
|||||||
else if (selection == "newrace")
|
else if (selection == "newrace")
|
||||||
{
|
{
|
||||||
ModalDialog::dismiss();
|
ModalDialog::dismiss();
|
||||||
if (STKHost::existHost())
|
if (NetworkConfig::get()->isNetworking())
|
||||||
{
|
{
|
||||||
STKHost::get()->shutdown();
|
// back lobby
|
||||||
|
NetworkString back(PROTOCOL_LOBBY_ROOM);
|
||||||
|
back.setSynchronous(true);
|
||||||
|
back.addUInt8(LobbyProtocol::LE_CLIENT_BACK_LOBBY);
|
||||||
|
STKHost::get()->sendToServer(&back, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
World::getWorld()->scheduleUnpause();
|
||||||
|
race_manager->exitRace();
|
||||||
|
Screen* new_stack[] =
|
||||||
|
{
|
||||||
|
MainMenuScreen::getInstance(),
|
||||||
|
RaceSetupScreen::getInstance(),
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
StateManager::get()->resetAndSetStack(new_stack);
|
||||||
}
|
}
|
||||||
World::getWorld()->scheduleUnpause();
|
|
||||||
race_manager->exitRace();
|
|
||||||
Screen* new_stack[] =
|
|
||||||
{
|
|
||||||
MainMenuScreen::getInstance(),
|
|
||||||
RaceSetupScreen::getInstance(),
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
StateManager::get()->resetAndSetStack(
|
|
||||||
NetworkConfig::get()->isNetworking() ?
|
|
||||||
NetworkConfig::get()->getResetScreens().data() :
|
|
||||||
new_stack);
|
|
||||||
NetworkConfig::get()->unsetNetworking();
|
|
||||||
return GUIEngine::EVENT_BLOCK;
|
return GUIEngine::EVENT_BLOCK;
|
||||||
}
|
}
|
||||||
else if (selection == "endrace")
|
else if (selection == "endrace")
|
||||||
@ -224,7 +236,6 @@ GUIEngine::EventPropagation
|
|||||||
} // processEvent
|
} // processEvent
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void RacePausedDialog::beforeAddingWidgets()
|
void RacePausedDialog::beforeAddingWidgets()
|
||||||
{
|
{
|
||||||
GUIEngine::RibbonWidget* choice_ribbon =
|
GUIEngine::RibbonWidget* choice_ribbon =
|
||||||
@ -238,7 +249,8 @@ void RacePausedDialog::beforeAddingWidgets()
|
|||||||
// Disable in game menu to avoid timer desync if not racing in network
|
// Disable in game menu to avoid timer desync if not racing in network
|
||||||
// game
|
// game
|
||||||
if (NetworkConfig::get()->isNetworking() &&
|
if (NetworkConfig::get()->isNetworking() &&
|
||||||
World::getWorld()->getPhase() != WorldStatus::RACE_PHASE)
|
!(World::getWorld()->getPhase() == WorldStatus::MUSIC_PHASE ||
|
||||||
|
World::getWorld()->getPhase() == WorldStatus::RACE_PHASE))
|
||||||
{
|
{
|
||||||
index = choice_ribbon->findItemNamed("help");
|
index = choice_ribbon->findItemNamed("help");
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
@ -246,8 +258,19 @@ void RacePausedDialog::beforeAddingWidgets()
|
|||||||
index = choice_ribbon->findItemNamed("options");
|
index = choice_ribbon->findItemNamed("options");
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
choice_ribbon->setItemVisible(index, false);
|
choice_ribbon->setItemVisible(index, false);
|
||||||
|
index = choice_ribbon->findItemNamed("newrace");
|
||||||
|
if (index != -1)
|
||||||
|
choice_ribbon->setItemVisible(index, false);
|
||||||
}
|
}
|
||||||
|
if (NetworkConfig::get()->isNetworking())
|
||||||
}
|
{
|
||||||
|
IconButtonWidget* new_race = dynamic_cast<IconButtonWidget*>
|
||||||
// ----------------------------------------------------------------------------
|
(choice_ribbon->findWidgetNamed("newrace"));
|
||||||
|
if (new_race)
|
||||||
|
{
|
||||||
|
//I18N show in race paused dialog in network to allow user to go
|
||||||
|
//back to lobby to end spectating (for example)
|
||||||
|
new_race->setText(_("Back to lobby"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // beforeAddingWidgets
|
||||||
|
Loading…
x
Reference in New Issue
Block a user