Synchronize check lines and lap status from server

This commit is contained in:
Benau 2019-01-26 02:05:03 +08:00
parent 664129e448
commit 66fa81c6c9
9 changed files with 124 additions and 9 deletions

View File

@ -33,7 +33,9 @@
#include "physics/physics.hpp"
#include "network/network_config.hpp"
#include "network/network_string.hpp"
#include "network/protocols/game_events_protocol.hpp"
#include "network/server_config.hpp"
#include "network/stk_host.hpp"
#include "race/history.hpp"
#include "states_screens/race_gui_base.hpp"
#include "tracks/check_manager.hpp"
@ -1156,3 +1158,66 @@ void LinearWorld::restoreCompleteState(const BareNetworkString& b)
for (unsigned i = 0; i < cc; i++)
CheckManager::get()->getCheckStructure(i)->restoreCompleteState(b);
} // restoreCompleteState
// ----------------------------------------------------------------------------
/** Called in server whenever a kart cross a check line, it send server
* all karts lap count, last triggered checkline and check structure status
* to all players in game (including spectators so that the lap count is
* correct)
*/
void LinearWorld::updateCheckLinesServer()
{
if (!NetworkConfig::get()->isNetworking() ||
NetworkConfig::get()->isClient())
return;
NetworkString cl(PROTOCOL_GAME_EVENTS);
cl.setSynchronous(true);
cl.addUInt8(GameEventsProtocol::GE_CHECK_LINE);
for (KartInfo& ki : m_kart_info)
{
int8_t finished_laps = (int8_t)ki.m_finished_laps;
cl.addUInt8(finished_laps);
}
for (TrackSector* ts : m_kart_track_sector)
{
int8_t ltcl = (int8_t)ts->getLastTriggeredCheckline();
cl.addUInt8(ltcl);
}
const uint8_t cc = (uint8_t)CheckManager::get()->getCheckStructureCount();
cl.addUInt8(cc);
for (unsigned i = 0; i < cc; i++)
CheckManager::get()->getCheckStructure(i)->saveIsActive(&cl);
STKHost::get()->sendPacketToAllPeers(&cl, true);
} // updateCheckLinesServer
// ----------------------------------------------------------------------------
/* Synchronize with server from the above data. */
void LinearWorld::updateCheckLinesClient(const BareNetworkString& b)
{
for (KartInfo& ki : m_kart_info)
{
int8_t finished_laps = b.getUInt8();
ki.m_finished_laps = finished_laps;
}
for (TrackSector* ts : m_kart_track_sector)
{
int8_t ltcl = b.getUInt8();
ts->setLastTriggeredCheckline(ltcl);
}
const unsigned cc = b.getUInt8();
if (cc != CheckManager::get()->getCheckStructureCount())
{
throw std::invalid_argument(
"Server has different check structures size.");
}
for (unsigned i = 0; i < cc; i++)
CheckManager::get()->getCheckStructure(i)->restoreIsActive(b);
} // updateCheckLinesClient

View File

@ -220,6 +220,10 @@ public:
virtual void saveCompleteState(BareNetworkString* bns) OVERRIDE;
// ------------------------------------------------------------------------
virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE;
// ------------------------------------------------------------------------
void updateCheckLinesServer();
// ------------------------------------------------------------------------
void updateCheckLinesClient(const BareNetworkString& b);
}; // LinearWorld
#endif

View File

@ -3,6 +3,7 @@
#include "karts/abstract_kart.hpp"
#include "karts/controller/player_controller.hpp"
#include "modes/capture_the_flag.hpp"
#include "modes/linear_world.hpp"
#include "modes/soccer_world.hpp"
#include "network/event.hpp"
#include "network/game_setup.hpp"
@ -52,6 +53,7 @@ bool GameEventsProtocol::notifyEvent(Event* event)
CaptureTheFlag* ctf = dynamic_cast<CaptureTheFlag*>(World::getWorld());
FreeForAll* ffa = dynamic_cast<FreeForAll*>(World::getWorld());
SoccerWorld* sw = dynamic_cast<SoccerWorld*>(World::getWorld());
LinearWorld* lw = dynamic_cast<LinearWorld*>(World::getWorld());
switch (type)
{
case GE_KART_FINISHED_RACE:
@ -126,6 +128,14 @@ bool GameEventsProtocol::notifyEvent(Event* event)
}
break;
}
case GE_CHECK_LINE:
{
if (!lw)
throw std::invalid_argument("No linear world");
if (NetworkConfig::get()->isClient())
lw->updateCheckLinesClient(data);
break;
}
default:
Log::warn("GameEventsProtocol", "Unkown message type.");
break;

View File

@ -17,6 +17,7 @@ public:
GE_CTF_SCORED = 4,
GE_RESET_BALL = 5,
GE_PLAYER_GOAL = 6,
GE_CHECK_LINE = 7
}; // GameEventType
private:
int m_last_finished_position;

View File

@ -20,6 +20,7 @@
#define HEADER_CHECK_LAP_HPP
#include "tracks/check_structure.hpp"
#include "utils/cpp2011.hpp"
class XMLNode;
class CheckManager;
@ -40,8 +41,9 @@ public:
CheckLap(const XMLNode &node, unsigned int index);
virtual ~CheckLap() {};
virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos,
int indx);
virtual void reset(const Track &track);
int indx) OVERRIDE;
virtual void reset(const Track &track) OVERRIDE;
virtual bool triggeringCheckline() const OVERRIDE { return true; }
}; // CheckLine
#endif

View File

@ -26,6 +26,7 @@
using namespace irr;
#include "tracks/check_structure.hpp"
#include "utils/cpp2011.hpp"
class XMLNode;
class CheckManager;
@ -88,11 +89,11 @@ public:
CheckLine(const XMLNode &node, unsigned int index);
virtual ~CheckLine();
virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos,
int indx);
virtual void reset(const Track &track);
virtual void resetAfterKartMove(unsigned int kart_index);
virtual void changeDebugColor(bool is_active);
virtual bool triggeringCheckline() const { return true; }
int indx) OVERRIDE;
virtual void reset(const Track &track) OVERRIDE;
virtual void resetAfterKartMove(unsigned int kart_index) OVERRIDE;
virtual void changeDebugColor(bool is_active) OVERRIDE;
virtual bool triggeringCheckline() const OVERRIDE { return true; }
// ------------------------------------------------------------------------
/** Returns the actual line data for this checkpoint. */
const core::line2df &getLine2D() const {return m_line;}
@ -102,9 +103,9 @@ public:
* be too heigh to otherwise trigger he cannon). */
void setIgnoreHeight(bool b) { m_ignore_height = b; }
// ------------------------------------------------------------------------
virtual void saveCompleteState(BareNetworkString* bns);
virtual void saveCompleteState(BareNetworkString* bns) OVERRIDE;
// ------------------------------------------------------------------------
virtual void restoreCompleteState(const BareNetworkString& b);
virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE;
}; // CheckLine
#endif

View File

@ -101,6 +101,7 @@ void CheckStructure::reset(const Track &track)
void CheckStructure::update(float dt)
{
World *world = World::getWorld();
LinearWorld* lw = dynamic_cast<LinearWorld*>(World::getWorld());
for(unsigned int i=0; i<world->getNumKarts(); i++)
{
const Vec3 &xyz = world->getKart(i)->getFrontXYZ();
@ -114,6 +115,8 @@ void CheckStructure::update(float dt)
m_index, world->getKart(i)->getIdent().c_str(),
World::getWorld()->getTime());
trigger(i);
if (triggeringCheckline() && lw)
lw->updateCheckLinesServer();
}
m_previous_position[i] = xyz;
} // for i<getNumKarts
@ -252,3 +255,23 @@ void CheckStructure::restoreCompleteState(const BareNetworkString& b)
m_is_active.push_back(is_active);
}
} // restoreCompleteState
// ----------------------------------------------------------------------------
void CheckStructure::saveIsActive(BareNetworkString* bns)
{
World* world = World::getWorld();
for (unsigned int i = 0; i < world->getNumKarts(); i++)
bns->addUInt8(m_is_active[i] ? 1 : 0);
} // saveIsActive
// ----------------------------------------------------------------------------
void CheckStructure::restoreIsActive(const BareNetworkString& b)
{
m_is_active.clear();
World* world = World::getWorld();
for (unsigned int i = 0; i < world->getNumKarts(); i++)
{
bool is_active = b.getUInt8() == 1;
m_is_active.push_back(is_active);
}
} // restoreIsActive

View File

@ -131,9 +131,15 @@ public:
m_check_structures_to_change_state.push_back(i);
} // addSuccessor
// ------------------------------------------------------------------------
virtual bool triggeringCheckline() const { return false; }
// ------------------------------------------------------------------------
virtual void saveCompleteState(BareNetworkString* bns);
// ------------------------------------------------------------------------
virtual void restoreCompleteState(const BareNetworkString& b);
// ------------------------------------------------------------------------
void saveIsActive(BareNetworkString* bns);
// ------------------------------------------------------------------------
void restoreIsActive(const BareNetworkString& b);
}; // CheckStructure
#endif

View File

@ -90,6 +90,9 @@ public:
// ------------------------------------------------------------------------
void setLastTriggeredCheckline(int i) { m_last_triggered_checkline = i; }
// ------------------------------------------------------------------------
int getLastTriggeredCheckline() const
{ return m_last_triggered_checkline; }
// ------------------------------------------------------------------------
int getLastValidGraphNode() const { return m_last_valid_graph_node; }
// ------------------------------------------------------------------------
void saveState(BareNetworkString* buffer) const;