Skip to content

Commit

Permalink
perf: pathfinder refactor (opentibiabr#2729)
Browse files Browse the repository at this point in the history
  • Loading branch information
mehah authored Jul 26, 2024
1 parent c6d5eb1 commit 1a6dac4
Show file tree
Hide file tree
Showing 17 changed files with 559 additions and 221 deletions.
3 changes: 2 additions & 1 deletion src/creatures/combat/combat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,8 @@ void Combat::addDistanceEffect(std::shared_ptr<Creature> caster, const Position

void Combat::doChainEffect(const Position &origin, const Position &dest, uint8_t effect) {
if (effect > 0) {
stdext::arraylist<Direction> dirList(128);
std::vector<Direction> dirList;

FindPathParams fpp;
fpp.minTargetDist = 0;
fpp.maxTargetDist = 1;
Expand Down
6 changes: 3 additions & 3 deletions src/creatures/combat/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1926,7 +1926,7 @@ bool ConditionFeared::getFleeDirection(std::shared_ptr<Creature> creature) {
return false;
}

bool ConditionFeared::getFleePath(std::shared_ptr<Creature> creature, const Position &pos, stdext::arraylist<Direction> &dirList) {
bool ConditionFeared::getFleePath(std::shared_ptr<Creature> creature, const Position &pos, std::vector<Direction> &dirList) {
const std::vector<uint8_t> walkSize { 15, 9, 3, 1 };
bool found = false;
std::ptrdiff_t found_size = 0;
Expand Down Expand Up @@ -2029,7 +2029,7 @@ bool ConditionFeared::startCondition(std::shared_ptr<Creature> creature) {

bool ConditionFeared::executeCondition(std::shared_ptr<Creature> creature, int32_t interval) {
Position currentPos = creature->getPosition();
stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;

g_logger().debug("[ConditionFeared::executeCondition] Executing condition, current position is {}", currentPos.toString());

Expand All @@ -2039,7 +2039,7 @@ bool ConditionFeared::executeCondition(std::shared_ptr<Creature> creature, int32
}

if (getFleePath(creature, currentPos, listDir)) {
g_dispatcher().addEvent([id = creature->getID(), listDir = listDir.data()] {
g_dispatcher().addEvent([id = creature->getID(), listDir] {
g_game().forcePlayerAutoWalk(id, listDir);
},
"ConditionFeared::executeCondition");
Expand Down
2 changes: 1 addition & 1 deletion src/creatures/combat/condition.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ class ConditionFeared final : public Condition {
private:
bool canWalkTo(std::shared_ptr<Creature> creature, Position pos, Direction moveDirection) const;
bool getFleeDirection(std::shared_ptr<Creature> creature);
bool getFleePath(std::shared_ptr<Creature> creature, const Position &pos, stdext::arraylist<Direction> &dirList);
bool getFleePath(std::shared_ptr<Creature> creature, const Position &pos, std::vector<Direction> &dirList);
bool getRandomDirection(std::shared_ptr<Creature> creature, Position pos);
bool isStuck(std::shared_ptr<Creature> creature, Position pos) const;

Expand Down
20 changes: 12 additions & 8 deletions src/creatures/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ bool Creature::getNextStep(Direction &dir, uint32_t &) {
return false;
}

dir = listWalkDir.front();
listWalkDir.pop_front();
dir = listWalkDir.back();
listWalkDir.pop_back();
onWalk(dir);
return true;
}
Expand Down Expand Up @@ -814,14 +814,14 @@ bool Creature::dropCorpse(std::shared_ptr<Creature> lastHitCreature, std::shared
player->sendLootMessage(lootMessage.str());
}

stdext::arraylist<Direction> dirList(128);
FindPathParams fpp;
fpp.minTargetDist = 0;
fpp.maxTargetDist = 1;
fpp.fullPathSearch = true;
fpp.clearSight = true;
fpp.maxSearchDist = 0;

std::vector<Direction> dirList;
auto isReachable = g_game().map.getPathMatching(player->getPosition(), dirList, FrozenPathingConditionCall(corpse->getPosition()), fpp);

if (player->checkAutoLoot(monster->isRewardBoss()) && isReachable) {
Expand Down Expand Up @@ -1078,7 +1078,8 @@ void Creature::goToFollowCreature() {
}

bool executeOnFollow = true;
stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
listDir.reserve(128);

FindPathParams fpp;
getPathSearchParams(followCreature, fpp);
Expand All @@ -1101,7 +1102,7 @@ void Creature::goToFollowCreature() {
hasFollowPath = getPathTo(followCreature->getPosition(), listDir, fpp);
}

startAutoWalk(listDir.data());
startAutoWalk(listDir);

if (executeOnFollow) {
onFollowCreatureComplete(followCreature);
Expand Down Expand Up @@ -1737,12 +1738,15 @@ bool Creature::isInvisible() const {
!= conditions.end();
}

bool Creature::getPathTo(const Position &targetPos, stdext::arraylist<Direction> &dirList, const FindPathParams &fpp) {
bool Creature::getPathTo(const Position &targetPos, std::vector<Direction> &dirList, const FindPathParams &fpp) {
metrics::method_latency measure(__METHOD_NAME__);
return g_game().map.getPathMatching(getCreature(), dirList, FrozenPathingConditionCall(targetPos), fpp);
if (fpp.maxSearchDist != 0 || fpp.keepDistance) {
return g_game().map.getPathMatchingCond(getCreature(), targetPos, dirList, FrozenPathingConditionCall(targetPos), fpp);
}
return g_game().map.getPathMatching(getCreature(), targetPos, dirList, FrozenPathingConditionCall(targetPos), fpp);
}

bool Creature::getPathTo(const Position &targetPos, stdext::arraylist<Direction> &dirList, int32_t minTargetDist, int32_t maxTargetDist, bool fullPathSearch /*= true*/, bool clearSight /*= true*/, int32_t maxSearchDist /*= 7*/) {
bool Creature::getPathTo(const Position &targetPos, std::vector<Direction> &dirList, int32_t minTargetDist, int32_t maxTargetDist, bool fullPathSearch /*= true*/, bool clearSight /*= true*/, int32_t maxSearchDist /*= 7*/) {
FindPathParams fpp;
fpp.fullPathSearch = fullPathSearch;
fpp.maxSearchDist = maxSearchDist;
Expand Down
6 changes: 3 additions & 3 deletions src/creatures/creature.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,8 @@ class Creature : virtual public Thing, public SharedObject {

double getDamageRatio(std::shared_ptr<Creature> attacker) const;

bool getPathTo(const Position &targetPos, stdext::arraylist<Direction> &dirList, const FindPathParams &fpp);
bool getPathTo(const Position &targetPos, stdext::arraylist<Direction> &dirList, int32_t minTargetDist, int32_t maxTargetDist, bool fullPathSearch = true, bool clearSight = true, int32_t maxSearchDist = 7);
bool getPathTo(const Position &targetPos, std::vector<Direction> &dirList, const FindPathParams &fpp);
bool getPathTo(const Position &targetPos, std::vector<Direction> &dirList, int32_t minTargetDist, int32_t maxTargetDist, bool fullPathSearch = true, bool clearSight = true, int32_t maxSearchDist = 7);

struct CountBlock_t {
int32_t total;
Expand Down Expand Up @@ -720,7 +720,7 @@ class Creature : virtual public Thing, public SharedObject {
CreatureEventList eventsList;
ConditionList conditions;

std::deque<Direction> listWalkDir;
std::vector<Direction> listWalkDir;

std::weak_ptr<Tile> m_tile;
std::weak_ptr<Creature> m_attackedCreature;
Expand Down
4 changes: 2 additions & 2 deletions src/creatures/monsters/monster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1257,12 +1257,12 @@ void Monster::doWalkBack(uint32_t &flags, Direction &nextDirection, bool &result
return;
}

stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (!getPathTo(masterPos, listDir, 0, std::max<int32_t>(0, distance - 5), true, true, distance)) {
isWalkingBack = false;
return;
}
startAutoWalk(listDir.data());
startAutoWalk(listDir);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/creatures/npcs/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ void Npc::onThinkWalk(uint32_t interval) {

if (Direction newDirection;
getRandomStep(newDirection)) {
listWalkDir.push_front(newDirection);
listWalkDir.emplace_back(newDirection);
addEventWalk();
}

Expand Down
4 changes: 2 additions & 2 deletions src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7818,9 +7818,9 @@ SoundEffect_t Player::getAttackSoundEffect() const {
bool Player::canAutoWalk(const Position &toPosition, const std::function<void()> &function, uint32_t delay /* = 500*/) {
if (!Position::areInRange<1, 1>(getPosition(), toPosition)) {
// Check if can walk to the toPosition and send event to use function
stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (getPathTo(toPosition, listDir, 0, 1, true, true)) {
g_dispatcher().addEvent([creatureId = getID(), dirs = listDir.data()] { g_game().playerAutoWalk(creatureId, dirs); }, __FUNCTION__);
g_dispatcher().addEvent([creatureId = getID(), listDir] { g_game().playerAutoWalk(creatureId, listDir); }, __FUNCTION__);

std::shared_ptr<Task> task = createPlayerTask(delay, function, __FUNCTION__);
setNextWalkActionTask(task);
Expand Down
60 changes: 30 additions & 30 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1405,9 +1405,9 @@ void Game::playerMoveCreature(std::shared_ptr<Player> player, std::shared_ptr<Cr

if (!Position::areInRange<1, 1, 0>(movingCreatureOrigPos, player->getPosition())) {
// need to walk to the creature first before moving it
stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (player->getPathTo(movingCreatureOrigPos, listDir, 0, 1, true, true)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
const auto &task = createPlayerTask(
600, [this, player, movingCreature, toTile, movingCreatureOrigPos] { playerMoveCreatureByID(player->getID(), movingCreature->getID(), movingCreatureOrigPos, toTile->getPosition()); }, "Game::playerMoveCreatureByID"
);
Expand Down Expand Up @@ -1694,9 +1694,9 @@ void Game::playerMoveItem(std::shared_ptr<Player> player, const Position &fromPo

if (!Position::areInRange<1, 1>(playerPos, mapFromPos)) {
// need to walk to the item first before using it
stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (player->getPathTo(item->getPosition(), listDir, 0, 1, true, true)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");

std::shared_ptr<Task> task = createPlayerTask(
400, [this, playerId = player->getID(), fromPos, itemId, fromStackPos, toPos, count] {
Expand Down Expand Up @@ -1756,9 +1756,9 @@ void Game::playerMoveItem(std::shared_ptr<Player> player, const Position &fromPo
internalGetPosition(moveItem, itemPos, itemStackPos);
}

stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (player->getPathTo(walkPos, listDir, 0, 0, true, true)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");

std::shared_ptr<Task> task = createPlayerTask(
400, [this, playerId = player->getID(), itemPos, itemId, itemStackPos, toPos, count] {
Expand Down Expand Up @@ -3681,9 +3681,9 @@ void Game::playerUseItemEx(uint32_t playerId, const Position &fromPos, uint8_t f
internalGetPosition(moveItem, itemPos, itemStackPos);
}

stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (player->getPathTo(walkToPos, listDir, 0, 1, true, true)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");

std::shared_ptr<Task> task = createPlayerTask(
400, [this, playerId, itemPos, itemStackPos, fromItemId, toPos, toStackPos, toItemId] { playerUseItemEx(playerId, itemPos, itemStackPos, fromItemId, toPos, toStackPos, toItemId); }, "Game::playerUseItemEx"
Expand Down Expand Up @@ -3795,9 +3795,9 @@ void Game::playerUseItem(uint32_t playerId, const Position &pos, uint8_t stackPo
ReturnValue ret = g_actions().canUse(player, pos);
if (ret != RETURNVALUE_NOERROR) {
if (ret == RETURNVALUE_TOOFARAWAY) {
stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (player->getPathTo(pos, listDir, 0, 1, true, true)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");

std::shared_ptr<Task> task = createPlayerTask(
400, [this, playerId, pos, stackPos, index, itemId] { playerUseItem(playerId, pos, stackPos, index, itemId); }, "Game::playerUseItem"
Expand Down Expand Up @@ -3952,9 +3952,9 @@ void Game::playerUseWithCreature(uint32_t playerId, const Position &fromPos, uin
internalGetPosition(moveItem, itemPos, itemStackPos);
}

stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (player->getPathTo(walkToPos, listDir, 0, 1, true, true)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");

std::shared_ptr<Task> task = createPlayerTask(
400, [this, playerId, itemPos, itemStackPos, creatureId, itemId] {
Expand Down Expand Up @@ -4113,9 +4113,9 @@ void Game::playerRotateItem(uint32_t playerId, const Position &pos, uint8_t stac
}

if (pos.x != 0xFFFF && !Position::areInRange<1, 1, 0>(pos, player->getPosition())) {
stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (player->getPathTo(pos, listDir, 0, 1, true, true)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");

std::shared_ptr<Task> task = createPlayerTask(
400, [this, playerId, pos, stackPos, itemId] {
Expand Down Expand Up @@ -4169,9 +4169,9 @@ void Game::playerConfigureShowOffSocket(uint32_t playerId, const Position &pos,

bool isPodiumOfRenown = itemId == ITEM_PODIUM_OF_RENOWN1 || itemId == ITEM_PODIUM_OF_RENOWN2;
if (!Position::areInRange<1, 1, 0>(pos, player->getPosition())) {
stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (player->getPathTo(pos, listDir, 0, 1, true, false)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
std::shared_ptr<Task> task;
if (isPodiumOfRenown) {
task = createPlayerTask(
Expand Down Expand Up @@ -4230,9 +4230,9 @@ void Game::playerSetShowOffSocket(uint32_t playerId, Outfit_t &outfit, const Pos
}

if (!Position::areInRange<1, 1, 0>(pos, player->getPosition())) {
stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (player->getPathTo(pos, listDir, 0, 1, true, false)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
std::shared_ptr<Task> task = createPlayerTask(
400, [this, playerId, pos] { playerBrowseField(playerId, pos); }, "Game::playerBrowseField"
);
Expand Down Expand Up @@ -4371,9 +4371,9 @@ void Game::playerWrapableItem(uint32_t playerId, const Position &pos, uint8_t st
}

if (pos.x != 0xFFFF && !Position::areInRange<1, 1, 0>(pos, player->getPosition())) {
stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (player->getPathTo(pos, listDir, 0, 1, true, true)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");

std::shared_ptr<Task> task = createPlayerTask(
400, [this, playerId, pos, stackPos, itemId] { playerWrapableItem(playerId, pos, stackPos, itemId); }, "Game::playerWrapableItem"
Expand Down Expand Up @@ -4552,9 +4552,9 @@ void Game::playerBrowseField(uint32_t playerId, const Position &pos) {
}

if (!Position::areInRange<1, 1>(playerPos, pos)) {
stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (player->getPathTo(pos, listDir, 0, 1, true, true)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
std::shared_ptr<Task> task = createPlayerTask(
400, [this, playerId, pos] { playerBrowseField(playerId, pos); }, "Game::playerBrowseField"
);
Expand Down Expand Up @@ -4815,9 +4815,9 @@ void Game::playerRequestTrade(uint32_t playerId, const Position &pos, uint8_t st
}

if (!Position::areInRange<1, 1>(tradeItemPosition, playerPosition)) {
stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (player->getPathTo(pos, listDir, 0, 1, true, true)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");

std::shared_ptr<Task> task = createPlayerTask(
400, [this, playerId, pos, stackPos, tradePlayerId, itemId] { playerRequestTrade(playerId, pos, stackPos, tradePlayerId, itemId); }, "Game::playerRequestTrade"
Expand Down Expand Up @@ -5394,9 +5394,9 @@ void Game::playerQuickLoot(uint32_t playerId, const Position &pos, uint16_t item
if (!autoLoot && pos.x != 0xffff) {
if (!Position::areInRange<1, 1, 0>(pos, player->getPosition())) {
// need to walk to the corpse first before looting it
stdext::arraylist<Direction> listDir(128);
std::vector<Direction> listDir;
if (player->getPathTo(pos, listDir, 0, 1, true, true)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
std::shared_ptr<Task> task = createPlayerTask(
0, [this, playerId = player->getID(), pos, itemId, stackPos, defaultItem, lootAllCorpses, autoLoot] {
playerQuickLoot(playerId, pos, itemId, stackPos, defaultItem, lootAllCorpses, autoLoot);
Expand Down Expand Up @@ -9486,9 +9486,9 @@ void Game::playerSetMonsterPodium(uint32_t playerId, uint32_t monsterRaceId, con
}

if (!Position::areInRange<1, 1, 0>(pos, player->getPosition())) {
if (stdext::arraylist<Direction> listDir(128);
if (std::vector<Direction> listDir;
player->getPathTo(pos, listDir, 0, 1, true, false)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
std::shared_ptr<Task> task = createPlayerTask(
400, [this, playerId, pos] { playerBrowseField(playerId, pos); }, "Game::playerBrowseField"
);
Expand Down Expand Up @@ -9586,9 +9586,9 @@ void Game::playerRotatePodium(uint32_t playerId, const Position &pos, uint8_t st
}

if (pos.x != 0xFFFF && !Position::areInRange<1, 1, 0>(pos, player->getPosition())) {
if (stdext::arraylist<Direction> listDir(128);
if (std::vector<Direction> listDir;
player->getPathTo(pos, listDir, 0, 1, true, true)) {
g_dispatcher().addEvent([this, playerId = player->getID(), listDir = listDir.data()] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
g_dispatcher().addEvent([this, playerId = player->getID(), listDir] { playerAutoWalk(playerId, listDir); }, "Game::playerAutoWalk");
std::shared_ptr<Task> task = createPlayerTask(
400, [this, playerId, pos, stackPos, itemId] {
playerRotatePodium(playerId, pos, stackPos, itemId);
Expand Down
Loading

0 comments on commit 1a6dac4

Please sign in to comment.