diff --git a/src/client/game.cpp b/src/client/game.cpp index 9c8289f4..cbeaa177 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -469,9 +469,6 @@ void Game::processAttackCancel(uint seq) void Game::processWalkCancel(Otc::Direction direction) { - if(m_localPlayer->isAutoWalking()) - m_protocolGame->sendStop(); - m_localPlayer->cancelWalk(direction); } diff --git a/src/client/localplayer.cpp b/src/client/localplayer.cpp index 17a491d9..2715dcf3 100644 --- a/src/client/localplayer.cpp +++ b/src/client/localplayer.cpp @@ -158,6 +158,17 @@ void LocalPlayer::cancelWalk(Otc::Direction direction) m_walkPingTimer.restart(); m_idleTimer.restart(); + if(m_autoWalkDestination.isValid()) { + g_game.stop(); + auto self = asLocalPlayer(); + if(m_autoWalkContinueEvent) + m_autoWalkContinueEvent->cancel(); + m_autoWalkContinueEvent = g_dispatcher.scheduleEvent([self]() { + if(self->m_autoWalkDestination.isValid()) + self->autoWalk(self->m_autoWalkDestination); + }, 500); + } + // turn to the cancel direction if(direction != Otc::InvalidDirection) setDirection(direction); @@ -167,25 +178,43 @@ void LocalPlayer::cancelWalk(Otc::Direction direction) bool LocalPlayer::autoWalk(const Position& destination) { - m_autoWalkDestination = destination; - - std::tuple, Otc::PathFindResult> result = g_map.findPath(m_position, destination, 1000, Otc::PathFindAllowNullTiles); - if(std::get<1>(result) != Otc::PathFindResultOk) - return false; - - Position currentPos = m_position; + std::tuple, Otc::PathFindResult> result; std::vector limitedPath; - for(auto dir : std::get<0>(result)) { - currentPos = currentPos.translatedToDirection(dir); - if(!hasSight(currentPos)) - break; - else - limitedPath.push_back(dir); + if(destination == m_position) + return true; + + // try to find a path that we know + result = g_map.findPath(m_position, destination, 1000, 0); + if(std::get<1>(result) == Otc::PathFindResultOk) { + limitedPath = std::get<0>(result); + // limit to 127 steps + if(limitedPath.size() > 127) + limitedPath.resize(127); + } else { + // no known path found, try to discover one + result = g_map.findPath(m_position, destination, 1000, Otc::PathFindAllowNullTiles); + if(std::get<1>(result) != Otc::PathFindResultOk) + return false; + + Position currentPos = m_position; + for(auto dir : std::get<0>(result)) { + currentPos = currentPos.translatedToDirection(dir); + if(!hasSight(currentPos)) + break; + else + limitedPath.push_back(dir); + } } + m_autoWalkDestination = destination; m_lastAutoWalkPosition = m_position.translatedToDirections(limitedPath).back(); + for(auto pos : m_position.translatedToDirections(limitedPath)) { + g_map.getOrCreateTile(pos)->overwriteMinimapColor(16); + g_map.notificateTileUpdate(pos); + } + g_game.autoWalk(limitedPath); return true; } @@ -194,6 +223,9 @@ void LocalPlayer::stopAutoWalk() { m_autoWalkDestination = Position(); m_lastAutoWalkPosition = Position(); + + if(m_autoWalkContinueEvent) + m_autoWalkContinueEvent->cancel(); } void LocalPlayer::stopWalk() diff --git a/src/client/localplayer.h b/src/client/localplayer.h index abdcef2f..6f2eaefc 100644 --- a/src/client/localplayer.h +++ b/src/client/localplayer.h @@ -123,6 +123,7 @@ private: Position m_autoWalkDestination; Position m_lastAutoWalkPosition; ScheduledEventPtr m_autoWalkEndEvent; + ScheduledEventPtr m_autoWalkContinueEvent; ticks_t m_walkLockExpiration; int m_lastWalkPing; stdext::boolean m_preWalking; diff --git a/src/client/map.cpp b/src/client/map.cpp index 72127d21..abf16761 100644 --- a/src/client/map.cpp +++ b/src/client/map.cpp @@ -611,8 +611,8 @@ std::tuple, Otc::PathFindResult> Map::findPath(const tiles, need to rework this for "fly servers" and blank map click, but it is breaking normal path finding. */ - if(!(flags & Otc::PathFindAllowNullTiles) && !tile) - walkFactor = 3.0f; + if(!(flags & Otc::PathFindAllowNullTiles) && (!tile || tile->isEmpty())) + continue; if(tile) { if(!(flags & Otc::PathFindAllowCreatures) && tile->hasCreature()) continue; diff --git a/src/client/position.h b/src/client/position.h index 50b1540d..82f7114c 100644 --- a/src/client/position.h +++ b/src/client/position.h @@ -128,13 +128,16 @@ public: Position lastPos = *this; std::vector positions; + if(!lastPos.isValid()) + return positions; + positions.push_back(lastPos); for(auto dir : dirs) { - if(lastPos.isValid()) { - positions.push_back(lastPos); - } lastPos = lastPos.translatedToDirection(dir); + if(!lastPos.isValid()) + break; + positions.push_back(lastPos); } return positions; diff --git a/src/client/tile.cpp b/src/client/tile.cpp index 6983ea2a..af5c082f 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -612,7 +612,7 @@ bool Tile::limitsFloorsView() bool Tile::canErase() { - return m_walkingCreatures.empty() && m_effects.empty() && m_things.empty() && m_flags == 0; + return m_walkingCreatures.empty() && m_effects.empty() && m_things.empty() && m_flags == 0 && m_minimapColor == 0; } bool Tile::hasElevation(int elevation)