Browse Source

Use bound parameters for pathfinding functions operating on entities

pull/2406/head
ephphatha 5 years ago committed by Anders Jenbo
parent
commit
190025e79f
  1. 2
      Source/controls/plrctrls.cpp
  2. 4
      Source/monster.cpp
  3. 8
      Source/path.cpp
  4. 6
      Source/path.h
  5. 11
      Source/player.cpp

2
Source/controls/plrctrls.cpp

@ -91,7 +91,7 @@ int GetDistance(Point destination, int maxDistance)
}
int8_t walkpath[MAX_PATH_LENGTH];
int steps = FindPath(PosOkPlayer, MyPlayerId, Players[MyPlayerId].position.future.x, Players[MyPlayerId].position.future.y, destination.x, destination.y, walkpath);
int steps = FindPath(std::bind(PosOkPlayer, MyPlayerId, std::placeholders::_1), Players[MyPlayerId].position.future.x, Players[MyPlayerId].position.future.y, destination.x, destination.y, walkpath);
if (steps > maxDistance)
return 0;

4
Source/monster.cpp

@ -2140,7 +2140,7 @@ bool AiPlanWalk(int i)
assert((DWORD)i < MAXMONSTERS);
auto &monster = Monsters[i];
if (FindPath(MonsterIsTileAccessible, i, monster.position.tile.x, monster.position.tile.y, monster.enemyPosition.x, monster.enemyPosition.y, path) == 0) {
if (FindPath(std::bind(MonsterIsTileAccessible, i, std::placeholders::_1), monster.position.tile.x, monster.position.tile.y, monster.enemyPosition.x, monster.enemyPosition.y, path) == 0) {
return false;
}
@ -2207,7 +2207,7 @@ bool AiPlanPath(int i)
}
bool clear = LineClear(
std::bind(MonsterIsTileAvalible, i, std::placeholders::_1),
std::bind(MonsterIsTileAvailable, i, std::placeholders::_1),
monster.position.tile,
monster.enemyPosition);
if (!clear || (monster._pathcount >= 5 && monster._pathcount < 8)) {

8
Source/path.cpp

@ -61,7 +61,7 @@ int8_t path_directions[9] = { 5, 1, 6, 2, 0, 3, 8, 4, 7 };
* check that each step is a valid position. Store the step directions (see
* path_directions) in path, which must have room for 24 steps
*/
int FindPath(bool (*posOk)(int, Point), int posOkArg, int sx, int sy, int dx, int dy, int8_t path[MAX_PATH_LENGTH])
int FindPath(const std::function<bool(Point)> &posOk, int sx, int sy, int dx, int dy, int8_t path[MAX_PATH_LENGTH])
{
// clear all nodes, create root nodes for the visited/frontier linked lists
gdwCurNodes = 0;
@ -97,7 +97,7 @@ int FindPath(bool (*posOk)(int, Point), int posOkArg, int sx, int sy, int dx, in
return 0;
}
// ran out of nodes, abort!
if (!path_get_path(posOk, posOkArg, nextNode, dx, dy))
if (!path_get_path(posOk, nextNode, dx, dy))
return 0;
}
// frontier is empty, no path!
@ -187,11 +187,11 @@ bool path_solid_pieces(PATHNODE *pPath, int dx, int dy)
*
* @return false if we ran out of preallocated nodes to use, else true
*/
bool path_get_path(bool (*posOk)(int, Point), int posOkArg, PATHNODE *pPath, int x, int y)
bool path_get_path(const std::function<bool(Point)> &posOk, PATHNODE *pPath, int x, int y)
{
for (auto dir : PathDirs) {
Point tile = pPath->position + dir;
bool ok = posOk(posOkArg, tile);
bool ok = posOk(tile);
if ((ok && path_solid_pieces(pPath, tile.x, tile.y)) || (!ok && tile == Point { x, y })) {
if (!path_parent_path(pPath, tile.x, tile.y, x, y))
return false;

6
Source/path.h

@ -5,6 +5,8 @@
*/
#pragma once
#include <functional>
#include <SDL.h>
#include "engine/direction.hpp"
@ -24,11 +26,11 @@ struct PATHNODE {
struct PATHNODE *NextNode;
};
int FindPath(bool (*PosOk)(int, Point), int PosOkArg, int sx, int sy, int dx, int dy, int8_t path[MAX_PATH_LENGTH]);
int FindPath(const std::function<bool(Point)> &posOk, int sx, int sy, int dx, int dy, int8_t path[MAX_PATH_LENGTH]);
int path_get_h_cost(int sx, int sy, int dx, int dy);
PATHNODE *GetNextPath();
bool path_solid_pieces(PATHNODE *pPath, int dx, int dy);
bool path_get_path(bool (*PosOk)(int, Point), int PosOkArg, PATHNODE *pPath, int x, int y);
bool path_get_path(const std::function<bool(Point)> &posOk, PATHNODE *pPath, int x, int y);
bool path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy);
PATHNODE *path_get_node1(int dx, int dy);
PATHNODE *path_get_node2(int dx, int dy);

11
Source/player.cpp

@ -3489,6 +3489,15 @@ void ClrPlrPath(PlayerStruct &player)
memset(player.walkpath, WALK_NONE, sizeof(player.walkpath));
}
/**
* @brief Determines if the target position is clear for the given player to stand on.
*
* This requires an ID instead of a PlayerStruct& to compare with the dPlayer lookup table values.
*
* @param pnum ID of the player.
* @param position Dungeon tile coordinates.
* @return False if something (other than the player themselves) is blocking the tile.
*/
bool PosOkPlayer(int pnum, Point position)
{
if (position.x < 0 || position.x >= MAXDUNX || position.y < 0 || position.y >= MAXDUNY)
@ -3550,7 +3559,7 @@ void MakePlrPath(int pnum, Point targetPosition, bool endspace)
return;
}
int path = FindPath(PosOkPlayer, pnum, player.position.future.x, player.position.future.y, targetPosition.x, targetPosition.y, player.walkpath);
int path = FindPath(std::bind(PosOkPlayer, pnum, std::placeholders::_1), player.position.future.x, player.position.future.y, targetPosition.x, targetPosition.y, player.walkpath);
if (path == 0) {
return;
}

Loading…
Cancel
Save