Skip to content

Commit

Permalink
Add ability to check sight path that is false when fully blocked
Browse files Browse the repository at this point in the history
  • Loading branch information
NRH-AA committed Apr 5, 2024
1 parent 4d9dcda commit ead7840
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,12 @@ void Creature::onAttacking(uint32_t interval)
if (g_game.isSightClear(getPosition(), attackedCreature->getPosition(), true)) {
doAttacking(interval);
} else if (getMonster()) {
getMonster()->updateLookDirection();
FindPathParams fpp;
getPathSearchParams(attackedCreature, fpp);

if (g_game.map.getPathMatchingSight(*this, attackedCreature->getPosition(), fpp)) {
getMonster()->updateLookDirection();
}
}
}

Expand Down
127 changes: 127 additions & 0 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,133 @@ bool Map::getPathMatching(const Creature& creature, std::vector<Direction>& dirL
return true;
}

bool Map::getPathMatchingSight(const Creature& creature, const Position& targetPos, const FindPathParams& fpp) const
{
Position pos = creature.getPosition();

AStarNodes nodes(pos.x, pos.y);

int32_t bestMatch = 0;

Check failure on line 831 in src/map.cpp

View workflow job for this annotation

GitHub Actions / test

unused variable ‘bestMatch’ [-Werror=unused-variable]

Check failure on line 831 in src/map.cpp

View workflow job for this annotation

GitHub Actions / ubuntu-Debug-luajit=off

unused variable ‘bestMatch’ [-Werror=unused-variable]

static int_fast32_t dirNeighbors[8][5][2] = {
{{-1, 0}, {0, 1}, {1, 0}, {1, 1}, {-1, 1}}, {{-1, 0}, {0, 1}, {0, -1}, {-1, -1}, {-1, 1}},
{{-1, 0}, {1, 0}, {0, -1}, {-1, -1}, {1, -1}}, {{0, 1}, {1, 0}, {0, -1}, {1, -1}, {1, 1}},
{{1, 0}, {0, -1}, {-1, -1}, {1, -1}, {1, 1}}, {{-1, 0}, {0, -1}, {-1, -1}, {1, -1}, {-1, 1}},
{{0, 1}, {1, 0}, {1, -1}, {1, 1}, {-1, 1}}, {{-1, 0}, {0, 1}, {-1, -1}, {1, 1}, {-1, 1}}};
static int_fast32_t allNeighbors[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, -1}, {1, -1}, {1, 1}, {-1, 1}};

const Position startPos = pos;

AStarNode* found = nullptr;
while (fpp.maxSearchDist != 0 || nodes.getClosedNodes() < 100) {
AStarNode* n = nodes.getBestNode();
if (!n) {
if (found) {
break;
}
return false;
}

const int_fast32_t x = n->x;
const int_fast32_t y = n->y;
pos.x = x;
pos.y = y;
if (pos.x == targetPos.x && pos.y == targetPos.y) {
found = n;
break;
}

uint_fast32_t dirCount;
int_fast32_t* neighbors;
if (n->parent) {
const int_fast32_t offset_x = n->parent->x - x;
const int_fast32_t offset_y = n->parent->y - y;
if (offset_y == 0) {
if (offset_x == -1) {
neighbors = *dirNeighbors[DIRECTION_WEST];
} else {
neighbors = *dirNeighbors[DIRECTION_EAST];
}
} else if (!fpp.allowDiagonal || offset_x == 0) {
if (offset_y == -1) {
neighbors = *dirNeighbors[DIRECTION_NORTH];
} else {
neighbors = *dirNeighbors[DIRECTION_SOUTH];
}
} else if (offset_y == -1) {
if (offset_x == -1) {
neighbors = *dirNeighbors[DIRECTION_NORTHWEST];
} else {
neighbors = *dirNeighbors[DIRECTION_NORTHEAST];
}
} else if (offset_x == -1) {
neighbors = *dirNeighbors[DIRECTION_SOUTHWEST];
} else {
neighbors = *dirNeighbors[DIRECTION_SOUTHEAST];
}
dirCount = fpp.allowDiagonal ? 5 : 3;
} else {
dirCount = 8;
neighbors = *allNeighbors;
}

const int_fast32_t f = n->f;
for (uint_fast32_t i = 0; i < dirCount; ++i) {
pos.x = x + *neighbors++;
pos.y = y + *neighbors++;

if (fpp.maxSearchDist != 0 && (Position::getDistanceX(startPos, pos) > fpp.maxSearchDist ||
Position::getDistanceY(startPos, pos) > fpp.maxSearchDist)) {
continue;
}

const Tile* tile;
AStarNode* neighborNode = nodes.getNodeByPosition(pos.x, pos.y);
const Tile* tile = getTile(pos.x, pos.y, pos.z);

Check failure on line 907 in src/map.cpp

View workflow job for this annotation

GitHub Actions / test

redeclaration of ‘const Tile* tile’

Check failure on line 907 in src/map.cpp

View workflow job for this annotation

GitHub Actions / ubuntu-Debug-luajit=off

redeclaration of ‘const Tile* tile’
if (!tile) {
continue;
}

if (tile->hasProperty(CONST_PROP_BLOCKSOLID)) {
continue;
}

// The cost (g) for this neighbor
const int_fast32_t cost = AStarNodes::getMapWalkCost(n, pos);
const int_fast32_t extraCost = AStarNodes::getTileWalkCost(creature, tile);
const int_fast32_t newf = f + cost + extraCost;

if (neighborNode) {
if (neighborNode->f <= newf) {
// The node on the closed/open list is cheaper than this one
continue;
}

neighborNode->f = newf;
neighborNode->parent = n;
nodes.openNode(neighborNode);
} else {
// Does not exist in the open/closed list, create a new node
neighborNode = nodes.createOpenNode(n, pos.x, pos.y, newf);
if (!neighborNode) {
if (found) {
break;
}
return false;
}
}
}

nodes.closeNode(n);
}

if (!found) {
return false;
}

return true;
}

// AStarNodes

AStarNodes::AStarNodes(uint32_t x, uint32_t y) : nodes(), openNodes()
Expand Down
2 changes: 2 additions & 0 deletions src/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,9 @@ class Map
void getSpectatorsInternal(SpectatorVec& spectators, const Position& centerPos, int32_t minRangeX,
int32_t maxRangeX, int32_t minRangeY, int32_t maxRangeY, int32_t minRangeZ,
int32_t maxRangeZ, bool onlyPlayers) const;
bool getPathMatchingSight(const Creature& creature, const Position& targetPos, const FindPathParams& fpp) const;

friend class Creature;
friend class Game;
friend class IOMap;
};
Expand Down

0 comments on commit ead7840

Please sign in to comment.