aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine/kpathing.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine/kpathing.cpp')
-rw-r--r--engines/sci/engine/kpathing.cpp25
1 files changed, 17 insertions, 8 deletions
diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp
index faf966af92..2b3b7f8f01 100644
--- a/engines/sci/engine/kpathing.cpp
+++ b/engines/sci/engine/kpathing.cpp
@@ -938,7 +938,7 @@ static Common::Point *fixup_start_point(PathfindingState *s, const Common::Point
// Fall through
case POLY_BARRED_ACCESS:
case POLY_NEAREST_ACCESS:
- if (cont == CONT_INSIDE) {
+ if (cont != CONT_OUTSIDE) {
if (s->_prependPoint != NULL) {
// We shouldn't get here twice.
// We need to break in this case, otherwise we'll end in an infinite
@@ -958,7 +958,8 @@ static Common::Point *fixup_start_point(PathfindingState *s, const Common::Point
// The original start position is in an invalid location, so we
// use the moved point and add the original one to the final path
// later on.
- s->_prependPoint = new Common::Point(start);
+ if (start != *new_start)
+ s->_prependPoint = new Common::Point(start);
}
}
@@ -1014,7 +1015,7 @@ static Common::Point *fixup_end_point(PathfindingState *s, const Common::Point &
// For near-point access polygons we need to add the original end point
// to the path after pathfinding.
- if (type == POLY_NEAREST_ACCESS)
+ if ((type == POLY_NEAREST_ACCESS) && (end != *new_end))
s->_appendPoint = new Common::Point(end);
}
}
@@ -1311,6 +1312,8 @@ static void AStar(PathfindingState *s) {
}
}
+ assert(vertex_min != 0); // the vertex cost should never be bigger than HUGE_DISTANCE
+
// Check if we are done
if (vertex_min == s->vertex_end)
break;
@@ -1328,15 +1331,21 @@ static void AStar(PathfindingState *s) {
if (closedSet.contains(vertex))
continue;
- // Avoid plotting path along screen edge
- if ((vertex_min != s->vertex_start) || (vertex != s->vertex_end))
- if (s->pointOnScreenBorder(vertex_min->v) && s->pointOnScreenBorder(vertex->v))
- continue;
-
if (!openSet.contains(vertex))
openSet.push_front(vertex);
new_dist = vertex_min->costG + (uint32)sqrt((float)vertex_min->v.sqrDist(vertex->v));
+
+ // When travelling to a vertex on the screen edge, we
+ // add a penalty score to make this path less appealing.
+ // NOTE: If an obstacle has only one vertex on a screen edge,
+ // later SSCI pathfinders will treat that vertex like any
+ // other, while we apply a penalty to paths traversing it.
+ // This difference might lead to problems, but none are
+ // known at the time of writing.
+ if (s->pointOnScreenBorder(vertex->v))
+ new_dist += 10000;
+
if (new_dist < vertex->costG) {
vertex->costG = new_dist;
vertex->costF = vertex->costG + (uint32)sqrt((float)vertex->v.sqrDist(s->vertex_end->v));