diff --git a/src/creature.cpp b/src/creature.cpp index 2b6bf1c9..feb615bd 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -1012,7 +1012,7 @@ bool Creature::setFollowCreature(Creature* creature) onWalkAborted(); } - hasFollowPath = false; + //hasFollowPath = false; followCreature = creature; creature->addFollowedByCreature(this); g_dispatcher.addTask(createTask([id = getID()]() { g_game.updateCreatureWalk(id); })); diff --git a/src/creature.h b/src/creature.h index 8c0471de..27ddb6ba 100644 --- a/src/creature.h +++ b/src/creature.h @@ -68,8 +68,8 @@ class Item; class Tile; static constexpr int32_t EVENT_CREATURECOUNT = 10; -static constexpr int32_t EVENT_CREATURE_THINK_INTERVAL = 200; -static constexpr int32_t EVENT_CREATURE_PATH_INTERVAL = 200; +static constexpr int32_t EVENT_CREATURE_THINK_INTERVAL = 1000; +static constexpr int32_t EVENT_CREATURE_PATH_INTERVAL = 2000; static constexpr int32_t EVENT_CHECK_CREATURE_INTERVAL = (EVENT_CREATURE_THINK_INTERVAL / EVENT_CREATURECOUNT); class FrozenPathingConditionCall diff --git a/src/map.cpp b/src/map.cpp index 0cbf1fbd..49a0f515 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -752,10 +752,10 @@ bool Map::getPathMatching(const Creature& creature, const Position& targetPos, s } } - const float walkCost = AStarNodes::getMapWalkCost(n, pos); - const float tileCost = AStarNodes::getTileWalkCost(creature, tile); - const float newf = n->f + walkCost + tileCost; - const float distEnd = Position::getDistanceX(pos, targetPos) + Position::getDistanceY(pos, targetPos) + newf; + // The cost to walk to this neighbor + const double g = n->g + AStarNodes::getMapWalkCost(n, pos) + AStarNodes::getTileWalkCost(creature, tile); + const double h = AStarNodes::calculateHeuristic(pos, targetPos); + const double newf = h + g; if (neighborNode) { if (neighborNode->f <= newf) { @@ -763,14 +763,14 @@ bool Map::getPathMatching(const Creature& creature, const Position& targetPos, s continue; } + neighborNode->g = g; neighborNode->f = newf; - neighborNode->h = distEnd; neighborNode->parent = n; nodes.addNode(neighborNode); } else { // Does not exist in the open/closed list, create a new node - nodes.createNewNode(n, pos.x, pos.y, distEnd, newf); + nodes.createNewNode(n, pos.x, pos.y, g, newf); } } @@ -827,7 +827,7 @@ AStarNodes::AStarNodes(uint16_t x, uint16_t y) : nodes(), nodeMap() firstNode->parent = nullptr; firstNode->x = x; firstNode->y = y; - firstNode->h = 0; + firstNode->g = 0; firstNode->f = 0; // Add node to node vector and map @@ -836,13 +836,13 @@ AStarNodes::AStarNodes(uint16_t x, uint16_t y) : nodes(), nodeMap() nodeMap[x][y] = firstNode; } -void AStarNodes::createNewNode(AStarNode* parent, uint16_t x, uint16_t y, float h, float f) +void AStarNodes::createNewNode(AStarNode* parent, uint16_t x, uint16_t y, double g, double f) { AStarNode* newNode = new AStarNode; newNode->parent = parent; newNode->x = x; newNode->y = y; - newNode->h = h; + newNode->g = g; newNode->f = f; nodes.push_back(newNode); @@ -855,13 +855,20 @@ AStarNode* AStarNodes::getBestNode() return nullptr; } - std::sort(nodes.begin(), nodes.end(), [](AStarNode* left, AStarNode* right) {return left->h > right->h; }); + std::sort(nodes.begin(), nodes.end(), [](AStarNode* left, AStarNode* right) { return left->f > right->f; }); AStarNode* retNode = nodes.back(); nodes.pop_back(); return retNode; } -float AStarNodes::getMapWalkCost(AStarNode* node, const Position& neighborPos) +double AStarNodes::calculateHeuristic(const Position& p1, const Position& p2) +{ + uint16_t dx = std::abs(p1.x - p2.x); + uint16_t dy = std::abs(p1.y - p2.y); + return std::sqrt((dx * dx) + (dy * dy)); +} + +double AStarNodes::getMapWalkCost(AStarNode* node, const Position& neighborPos) { if (std::abs(node->x - neighborPos.x) == std::abs(node->y - neighborPos.y)) { // diagonal movement extra cost @@ -870,9 +877,9 @@ float AStarNodes::getMapWalkCost(AStarNode* node, const Position& neighborPos) return MAP_NORMALWALKCOST; } -float AStarNodes::getTileWalkCost(const Creature& creature, const Tile* tile) +double AStarNodes::getTileWalkCost(const Creature& creature, const Tile* tile) { - float cost = 0; + double cost = 0; if (tile->getTopVisibleCreature(&creature)) { // destroy creature cost cost += MAP_NORMALWALKCOST * 3; diff --git a/src/map.h b/src/map.h index a951b38f..ef10131d 100644 --- a/src/map.h +++ b/src/map.h @@ -40,29 +40,30 @@ static constexpr int32_t MAP_MAX_LAYERS = 16; struct FindPathParams; -static constexpr float MAP_NORMALWALKCOST = 1.0f; -static constexpr float MAP_DIAGONALWALKCOST = 2.5f; - struct AStarNode { AStarNode* parent; - float h; - float f; + double g; + double f; uint16_t x, y; }; +static constexpr float MAP_NORMALWALKCOST = 1.0f; +static constexpr float MAP_DIAGONALWALKCOST = 2.5f; + class AStarNodes { public: AStarNodes(uint16_t x, uint16_t y); - void createNewNode(AStarNode* parent, uint16_t x, uint16_t y, float h, float f); + void createNewNode(AStarNode* parent, uint16_t x, uint16_t y, double g, double f); void addNode(AStarNode* node) { nodes.push_back(node); }; AStarNode* getBestNode(); AStarNode* getNodeByPosition(uint16_t x, uint16_t y) { return nodeMap[x][y]; }; - static float getMapWalkCost(AStarNode* node, const Position& neighborPos); - static float getTileWalkCost(const Creature& creature, const Tile* tile); + static double calculateHeuristic(const Position& p1, const Position& p2); + static double getMapWalkCost(AStarNode* node, const Position& neighborPos); + static double getTileWalkCost(const Creature& creature, const Tile* tile); private: std::vector nodes; diff --git a/src/monster.cpp b/src/monster.cpp index d65dd6b7..78e3f23f 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -884,6 +884,7 @@ void Monster::doAttacking(uint32_t interval) } } + // ensure ranged creatures turn to player if (updateLook && lastMeleeAttack == 0 && !isFleeing()) { updateLookDirection(); }