diff --git a/src/configmanager.cpp b/src/configmanager.cpp index dfed0566..eba5406c 100644 --- a/src/configmanager.cpp +++ b/src/configmanager.cpp @@ -324,6 +324,8 @@ bool ConfigManager::load() integer[VIP_PREMIUM_LIMIT] = getGlobalNumber(L, "vipPremiumLimit", 100); integer[DEPOT_FREE_LIMIT] = getGlobalNumber(L, "depotFreeLimit", 2000); integer[DEPOT_PREMIUM_LIMIT] = getGlobalNumber(L, "depotPremiumLimit", 10000); + integer[PATHFINDING_INTERVAL] = getGlobalNumber(L, "pathfindingInterval", 100); + integer[PATHFINDING_DELAY] = getGlobalNumber(L, "pathfindingDelay", 200); expStages = loadXMLStages(); if (expStages.empty()) { diff --git a/src/configmanager.h b/src/configmanager.h index 7313a723..817a2daa 100644 --- a/src/configmanager.h +++ b/src/configmanager.h @@ -134,6 +134,8 @@ class ConfigManager VIP_PREMIUM_LIMIT, DEPOT_FREE_LIMIT, DEPOT_PREMIUM_LIMIT, + PATHFINDING_INTERVAL, + PATHFINDING_DELAY, LAST_INTEGER_CONFIG /* this must be the last one */ }; diff --git a/src/creature.cpp b/src/creature.cpp index b1b18e25..142a5d69 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -158,13 +158,16 @@ void Creature::onThink(uint32_t interval) void Creature::forceUpdatePath() { - if (attackedCreature || followCreature) { - const Position& position = attackedCreature ? attackedCreature->getPosition() : followCreature->getPosition(); - - if (g_game.isSightClear(getPosition(), position, true)) { - g_dispatcher.addTask(createTask([id = getID()]() { g_game.updateCreatureWalk(id); })); + if (!attackedCreature && !followCreature) { + return; } + + if (lastPathUpdate - OTSYS_TIME() > 0) { + return; } + + lastPathUpdate = OTSYS_TIME() + EVENT_CREATURE_PATH_DELAY; + g_dispatcher.addTask(createTask([id = getID()]() { g_game.updateCreatureWalk(id); })); } void Creature::onAttacking(uint32_t interval) @@ -224,23 +227,8 @@ void Creature::onWalk() addEventWalk(); } - if (getTimeSinceLastMove() >= 500) { - const Position& position = getPosition(); - - if (attackedCreature) { - const Position& targetPosition = attackedCreature->getPosition(); - if (Position::getDistanceX(position, targetPosition) <= Map::maxViewportX && - Position::getDistanceY(position, targetPosition) <= Map::maxViewportY) { - g_dispatcher.addTask(createTask([id = getID()]() { g_game.updateCreatureWalk(id); })); - } - } - else if (followCreature) { - const Position& targetPosition = followCreature->getPosition(); - if (Position::getDistanceX(position, targetPosition) <= Map::maxViewportX && - Position::getDistanceY(position, targetPosition) <= Map::maxViewportY) { - g_dispatcher.addTask(createTask([id = getID()]() { g_game.updateCreatureWalk(id); })); - } - } + if (attackedCreature || followCreature) { + g_dispatcher.addTask(createTask([id = getID()]() { g_game.updateCreatureWalk(id); })); } } @@ -928,7 +916,7 @@ void Creature::getPathSearchParams(const Creature*, FindPathParams& fpp) const { fpp.fullPathSearch = !hasFollowPath; fpp.clearSight = true; - fpp.maxSearchDist = Map::maxViewportX; + fpp.maxSearchDist = Map::maxViewportX + Map::maxViewportY; fpp.minTargetDist = 1; fpp.maxTargetDist = 1; } @@ -1031,14 +1019,6 @@ bool Creature::setFollowCreature(Creature* creature) return true; } -// Pathfinding Functions -void Creature::addFollowedByCreature(Creature* creature) -{ - if (creature) { - followedByCreatures.push_back(creature); - } -} - // Pathfinding Events void Creature::updateFollowingCreaturesPath() { @@ -1046,28 +1026,9 @@ void Creature::updateFollowingCreaturesPath() return; } - std::list newFollowedByList; - for (Creature* followedByCreature : followedByCreatures) { - if (followedByCreature == nullptr) { - continue; - } - - if (!canSee(followedByCreature->getPosition())) { - continue; - } - newFollowedByList.push_back(followedByCreature); - g_dispatcher.addTask(createTask([id = followedByCreature->getID()]() { g_game.updateCreatureWalk(id); })); - } - - followedByCreatures.clear(); - - for (Creature* newFollowCreature : newFollowedByList) { - if (newFollowCreature == nullptr) { - continue; - } - - addFollowedByCreature(newFollowCreature); + for (Creature* followedByCreature : followedByCreatures) { + g_dispatcher.addTask(createTask([id = followedByCreature->getID()]() { g_game.updateCreatureWalk(id); })); } } diff --git a/src/creature.h b/src/creature.h index 4b214d14..6adfd428 100644 --- a/src/creature.h +++ b/src/creature.h @@ -20,6 +20,7 @@ #ifndef FS_CREATURE_H_5363C04015254E298F84E6D59A139508 #define FS_CREATURE_H_5363C04015254E298F84E6D59A139508 +#include "configmanager.h" #include "map.h" #include "position.h" #include "condition.h" @@ -28,6 +29,8 @@ #include "enums.h" #include "creatureevent.h" +extern ConfigManager g_config; + using ConditionList = std::list; using CreatureEventList = std::list; @@ -69,9 +72,12 @@ class Tile; static constexpr int32_t EVENT_CREATURECOUNT = 10; static constexpr int32_t EVENT_CREATURE_THINK_INTERVAL = 1000; -static constexpr int32_t EVENT_CREATURE_PATH_INTERVAL = 200; +//static constexpr int32_t EVENT_CREATURE_PATH_INTERVAL = 100; static constexpr int32_t EVENT_CHECK_CREATURE_INTERVAL = (EVENT_CREATURE_THINK_INTERVAL / EVENT_CREATURECOUNT); +static int32_t EVENT_CREATURE_PATH_INTERVAL = g_config.getNumber(ConfigManager::PATHFINDING_INTERVAL); +static int32_t EVENT_CREATURE_PATH_DELAY = g_config.getNumber(ConfigManager::PATHFINDING_DELAY); + class FrozenPathingConditionCall { public: @@ -274,7 +280,7 @@ class Creature : virtual public Thing virtual void onFollowCreatureComplete(const Creature*) {} // Pathfinding functions - virtual void addFollowedByCreature(Creature * creature); + virtual void addFollowedByCreature(Creature* creature) { followedByCreatures.push_back(creature); }; // Pathfinding events void updateFollowingCreaturesPath(); @@ -514,6 +520,7 @@ class Creature : virtual public Thing std::list followedByCreatures; uint64_t lastStep = 0; + int64_t lastPathUpdate = 0; uint32_t referenceCounter = 0; uint32_t id = 0; uint32_t scriptEventsBitField = 0; diff --git a/src/map.cpp b/src/map.cpp index 49a0f515..8e49807b 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -691,6 +691,12 @@ bool Map::getPathMatching(const Creature& creature, const Position& targetPos, s } } + // Don't update path. Target in not in the viewport. + if (Position::getDistanceX(startPos, targetPos) > Map::maxViewportX + 1 || + Position::getDistanceY(startPos, targetPos) > Map::maxViewportY + 1) { + return false; + } + // Dont update path. We are on top of our target position. Let dance step decide. if (startPos.x == targetPos.x && startPos.y == targetPos.y) { return false; @@ -708,7 +714,7 @@ bool Map::getPathMatching(const Creature& creature, const Position& targetPos, s while (n) { iterations++; - if (iterations >= 250) { + if (iterations >= 200) { return false; } @@ -737,10 +743,6 @@ bool Map::getPathMatching(const Creature& creature, const Position& targetPos, s continue; } - if (Position::getDistanceX(pos, startPos) >= 20 || Position::getDistanceY(pos, startPos) >= 20) { - return false; - } - const Tile* tile; AStarNode* neighborNode = nodes.getNodeByPosition(pos.x, pos.y); if (neighborNode) {