This patch is become useless with r6623 from yourself :) Thanks,
Matt (gentildemon) Florian Köberle a écrit : > Why is it necessary? > > Extreme example: The game time is 59,9 seconds and the turn master orders the > character to jump in oder to save him from the water which will increase in > 0.1 seconds. > It's important that the non turn master does not continue the game to the > 60th game second, if it hasn't received the jump action yet. Otherwise the > non turn master will see the character drown and no resurrection system can > bring him back as the water has already risen. > > How to detect that there are no further actions for the current physics frame? > > If there had been actions in a physics frame wormux will send now one "echo" > action at the end of the physics frame. > The non turn masters knows when receiving it that they can render all physics > frames until that time. > --- > lib/wormux/include/WORMUX_action.h | 2 +- > src/game/game.cpp | 1 + > src/game/time.cpp | 35 +++++++++++++++++++++-------------- > src/game/time.h | 4 ++-- > src/include/action_handler.cpp | 30 ++++++++++++++++++++++++++++-- > src/network/network.cpp | 21 +++++++++++++++++---- > src/network/network.h | 11 ++++++----- > src/network/network_local.cpp | 2 +- > src/network/network_local.h | 2 +- > 9 files changed, 78 insertions(+), 30 deletions(-) > > diff --git a/lib/wormux/include/WORMUX_action.h > b/lib/wormux/include/WORMUX_action.h > index 14238c9..4f9dc21 100644 > --- a/lib/wormux/include/WORMUX_action.h > +++ b/lib/wormux/include/WORMUX_action.h > @@ -106,7 +106,7 @@ public: > ACTION_NETWORK_RANDOM_INIT, > ACTION_INFO_CLIENT_CONNECT, > ACTION_INFO_CLIENT_DISCONNECT, > - > + ACTION_ECHO, > // ######################################################## > } Action_t; > > diff --git a/src/game/game.cpp b/src/game/game.cpp > index d24bd99..70df1d8 100644 > --- a/src/game/game.cpp > +++ b/src/game/game.cpp > @@ -552,6 +552,7 @@ void Game::MainLoop() > } > } > #endif > + Network::GetInstance()->SendEcho(); > > delay = time_of_next_phy_frame - Time::GetInstance()->ReadRealTime(); > if (delay >= 0) > diff --git a/src/game/time.cpp b/src/game/time.cpp > index c345817..05ec829 100644 > --- a/src/game/time.cpp > +++ b/src/game/time.cpp > @@ -19,7 +19,11 @@ > * Handle the game time. The game can be paused. > > *****************************************************************************/ > > +#include "game/game.h" > #include "game/time.h" > +#include "network/network.h" > +#include "team/team.h" > +#include "team/teams_list.h" > #include <SDL.h> > #include <sstream> > #include <iomanip> > @@ -34,7 +38,7 @@ Time::Time() > is_game_paused = false; > delta_t = 20; > current_time = 0; > - //max_time = 0; > + max_time_plus_one = 0; > real_time_game_start = 0; > real_time_pause_dt = 0; > } > @@ -42,6 +46,7 @@ Time::Time() > void Time::Reset() > { > current_time = 0; > + max_time_plus_one = 0; > is_game_paused = false; > real_time_game_start = SDL_GetTicks(); > real_time_pause_dt = 0; > @@ -55,19 +60,21 @@ uint Time::ReadRealTime() const > > void Time::Refresh() > { > - /* > - TODO : Activate this condition later. > - Refresh time condition : > - - active team is Local > - - current node is server and game loop is not in Playing state > - - game don't use network > - if((ActiveTeam().IsLocal() || ActiveTeam().IsLocalAI()) || > - (Network::GetInstance()->IsServer() && Game::GetInstance()->ReadState() > != Game::PLAYING) || > - (!Network::GetInstance()->IsServer() && > !Network::GetInstance()->IsClient()) || > - current_time < max_time) > - */ > - current_time += delta_t; > - //RefreshMaxTime(current_time); > + uint newValue = current_time + delta_t; > + bool activeTeamLocal = ActiveTeam().IsLocal() || ActiveTeam().IsLocalAI(); > + bool serverButNotPlaying = Network::GetInstance()->IsServer() && > Game::GetInstance()->ReadState() != Game::PLAYING; > + bool noNetworkGame = !Network::GetInstance()->IsServer() && > !Network::GetInstance()->IsClient(); > + bool ignoreMaxTime = activeTeamLocal || serverButNotPlaying || > noNetworkGame; > + if (ignoreMaxTime || (newValue < max_time_plus_one)) > + current_time = newValue; > + else > + real_time_pause_dt += delta_t; > +} > + > +void Time::RefreshMaxTimePlusOne(uint updated_max_time_plus_one) > +{ > + if (updated_max_time_plus_one >= max_time_plus_one) > + max_time_plus_one = updated_max_time_plus_one; > } > > void Time::TogglePause() > diff --git a/src/game/time.h b/src/game/time.h > index 193c8e9..edb9109 100644 > --- a/src/game/time.h > +++ b/src/game/time.h > @@ -31,7 +31,7 @@ class Time : public Singleton<Time> > { > private: > uint current_time; > - //uint max_time; > + uint max_time_plus_one; > uint delta_t; > bool is_game_paused; > > @@ -59,7 +59,7 @@ public: > uint ReadMin() const { return ReadSec() / 60; }; > void Refresh(); > uint GetDelta() const { return delta_t; }; > - //void RefreshMaxTime(uint updated_max_time); > + void RefreshMaxTimePlusOne(uint updated_max_time_plus_one); > > // Read the clock time > uint ClockSec() const { return ReadSec() % 60; }; > diff --git a/src/include/action_handler.cpp b/src/include/action_handler.cpp > index df17a05..f22348d 100644 > --- a/src/include/action_handler.cpp > +++ b/src/include/action_handler.cpp > @@ -825,6 +825,11 @@ static void Action_Network_Ping(Action */*a*/) > { > } > > +// Nothing to do here. The action handler will use the timestamp to set the > maximal time. > +static void Action_Echo(Action */*a*/) > +{ > +} > + > // ######################################################## > > static void _Info_ConnectHost(const std::string& hostname, const > std::string& nicknames) > @@ -1084,7 +1089,7 @@ void Action_Handler_Init() > ActionHandler::GetInstance()->Register > (Action::ACTION_NETWORK_RANDOM_INIT, "NETWORK_random_init", > &Action_Network_RandomInit); > ActionHandler::GetInstance()->Register > (Action::ACTION_INFO_CLIENT_DISCONNECT, "INFO_client_disconnect", > &Action_Info_ClientDisconnect); > ActionHandler::GetInstance()->Register > (Action::ACTION_INFO_CLIENT_CONNECT, "INFO_client_connect", > &Action_Info_ClientConnect); > - > + ActionHandler::GetInstance()->Register (Action::ACTION_ECHO, > "ACTION_echo", &Action_Echo); > // ######################################################## > ActionHandler::GetInstance()->UnLock(); > } > @@ -1106,11 +1111,32 @@ void ActionHandler::ExecActions() > { > Action * a; > std::list<Action*>::iterator it; > + Time * time = Time::GetInstance(); > + > + // The game can continue until the point at which all actions are known. > + // If for example a non turn master receives: > + // 5s game time: jump > + // 6s game time: jump > + // then the game can continue until the game time is (6s - smallest time > unit). > + // The physics frame for the 6th game second must not be calculated > + // as more actions for the 6th game second might be received in future. > + for (it = queue.begin(); it != queue.end() ;it++) > + { > + Lock(); > + a = (*it); > + // The action echo gets send at the end of a physics frame: > + // No more physic related actions are expected for the current frame. > + if (a->GetType() == Action::ACTION_ECHO) > + time->RefreshMaxTimePlusOne(a->GetTimestamp() + 1); > + else > + time->RefreshMaxTimePlusOne(a->GetTimestamp()); > + UnLock(); > + } > + > for (it = queue.begin(); it != queue.end() ;) > { > Lock(); > a = (*it); > - //Time::GetInstance()->RefreshMaxTime((*it)->GetTimestamp()); > // If action is in the future, wait for next refresh > if (a->GetTimestamp() > Time::GetInstance()->Read()) { > UnLock(); > diff --git a/src/network/network.cpp b/src/network/network.cpp > index da56cab..5652b5c 100644 > --- a/src/network/network.cpp > +++ b/src/network/network.cpp > @@ -340,7 +340,7 @@ void Network::DisconnectNetwork() > > //----------------------------------------------------------------------------- > > // Send Messages > -void Network::SendActionToAll(const Action& a) const > +void Network::SendActionToAll(const Action& a) > { > MSG_DEBUG("network.traffic","Send action %s to all remote computers", > > ActionHandler::GetInstance()->GetActionName(a.GetType()).c_str()); > @@ -348,7 +348,7 @@ void Network::SendActionToAll(const Action& a) const > SendAction(a, NULL, false); > } > > -void Network::SendActionToOne(const Action& a, DistantComputer* client) const > +void Network::SendActionToOne(const Action& a, DistantComputer* client) > { > MSG_DEBUG("network.traffic","Send action %s to %s (%s)", > ActionHandler::GetInstance()->GetActionName(a.GetType()).c_str(), > @@ -357,7 +357,7 @@ void Network::SendActionToOne(const Action& a, > DistantComputer* client) const > SendAction(a, client, true); > } > > -void Network::SendActionToAllExceptOne(const Action& a, DistantComputer* > client) const > +void Network::SendActionToAllExceptOne(const Action& a, DistantComputer* > client) > { > MSG_DEBUG("network.traffic","Send action %s to all EXCEPT %s", > ActionHandler::GetInstance()->GetActionName(a.GetType()).c_str(), > @@ -369,11 +369,13 @@ void Network::SendActionToAllExceptOne(const Action& a, > DistantComputer* client) > // if (client == NULL) sending to every clients > // if (clt_as_rcver) sending only to client 'client' > // if (!clt_as_rcver) sending to all EXCEPT client 'client' > -void Network::SendAction(const Action& a, DistantComputer* client, bool > clt_as_rcver) const > +void Network::SendAction(const Action& a, DistantComputer* client, bool > clt_as_rcver) > { > char* packet; > int size; > > + echo_outstanding = true; > + > a.WriteToPacket(packet, size); > ASSERT(packet != NULL); > > @@ -405,6 +407,17 @@ void Network::SendAction(const Action& a, > DistantComputer* client, bool clt_as_r > free(packet); > } > > +void Network::SendEcho() { > + if (echo_outstanding) > + { > + Action a(Action::ACTION_ECHO); > + SendActionToAll(a); > + > + // this must be set after SendActionToAll as SendActionToAll would set > it to true otherwise. > + echo_outstanding = false; > + } > +} > + > > //----------------------------------------------------------------------------- > > // Static method > diff --git a/src/network/network.h b/src/network/network.h > index 1a1964b..a9bd1c2 100644 > --- a/src/network/network.h > +++ b/src/network/network.h > @@ -85,7 +85,7 @@ private: > > Player player; > bool turn_master_player; > - > + bool echo_outstanding; > protected: > bool game_master_player; > WNet::net_game_state_t state; > @@ -99,7 +99,7 @@ protected: > int fin; > #endif > > - virtual void SendAction(const Action& a, DistantComputer* client, bool > clt_as_rcver) const; > + virtual void SendAction(const Action& a, DistantComputer* client, bool > clt_as_rcver); > > void DisconnectNetwork(); > > @@ -150,9 +150,10 @@ public: > virtual void CloseConnection(std::list<DistantComputer*>::iterator closed) > = 0; > > // Action handling > - void SendActionToAll(const Action& action) const; > - void SendActionToOne(const Action& action, DistantComputer* client) const; > - void SendActionToAllExceptOne(const Action& action, DistantComputer* > client) const; > + void SendActionToAll(const Action& action); > + void SendActionToOne(const Action& action, DistantComputer* client); > + void SendActionToAllExceptOne(const Action& action, DistantComputer* > client); > + void SendEcho(); > > // Manage network state > void SetState(WNet::net_game_state_t state); > diff --git a/src/network/network_local.cpp b/src/network/network_local.cpp > index 48c70e6..3e6cc14 100644 > --- a/src/network/network_local.cpp > +++ b/src/network/network_local.cpp > @@ -25,7 +25,7 @@ NetworkLocal::NetworkLocal() : Network("-", "") {} > > NetworkLocal::~NetworkLocal() {} > > -void NetworkLocal::SendAction(const Action& /*a*/, DistantComputer* > /*client*/, bool /*clt_as_rcver*/) const {} > +void NetworkLocal::SendAction(const Action& /*a*/, DistantComputer* > /*client*/, bool /*clt_as_rcver*/) {} > > void NetworkLocal::CloseConnection(std::list<DistantComputer*>::iterator > /*closed*/) > { > diff --git a/src/network/network_local.h b/src/network/network_local.h > index 6d29dbc..727a577 100644 > --- a/src/network/network_local.h > +++ b/src/network/network_local.h > @@ -30,7 +30,7 @@ class NetworkLocal : public Network > protected: > virtual void HandleAction(Action* /*a*/, DistantComputer* /*sender*/) { > ASSERT(false) }; > virtual void WaitActionSleep() { ASSERT(false) }; > - virtual void SendAction(const Action& a, DistantComputer* client, bool > clt_as_rcver) const; > + virtual void SendAction(const Action& a, DistantComputer* client, bool > clt_as_rcver); > > public: > NetworkLocal(); > _______________________________________________ Wormux-dev mailing list Wormux-dev@gna.org https://mail.gna.org/listinfo/wormux-dev