Browse Source

Added functions to AStar for disable/enable points

(cherry picked from commit cc71fb2308b04f6fab67490e99d0fb0ea1251031)
Chaosus 6 years ago
parent
commit
9535a6079e
3 changed files with 46 additions and 0 deletions
  1. 22 0
      core/math/a_star.cpp
  2. 4 0
      core/math/a_star.h
  3. 20 0
      doc/classes/AStar.xml

+ 22 - 0
core/math/a_star.cpp

@@ -55,6 +55,7 @@ void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) {
 		pt->weight_scale = p_weight_scale;
 		pt->prev_point = NULL;
 		pt->last_pass = 0;
+		pt->enabled = true;
 		points[p_id] = pt;
 	} else {
 		points[p_id]->pos = p_pos;
@@ -242,6 +243,9 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
 
 	pass++;
 
+	if (!end_point->enabled)
+		return false;
+
 	SelfList<Point>::List open_list;
 
 	bool found_route = false;
@@ -249,6 +253,10 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
 	for (Set<Point *>::Element *E = begin_point->neighbours.front(); E; E = E->next()) {
 
 		Point *n = E->get();
+
+		if (!n->enabled)
+			continue;
+
 		n->prev_point = begin_point;
 		n->distance = _compute_cost(begin_point->id, n->id) * n->weight_scale;
 		n->last_pass = pass;
@@ -290,6 +298,9 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
 
 			Point *e = E->get();
 
+			if (!e->enabled)
+				continue;
+
 			real_t distance = _compute_cost(p->id, e->id) * e->weight_scale + p->distance;
 
 			if (e->last_pass == pass) {
@@ -438,6 +449,14 @@ PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
 	return path;
 }
 
+void AStar::set_point_disabled(int p_id, bool p_disabled) {
+	points[p_id]->enabled = !p_disabled;
+}
+
+bool AStar::is_point_disabled(int p_id) const {
+	return !points[p_id]->enabled;
+}
+
 void AStar::_bind_methods() {
 
 	ClassDB::bind_method(D_METHOD("get_available_point_id"), &AStar::get_available_point_id);
@@ -450,6 +469,9 @@ void AStar::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar::has_point);
 	ClassDB::bind_method(D_METHOD("get_points"), &AStar::get_points);
 
+	ClassDB::bind_method(D_METHOD("set_point_disabled", "id", "disabled"), &AStar::set_point_disabled, DEFVAL(true));
+	ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar::is_point_disabled);
+
 	ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar::get_point_connections);
 
 	ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id", "bidirectional"), &AStar::connect_points, DEFVAL(true));

+ 4 - 0
core/math/a_star.h

@@ -54,6 +54,7 @@ class AStar : public Reference {
 		Vector3 pos;
 		real_t weight_scale;
 		uint64_t last_pass;
+		bool enabled;
 
 		Set<Point *> neighbours;
 
@@ -114,6 +115,9 @@ public:
 	PoolVector<int> get_point_connections(int p_id);
 	Array get_points();
 
+	void set_point_disabled(int p_id, bool p_disabled = true);
+	bool is_point_disabled(int p_id) const;
+
 	void connect_points(int p_id, int p_with_id, bool bidirectional = true);
 	void disconnect_points(int p_id, int p_with_id);
 	bool are_points_connected(int p_id, int p_with_id) const;

+ 20 - 0
doc/classes/AStar.xml

@@ -224,6 +224,15 @@
 				Returns whether a point associated with the given id exists.
 			</description>
 		</method>
+		<method name="is_point_disabled" qualifiers="const">
+			<return type="bool">
+			</return>
+			<argument index="0" name="id" type="int">
+			</argument>
+			<description>
+				Returns whether a point is disabled or not for pathfinding. By default, all points are enabled.
+			</description>
+		</method>
 		<method name="remove_point">
 			<return type="void">
 			</return>
@@ -233,6 +242,17 @@
 				Removes the point associated with the given id from the points pool.
 			</description>
 		</method>
+		<method name="set_point_disabled">
+			<return type="void">
+			</return>
+			<argument index="0" name="id" type="int">
+			</argument>
+			<argument index="1" name="disabled" type="bool" default="true">
+			</argument>
+			<description>
+				Disables or enables the specified point for pathfinding. Useful for making a temporary obstacle.
+			</description>
+		</method>
 		<method name="set_point_position">
 			<return type="void">
 			</return>