[Scummvm-cvs-logs] SF.net SVN: scummvm:[39714] scummvm/trunk/engines/sci/engine/kpathing.cpp

waltervn at users.sourceforge.net waltervn at users.sourceforge.net
Sat Mar 28 00:01:14 CET 2009


Revision: 39714
          http://scummvm.svn.sourceforge.net/scummvm/?rev=39714&view=rev
Author:   waltervn
Date:     2009-03-27 23:01:13 +0000 (Fri, 27 Mar 2009)

Log Message:
-----------
SCI: AvoidPath workaround for intersecting polygons in Longbow, room 210.

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/kpathing.cpp

Modified: scummvm/trunk/engines/sci/engine/kpathing.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kpathing.cpp	2009-03-27 21:31:03 UTC (rev 39713)
+++ scummvm/trunk/engines/sci/engine/kpathing.cpp	2009-03-27 23:01:13 UTC (rev 39714)
@@ -126,7 +126,18 @@
 
 typedef Common::List<Vertex *> VertexList;
 
+/* Circular list definitions. */
 
+#define CLIST_FOREACH(var, head)					\
+	for ((var) = (head)->first();					\
+		(var);							\
+		(var) = ((var)->_next == (head)->first() ?	\
+		    NULL : (var)->_next))
+
+/* Circular list access methods. */
+#define CLIST_NEXT(elm)		((elm)->_next)
+#define CLIST_PREV(elm)		((elm)->_prev)
+
 class CircularVertexList {
 public:
 	Vertex *_head;
@@ -134,7 +145,7 @@
 public:
 	CircularVertexList() : _head(0) {}
 	
-	Vertex *first() {
+	Vertex *first() const {
 		return _head;
 	}
 	
@@ -172,6 +183,14 @@
 		return _head == NULL;
 	}
 
+	uint size() const {
+		int n = 0;
+		Vertex *v;
+		CLIST_FOREACH(v, this)
+			++n;
+		return n;
+	}
+
 	/**
 	 * Reverse the order of the elements in this circular list.
 	 */
@@ -187,19 +206,6 @@
 	}
 };
 
-/* Circular list definitions. */
-
-#define CLIST_FOREACH(var, head)					\
-	for ((var) = (head)->first();					\
-		(var);							\
-		(var) = ((var)->_next == (head)->first() ?	\
-		    NULL : (var)->_next))
-
-/* Circular list access methods. */
-#define CLIST_NEXT(elm)		((elm)->_next)
-#define CLIST_PREV(elm)		((elm)->_prev)
-
-
 struct Polygon {
 	// SCI polygon type
 	int type;
@@ -1217,6 +1223,56 @@
 	return poly;
 }
 
+// WORKAROUND: intersecting polygons in Longbow, room 210.
+static void fixLongbowRoom210(PathfindingState *s, const Common::Point &start, const Common::Point &end) {
+	Polygon *barred = NULL;
+	Polygon *total = NULL;
+
+	// Find the intersecting polygons
+	for (PolygonList::iterator it = s->polygons.begin(); it != s->polygons.end(); ++it) {
+		Polygon *polygon = *it;
+		assert(polygon);
+
+		if ((polygon->type == POLY_BARRED_ACCESS) && (polygon->vertices.size() == 11)
+		&& (polygon->vertices.first()->v == Common::Point(319, 161)))
+			barred = polygon;
+		else if ((polygon->type == POLY_TOTAL_ACCESS) && (polygon->vertices.size() == 8)
+		&& (polygon->vertices.first()->v == Common::Point(313, 58)))
+			total = polygon;
+	}
+
+	if (!barred || !total)
+		return;
+
+	debug(1, "[avoidpath] Applying fix for intersecting polygons in Longbow, room 210");
+
+	// If the start or end point is contained in the total access polygon, removing that
+	// polygon is sufficient. Otherwise we merge the total and barred access polygons.
+	bool both_outside = (contained(start, total) == CONT_OUTSIDE) && (contained(end, total) == CONT_OUTSIDE);
+
+	s->polygons.remove(total);
+	delete total;
+
+	if (both_outside) {
+		int points[28] = {
+			224, 159, 223, 162 ,194, 173 ,107, 173, 74, 162, 67, 156, 2, 58,
+			63, 160, 0, 160, 0, 0, 319, 0, 319, 161, 228, 161, 313, 58
+		};
+
+		s->polygons.remove(barred);
+		delete barred;
+
+		barred = new Polygon(POLY_BARRED_ACCESS);
+
+		for (int i = 0; i < 14; i++) {
+			Vertex *vertex = new Vertex(Common::Point(points[i * 2], points[i * 2 + 1]));
+			barred->vertices.insertHead(vertex);
+		}
+
+		s->polygons.push_front(barred);
+	}
+}
+
 static void change_polygons_opt_0(PathfindingState *s) {
 	// Changes the polygon list for optimization level 0 (used for keyboard
 	// support). Totally accessible polygons are removed and near-point
@@ -1275,7 +1331,7 @@
 			if (dup == node) {
 				// Polygon is not a duplicate, so convert it
 				polygon = convert_polygon(s, node->value);
-				pf_s->polygons.push_front(polygon);
+				pf_s->polygons.push_back(polygon);
 				count += KP_UINT(GET_SEL32(node->value, size));
 			}
 
@@ -1321,6 +1377,12 @@
 			pf_s->_appendPoint = new Common::Point(end);
 	}
 
+	if (s->_gameName == "Longbow") {
+		// FIXME: implement function to get current room number
+		if ((KP_UINT(s->script_000->locals_block->locals[13]) == 210))
+			fixLongbowRoom210(pf_s, new_start, new_end);
+	}
+
 	// Merge start and end points into polygon set
 	pf_s->vertex_start = merge_point(pf_s, new_start);
 	pf_s->vertex_end = merge_point(pf_s, new_end);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list