Improve walk when lagging

This commit is contained in:
Eduardo Bart
2013-03-13 20:55:20 -03:00
parent 0891e2b30a
commit e9e4dcd71b
9 changed files with 79 additions and 29 deletions

View File

@@ -99,6 +99,11 @@ void Game::resetGameStates()
m_walkEvent = nullptr;
}
if(m_checkConnectionEvent) {
m_checkConnectionEvent->cancel();
m_checkConnectionEvent = nullptr;
}
m_containers.clear();
m_vips.clear();
m_gmActions.clear();
@@ -183,6 +188,16 @@ void Game::processGameStart()
g_game.ping();
}, m_pingDelay);
}
m_checkConnectionEvent = g_dispatcher.cycleEvent([this] {
if(!g_game.isConnectionOk() && !m_connectionFailWarned) {
g_lua.callGlobalField("g_game", "onConnectionFailing", true);
m_connectionFailWarned = true;
} else if(g_game.isConnectionOk() && m_connectionFailWarned) {
g_lua.callGlobalField("g_game", "onConnectionFailing", false);
m_connectionFailWarned = false;
}
}, 1000);
}
void Game::processGameEnd()
@@ -190,6 +205,11 @@ void Game::processGameEnd()
m_online = false;
g_lua.callGlobalField("g_game", "onGameEnd");
if(m_connectionFailWarned) {
g_lua.callGlobalField("g_game", "onConnectionFailing", false);
m_connectionFailWarned = false;
}
// reset game state
resetGameStates();
@@ -551,6 +571,7 @@ bool Game::walk(Otc::Direction direction)
// check we can walk and add new walk event if false
if(!m_localPlayer->canWalk(direction)) {
/*
if(m_lastWalkDir != direction) {
// must add a new walk event
float ticks = m_localPlayer->getStepTicksLeft();
@@ -562,6 +583,7 @@ bool Game::walk(Otc::Direction direction)
}
m_walkEvent = g_dispatcher.scheduleEvent([=] { walk(direction); }, ticks);
}
*/
return false;
}
@@ -697,15 +719,16 @@ void Game::autoWalk(std::vector<Otc::Direction> dirs)
auto it = dirs.begin();
Otc::Direction direction = *it;
if(m_localPlayer->canWalk(direction)) {
TilePtr toTile = g_map.getTile(m_localPlayer->getPosition().translatedToDirection(direction));
if(toTile && toTile->isWalkable() && !m_localPlayer->isServerWalking()) {
m_localPlayer->preWalk(direction);
if(!m_localPlayer->canWalk(direction))
return;
if(getFeature(Otc::GameForceFirstAutoWalkStep)) {
forceWalk(direction);
dirs.erase(it);
}
TilePtr toTile = g_map.getTile(m_localPlayer->getPosition().translatedToDirection(direction));
if(toTile && toTile->isWalkable() && !m_localPlayer->isServerWalking()) {
m_localPlayer->preWalk(direction);
if(getFeature(Otc::GameForceFirstAutoWalkStep)) {
forceWalk(direction);
dirs.erase(it);
}
}

View File

@@ -231,7 +231,7 @@ public:
void openRuleViolation(const std::string& reporter);
void closeRuleViolation(const std::string& reporter);
void cancelRuleViolation();
// reports
void reportBug(const std::string& comment);
void reportRuleViolation(const std::string& target, int reason, int action, const std::string& comment, const std::string& statement, int statementId, bool ipBanishment);
@@ -281,6 +281,7 @@ public:
bool isDead() { return m_dead; }
bool isAttacking() { return !!m_attackingCreature; }
bool isFollowing() { return !!m_followingCreature; }
bool isConnectionOk() { return m_protocolGame && m_protocolGame->getElapsedTicksSinceLastRead() < 5000; }
int getPing() { return m_ping >= 0 ? std::max(m_ping, m_pingTimer.elapsed_millis()) : -1; }
ContainerPtr getContainer(int index) { return m_containers[index]; }
@@ -340,6 +341,8 @@ private:
std::bitset<Otc::LastGameFeature> m_features;
ScheduledEventPtr m_pingEvent;
ScheduledEventPtr m_walkEvent;
ScheduledEventPtr m_checkConnectionEvent;
bool m_connectionFailWarned;
int m_protocolVersion;
int m_clientVersion;
std::string m_clientSignature;

View File

@@ -83,7 +83,7 @@ bool LocalPlayer::canWalk(Otc::Direction direction)
return false;
// cannot walk while already walking
if(m_walking && !prewalkTimeouted)
if(m_walking && (!prewalkTimeouted || m_secondPreWalk))
return false;
return true;
@@ -95,6 +95,7 @@ void LocalPlayer::walk(const Position& oldPos, const Position& newPos)
if(m_preWalking) {
// switch to normal walking
m_preWalking = false;
m_secondPreWalk = false;
m_lastPrewalkDone = true;
// if is to the last prewalk destination, updates the walk preserving the animation
if(newPos == m_lastPrewalkDestination) {
@@ -118,7 +119,8 @@ void LocalPlayer::preWalk(Otc::Direction direction)
Position newPos = m_position.translatedToDirection(direction);
// avoid reanimating prewalks
if(m_preWalking && m_lastPrewalkDestination == newPos) {
if(m_preWalking) {
m_secondPreWalk = true;
return;
}
@@ -277,6 +279,7 @@ void LocalPlayer::terminateWalk()
{
Creature::terminateWalk();
m_preWalking = false;
m_secondPreWalk = false;
m_idleTimer.restart();
auto self = asLocalPlayer();

View File

@@ -126,6 +126,7 @@ private:
ticks_t m_walkLockExpiration;
stdext::boolean<false> m_preWalking;
stdext::boolean<true> m_lastPrewalkDone;
stdext::boolean<false> m_secondPreWalk;
stdext::boolean<false> m_serverWalking;
stdext::boolean<false> m_knownCompletePath;

View File

@@ -230,6 +230,7 @@ void Client::registerLuaFunctions()
g_lua.bindSingletonFunction("g_game", "isDead", &Game::isDead, &g_game);
g_lua.bindSingletonFunction("g_game", "isAttacking", &Game::isAttacking, &g_game);
g_lua.bindSingletonFunction("g_game", "isFollowing", &Game::isFollowing, &g_game);
g_lua.bindSingletonFunction("g_game", "isConnectionOk", &Game::isConnectionOk, &g_game);
g_lua.bindSingletonFunction("g_game", "getPing", &Game::getPing, &g_game);
g_lua.bindSingletonFunction("g_game", "getContainer", &Game::getContainer, &g_game);
g_lua.bindSingletonFunction("g_game", "getContainers", &Game::getContainers, &g_game);

View File

@@ -125,7 +125,7 @@ void Connection::write(uint8* buffer, size_t size)
m_outputStream = std::shared_ptr<asio::streambuf>(new asio::streambuf);
m_delayedWriteTimer.cancel();
m_delayedWriteTimer.expires_from_now(boost::posix_time::milliseconds(1));
m_delayedWriteTimer.expires_from_now(boost::posix_time::milliseconds(10));
m_delayedWriteTimer.async_wait(std::bind(&Connection::onCanWrite, asConnection(), std::placeholders::_1));
}
@@ -215,6 +215,7 @@ void Connection::onResolve(const boost::system::error_code& error, asio::ip::bas
void Connection::onConnect(const boost::system::error_code& error)
{
m_readTimer.cancel();
m_activityTimer.restart();
if(error == asio::error::operation_aborted)
return;
@@ -263,6 +264,7 @@ void Connection::onWrite(const boost::system::error_code& error, size_t writeSiz
void Connection::onRecv(const boost::system::error_code& error, size_t recvSize)
{
m_readTimer.cancel();
m_activityTimer.restart();
if(error == asio::error::operation_aborted)
return;

View File

@@ -61,6 +61,7 @@ public:
boost::system::error_code getError() { return m_error; }
bool isConnecting() { return m_connecting; }
bool isConnected() { return m_connected; }
ticks_t getElapsedTicksSinceLastRead() { return m_connected ? m_activityTimer.elapsed_millis() : -1; }
ConnectionPtr asConnection() { return static_self_cast<Connection>(); }
@@ -91,6 +92,7 @@ protected:
bool m_connected;
bool m_connecting;
boost::system::error_code m_error;
stdext::timer m_activityTimer;
friend class Server;
};

View File

@@ -42,6 +42,8 @@ public:
bool isConnected();
bool isConnecting();
ticks_t getElapsedTicksSinceLastRead() { return m_connection ? m_connection->getElapsedTicksSinceLastRead() : -1; }
ConnectionPtr getConnection() { return m_connection; }
void setConnection(const ConnectionPtr& connection) { m_connection = connection; }