scummvm/engines/crab/PathfindingAgent.h
2023-08-10 17:06:59 +02:00

220 lines
5.7 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* This code is based on the CRAB engine
*
* Copyright (c) Arvind Raja Yadav
*
* Licensed under MIT
*
*/
#ifndef CRAB_PATHFINDINGAGENT_H
#define CRAB_PATHFINDINGAGENT_H
#include "common/stablemap.h"
#include "crab/PathfindingGrid.h"
#include "crab/PriorityQueue.h"
#include "crab/vectors.h"
namespace Crab {
// This class represents the actual pathfinding and following agent that utilizes
// the pathfinding grid
class PlannerNode {
PlannerNode *_parent;
PlannerNode *_child;
double _cost; // Heuristic cost equivalent to cost to reach goal from planner node's position.
double _finalCost; // Final cost of route through the planner node. Used to determine optimal path.
double _givenCost; // The current distance of the route.
public:
PathfindingGraphNode *_location;
PlannerNode() {
_location = nullptr;
_parent = nullptr;
_child = nullptr;
_cost = 0;
_finalCost = 0;
_givenCost = 0;
}
~PlannerNode() {}
PathfindingGraphNode *getLocation() {
return _location;
}
PlannerNode *getParent() {
return _parent;
}
PlannerNode *getChild() {
return _child;
}
double getHCost() const {
return _cost;
}
double getFinalCost() const {
return _finalCost;
}
double getGivenCost() const {
return _givenCost;
}
void setLocation(PathfindingGraphNode *loc) {
_location = loc;
}
void setParent(PlannerNode *p) {
_parent = p;
}
void setChild(PlannerNode *c) {
_child = c;
}
void setHCost(double c) {
_cost = c;
}
void setFinalCost(double c) {
_finalCost = c;
}
void setGivenCost(double c) {
_givenCost = c;
}
};
class PathfindingAgent {
Vector2f _position;
Vector2f _prevPosition; // Used to determine that we are making progress toward the goal
Vector2i _immediateDest; // The next stop on the AI's path
bool _destinationSet; // Was a destination specified.
bool _destinationReachable; // Can the agent actually get to the destination?
float _nodeBufferDistance; // How much leeway is there for reaching the destination
public:
PathfindingAgent();
~PathfindingAgent();
PathfindingGrid *_grid;
Vector2f _destination;
PathfindingGraphNode *_startTile; // The system originally used tiles, but this one uses discreet points.
PathfindingGraphNode *_goalTile; // The tile we are trying to reach. May not be the tile that was clicked if the clicked tile is blocked.
PathfindingGraphNode *_clickedTile; // The tile that was clicked. If it is open, it will be the goal node.
bool _solutionFound;
bool _noSolution;
Common::Array<PathfindingGraphNode const *> _vSolution;
void setNodeBufferDistance(float w) {
_nodeBufferDistance = w;
}
float getNodeBufferDistance() {
return _nodeBufferDistance;
}
// Added for Greedy search
double distSquared(PathfindingGraphNode *tileA, PathfindingGraphNode *tileB);
// Added for A* search
double distExact(PathfindingGraphNode *tileA, PathfindingGraphNode *tileB);
PriorityQueue<PlannerNode> _nodeQueue;
Common::StableMap<PathfindingGraphNode *, PlannerNode *> _createdList;
// void SetSprite(pyrodactyl::anim::Sprite* s){entitySprite = s;}
//! \brief Sets the tile map.
//!
//! Invoked when the user opens a tile map file.
//!
//! \param _tileMap the data structure that this algorithm will use
//! to access each tile's location and weight data.
void initialize(PathfindingGrid *g);
void setDestination(Vector2f d);
void setDestination(Vector2f d, bool r);
void setDestination(Vector2i d);
void setDestination(Vector2i d, bool r);
void setPosition(Vector2f p) {
_position = p;
}
void setPrevPosition(Vector2f p) {
_prevPosition = p;
}
Vector2f getPosition() {
return _position;
}
bool positionChanged() {
return _position != _prevPosition;
}
Vector2i getImmediateDest() {
return _immediateDest;
}
//! \brief Performs the main part of the algorithm until the specified time has elapsed or
//! no nodes are left open.
void update(uint32 timeslice);
//! \brief Returns <code>true</code> if and only if no nodes are left open.
//!
//! \return <code>true</code> if no nodes are left open, <code>false</code> otherwise.
bool isDone() const;
//! \brief Returns an unmodifiable view of the solution path found by this algorithm.
Common::Array<PathfindingGraphNode const *> const getSolution(PathfindingGraphNode *destNode) const;
// Get the solution removing any nodes that are completely surrounded by open space.
// This will result in a more linear path to the goal.
Common::Array<PathfindingGraphNode const *> const getPrunedSolution(PathfindingGraphNode *destNode);
//! \brief Resets the algorithm.
void reset();
//! \brief Uninitializes the algorithm before the tile map is unloaded.
void shutdown();
// Returns true if the node connects to the goal node
bool adjacentToGoal(PathfindingGraphNode *node);
};
} // End of namespace Crab
#endif // CRAB_PATHFINDINGAGENT_H