Improve walk when lagging
This commit is contained in:
parent
0891e2b30a
commit
e9e4dcd71b
|
@ -104,8 +104,8 @@ function bindKeys()
|
|||
g_keyboard.bindKeyPress('Escape', function() g_game.cancelAttackAndFollow() end, gameRootPanel)
|
||||
g_keyboard.bindKeyPress('Ctrl+=', function() gameMapPanel:zoomIn() end, gameRootPanel)
|
||||
g_keyboard.bindKeyPress('Ctrl+-', function() gameMapPanel:zoomOut() end, gameRootPanel)
|
||||
g_keyboard.bindKeyDown('Ctrl+Q', logout, gameRootPanel)
|
||||
g_keyboard.bindKeyDown('Ctrl+L', logout, gameRootPanel)
|
||||
g_keyboard.bindKeyDown('Ctrl+Q', tryLogout, gameRootPanel)
|
||||
g_keyboard.bindKeyDown('Ctrl+L', tryLogout, gameRootPanel)
|
||||
g_keyboard.bindKeyDown('Ctrl+W', function() g_map.cleanTexts() modules.game_textmessage.clearMessages() end, gameRootPanel)
|
||||
g_keyboard.bindKeyDown('Ctrl+.', nextViewMode, gameRootPanel)
|
||||
end
|
||||
|
@ -215,8 +215,8 @@ function tryExit()
|
|||
return true
|
||||
end
|
||||
|
||||
local exitFunc = function() logout() forceExit() end
|
||||
local logoutFunc = function() logout() exitWindow:destroy() exitWindow = nil end
|
||||
local exitFunc = function() g_game.safeLogout() forceExit() end
|
||||
local logoutFunc = function() g_game.safeLogout() exitWindow:destroy() exitWindow = nil end
|
||||
local cancelFunc = function() exitWindow:destroy() exitWindow = nil end
|
||||
|
||||
exitWindow = displayGeneralBox(tr('Exit'), tr("If you shut down the program, your character might stay in the game.\nClick on 'Logout' to ensure that you character leaves the game properly.\nClick on 'Exit' if you want to exit the program without logging out your character."),
|
||||
|
@ -228,13 +228,6 @@ function tryExit()
|
|||
return true
|
||||
end
|
||||
|
||||
function logout()
|
||||
if g_game.isOnline() then
|
||||
g_game.safeLogout()
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function tryLogout()
|
||||
if not g_game.isOnline() then
|
||||
exit()
|
||||
|
@ -245,13 +238,33 @@ function tryLogout()
|
|||
return
|
||||
end
|
||||
|
||||
local yesCallback = function() logout() logoutWindow:destroy() logoutWindow=nil end
|
||||
local noCallback = function() logoutWindow:destroy() logoutWindow=nil end
|
||||
if not g_game.isConnectionOk() then
|
||||
local yesCallback = function()
|
||||
g_game.forceLogout()
|
||||
logoutWindow=nil
|
||||
end
|
||||
local noCallback = function()
|
||||
logoutWindow=nil
|
||||
end
|
||||
|
||||
logoutWindow = displayGeneralBox(tr('Logout'), tr('Are you sure you want to logout?'), {
|
||||
{ text=tr('Yes'), callback=yesCallback },
|
||||
{ text=tr('No'), callback=noCallback },
|
||||
anchor=AnchorHorizontalCenter}, yesCallback, noCallback)
|
||||
logoutWindow = displayGeneralBox(tr('Logout'), tr('Your connection is failing, if you logout now your character will be still online, do you want to force logout?'), {
|
||||
{ text=tr('Yes'), callback=yesCallback },
|
||||
{ text=tr('No'), callback=noCallback },
|
||||
anchor=AnchorHorizontalCenter}, yesCallback, noCallback)
|
||||
else
|
||||
local yesCallback = function()
|
||||
g_game.safeLogout()
|
||||
logoutWindow=nil
|
||||
end
|
||||
local noCallback = function()
|
||||
logoutWindow=nil
|
||||
end
|
||||
|
||||
logoutWindow = displayGeneralBox(tr('Logout'), tr('Are you sure you want to logout?'), {
|
||||
{ text=tr('Yes'), callback=yesCallback },
|
||||
{ text=tr('No'), callback=noCallback },
|
||||
anchor=AnchorHorizontalCenter}, yesCallback, noCallback)
|
||||
end
|
||||
end
|
||||
|
||||
function stopSmartWalk()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
Loading…
Reference in New Issue