Improve autowalk

This commit is contained in:
Eduardo Bart 2013-01-22 16:04:36 -02:00
parent 01e48fbcc8
commit e900a7679a
6 changed files with 55 additions and 22 deletions

View File

@ -469,9 +469,6 @@ void Game::processAttackCancel(uint seq)
void Game::processWalkCancel(Otc::Direction direction) void Game::processWalkCancel(Otc::Direction direction)
{ {
if(m_localPlayer->isAutoWalking())
m_protocolGame->sendStop();
m_localPlayer->cancelWalk(direction); m_localPlayer->cancelWalk(direction);
} }

View File

@ -158,6 +158,17 @@ void LocalPlayer::cancelWalk(Otc::Direction direction)
m_walkPingTimer.restart(); m_walkPingTimer.restart();
m_idleTimer.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 // turn to the cancel direction
if(direction != Otc::InvalidDirection) if(direction != Otc::InvalidDirection)
setDirection(direction); setDirection(direction);
@ -167,25 +178,43 @@ void LocalPlayer::cancelWalk(Otc::Direction direction)
bool LocalPlayer::autoWalk(const Position& destination) bool LocalPlayer::autoWalk(const Position& destination)
{ {
m_autoWalkDestination = destination; std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> result;
std::tuple<std::vector<Otc::Direction>, 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::vector<Otc::Direction> limitedPath; std::vector<Otc::Direction> limitedPath;
for(auto dir : std::get<0>(result)) { if(destination == m_position)
currentPos = currentPos.translatedToDirection(dir); return true;
if(!hasSight(currentPos))
break; // try to find a path that we know
else result = g_map.findPath(m_position, destination, 1000, 0);
limitedPath.push_back(dir); 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(); 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); g_game.autoWalk(limitedPath);
return true; return true;
} }
@ -194,6 +223,9 @@ void LocalPlayer::stopAutoWalk()
{ {
m_autoWalkDestination = Position(); m_autoWalkDestination = Position();
m_lastAutoWalkPosition = Position(); m_lastAutoWalkPosition = Position();
if(m_autoWalkContinueEvent)
m_autoWalkContinueEvent->cancel();
} }
void LocalPlayer::stopWalk() void LocalPlayer::stopWalk()

View File

@ -123,6 +123,7 @@ private:
Position m_autoWalkDestination; Position m_autoWalkDestination;
Position m_lastAutoWalkPosition; Position m_lastAutoWalkPosition;
ScheduledEventPtr m_autoWalkEndEvent; ScheduledEventPtr m_autoWalkEndEvent;
ScheduledEventPtr m_autoWalkContinueEvent;
ticks_t m_walkLockExpiration; ticks_t m_walkLockExpiration;
int m_lastWalkPing; int m_lastWalkPing;
stdext::boolean<false> m_preWalking; stdext::boolean<false> m_preWalking;

View File

@ -611,8 +611,8 @@ std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> Map::findPath(const
tiles, need to rework this for "fly servers" and blank map click, tiles, need to rework this for "fly servers" and blank map click,
but it is breaking normal path finding. but it is breaking normal path finding.
*/ */
if(!(flags & Otc::PathFindAllowNullTiles) && !tile) if(!(flags & Otc::PathFindAllowNullTiles) && (!tile || tile->isEmpty()))
walkFactor = 3.0f; continue;
if(tile) { if(tile) {
if(!(flags & Otc::PathFindAllowCreatures) && tile->hasCreature()) if(!(flags & Otc::PathFindAllowCreatures) && tile->hasCreature())
continue; continue;

View File

@ -128,13 +128,16 @@ public:
Position lastPos = *this; Position lastPos = *this;
std::vector<Position> positions; std::vector<Position> positions;
if(!lastPos.isValid())
return positions;
positions.push_back(lastPos); positions.push_back(lastPos);
for(auto dir : dirs) { for(auto dir : dirs) {
if(lastPos.isValid()) {
positions.push_back(lastPos);
}
lastPos = lastPos.translatedToDirection(dir); lastPos = lastPos.translatedToDirection(dir);
if(!lastPos.isValid())
break;
positions.push_back(lastPos);
} }
return positions; return positions;

View File

@ -612,7 +612,7 @@ bool Tile::limitsFloorsView()
bool Tile::canErase() 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) bool Tile::hasElevation(int elevation)