diff options
-rw-r--r-- | engines/sludge/builtin.cpp | 6 | ||||
-rw-r--r-- | engines/sludge/floor.cpp | 296 | ||||
-rw-r--r-- | engines/sludge/floor.h | 41 | ||||
-rw-r--r-- | engines/sludge/loadsave.cpp | 16 | ||||
-rw-r--r-- | engines/sludge/people.cpp | 122 | ||||
-rw-r--r-- | engines/sludge/people.h | 2 | ||||
-rw-r--r-- | engines/sludge/sludge.cpp | 4 | ||||
-rw-r--r-- | engines/sludge/sludge.h | 2 | ||||
-rw-r--r-- | engines/sludge/sludger.cpp | 4 |
9 files changed, 270 insertions, 223 deletions
diff --git a/engines/sludge/builtin.cpp b/engines/sludge/builtin.cpp index 4ea9caddde..e06cea204b 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 71aa75cbe7..c51fcc4309 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 4db7e22deb..22c8b12f30 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 f1dfb6cf42..8706f7f0a4 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 dd7aeff964..36249501bd 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 8780ed10f6..2d19a14d73 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 38fe12a4a6..a864a61ae9 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 66a443e32a..6a0848a26d 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 5f22acb368..dd3b319d52 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(); |