mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
220 lines
5.7 KiB
C++
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
|