Eliminate disconnected kart

This commit is contained in:
Benau 2018-04-16 15:18:10 +08:00
parent 6f30fd0cb0
commit d4fb888ffa
5 changed files with 50 additions and 13 deletions

View File

@ -1202,6 +1202,7 @@ AbstractKart *World::getLocalPlayerKart(unsigned int n) const
/** Remove (eliminate) a kart from the race */
void World::eliminateKart(int kart_id, bool notify_of_elimination)
{
assert(kart_id < (int)m_karts.size());
AbstractKart *kart = m_karts[kart_id];
if (kart->isGhostKart()) return;

View File

@ -113,7 +113,6 @@ protected:
void updateHighscores (int* best_highscore_rank);
void resetAllKarts ();
void eliminateKart (int kart_number, bool notifyOfElimination=true);
Controller*
loadAIController (AbstractKart *kart);
@ -321,6 +320,8 @@ public:
virtual void escapePressed();
// ------------------------------------------------------------------------
virtual void loadCustomModels() {}
// ------------------------------------------------------------------------
void eliminateKart(int kart_number, bool notify_of_elimination = true);
/** Set the network mode (true if networked) */
void setNetworkWorld(bool is_networked) { m_is_network_world = is_networked; }

View File

@ -23,14 +23,15 @@
#include "modes/world.hpp"
#include "network/network_config.hpp"
#include "network/network_player_profile.hpp"
#include "online/online_profile.hpp"
#include "network/protocols/game_events_protocol.hpp"
#include "network/stk_host.hpp"
#include "race/race_manager.hpp"
#include "utils/log.hpp"
//-----------------------------------------------------------------------------
/** Update and see if any player disconnects.
* \param remove_disconnected_players remove the disconnected players,
* otherwise replace with AI (when racing), so this function must be called
* otherwise eliminate the kart in world, so this function must be called
* in main thread.
*/
void GameSetup::update(bool remove_disconnected_players)
@ -46,8 +47,27 @@ void GameSetup::update(bool remove_disconnected_players)
return;
}
lock.unlock();
if (!World::getWorld())
if (!World::getWorld() ||
World::getWorld()->getPhase() < WorldStatus::MUSIC_PHASE)
return;
for (uint8_t i = 0; i < (uint8_t)m_players.size(); i++)
{
if (!m_players[i].expired())
continue;
AbstractKart* k = World::getWorld()->getKart(i);
if (!k->isEliminated())
{
World::getWorld()->eliminateKart(i,
false/*notify_of_elimination*/);
k->setPosition(
World::getWorld()->getCurrentNumKarts() + 1);
k->finishedRace(World::getWorld()->getTime());
NetworkString p(PROTOCOL_GAME_EVENTS);
p.setSynchronous(true);
p.addUInt8(GameEventsProtocol::GE_PLAYER_DISCONNECT).addUInt8(i);
STKHost::get()->sendPacketToAllPeers(&p, true);
}
}
} // removePlayer
//-----------------------------------------------------------------------------

View File

@ -46,11 +46,6 @@ bool GameEventsProtocol::notifyEvent(Event* event)
Log::warn("GameEventsProtocol", "Too short message.");
return true;
}
if ( event->getPeer()->getClientServerToken() != data.getToken())
{
Log::warn("GameEventsProtocol", "Bad token.");
return true;
}
uint8_t type = data.getUInt8();
switch (type)
{
@ -58,7 +53,8 @@ bool GameEventsProtocol::notifyEvent(Event* event)
collectedItem(data); break;
case GE_KART_FINISHED_RACE:
kartFinishedRace(data); break;
case GE_PLAYER_DISCONNECT:
eliminatePlayer(data); break;
default:
Log::warn("GameEventsProtocol", "Unkown message type.");
break;
@ -90,6 +86,22 @@ void GameEventsProtocol::collectedItem(Item* item, AbstractKart* kart)
delete ns;
} // collectedItem
// ----------------------------------------------------------------------------
void GameEventsProtocol::eliminatePlayer(const NetworkString &data)
{
assert(NetworkConfig::get()->isClient());
if (data.size() < 1)
{
Log::warn("GameEventsProtocol", "eliminatePlayer: Too short message.");
}
int kartid = data.getUInt8();
World::getWorld()->eliminateKart(kartid, false/*notify_of_elimination*/);
World::getWorld()->getKart(kartid)->setPosition(
World::getWorld()->getCurrentNumKarts() + 1);
World::getWorld()->getKart(kartid)->finishedRace(
World::getWorld()->getTime());
} // eliminatePlayer
// ----------------------------------------------------------------------------
/** Called on the client when an itemCollected message is received.
*/

View File

@ -9,12 +9,15 @@ class Item;
class GameEventsProtocol : public Protocol
{
private:
public:
enum GameEventType : uint8_t
{
GE_ITEM_COLLECTED = 1,
GE_KART_FINISHED_RACE = 2
GE_KART_FINISHED_RACE = 2,
GE_PLAYER_DISCONNECT = 3
}; // GameEventType
private:
void eliminatePlayer(const NetworkString &ns);
public:
GameEventsProtocol();
@ -31,7 +34,7 @@ public:
// ------------------------------------------------------------------------
virtual bool notifyEventAsynchronous(Event* event) OVERRIDE
{
return false;
return false;
} // notifyEventAsynchronous