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
[email protected]
https://mail.gna.org/listinfo/wormux-dev