aboutsummaryrefslogtreecommitdiff
path: root/engines/gnap/character.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gnap/character.cpp')
-rw-r--r--engines/gnap/character.cpp400
1 files changed, 399 insertions, 1 deletions
diff --git a/engines/gnap/character.cpp b/engines/gnap/character.cpp
index 9503bfdd39..a15f4e9cad 100644
--- a/engines/gnap/character.cpp
+++ b/engines/gnap/character.cpp
@@ -35,10 +35,76 @@ Character::Character(GnapEngine *vm) : _vm(vm) {
_id = 0;
_gridX = 0;
_gridY = 0;
+
+ _walkNodesCount = 0;
+ _walkDestX = _walkDestY = 0;
+ _walkDeltaX = _walkDeltaY = 0;
+ _walkDirX = _walkDirY = 0;
+ _walkDirXIncr = _walkDirYIncr = 0;
+
+ for(int i = 0; i < kMaxGridStructs; i++) {
+ _walkNodes[i]._id = 0;
+ _walkNodes[i]._sequenceId = 0;
+ _walkNodes[i]._deltaX = 0;
+ _walkNodes[i]._deltaY = 0;
+ _walkNodes[i]._gridX1 = 0;
+ _walkNodes[i]._gridY1 = 0;
+ }
}
Character::~Character() {}
+void Character::walkStep() {
+ for (int i = 1; i < _vm->_gridMaxX; ++i) {
+ Common::Point checkPt = Common::Point(_pos.x + i, _pos.y);
+ if (!_vm->isPointBlocked(checkPt)) {
+ walkTo(checkPt, -1, -1, 1);
+ break;
+ }
+
+ checkPt = Common::Point(_pos.x - i, _pos.y);
+ if (!_vm->isPointBlocked(checkPt)) {
+ walkTo(checkPt, -1, -1, 1);
+ break;
+ }
+
+ checkPt = Common::Point(_pos.x, _pos.y + 1);
+ if (!_vm->isPointBlocked(checkPt)) {
+ walkTo(checkPt, -1, -1, 1);
+ break;
+ }
+
+ checkPt = Common::Point(_pos.x, _pos.y - 1);
+ if (!_vm->isPointBlocked(checkPt)) {
+ walkTo(checkPt, -1, -1, 1);
+ break;
+ }
+
+ checkPt = Common::Point(_pos.x + 1, _pos.y + 1);
+ if (!_vm->isPointBlocked(checkPt)) {
+ walkTo(checkPt, -1, -1, 1);
+ break;
+ }
+
+ checkPt = Common::Point(_pos.x - 1, _pos.y + 1);
+ if (!_vm->isPointBlocked(checkPt)) {
+ walkTo(checkPt, -1, -1, 1);
+ break;
+ }
+
+ checkPt = Common::Point(_pos.x + 1, _pos.y - 1);
+ if (!_vm->isPointBlocked(checkPt)) {
+ walkTo(checkPt, -1, -1, 1);
+ break;
+ }
+
+ checkPt = Common::Point(_pos.x - 1, _pos.y - 1);
+ if (!_vm->isPointBlocked(checkPt)) {
+ walkTo(checkPt, -1, -1, 1);
+ break;
+ }
+ }
+}
/************************************************************************************************/
PlayerGnap::PlayerGnap(GnapEngine * vm) : Character(vm) {
@@ -412,7 +478,7 @@ void PlayerGnap::useJointOnPlatypus() {
_vm->_plat->_sequenceId = 0x876;
_vm->_plat->_idleFacing = kDirNone;
playSequence(0x107B5);
- _vm->gnapWalkStep();
+ _vm->_gnap->walkStep();
while (_vm->_gameSys->getAnimationStatus(0) != 2) {
_vm->updateMouseCursor();
_vm->gameUpdateTick();
@@ -608,6 +674,180 @@ int PlayerGnap::getWalkSequenceId(int deltaX, int deltaY) {
return walkSequenceIds[3 * deltaX + 3 + 1 + deltaY];
}
+bool PlayerGnap::walkTo(Common::Point gridPos, int animationIndex, int sequenceId, int flags) {
+ int datNum = flags & 3;
+ bool done = false;
+
+ _vm->_timers[2] = 200;
+ _vm->_timers[3] = 300;
+
+ int gridX = gridPos.x;
+ if (gridX < 0)
+ gridX = (_vm->_leftClickMouseX - _vm->_gridMinX + 37) / 75;
+
+ int gridY = gridPos.y;
+ if (gridY < 0)
+ gridY = (_vm->_leftClickMouseY - _vm->_gridMinY + 24) / 48;
+
+ _walkDestX = CLIP(gridX, 0, _vm->_gridMaxX - 1);
+ _walkDestY = CLIP(gridY, 0, _vm->_gridMaxY - 1);
+
+ if (animationIndex >= 0 && _walkDestX == _vm->_plat->_pos.x && _walkDestY == _vm->_plat->_pos.y)
+ _vm->platypusMakeRoom();
+
+ if (findPath1(_pos.x, _pos.y, 0))
+ done = true;
+
+ if (!done && findPath2(_pos.x, _pos.y, 0))
+ done = true;
+
+ if (!done && findPath3(_pos.x, _pos.y))
+ done = true;
+
+ if (!done && findPath4(_pos.x, _pos.y))
+ done = true;
+
+ _vm->gnapIdle();
+
+ int gnapSequenceId = _sequenceId;
+ int gnapId = _id;
+ int gnapSequenceDatNum = _sequenceDatNum;
+
+ debugC(kDebugBasic, "_gnap->_walkNodesCount: %d", _walkNodesCount);
+
+ for (int index = 0; index < _walkNodesCount; ++index) {
+ _walkNodes[index]._id = index + 20 * _walkNodes[index]._gridY1;
+ if (_walkNodes[index]._deltaX == 1 && _walkNodes[index]._deltaY == 0) {
+ if (index % 2) {
+ _vm->_gameSys->insertSequence(makeRid(datNum, 0x7AB), _walkNodes[index]._id,
+ makeRid(gnapSequenceDatNum, gnapSequenceId), gnapId,
+ kSeqScale | kSeqSyncWait, 0, 75 * _walkNodes[index]._gridX1 - _gridX, 48 * _walkNodes[index]._gridY1 - _gridY);
+ _walkNodes[index]._sequenceId = 0x7AB;
+ gnapSequenceId = 0x7AB;
+ } else {
+ _vm->_gameSys->insertSequence(makeRid(datNum, 0x7AC), _walkNodes[index]._id,
+ makeRid(gnapSequenceDatNum, gnapSequenceId), gnapId,
+ kSeqScale | kSeqSyncWait, 0, 75 * _walkNodes[index]._gridX1 - _gridX, 48 * _walkNodes[index]._gridY1 - _gridY);
+ _walkNodes[index]._sequenceId = 0x7AC;
+ gnapSequenceId = 0x7AC;
+ }
+ } else if (_walkNodes[index]._deltaX == -1 && _walkNodes[index]._deltaY == 0) {
+ if (index % 2) {
+ _vm->_gameSys->insertSequence(makeRid(datNum, 0x7AF), _walkNodes[index]._id,
+ makeRid(gnapSequenceDatNum, gnapSequenceId), gnapId,
+ kSeqScale | kSeqSyncWait, 0, 75 * _walkNodes[index]._gridX1 - _gridX, 48 * _walkNodes[index]._gridY1 - _gridY);
+ _walkNodes[index]._sequenceId = 0x7AF;
+ gnapSequenceId = 0x7AF;
+ } else {
+ _vm->_gameSys->insertSequence(makeRid(datNum, 0x7B0), _walkNodes[index]._id,
+ makeRid(gnapSequenceDatNum, gnapSequenceId), gnapId,
+ kSeqScale | kSeqSyncWait, 0, 75 * _walkNodes[index]._gridX1 - _gridX, 48 * _walkNodes[index]._gridY1 - _gridY);
+ _walkNodes[index]._sequenceId = 0x7B0;
+ gnapSequenceId = 0x7B0;
+ }
+ } else {
+ if (_walkNodes[index]._deltaY == -1)
+ _walkNodes[index]._id -= 10;
+ else
+ _walkNodes[index]._id += 10;
+ int newSequenceId = getWalkSequenceId(_walkNodes[index]._deltaX, _walkNodes[index]._deltaY);
+ _vm->_gameSys->insertSequence(makeRid(datNum, newSequenceId), _walkNodes[index]._id,
+ makeRid(gnapSequenceDatNum, gnapSequenceId), gnapId,
+ kSeqScale | kSeqSyncWait, 0, 75 * _walkNodes[index]._gridX1 - _gridX, 48 * _walkNodes[index]._gridY1 - _gridY);
+ _walkNodes[index]._sequenceId = newSequenceId;
+ gnapSequenceId = newSequenceId;
+ }
+ gnapId = _walkNodes[index]._id;
+ gnapSequenceDatNum = datNum;
+ }
+
+ if (flags & 8) {
+ if (_walkNodesCount > 0) {
+ _sequenceId = gnapSequenceId;
+ _id = gnapId;
+ _idleFacing = _vm->getGnapWalkFacing(_walkNodes[_walkNodesCount - 1]._deltaX, _walkNodes[_walkNodesCount - 1]._deltaY);
+ _sequenceDatNum = datNum;
+ if (animationIndex >= 0)
+ _vm->_gameSys->setAnimation(makeRid(_sequenceDatNum, _sequenceId), _id, animationIndex);
+ } else if (animationIndex >= 0) {
+ _vm->_gameSys->setAnimation(0x107D3, 1, animationIndex);
+ _vm->_gameSys->insertSequence(0x107D3, 1, 0, 0, kSeqNone, 0, 0, 0);
+ }
+ } else {
+ if (sequenceId >= 0 && sequenceId != -1) {
+ _sequenceId = ridToEntryIndex(sequenceId);
+ _sequenceDatNum = ridToDatIndex(sequenceId);
+ if (_sequenceId == 0x7B9) {
+ _idleFacing = kDirBottomRight;
+ } else {
+ switch (_sequenceId) {
+ case 0x7BA:
+ _idleFacing = kDirBottomLeft;
+ break;
+ case 0x7BB:
+ _idleFacing = kDirUpRight;
+ break;
+ case 0x7BC:
+ _idleFacing = kDirUpLeft;
+ break;
+ }
+ }
+ } else {
+ if (_walkNodesCount > 0) {
+ _sequenceId = _vm->getGnapWalkStopSequenceId(_walkNodes[_walkNodesCount - 1]._deltaX, _walkNodes[_walkNodesCount - 1]._deltaY);
+ _idleFacing = _vm->getGnapWalkFacing(_walkNodes[_walkNodesCount - 1]._deltaX, _walkNodes[_walkNodesCount - 1]._deltaY);
+ } else if (gridX >= 0 || gridY >= 0) {
+ switch (_idleFacing) {
+ case kDirBottomRight:
+ _sequenceId = 0x7B9;
+ break;
+ case kDirBottomLeft:
+ _sequenceId = 0x7BA;
+ break;
+ case kDirUpRight:
+ _sequenceId = 0x7BB;
+ break;
+ default:
+ _sequenceId = 0x7BC;
+ break;
+ }
+ } else {
+ //TODO: simplify the checks by using v10 and v11
+ int v10 = _vm->_leftClickMouseX - (_vm->_gridMinX + 75 * _pos.x);
+ int v11 = _vm->_leftClickMouseY - (_vm->_gridMinY + 48 * _pos.y);
+ if (_vm->_leftClickMouseX == _vm->_gridMinX + 75 * _pos.x)
+ ++v10;
+ if (_vm->_leftClickMouseY == _vm->_gridMinY + 48 * _pos.y)
+ v11 = 1;
+ _sequenceId = _vm->getGnapWalkStopSequenceId(v10 / abs(v10), v11 / abs(v11));
+ _idleFacing = _vm->getGnapWalkFacing(v10 / abs(v10), v11 / abs(v11));
+ }
+ _sequenceDatNum = datNum;
+ }
+
+ if (animationIndex < 0) {
+ _id = 20 * _walkDestY + 1;
+ } else {
+ _id = _walkNodesCount + animationIndex + 20 * _walkDestY;
+ _vm->_gameSys->setAnimation(makeRid(_sequenceDatNum, _sequenceId), _walkNodesCount + animationIndex + 20 * _walkDestY, animationIndex);
+ }
+
+ if (flags & 4) {
+ _vm->_gameSys->insertSequence(makeRid(_sequenceDatNum, _sequenceId), _id,
+ makeRid(gnapSequenceDatNum, gnapSequenceId), gnapId,
+ kSeqScale | kSeqSyncWait, 0, 0, 0);
+ } else {
+ _vm->_gameSys->insertSequence(makeRid(_sequenceDatNum, _sequenceId), _id,
+ makeRid(gnapSequenceDatNum, gnapSequenceId), gnapId,
+ kSeqScale | kSeqSyncWait, 0, 75 * _walkDestX - _gridX, 48 * _walkDestY - _gridY);
+ }
+ }
+
+ _pos = Common::Point(_walkDestX, _walkDestY);
+
+ return done;
+}
+
/************************************************************************************************/
PlayerPlat::PlayerPlat(GnapEngine * vm) : Character(vm) {}
@@ -731,4 +971,162 @@ int PlayerPlat::getWalkSequenceId(int deltaX, int deltaY) {
return walkSequenceIds[3 * deltaX + 3 + 1 + deltaY];
}
+bool PlayerPlat::walkTo(Common::Point gridPos, int animationIndex, int sequenceId, int flags) {
+ int datNum = flags & 3;
+ bool done = false;
+
+ _vm->_timers[1] = 60;
+
+ int gridX = gridPos.x;
+ if (gridX < 0)
+ gridX = (_vm->_leftClickMouseX - _vm->_gridMinX + 37) / 75;
+
+ int gridY = gridPos.y;
+ if (gridY < 0)
+ gridY = (_vm->_leftClickMouseY - _vm->_gridMinY + 24) / 48;
+
+ _walkDestX = CLIP(gridX, 0, _vm->_gridMaxX - 1);
+ _walkDestY = CLIP(gridY, 0, _vm->_gridMaxY - 1);
+
+ if (animationIndex >= 0 && _vm->_gnap->_pos == Common::Point(_walkDestX, _walkDestY))
+ _vm->_gnap->walkStep();
+
+ if (findPath1(_pos.x, _pos.y, 0))
+ done = true;
+
+ if (!done && findPath2(_pos.x, _pos.y, 0))
+ done = true;
+
+ if (!done && findPath3(_pos.x, _pos.y))
+ done = true;
+
+ if (!done && findPath4(_pos.x, _pos.y))
+ done = true;
+
+ int platSequenceId = _sequenceId;
+ int platId = _id;
+ int platSequenceDatNum = _sequenceDatNum;
+
+ for (int index = 0; index < _walkNodesCount; ++index) {
+ _walkNodes[index]._id = index + 20 * _walkNodes[index]._gridY1;
+ if (_walkNodes[index]._deltaX == 1 && _walkNodes[index]._deltaY == 0) {
+ if (index % 2) {
+ _vm->_gameSys->insertSequence(makeRid(datNum, 0x7CD), _walkNodes[index]._id,
+ makeRid(platSequenceDatNum, platSequenceId), platId,
+ kSeqScale | kSeqSyncWait, 0, 75 * _walkNodes[index]._gridX1 - _gridX, 48 * _walkNodes[index]._gridY1 - _gridY);
+ _walkNodes[index]._sequenceId = 0x7CD;
+ platSequenceId = 0x7CD;
+ } else {
+ _vm->_gameSys->insertSequence(makeRid(datNum, 0x7CE), _walkNodes[index]._id,
+ makeRid(platSequenceDatNum, platSequenceId), platId,
+ kSeqScale | kSeqSyncWait, 0, 75 * _walkNodes[index]._gridX1 - _gridX, 48 * _walkNodes[index]._gridY1 - _gridY);
+ _walkNodes[index]._sequenceId = 0x7CE;
+ platSequenceId = 0x7CE;
+ }
+ } else if (_walkNodes[index]._deltaX == -1 && _walkNodes[index]._deltaY == 0) {
+ if (index % 2) {
+ _vm->_gameSys->insertSequence(makeRid(datNum, 0x7CF), _walkNodes[index]._id,
+ makeRid(platSequenceDatNum, platSequenceId), platId,
+ kSeqScale | kSeqSyncWait, 0, 75 * _walkNodes[index]._gridX1 - _gridX, 48 * _walkNodes[index]._gridY1 - _gridY);
+ _walkNodes[index]._sequenceId = 0x7CF;
+ platSequenceId = 0x7CF;
+ } else {
+ _vm->_gameSys->insertSequence(makeRid(datNum, 0x7D0), _walkNodes[index]._id,
+ makeRid(platSequenceDatNum, platSequenceId), platId,
+ kSeqScale | kSeqSyncWait, 0, 75 * _walkNodes[index]._gridX1 - _gridX, 48 * _walkNodes[index]._gridY1 - _gridY);
+ _walkNodes[index]._sequenceId = 0x7D0;
+ platSequenceId = 0x7D0;
+ }
+ } else {
+ if (_walkNodes[index]._deltaY == -1)
+ _walkNodes[index]._id -= 10;
+ else
+ _walkNodes[index]._id += 10;
+ int newSequenceId = getWalkSequenceId(_walkNodes[index]._deltaX, _walkNodes[index]._deltaY);
+ _vm->_gameSys->insertSequence(makeRid(datNum, newSequenceId), _walkNodes[index]._id,
+ makeRid(platSequenceDatNum, platSequenceId), platId,
+ kSeqScale | kSeqSyncWait, 0, 75 * _walkNodes[index]._gridX1 - _gridX, 48 * _walkNodes[index]._gridY1 - _gridY);
+ _walkNodes[index]._sequenceId = newSequenceId;
+ platSequenceId = newSequenceId;
+ }
+ platId = _walkNodes[index]._id;
+ platSequenceDatNum = datNum;
+ }
+
+ if (flags & 8) {
+ if (_walkNodesCount > 0) {
+ _sequenceId = platSequenceId;
+ _id = platId;
+ _sequenceDatNum = datNum;
+ // CHECKME Not sure if this is correct...
+ if (_walkNodes[_walkNodesCount - 1]._deltaX > 0)
+ _idleFacing = kDirNone;
+ else if (_walkNodes[_walkNodesCount - 1]._deltaX < 0)
+ _idleFacing = kDirUnk4;
+ else if (_walkNodes[_walkNodesCount - 1]._gridX1 % 2)
+ _idleFacing = kDirUnk4;
+ else
+ _idleFacing = kDirNone;
+ if (animationIndex >= 0)
+ _vm->_gameSys->setAnimation(makeRid(_sequenceDatNum, _sequenceId), _id, animationIndex);
+ } else if (animationIndex >= 0) {
+ _vm->_gameSys->setAnimation(0x107D3, 1, animationIndex);
+ _vm->_gameSys->insertSequence(0x107D3, 1, 0, 0, kSeqNone, 0, 0, 0);
+ }
+ } else {
+ if (sequenceId >= 0 && sequenceId != -1) {
+ _sequenceId = ridToEntryIndex(sequenceId);
+ _sequenceDatNum = ridToDatIndex(sequenceId);
+ if (_sequenceId == 0x7C2) {
+ _idleFacing = kDirNone;
+ } else if (_sequenceId == 0x7D2) {
+ _idleFacing = kDirUnk4;
+ }
+ } else {
+ if (_walkNodesCount > 0) {
+ if (_walkNodes[_walkNodesCount - 1]._deltaX > 0) {
+ _sequenceId = 0x7C2;
+ _idleFacing = kDirNone;
+ } else if (_walkNodes[_walkNodesCount - 1]._deltaX < 0) {
+ _sequenceId = 0x7D2;
+ _idleFacing = kDirUnk4;
+ } else if (_walkNodes[0]._deltaX > 0) {
+ _sequenceId = 0x7C2;
+ _idleFacing = kDirNone;
+ } else if (_walkNodes[0]._deltaX < 0) {
+ _sequenceId = 0x7D2;
+ _idleFacing = kDirUnk4;
+ } else {
+ _sequenceId = 0x7D2;
+ _idleFacing = kDirUnk4;
+ }
+ } else if (_idleFacing != kDirNone) {
+ _sequenceId = 0x7D2;
+ } else {
+ _sequenceId = 0x7C2;
+ }
+ _sequenceDatNum = datNum;
+ }
+
+ if (animationIndex < 0) {
+ _id = 20 * _walkDestY;
+ } else {
+ _id = animationIndex + 20 * _walkDestY;
+ _vm->_gameSys->setAnimation(makeRid(_sequenceDatNum, _sequenceId), animationIndex + 20 * _walkDestY, animationIndex);
+ }
+
+ if (flags & 4)
+ _vm->_gameSys->insertSequence(makeRid(_sequenceDatNum, _sequenceId), _id,
+ makeRid(platSequenceDatNum, platSequenceId), platId,
+ 9, 0, 0, 0);
+ else
+ _vm->_gameSys->insertSequence(makeRid(_sequenceDatNum, _sequenceId), _id,
+ makeRid(platSequenceDatNum, platSequenceId), platId,
+ 9, 0, 75 * _walkDestX - _gridX, 48 * _walkDestY - _gridY);
+ }
+
+ _pos = Common::Point(_walkDestX, _walkDestY);
+
+ return done;
+}
} // End of namespace Gnap