Allow spectating linear race
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include "guiengine/modaldialog.hpp"
|
||||
#include "physics/physics.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/server_config.hpp"
|
||||
#include "race/history.hpp"
|
||||
#include "states_screens/race_gui_base.hpp"
|
||||
@@ -1075,3 +1076,61 @@ std::pair<uint32_t, uint32_t> LinearWorld::getGameStartedProgress() const
|
||||
}
|
||||
return progress;
|
||||
} // getGameStartedProgress
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void LinearWorld::KartInfo::saveCompleteState(BareNetworkString* bns)
|
||||
{
|
||||
bns->addUInt32(m_finished_laps);
|
||||
bns->addUInt32(m_ticks_at_last_lap);
|
||||
bns->addUInt32(m_lap_start_ticks);
|
||||
bns->addFloat(m_estimated_finish);
|
||||
bns->addFloat(m_overall_distance);
|
||||
bns->addFloat(m_wrong_way_timer);
|
||||
} // saveCompleteState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void LinearWorld::KartInfo::restoreCompleteState(const BareNetworkString& b)
|
||||
{
|
||||
m_finished_laps = b.getUInt32();
|
||||
m_ticks_at_last_lap = b.getUInt32();
|
||||
m_lap_start_ticks = b.getUInt32();
|
||||
m_estimated_finish = b.getFloat();
|
||||
m_overall_distance = b.getFloat();
|
||||
m_wrong_way_timer = b.getFloat();
|
||||
} // restoreCompleteState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void LinearWorld::saveCompleteState(BareNetworkString* bns)
|
||||
{
|
||||
bns->addUInt32(m_fastest_lap_ticks);
|
||||
bns->addFloat(m_distance_increase);
|
||||
for (auto& kart : m_karts)
|
||||
{
|
||||
bns->add(kart->getXYZ());
|
||||
bns->add(kart->getRotation());
|
||||
}
|
||||
for (KartInfo& ki : m_kart_info)
|
||||
ki.saveCompleteState(bns);
|
||||
for (TrackSector* ts : m_kart_track_sector)
|
||||
ts->saveCompleteState(bns);
|
||||
} // saveCompleteState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void LinearWorld::restoreCompleteState(const BareNetworkString& b)
|
||||
{
|
||||
m_fastest_lap_ticks = b.getUInt32();
|
||||
m_distance_increase = b.getFloat();
|
||||
for (auto& kart : m_karts)
|
||||
{
|
||||
btTransform t;
|
||||
t.setOrigin(b.getVec3());
|
||||
t.setRotation(b.getQuat());
|
||||
kart->setTrans(t);
|
||||
}
|
||||
for (KartInfo& ki : m_kart_info)
|
||||
ki.restoreCompleteState(b);
|
||||
for (TrackSector* ts : m_kart_track_sector)
|
||||
ts->restoreCompleteState(b);
|
||||
|
||||
updateRacePosition();
|
||||
} // restoreCompleteState
|
||||
|
||||
@@ -112,6 +112,10 @@ private:
|
||||
m_overall_distance = 0.0f;
|
||||
m_wrong_way_timer = 0.0f;
|
||||
} // reset
|
||||
// --------------------------------------------------------------------
|
||||
void saveCompleteState(BareNetworkString* bns);
|
||||
// --------------------------------------------------------------------
|
||||
void restoreCompleteState(const BareNetworkString& b);
|
||||
};
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -121,7 +125,7 @@ protected:
|
||||
* This member is not strictly private but try not to use it directly outside
|
||||
* tightly related classes (e.g. AI)
|
||||
*/
|
||||
AlignedArray<KartInfo> m_kart_info;
|
||||
std::vector<KartInfo> m_kart_info;
|
||||
|
||||
virtual void checkForWrongDirection(unsigned int i, float dt);
|
||||
virtual float estimateFinishTimeForKart(AbstractKart* kart) OVERRIDE;
|
||||
@@ -204,6 +208,10 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
virtual std::pair<uint32_t, uint32_t> getGameStartedProgress() const
|
||||
OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void saveCompleteState(BareNetworkString* bns) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE;
|
||||
}; // LinearWorld
|
||||
|
||||
#endif
|
||||
|
||||
@@ -155,9 +155,7 @@ void GameSetup::addServerInfo(NetworkString* ns)
|
||||
|
||||
ns->encodeString16(m_message_of_today);
|
||||
ns->addUInt8((uint8_t)ServerConfig::m_server_configurable);
|
||||
ns->addUInt8(
|
||||
ServerConfig::m_live_players && race_manager->supportsLiveJoining() ?
|
||||
1 : 0);
|
||||
ns->addUInt8(ServerConfig::m_live_players? 1 : 0);
|
||||
} // addServerInfo
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -518,7 +518,7 @@ void ClientLobby::disconnectedPlayer(Event* event)
|
||||
{
|
||||
std::string name;
|
||||
data.decodeString(&name);
|
||||
if (!World::getWorld())
|
||||
if (World::getWorld())
|
||||
continue;
|
||||
core::stringw player_name = StringUtils::utf8ToWide(name);
|
||||
core::stringw msg = _("%s disconnected.", player_name);
|
||||
|
||||
@@ -661,8 +661,34 @@ NetworkString* ServerLobby::getLoadWorldMessage(
|
||||
*/
|
||||
bool ServerLobby::canLiveJoinNow() const
|
||||
{
|
||||
return ServerConfig::m_live_players &&
|
||||
race_manager->supportsLiveJoining() && worldIsActive();
|
||||
bool live_join = ServerConfig::m_live_players && worldIsActive();
|
||||
if (!live_join)
|
||||
return false;
|
||||
if (race_manager->modeHasLaps())
|
||||
{
|
||||
// No spectate when fastest kart is nearly finish, because if there
|
||||
// is endcontroller the spectating remote may not be knowing this
|
||||
// on time
|
||||
LinearWorld* w = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
if (!w)
|
||||
return false;
|
||||
AbstractKart* fastest_kart = NULL;
|
||||
for (unsigned i = 0; i < w->getNumKarts(); i++)
|
||||
{
|
||||
fastest_kart = w->getKartAtPosition(i + 1);
|
||||
if (fastest_kart && !fastest_kart->isEliminated())
|
||||
break;
|
||||
}
|
||||
if (!fastest_kart)
|
||||
return false;
|
||||
float progress = w->getOverallDistance(
|
||||
fastest_kart->getWorldKartId()) /
|
||||
(Track::getCurrentTrack()->getTrackLength() *
|
||||
(float)race_manager->getNumLaps());
|
||||
if (progress > 0.9f)
|
||||
return false;
|
||||
}
|
||||
return live_join;
|
||||
} // canLiveJoinNow
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -712,6 +738,13 @@ void ServerLobby::liveJoinRequest(Event* event)
|
||||
return;
|
||||
}
|
||||
bool spectator = data.getUInt8() == 1;
|
||||
if (race_manager->modeHasLaps() && !spectator)
|
||||
{
|
||||
// No live join for linear race
|
||||
rejectLiveJoin(peer, BLR_NO_GAME_FOR_LIVE_JOIN);
|
||||
return;
|
||||
}
|
||||
|
||||
peer->clearAvailableKartIDs();
|
||||
if (!spectator)
|
||||
{
|
||||
@@ -761,10 +794,22 @@ void ServerLobby::liveJoinRequest(Event* event)
|
||||
rki.getNetworkPlayerProfile().lock();
|
||||
if (!player)
|
||||
{
|
||||
player = NetworkPlayerProfile::getReservedProfile(
|
||||
race_manager->getMinorMode() ==
|
||||
RaceManager::MINOR_MODE_FREE_FOR_ALL ?
|
||||
KART_TEAM_NONE : rki.getKartTeam());
|
||||
if (race_manager->modeHasLaps())
|
||||
{
|
||||
player = std::make_shared<NetworkPlayerProfile>(
|
||||
nullptr, rki.getPlayerName(),
|
||||
std::numeric_limits<uint32_t>::max(),
|
||||
rki.getDefaultKartColor(),
|
||||
rki.getOnlineId(), rki.getDifficulty(),
|
||||
rki.getLocalPlayerId(), KART_TEAM_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
player = NetworkPlayerProfile::getReservedProfile(
|
||||
race_manager->getMinorMode() ==
|
||||
RaceManager::MINOR_MODE_FREE_FOR_ALL ?
|
||||
KART_TEAM_NONE : rki.getKartTeam());
|
||||
}
|
||||
}
|
||||
players.push_back(player);
|
||||
}
|
||||
|
||||
@@ -592,8 +592,7 @@ void RaceManager::startNextRace()
|
||||
// functions.
|
||||
World::getWorld()->reset();
|
||||
|
||||
if (NetworkConfig::get()->isNetworking() &&
|
||||
race_manager->supportsLiveJoining())
|
||||
if (NetworkConfig::get()->isNetworking())
|
||||
{
|
||||
for (unsigned i = 0; i < race_manager->getNumPlayers(); i++)
|
||||
{
|
||||
|
||||
@@ -268,7 +268,7 @@ void RacePausedDialog::beforeAddingWidgets()
|
||||
(choice_ribbon->findWidgetNamed("newrace"));
|
||||
if (new_race)
|
||||
{
|
||||
//I18N show in race paused dialog in network to allow user to go
|
||||
//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"));
|
||||
}
|
||||
|
||||
@@ -374,8 +374,13 @@ void NetworkingLobby::onUpdate(float delta)
|
||||
|
||||
if (m_client_live_joinable)
|
||||
{
|
||||
m_start_button->setVisible(true);
|
||||
m_start_button->setLabel(m_live_join_text);
|
||||
if (race_manager->supportsLiveJoining())
|
||||
{
|
||||
m_start_button->setVisible(true);
|
||||
m_start_button->setLabel(m_live_join_text);
|
||||
}
|
||||
else
|
||||
m_start_button->setVisible(false);
|
||||
m_config_button->setLabel(m_spectate_text);
|
||||
m_config_button->setImage(m_spectate_texture);
|
||||
m_config_button->setVisible(true);
|
||||
|
||||
@@ -192,3 +192,31 @@ void TrackSector::rewindTo(BareNetworkString* buffer)
|
||||
m_current_graph_node = node;
|
||||
m_current_track_coords.setZ(buffer->getFloat());
|
||||
} // rewindTo
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Save completely for spectating in linear race
|
||||
*/
|
||||
void TrackSector::saveCompleteState(BareNetworkString* bns)
|
||||
{
|
||||
bns->addUInt32(m_current_graph_node);
|
||||
bns->addUInt32(m_estimated_valid_graph_node);
|
||||
bns->addUInt32(m_last_valid_graph_node);
|
||||
bns->add(m_current_track_coords);
|
||||
bns->add(m_estimated_valid_track_coords);
|
||||
bns->add(m_latest_valid_track_coords);
|
||||
bns->addUInt8(m_on_road ? 0 : 1);
|
||||
bns->addUInt32(m_last_triggered_checkline);
|
||||
} // saveCompleteState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void TrackSector::restoreCompleteState(const BareNetworkString& b)
|
||||
{
|
||||
m_current_graph_node = b.getUInt32();
|
||||
m_estimated_valid_graph_node = b.getUInt32();
|
||||
m_last_valid_graph_node = b.getUInt32();
|
||||
m_current_track_coords = b.getVec3();
|
||||
m_estimated_valid_track_coords = b.getVec3();
|
||||
m_latest_valid_track_coords = b.getVec3();
|
||||
m_on_road = b.getUInt8() == 1;
|
||||
m_last_triggered_checkline = b.getUInt32();
|
||||
} // restoreCompleteState
|
||||
|
||||
@@ -95,6 +95,10 @@ public:
|
||||
void saveState(BareNetworkString* buffer) const;
|
||||
// ------------------------------------------------------------------------
|
||||
void rewindTo(BareNetworkString* buffer);
|
||||
// ------------------------------------------------------------------------
|
||||
void saveCompleteState(BareNetworkString* bns);
|
||||
// ------------------------------------------------------------------------
|
||||
void restoreCompleteState(const BareNetworkString& b);
|
||||
|
||||
}; // TrackSector
|
||||
|
||||
|
||||
Reference in New Issue
Block a user