[Scummvm-git-logs] scummvm master -> 535034d6b96e2adc6c189fce0a5cf7d5fd618224

yinsimei roseline.yin at gmail.com
Tue May 1 18:43:29 CEST 2018


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
535034d6b9 SLUDGE: Objectify FloorManager


Commit: 535034d6b96e2adc6c189fce0a5cf7d5fd618224
    https://github.com/scummvm/scummvm/commit/535034d6b96e2adc6c189fce0a5cf7d5fd618224
Author: Simei Yin (roseline.yin at gmail.com)
Date: 2018-05-01T18:41:51+02:00

Commit Message:
SLUDGE: Objectify FloorManager

Changed paths:
    engines/sludge/builtin.cpp
    engines/sludge/floor.cpp
    engines/sludge/floor.h
    engines/sludge/loadsave.cpp
    engines/sludge/people.cpp
    engines/sludge/people.h
    engines/sludge/sludge.cpp
    engines/sludge/sludge.h
    engines/sludge/sludger.cpp


diff --git a/engines/sludge/builtin.cpp b/engines/sludge/builtin.cpp
index 4ea9cad..e06cea2 100644
--- a/engines/sludge/builtin.cpp
+++ b/engines/sludge/builtin.cpp
@@ -1208,18 +1208,18 @@ builtIn(setFloor) {
 		int v;
 		getValueType(v, SVT_FILE, fun->stack->thisVar);
 		trimStack(fun->stack);
-		if (!setFloor(v))
+		if (!g_sludge->_floorMan->setFloor(v))
 			return BR_ERROR;
 	} else {
 		trimStack(fun->stack);
-		setFloorNull();
+		g_sludge->_floorMan->setFloorNull();
 	}
 	return BR_CONTINUE;
 }
 
 builtIn(showFloor) {
 	UNUSEDALL
-	drawFloor();
+	g_sludge->_floorMan->drawFloor();
 	return BR_CONTINUE;
 }
 
diff --git a/engines/sludge/floor.cpp b/engines/sludge/floor.cpp
index 71aa75c..c51fcc4 100644
--- a/engines/sludge/floor.cpp
+++ b/engines/sludge/floor.cpp
@@ -28,23 +28,33 @@
 #include "sludge/graphics.h"
 #include "sludge/moreio.h"
 #include "sludge/newfatal.h"
+#include "sludge/people.h"
 #include "sludge/sludge.h"
 
+#define ANGLEFIX (180.0 / 3.14157)
+
 namespace Sludge {
 
-Floor *currentFloor = NULL;
+FloorManager::FloorManager(SludgeEngine *vm) {
+	_vm = vm;
+	_currentFloor = nullptr;
+}
 
-bool pointInFloorPolygon(FloorPolygon &floorPoly, int x, int y) {
+FloorManager::~FloorManager() {
+	kill();
+}
+
+bool FloorManager::pointInFloorPolygon(FloorPolygon &floorPoly, int x, int y) {
 	int i = 0, j, c = 0;
 	float xp_i, yp_i;
 	float xp_j, yp_j;
 
 	for (j = floorPoly.numVertices - 1; i < floorPoly.numVertices; j = i++) {
 
-		xp_i = currentFloor->vertex[floorPoly.vertexID[i]].x;
-		yp_i = currentFloor->vertex[floorPoly.vertexID[i]].y;
-		xp_j = currentFloor->vertex[floorPoly.vertexID[j]].x;
-		yp_j = currentFloor->vertex[floorPoly.vertexID[j]].y;
+		xp_i = _currentFloor->vertex[floorPoly.vertexID[i]].x;
+		yp_i = _currentFloor->vertex[floorPoly.vertexID[i]].y;
+		xp_j = _currentFloor->vertex[floorPoly.vertexID[j]].x;
+		yp_j = _currentFloor->vertex[floorPoly.vertexID[j]].y;
 
 		if ((((yp_i <= y) && (y < yp_j)) || ((yp_j <= y) && (y < yp_i))) && (x < (xp_j - xp_i) * (y - yp_i) / (yp_j - yp_i) + xp_i)) {
 			c = !c;
@@ -53,7 +63,7 @@ bool pointInFloorPolygon(FloorPolygon &floorPoly, int x, int y) {
 	return c;
 }
 
-bool getMatchingCorners(FloorPolygon &a, FloorPolygon &b, int &cornerA, int &cornerB) {
+bool FloorManager::getMatchingCorners(FloorPolygon &a, FloorPolygon &b, int &cornerA, int &cornerB) {
 	int sharedVertices = 0;
 	int i, j;
 
@@ -73,7 +83,7 @@ bool getMatchingCorners(FloorPolygon &a, FloorPolygon &b, int &cornerA, int &cor
 	return false;
 }
 
-bool polysShareSide(FloorPolygon &a, FloorPolygon &b) {
+bool FloorManager::polysShareSide(FloorPolygon &a, FloorPolygon &b) {
 	int sharedVertices = 0;
 	int i, j;
 
@@ -89,46 +99,45 @@ bool polysShareSide(FloorPolygon &a, FloorPolygon &b) {
 	return false;
 }
 
-void noFloor() {
-	currentFloor->numPolygons = 0;
-	currentFloor->polygon = NULL;
-	currentFloor->vertex = NULL;
-	currentFloor->matrix = NULL;
-}
-
-bool initFloor() {
-	currentFloor = new Floor;
-	if (!checkNew(currentFloor))
+bool FloorManager::init() {
+	_currentFloor = new Floor;
+	if (!checkNew(_currentFloor))
 		return false;
-	noFloor();
+	_currentFloor->numPolygons = 0;
+	_currentFloor->polygon = nullptr;
+	_currentFloor->vertex = nullptr;
+	_currentFloor->matrix = nullptr;
 	return true;
 }
 
-void killFloor() {
-	if (currentFloor) {
-		for (int i = 0; i < currentFloor->numPolygons; i++) {
-			delete []currentFloor->polygon[i].vertexID;
-			delete []currentFloor->matrix[i];
+void FloorManager::setFloorNull() {
+	if (_currentFloor) {
+		for (int i = 0; i < _currentFloor->numPolygons; i++) {
+			delete[] _currentFloor->polygon[i].vertexID;
+			delete[] _currentFloor->matrix[i];
 		}
-		delete []currentFloor->polygon;
-		currentFloor->polygon = NULL;
-		delete []currentFloor->vertex;
-		currentFloor->vertex = NULL;
-		delete []currentFloor->matrix;
-		currentFloor->matrix = NULL;
+		delete[] _currentFloor->polygon;
+		_currentFloor->polygon = nullptr;
+		delete[] _currentFloor->vertex;
+		_currentFloor->vertex = nullptr;
+		delete[] _currentFloor->matrix;
+		_currentFloor->matrix = nullptr;
 	}
 }
 
-void setFloorNull() {
-	killFloor();
-	noFloor();
+void FloorManager::kill() {
+	setFloorNull();
+	if (_currentFloor) {
+		delete _currentFloor;
+		_currentFloor = nullptr;
+	}
 }
 
-bool setFloor(int fileNum) {
+bool FloorManager::setFloor(int fileNum) {
 
 	int i, j;
 
-	killFloor();
+	setFloorNull();
 
 	setResourceForFatal(fileNum);
 
@@ -137,73 +146,73 @@ bool setFloor(int fileNum) {
 
 	// Find out how many polygons there are and reserve memory
 
-	currentFloor->originalNum = fileNum;
-	currentFloor->numPolygons = g_sludge->_resMan->getData()->readByte();
-	currentFloor->polygon = new FloorPolygon[currentFloor->numPolygons];
-	if (!checkNew(currentFloor->polygon))
+	_currentFloor->originalNum = fileNum;
+	_currentFloor->numPolygons = g_sludge->_resMan->getData()->readByte();
+	_currentFloor->polygon = new FloorPolygon[_currentFloor->numPolygons];
+	if (!checkNew(_currentFloor->polygon))
 		return false;
 
 	// Read in each polygon
 
-	for (i = 0; i < currentFloor->numPolygons; i++) {
+	for (i = 0; i < _currentFloor->numPolygons; i++) {
 
 		// Find out how many vertex IDs there are and reserve memory
 
-		currentFloor->polygon[i].numVertices = g_sludge->_resMan->getData()->readByte();
-		currentFloor->polygon[i].vertexID = new int[currentFloor->polygon[i].numVertices];
-		if (!checkNew(currentFloor->polygon[i].vertexID))
+		_currentFloor->polygon[i].numVertices = g_sludge->_resMan->getData()->readByte();
+		_currentFloor->polygon[i].vertexID = new int[_currentFloor->polygon[i].numVertices];
+		if (!checkNew(_currentFloor->polygon[i].vertexID))
 			return false;
 
 		// Read in each vertex ID
 
-		for (j = 0; j < currentFloor->polygon[i].numVertices; j++) {
-			currentFloor->polygon[i].vertexID[j] = g_sludge->_resMan->getData()->readUint16BE();
+		for (j = 0; j < _currentFloor->polygon[i].numVertices; j++) {
+			_currentFloor->polygon[i].vertexID[j] = g_sludge->_resMan->getData()->readUint16BE();
 		}
 	}
 
 	// Find out how many vertices there are and reserve memory
 
 	i = g_sludge->_resMan->getData()->readUint16BE();
-	currentFloor->vertex = new Common::Point[i];
-	if (!checkNew(currentFloor->vertex))
+	_currentFloor->vertex = new Common::Point[i];
+	if (!checkNew(_currentFloor->vertex))
 		return false;
 
 	for (j = 0; j < i; j++) {
 
-		currentFloor->vertex[j].x = g_sludge->_resMan->getData()->readUint16BE();
-		currentFloor->vertex[j].y = g_sludge->_resMan->getData()->readUint16BE();
+		_currentFloor->vertex[j].x = g_sludge->_resMan->getData()->readUint16BE();
+		_currentFloor->vertex[j].y = g_sludge->_resMan->getData()->readUint16BE();
 	}
 
 	g_sludge->_resMan->finishAccess();
 
 	// Now build the movement martix
 
-	currentFloor->matrix = new int *[currentFloor->numPolygons];
-	int **distanceMatrix = new int *[currentFloor->numPolygons];
+	_currentFloor->matrix = new int *[_currentFloor->numPolygons];
+	int **distanceMatrix = new int *[_currentFloor->numPolygons];
 
-	if (!checkNew(currentFloor->matrix))
+	if (!checkNew(_currentFloor->matrix))
 		return false;
 
-	for (i = 0; i < currentFloor->numPolygons; i++) {
-		currentFloor->matrix[i] = new int[currentFloor->numPolygons];
-		distanceMatrix[i] = new int[currentFloor->numPolygons];
-		if (!checkNew(currentFloor->matrix[i]))
+	for (i = 0; i < _currentFloor->numPolygons; i++) {
+		_currentFloor->matrix[i] = new int[_currentFloor->numPolygons];
+		distanceMatrix[i] = new int[_currentFloor->numPolygons];
+		if (!checkNew(_currentFloor->matrix[i]))
 			return false;
-		for (j = 0; j < currentFloor->numPolygons; j++) {
-			currentFloor->matrix[i][j] = -1;
+		for (j = 0; j < _currentFloor->numPolygons; j++) {
+			_currentFloor->matrix[i][j] = -1;
 			distanceMatrix[i][j] = 10000;
 		}
 	}
 
-	for (i = 0; i < currentFloor->numPolygons; i++) {
-		for (j = 0; j < currentFloor->numPolygons; j++) {
+	for (i = 0; i < _currentFloor->numPolygons; i++) {
+		for (j = 0; j < _currentFloor->numPolygons; j++) {
 			if (i != j) {
-				if (polysShareSide(currentFloor->polygon[i], currentFloor->polygon[j])) {
-					currentFloor->matrix[i][j] = j;
+				if (polysShareSide(_currentFloor->polygon[i], _currentFloor->polygon[j])) {
+					_currentFloor->matrix[i][j] = j;
 					distanceMatrix[i][j] = 1;
 				}
 			} else {
-				currentFloor->matrix[i][j] = -2;
+				_currentFloor->matrix[i][j] = -2;
 				distanceMatrix[i][j] = 0;
 			}
 		}
@@ -214,17 +223,16 @@ bool setFloor(int fileNum) {
 
 	do {
 		lookForDistance++;
-//		debugMatrix ();
 		madeChange = false;
-		for (i = 0; i < currentFloor->numPolygons; i++) {
-			for (j = 0; j < currentFloor->numPolygons; j++) {
-				if (currentFloor->matrix[i][j] == -1) {
+		for (i = 0; i < _currentFloor->numPolygons; i++) {
+			for (j = 0; j < _currentFloor->numPolygons; j++) {
+				if (_currentFloor->matrix[i][j] == -1) {
 
 					// OK, so we don't know how to get from i to j...
-					for (int d = 0; d < currentFloor->numPolygons; d++) {
+					for (int d = 0; d < _currentFloor->numPolygons; d++) {
 						if (d != i && d != j) {
-							if (currentFloor->matrix[i][d] == d && currentFloor->matrix[d][j] >= 0 && distanceMatrix[d][j] <= lookForDistance) {
-								currentFloor->matrix[i][j] = d;
+							if (_currentFloor->matrix[i][d] == d && _currentFloor->matrix[d][j] >= 0 && distanceMatrix[d][j] <= lookForDistance) {
+								_currentFloor->matrix[i][j] = d;
 								distanceMatrix[i][j] = lookForDistance + 1;
 								madeChange = true;
 							}
@@ -235,44 +243,44 @@ bool setFloor(int fileNum) {
 		}
 	} while (madeChange);
 
-	for (i = 0; i < currentFloor->numPolygons; i++) {
+	for (i = 0; i < _currentFloor->numPolygons; i++) {
 		delete[] distanceMatrix[i];
 	}
 
 	delete []distanceMatrix;
-	distanceMatrix = NULL;
+	distanceMatrix = nullptr;
 
 	setResourceForFatal(-1);
 
 	return true;
 }
 
-void drawFloor() {
+void FloorManager::drawFloor() {
 	int i, j, nV;
-	for (i = 0; i < currentFloor->numPolygons; i++) {
-		nV = currentFloor->polygon[i].numVertices;
+	for (i = 0; i < _currentFloor->numPolygons; i++) {
+		nV = _currentFloor->polygon[i].numVertices;
 		if (nV > 1) {
 			for (j = 1; j < nV; j++) {
-				g_sludge->_gfxMan->drawLine(currentFloor->vertex[currentFloor->polygon[i].vertexID[j - 1]].x, currentFloor->vertex[currentFloor->polygon[i].vertexID[j - 1]].y,
-						currentFloor->vertex[currentFloor->polygon[i].vertexID[j]].x, currentFloor->vertex[currentFloor->polygon[i].vertexID[j]].y);
+				g_sludge->_gfxMan->drawLine(_currentFloor->vertex[_currentFloor->polygon[i].vertexID[j - 1]].x, _currentFloor->vertex[_currentFloor->polygon[i].vertexID[j - 1]].y,
+						_currentFloor->vertex[_currentFloor->polygon[i].vertexID[j]].x, _currentFloor->vertex[_currentFloor->polygon[i].vertexID[j]].y);
 			}
-			g_sludge->_gfxMan->drawLine(currentFloor->vertex[currentFloor->polygon[i].vertexID[0]].x, currentFloor->vertex[currentFloor->polygon[i].vertexID[0]].y,
-					currentFloor->vertex[currentFloor->polygon[i].vertexID[nV - 1]].x, currentFloor->vertex[currentFloor->polygon[i].vertexID[nV - 1]].y);
+			g_sludge->_gfxMan->drawLine(_currentFloor->vertex[_currentFloor->polygon[i].vertexID[0]].x, _currentFloor->vertex[_currentFloor->polygon[i].vertexID[0]].y,
+					_currentFloor->vertex[_currentFloor->polygon[i].vertexID[nV - 1]].x, _currentFloor->vertex[_currentFloor->polygon[i].vertexID[nV - 1]].y);
 		}
 	}
 }
 
-int inFloor(int x, int y) {
+int FloorManager::inFloor(int x, int y) {
 	int i, r = -1;
 
-	for (i = 0; i < currentFloor->numPolygons; i++)
-		if (pointInFloorPolygon(currentFloor->polygon[i], x, y))
+	for (i = 0; i < _currentFloor->numPolygons; i++)
+		if (pointInFloorPolygon(_currentFloor->polygon[i], x, y))
 			r = i;
 
 	return r;
 }
 
-bool closestPointOnLine(int &closestX, int &closestY, int x1, int y1, int x2, int y2, int xP, int yP) {
+bool FloorManager::closestPointOnLine(int &closestX, int &closestY, int x1, int y1, int x2, int y2, int xP, int yP) {
 	int xDiff = x2 - x1;
 	int yDiff = y2 - y1;
 
@@ -293,4 +301,126 @@ bool closestPointOnLine(int &closestX, int &closestY, int x1, int y1, int x2, in
 	return false;
 }
 
+bool FloorManager::handleClosestPoint(int &setX, int &setY, int &setPoly) {
+	int gotX = 320, gotY = 200, gotPoly = -1, i, j, xTest1, yTest1, xTest2, yTest2, closestX, closestY, oldJ, currentDistance = 0xFFFFF, thisDistance;
+
+	for (i = 0; i < _currentFloor->numPolygons; i++) {
+		oldJ = _currentFloor->polygon[i].numVertices - 1;
+		for (j = 0; j < _currentFloor->polygon[i].numVertices; j++) {
+			xTest1 = _currentFloor->vertex[_currentFloor->polygon[i].vertexID[j]].x;
+			yTest1 = _currentFloor->vertex[_currentFloor->polygon[i].vertexID[j]].y;
+			xTest2 = _currentFloor->vertex[_currentFloor->polygon[i].vertexID[oldJ]].x;
+			yTest2 = _currentFloor->vertex[_currentFloor->polygon[i].vertexID[oldJ]].y;
+			closestPointOnLine(closestX, closestY, xTest1, yTest1, xTest2, yTest2, setX, setY);
+			xTest1 = setX - closestX;
+			yTest1 = setY - closestY;
+			thisDistance = xTest1 * xTest1 + yTest1 * yTest1;
+
+			if (thisDistance < currentDistance) {
+				currentDistance = thisDistance;
+				gotX = closestX;
+				gotY = closestY;
+				gotPoly = i;
+			}
+			oldJ = j;
+		}
+	}
+
+	if (gotPoly == -1)
+		return false;
+	setX = gotX;
+	setY = gotY;
+	setPoly = gotPoly;
+	return true;
+}
+
+bool FloorManager::doBorderStuff(OnScreenPerson *moveMe) {
+	if (moveMe->inPoly == moveMe->walkToPoly) {
+		moveMe->inPoly = -1;
+		moveMe->thisStepX = moveMe->walkToX;
+		moveMe->thisStepY = moveMe->walkToY;
+	} else {
+		// The section in which we need to be next...
+		int newPoly = _currentFloor->matrix[moveMe->inPoly][moveMe->walkToPoly];
+		if (newPoly == -1)
+			return false;
+
+		// Grab the index of the second matching corner...
+		int ID, ID2;
+		if (!getMatchingCorners(_currentFloor->polygon[moveMe->inPoly], _currentFloor->polygon[newPoly], ID, ID2))
+			return fatal("Not a valid floor plan!");
+
+		// Remember that we're walking to the new polygon...
+		moveMe->inPoly = newPoly;
+
+		// Calculate the destination position on the coincidantal line...
+		int x1 = moveMe->x, y1 = moveMe->y;
+		int x2 = moveMe->walkToX, y2 = moveMe->walkToY;
+		int x3 = _currentFloor->vertex[ID].x, y3 = _currentFloor->vertex[ID].y;
+		int x4 = _currentFloor->vertex[ID2].x, y4 = _currentFloor->vertex[ID2].y;
+
+		int xAB = x1 - x2;
+		int yAB = y1 - y2;
+		int xCD = x4 - x3;
+		int yCD = y4 - y3;
+
+		double m = (yAB * (x3 - x1) - xAB * (y3 - y1));
+		m /= ((xAB * yCD) - (yAB * xCD));
+
+		if (m > 0 && m < 1) {
+			moveMe->thisStepX = x3 + m * xCD;
+			moveMe->thisStepY = y3 + m * yCD;
+		} else {
+			int dx13 = x1 - x3, dx14 = x1 - x4, dx23 = x2 - x3, dx24 = x2 - x4;
+			int dy13 = y1 - y3, dy14 = y1 - y4, dy23 = y2 - y3, dy24 = y2 - y4;
+
+			dx13 *= dx13;
+			dx14 *= dx14;
+			dx23 *= dx23;
+			dx24 *= dx24;
+			dy13 *= dy13;
+			dy14 *= dy14;
+			dy23 *= dy23;
+			dy24 *= dy24;
+
+			if (sqrt((double)dx13 + dy13) + sqrt((double)dx23 + dy23) < sqrt((double)dx14 + dy14) + sqrt((double)dx24 + dy24)) {
+				moveMe->thisStepX = x3;
+				moveMe->thisStepY = y3;
+			} else {
+				moveMe->thisStepX = x4;
+				moveMe->thisStepY = y4;
+			}
+		}
+	}
+
+	float yDiff = moveMe->thisStepY - moveMe->y;
+	float xDiff = moveMe->x - moveMe->thisStepX;
+	if (xDiff || yDiff) {
+		moveMe->wantAngle = 180 + ANGLEFIX * atan2(xDiff, yDiff * 2);
+		moveMe->spinning = true;
+	}
+
+	moveMe->makeTalker();
+	return true;
+}
+
+void FloorManager::save(Common::WriteStream *stream) {
+	if (_currentFloor->numPolygons) {
+		stream->writeByte(1);
+		stream->writeUint16BE(_currentFloor->originalNum);
+	} else {
+		stream->writeByte(0);
+	}
+}
+
+bool FloorManager::load(Common::SeekableReadStream *stream) {
+	if (stream->readByte()) {
+		if (!setFloor(stream->readUint16BE()))
+			return false;
+	} else {
+		setFloorNull();
+	}
+	return true;
+}
+
 } // End of namespace Sludge
diff --git a/engines/sludge/floor.h b/engines/sludge/floor.h
index 4db7e22..22c8b12 100644
--- a/engines/sludge/floor.h
+++ b/engines/sludge/floor.h
@@ -26,6 +26,9 @@
 
 namespace Sludge {
 
+class SludgeEngine;
+struct OnScreenPerson;
+
 struct FloorPolygon {
 	int numVertices;
 	int *vertexID;
@@ -39,13 +42,37 @@ struct Floor {
 	int **matrix;
 };
 
-bool initFloor();
-void setFloorNull();
-bool setFloor(int fileNum);
-void drawFloor();
-int inFloor(int x, int y);
-bool getMatchingCorners(FloorPolygon &, FloorPolygon &, int &, int &);
-bool closestPointOnLine(int &closestX, int &closestY, int x1, int y1, int x2, int y2, int xP, int yP);
+class FloorManager {
+public:
+	FloorManager(SludgeEngine *vm);
+	~FloorManager();
+
+	bool init();
+	void kill();
+
+	void setFloorNull();
+	bool setFloor(int fileNum);
+	void drawFloor();
+	int inFloor(int x, int y);
+	bool isFloorNoPolygon() { return !_currentFloor || _currentFloor->numPolygons == 0; }
+
+	// For Person collision detection
+	bool handleClosestPoint(int &setX, int &setY, int &setPoly);
+	bool doBorderStuff(OnScreenPerson *moveMe);
+
+	// Save & load
+	void save(Common::WriteStream *stream);
+	bool load(Common::SeekableReadStream *stream);
+
+private:
+	Floor *_currentFloor;
+	SludgeEngine *_vm;
+
+	bool getMatchingCorners(FloorPolygon &, FloorPolygon &, int &, int &);
+	bool closestPointOnLine(int &closestX, int &closestY, int x1, int y1, int x2, int y2, int xP, int yP);
+	bool pointInFloorPolygon(FloorPolygon &floorPoly, int x, int y);
+	bool polysShareSide(FloorPolygon &a, FloorPolygon &b);
+};
 
 } // End of namespace Sludge
 
diff --git a/engines/sludge/loadsave.cpp b/engines/sludge/loadsave.cpp
index f1dfb6c..8706f7f 100644
--- a/engines/sludge/loadsave.cpp
+++ b/engines/sludge/loadsave.cpp
@@ -59,7 +59,6 @@ extern LoadedFunction *allRunningFunctions;         // In sludger.cpp
 extern const char *typeName[];                      // In variable.cpp
 extern int numGlobals;                              // In sludger.cpp
 extern Variable *globalVars;                        // In sludger.cpp
-extern Floor *currentFloor;                          // In floor.cpp
 extern FILETIME fileTime;                           // In sludger.cpp
 extern bool allowAnyFilename;
 
@@ -392,12 +391,7 @@ bool saveGame(const Common::String &fname) {
 
 	g_sludge->_peopleMan->savePeople(fp);
 
-	if (currentFloor->numPolygons) {
-		fp->writeByte(1);
-		fp->writeUint16BE(currentFloor->originalNum);
-	} else {
-		fp->writeByte(0);
-	}
+	g_sludge->_floorMan->save(fp);
 
 	g_sludge->_gfxMan->saveZBuffer(fp);
 	g_sludge->_gfxMan->saveLightMap(fp);
@@ -523,11 +517,9 @@ bool loadGame(const Common::String &fname) {
 
 	g_sludge->_peopleMan->loadPeople(fp);
 
-	if (fp->readByte()) {
-		if (!setFloor(fp->readUint16BE()))
-			return false;
-	} else
-		setFloorNull();
+	if (!g_sludge->_floorMan->load(fp)) {
+		return false;
+	}
 
 	if (!g_sludge->_gfxMan->loadZBuffer(fp))
 		return false;
diff --git a/engines/sludge/people.cpp b/engines/sludge/people.cpp
index dd7aeff..3624950 100644
--- a/engines/sludge/people.cpp
+++ b/engines/sludge/people.cpp
@@ -39,7 +39,6 @@
 #include "sludge/version.h"
 #include "sludge/zbuffer.h"
 
-#define ANGLEFIX (180.0 / 3.14157)
 #define ANI_STAND 0
 #define ANI_WALK 1
 #define ANI_TALK 2
@@ -48,7 +47,6 @@ namespace Sludge {
 
 extern VariableStack *noStack;
 extern int ssgVersion;
-extern Floor *currentFloor;
 
 PersonaAnimation::PersonaAnimation() {
 	theSprites = nullptr;
@@ -559,110 +557,6 @@ void PeopleManager::drawPeople() {
 	}
 }
 
-bool PeopleManager::handleClosestPoint(int &setX, int &setY, int &setPoly) {
-	int gotX = 320, gotY = 200, gotPoly = -1, i, j, xTest1, yTest1, xTest2, yTest2, closestX, closestY, oldJ, currentDistance = 0xFFFFF, thisDistance;
-
-	for (i = 0; i < currentFloor->numPolygons; i++) {
-		oldJ = currentFloor->polygon[i].numVertices - 1;
-		for (j = 0; j < currentFloor->polygon[i].numVertices; j++) {
-			xTest1 = currentFloor->vertex[currentFloor->polygon[i].vertexID[j]].x;
-			yTest1 = currentFloor->vertex[currentFloor->polygon[i].vertexID[j]].y;
-			xTest2 = currentFloor->vertex[currentFloor->polygon[i].vertexID[oldJ]].x;
-			yTest2 = currentFloor->vertex[currentFloor->polygon[i].vertexID[oldJ]].y;
-			closestPointOnLine(closestX, closestY, xTest1, yTest1, xTest2, yTest2, setX, setY);
-			xTest1 = setX - closestX;
-			yTest1 = setY - closestY;
-			thisDistance = xTest1 * xTest1 + yTest1 * yTest1;
-
-			if (thisDistance < currentDistance) {
-				currentDistance = thisDistance;
-				gotX = closestX;
-				gotY = closestY;
-				gotPoly = i;
-			}
-			oldJ = j;
-		}
-	}
-
-	if (gotPoly == -1)
-		return false;
-	setX = gotX;
-	setY = gotY;
-	setPoly = gotPoly;
-
-	return true;
-}
-
-bool PeopleManager::doBorderStuff(OnScreenPerson *moveMe) {
-	if (moveMe->inPoly == moveMe->walkToPoly) {
-		moveMe->inPoly = -1;
-		moveMe->thisStepX = moveMe->walkToX;
-		moveMe->thisStepY = moveMe->walkToY;
-	} else {
-		// The section in which we need to be next...
-		int newPoly = currentFloor->matrix[moveMe->inPoly][moveMe->walkToPoly];
-		if (newPoly == -1)
-			return false;
-
-		// Grab the index of the second matching corner...
-		int ID, ID2;
-		if (!getMatchingCorners(currentFloor->polygon[moveMe->inPoly], currentFloor->polygon[newPoly], ID, ID2))
-			return fatal("Not a valid floor plan!");
-
-		// Remember that we're walking to the new polygon...
-		moveMe->inPoly = newPoly;
-
-		// Calculate the destination position on the coincidantal line...
-		int x1 = moveMe->x, y1 = moveMe->y;
-		int x2 = moveMe->walkToX, y2 = moveMe->walkToY;
-		int x3 = currentFloor->vertex[ID].x, y3 = currentFloor->vertex[ID].y;
-		int x4 = currentFloor->vertex[ID2].x, y4 = currentFloor->vertex[ID2].y;
-
-		int xAB = x1 - x2;
-		int yAB = y1 - y2;
-		int xCD = x4 - x3;
-		int yCD = y4 - y3;
-
-		double m = (yAB * (x3 - x1) - xAB * (y3 - y1));
-		m /= ((xAB * yCD) - (yAB * xCD));
-
-		if (m > 0 && m < 1) {
-			moveMe->thisStepX = x3 + m * xCD;
-			moveMe->thisStepY = y3 + m * yCD;
-		} else {
-			int dx13 = x1 - x3, dx14 = x1 - x4, dx23 = x2 - x3, dx24 = x2 - x4;
-			int dy13 = y1 - y3, dy14 = y1 - y4, dy23 = y2 - y3, dy24 = y2 - y4;
-
-			dx13 *= dx13;
-			dx14 *= dx14;
-			dx23 *= dx23;
-			dx24 *= dx24;
-			dy13 *= dy13;
-			dy14 *= dy14;
-			dy23 *= dy23;
-			dy24 *= dy24;
-
-			if (sqrt((double)dx13 + dy13) + sqrt((double)dx23 + dy23) < sqrt((double)dx14 + dy14) + sqrt((double)dx24 + dy24)) {
-				moveMe->thisStepX = x3;
-				moveMe->thisStepY = y3;
-			} else {
-				moveMe->thisStepX = x4;
-				moveMe->thisStepY = y4;
-			}
-		}
-	}
-
-	float yDiff = moveMe->thisStepY - moveMe->y;
-	float xDiff = moveMe->x - moveMe->thisStepX;
-	if (xDiff || yDiff) {
-		moveMe->wantAngle = 180 + ANGLEFIX * atan2(xDiff, yDiff * 2);
-		moveMe->spinning = true;
-	}
-
-	moveMe->setFrames(ANI_WALK);
-	return true;
-}
-
 bool PeopleManager::walkMe(OnScreenPerson *thisPerson, bool move) {
 	float xDiff, yDiff, maxDiff, s;
 
@@ -694,7 +588,7 @@ bool PeopleManager::walkMe(OnScreenPerson *thisPerson, bool move) {
 			}
 			break;
 		}
-		if (!doBorderStuff(thisPerson))
+		if (!_vm->_floorMan->doBorderStuff(thisPerson))
 			break;
 	}
 
@@ -707,7 +601,7 @@ bool PeopleManager::walkMe(OnScreenPerson *thisPerson, bool move) {
 bool PeopleManager::makeWalkingPerson(int x, int y, int objNum, LoadedFunction *func, int di) {
 	if (x == 0 && y == 0)
 		return false;
-	if (currentFloor->numPolygons == 0)
+	if (_vm->_floorMan->isFloorNoPolygon())
 		return false;
 	OnScreenPerson *moveMe = findPerson(objNum);
 	if (!moveMe)
@@ -721,20 +615,20 @@ bool PeopleManager::makeWalkingPerson(int x, int y, int objNum, LoadedFunction *
 
 	moveMe->walkToX = x;
 	moveMe->walkToY = y;
-	moveMe->walkToPoly = inFloor(x, y);
+	moveMe->walkToPoly = _vm->_floorMan->inFloor(x, y);
 	if (moveMe->walkToPoly == -1) {
-		if (!handleClosestPoint(moveMe->walkToX, moveMe->walkToY, moveMe->walkToPoly))
+		if (!_vm->_floorMan->handleClosestPoint(moveMe->walkToX, moveMe->walkToY, moveMe->walkToPoly))
 			return false;
 	}
 
-	moveMe->inPoly = inFloor(moveMe->x, moveMe->y);
+	moveMe->inPoly = _vm->_floorMan->inFloor(moveMe->x, moveMe->y);
 	if (moveMe->inPoly == -1) {
 		int xxx = moveMe->x, yyy = moveMe->y;
-		if (!handleClosestPoint(xxx, yyy, moveMe->inPoly))
+		if (!_vm->_floorMan->handleClosestPoint(xxx, yyy, moveMe->inPoly))
 			return false;
 	}
 
-	doBorderStuff(moveMe);
+	_vm->_floorMan->doBorderStuff(moveMe);
 	if (walkMe(moveMe, false) || moveMe->spinning) {
 		moveMe->continueAfterWalking = func;
 		return true;
@@ -778,7 +672,7 @@ bool PeopleManager::forceWalkingPerson(int x, int y, int objNum, LoadedFunction
 	moveMe->inPoly = 0;
 	moveMe->walkToPoly = 0;
 
-	doBorderStuff(moveMe);
+	_vm->_floorMan->doBorderStuff(moveMe);
 	if (walkMe(moveMe) || moveMe->spinning) {
 		moveMe->continueAfterWalking = func;
 		return true;
diff --git a/engines/sludge/people.h b/engines/sludge/people.h
index 8780ed1..2d19a14 100644
--- a/engines/sludge/people.h
+++ b/engines/sludge/people.h
@@ -156,7 +156,6 @@ private:
 	SludgeEngine *_vm;
 
 	void shufflePeople();
-	bool handleClosestPoint(int &setX, int &setY, int &setPoly);
 
 	// OnScreenPerson manipulation
 	void turnMeAngle(OnScreenPerson *thisPerson, int direc);
@@ -164,7 +163,6 @@ private:
 	void rethinkAngle(OnScreenPerson *thisPerson);
 	void moveAndScale(OnScreenPerson &me, float x, float y);
 	void setMyDrawMode(OnScreenPerson *moveMe, int h);
-	bool doBorderStuff(OnScreenPerson *moveMe);
 	bool walkMe(OnScreenPerson *thisPerson, bool move = true);
 };
 
diff --git a/engines/sludge/sludge.cpp b/engines/sludge/sludge.cpp
index 38fe12a..a864a61 100644
--- a/engines/sludge/sludge.cpp
+++ b/engines/sludge/sludge.cpp
@@ -28,6 +28,7 @@
 #include "sludge/cursors.h"
 #include "sludge/event.h"
 #include "sludge/fonttext.h"
+#include "sludge/floor.h"
 #include "sludge/graphics.h"
 #include "sludge/people.h"
 #include "sludge/region.h"
@@ -86,6 +87,7 @@ SludgeEngine::SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc)
 	_cursorMan = new CursorManager(this);
 	_speechMan = new SpeechManager(this);
 	_regionMan = new RegionManager(this);
+	_floorMan = new FloorManager(this);
 }
 
 SludgeEngine::~SludgeEngine() {
@@ -130,6 +132,8 @@ SludgeEngine::~SludgeEngine() {
 	_regionMan = nullptr;
 	delete _peopleMan;
 	_peopleMan = nullptr;
+	delete _floorMan;
+	_floorMan = nullptr;
 }
 
 Common::Error SludgeEngine::run() {
diff --git a/engines/sludge/sludge.h b/engines/sludge/sludge.h
index 66a443e..6a0848a 100644
--- a/engines/sludge/sludge.h
+++ b/engines/sludge/sludge.h
@@ -40,6 +40,7 @@ extern SludgeEngine *g_sludge;
 
 class CursorManager;
 class EventManager;
+class FloorManager;
 class GraphicsManager;
 class PeopleManager;
 class RegionManager;
@@ -92,6 +93,7 @@ public:
 	SpeechManager *_speechMan;
 	RegionManager *_regionMan;
 	PeopleManager *_peopleMan;
+	FloorManager *_floorMan;
 
 	SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc);
 	virtual ~SludgeEngine();
diff --git a/engines/sludge/sludger.cpp b/engines/sludge/sludger.cpp
index 5f22acb..dd3b319 100644
--- a/engines/sludge/sludger.cpp
+++ b/engines/sludge/sludger.cpp
@@ -142,7 +142,7 @@ void initSludge() {
 	g_sludge->_gfxMan->init();
 	g_sludge->_resMan->init();
 	g_sludge->_peopleMan->init();
-	initFloor();
+	g_sludge->_floorMan->init();
 	g_sludge->_objMan->init();
 	g_sludge->_speechMan->init();
 	initStatusBar();
@@ -172,7 +172,7 @@ void killSludge() {
 	killAllFunctions();
 	g_sludge->_peopleMan->kill();
 	g_sludge->_regionMan->kill();
-	setFloorNull();
+	g_sludge->_floorMan->kill();
 	g_sludge->_speechMan->kill();
 	g_sludge->_languageMan->kill();
 	g_sludge->_gfxMan->kill();





More information about the Scummvm-git-logs mailing list