diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sherlock/objects.cpp | 8 | ||||
-rw-r--r-- | engines/sherlock/objects.h | 6 | ||||
-rw-r--r-- | engines/sherlock/people.cpp | 338 | ||||
-rw-r--r-- | engines/sherlock/people.h | 25 | ||||
-rw-r--r-- | engines/sherlock/scalpel/scalpel_map.cpp | 16 | ||||
-rw-r--r-- | engines/sherlock/scalpel/scalpel_people.cpp | 161 | ||||
-rw-r--r-- | engines/sherlock/scalpel/scalpel_people.h | 6 | ||||
-rw-r--r-- | engines/sherlock/scalpel/scalpel_user_interface.cpp | 2 | ||||
-rw-r--r-- | engines/sherlock/talk.cpp | 2 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_people.h | 2 |
10 files changed, 285 insertions, 281 deletions
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 120fb997da..19561f6eb7 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -321,7 +321,7 @@ void Sprite::checkSprite() { break; case WALK_AROUND: - if (objBounds.contains(people._walkTo.front())) { + if (objBounds.contains(people[PLAYER]._walkTo.front())) { // Reached zone gotoStand(); } else { @@ -369,8 +369,8 @@ void Sprite::checkSprite() { walkPos.x += people[PLAYER]._imageFrame->_frame.w / 2; people._walkDest = walkPos; - people._walkTo.push(walkPos); - people.setWalking(); + people[PLAYER]._walkTo.push(walkPos); + people[PLAYER].setWalking(); } break; @@ -1433,7 +1433,7 @@ int Object::pickUpObject(const char *const messages[]) { } else { // Play generic pickup sequence // Original moved cursor position here - people.goAllTheWay(); + people[PLAYER].goAllTheWay(); ui._menuCounter = 25; ui._temp1 = 1; } diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index b9911c7946..a22606bcb3 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -309,6 +309,12 @@ public: * Bring a moving character using the sprite to a standing position */ virtual void gotoStand() = 0; + + /** + * Set the variables for moving a character from one poisition to another + * in a straight line + */ + virtual void setWalking() = 0; }; enum { OBJ_BEHIND = 1, OBJ_FLIPPED = 2, OBJ_FORWARD = 4, TURNON_OBJ = 0x20, TURNOFF_OBJ = 0x40 }; diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index bb95c51f0f..4ad0b2dc88 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -27,11 +27,6 @@ namespace Sherlock { -// Walk speeds -#define MWALK_SPEED 2 -#define XWALK_SPEED 4 -#define YWALK_SPEED 1 - // Characer animation sequences static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = { { 29, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Right @@ -80,6 +75,8 @@ Person::Person() : Sprite(), _walkLoaded(false), _npcIndex(0), _npcStack(0), _np _savedNpcFrame = 0; _updateNPCPath = false; _npcPause = false; + _oldWalkSequence = -1; + _srcZone = _destZone = 0; } void Person::clearNPC() { @@ -92,6 +89,94 @@ void Person::updateNPC() { // TODO } +void Person::goAllTheWay() { + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Common::Point srcPt(_position.x / FIXED_INT_MULTIPLIER + frameWidth() / 2, + _position.y / FIXED_INT_MULTIPLIER); + + // Get the zone the player is currently in + _srcZone = scene.whichZone(srcPt); + if (_srcZone == -1) + _srcZone = scene.closestZone(srcPt); + + // Get the zone of the destination + _destZone = scene.whichZone(people._walkDest); + if (_destZone == -1) { + _destZone = scene.closestZone(people._walkDest); + + // The destination isn't in a zone + if (people._walkDest.x >= (SHERLOCK_SCREEN_WIDTH - 1)) + people._walkDest.x = SHERLOCK_SCREEN_WIDTH - 2; + + // Trace a line between the centroid of the found closest zone to + // the destination, to find the point at which the zone will be left + const Common::Rect &destRect = scene._zones[_destZone]; + const Common::Point destCenter((destRect.left + destRect.right) / 2, + (destRect.top + destRect.bottom) / 2); + const Common::Point delta = people._walkDest - destCenter; + Point32 pt(destCenter.x * FIXED_INT_MULTIPLIER, destCenter.y * FIXED_INT_MULTIPLIER); + + // Move along the line until the zone is left + do { + pt += delta; + } while (destRect.contains(pt.x / FIXED_INT_MULTIPLIER, pt.y / FIXED_INT_MULTIPLIER)); + + // Set the new walk destination to the last point that was in the + // zone just before it was left + people._walkDest = Common::Point((pt.x - delta.x * 2) / FIXED_INT_MULTIPLIER, + (pt.y - delta.y * 2) / FIXED_INT_MULTIPLIER); + } + + // Only do a walk if both zones are acceptable + if (_srcZone == -2 || _destZone == -2) + return; + + // If the start and dest zones are the same, walk directly to the dest point + if (_srcZone == _destZone) { + setWalking(); + } else { + // Otherwise a path needs to be formed from the path information + int i = scene._walkDirectory[_srcZone][_destZone]; + + // See if we need to use a reverse path + if (i == -1) + i = scene._walkDirectory[_destZone][_srcZone]; + + int count = scene._walkData[i]; + ++i; + + // See how many points there are between the src and dest zones + if (!count || count == -1) { + // There are none, so just walk to the new zone + setWalking(); + } else { + // There are points, so set up a multi-step path between points + // to reach the given destination + _walkTo.clear(); + + if (scene._walkDirectory[_srcZone][_destZone] != -1) { + i += 3 * (count - 1); + for (int idx = 0; idx < count; ++idx, i -= 3) { + _walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]), + scene._walkData[i + 2])); + } + } else { + for (int idx = 0; idx < count; ++idx, i += 3) { + _walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]), scene._walkData[i + 2])); + } + } + + // Final position + _walkTo.push(people._walkDest); + + // Start walking + people._walkDest = _walkTo.pop(); + setWalking(); + } + } +} + /*----------------------------------------------------------------*/ People *People::init(SherlockEngine *vm) { @@ -103,12 +188,10 @@ People *People::init(SherlockEngine *vm) { People::People(SherlockEngine *vm) : _vm(vm) { _holmesOn = true; - _oldWalkSequence = -1; _allowWalkAbort = false; _portraitLoaded = false; _portraitsOn = true; _clearingThePortrait = false; - _srcZone = _destZone = 0; _talkPics = nullptr; _portraitSide = 0; _speakerFlip = false; @@ -140,7 +223,7 @@ void People::reset() { // Note: Serrated Scalpel only uses a single Person slot for Sherlock.. Watson is handled by scene sprites int count = IS_SERRATED_SCALPEL ? 1 : MAX_CHARACTERS; for (int idx = 0; idx < count; ++idx) { - Sprite &p = *_data[idx]; + Person &p = *_data[idx]; p._type = (idx == 0) ? CHARACTER : INVALID; if (IS_SERRATED_SCALPEL) @@ -173,6 +256,7 @@ void People::reset() { p._adjust = Common::Point(0, 0); // Load the default walk sequences + p._walkTo.clear(); p._oldWalkSequence = -1; p._walkSequences.clear(); if (IS_SERRATED_SCALPEL) { @@ -187,9 +271,6 @@ void People::reset() { } } } - - // Reset any walk path in progress when Sherlock leaves scenes - _walkTo.clear(); } bool People::loadWalk() { @@ -286,152 +367,6 @@ bool People::freeWalk() { return result; } -void People::setWalking() { - Map &map = *_vm->_map; - Scene &scene = *_vm->_scene; - int oldDirection, oldFrame; - Common::Point speed, delta; - - // Flag that player has now walked in the scene - scene._walkedInScene = true; - - // Stop any previous walking, since a new dest is being set - _data[PLAYER]->_walkCount = 0; - oldDirection = _data[PLAYER]->_sequenceNumber; - oldFrame = _data[PLAYER]->_frameNumber; - - // Set speed to use horizontal and vertical movement - if (map._active) { - speed = Common::Point(MWALK_SPEED, MWALK_SPEED); - } else { - speed = Common::Point(XWALK_SPEED, YWALK_SPEED); - } - - // If the player is already close to the given destination that no - // walking is needed, move to the next straight line segment in the - // overall walking route, if there is one - for (;;) { - // Since we want the player to be centered on the destination they - // clicked, but characters draw positions start at their left, move - // the destination half the character width to draw him centered - int temp; - if (_walkDest.x >= (temp = _data[PLAYER]->_imageFrame->_frame.w / 2)) - _walkDest.x -= temp; - - delta = Common::Point( - ABS(_data[PLAYER]->_position.x / FIXED_INT_MULTIPLIER - _walkDest.x), - ABS(_data[PLAYER]->_position.y / FIXED_INT_MULTIPLIER - _walkDest.y) - ); - - // If we're ready to move a sufficient distance, that's it. Otherwise, - // move onto the next portion of the walk path, if there is one - if ((delta.x > 3 || delta.y > 0) || _walkTo.empty()) - break; - - // Pop next walk segment off the walk route stack - _walkDest = _walkTo.pop(); - } - - // If a sufficient move is being done, then start the move - if (delta.x > 3 || delta.y) { - // See whether the major movement is horizontal or vertical - if (delta.x >= delta.y) { - // Set the initial frame sequence for the left and right, as well - // as setting the delta x depending on direction - if (_walkDest.x < (_data[PLAYER]->_position.x / FIXED_INT_MULTIPLIER)) { - _data[PLAYER]->_sequenceNumber = (map._active ? (int)MAP_LEFT : (int)Scalpel::WALK_LEFT); - _data[PLAYER]->_delta.x = speed.x * -FIXED_INT_MULTIPLIER; - } else { - _data[PLAYER]->_sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)Scalpel::WALK_RIGHT); - _data[PLAYER]->_delta.x = speed.x * FIXED_INT_MULTIPLIER; - } - - // See if the x delta is too small to be divided by the speed, since - // this would cause a divide by zero error - if (delta.x >= speed.x) { - // Det the delta y - _data[PLAYER]->_delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x / speed.x); - if (_walkDest.y < (_data[PLAYER]->_position.y / FIXED_INT_MULTIPLIER)) - _data[PLAYER]->_delta.y = -_data[PLAYER]->_delta.y; - - // Set how many times we should add the delta to the player's position - _data[PLAYER]->_walkCount = delta.x / speed.x; - } else { - // The delta x was less than the speed (ie. we're really close to - // the destination). So set delta to 0 so the player won't move - _data[PLAYER]->_delta = Point32(0, 0); - _data[PLAYER]->_position = Point32(_walkDest.x * FIXED_INT_MULTIPLIER, _walkDest.y * FIXED_INT_MULTIPLIER); -assert(_data[PLAYER]->_position.y >= 10000);/***DEBUG****/ - _data[PLAYER]->_walkCount = 1; - } - - // See if the sequence needs to be changed for diagonal walking - if (_data[PLAYER]->_delta.y > 150) { - if (!map._active) { - switch (_data[PLAYER]->_sequenceNumber) { - case Scalpel::WALK_LEFT: - _data[PLAYER]->_sequenceNumber = Scalpel::WALK_DOWNLEFT; - break; - case Scalpel::WALK_RIGHT: - _data[PLAYER]->_sequenceNumber = Scalpel::WALK_DOWNRIGHT; - break; - } - } - } else if (_data[PLAYER]->_delta.y < -150) { - if (!map._active) { - switch (_data[PLAYER]->_sequenceNumber) { - case Scalpel::WALK_LEFT: - _data[PLAYER]->_sequenceNumber = Scalpel::WALK_UPLEFT; - break; - case Scalpel::WALK_RIGHT: - _data[PLAYER]->_sequenceNumber = Scalpel::WALK_UPRIGHT; - break; - } - } - } - } else { - // Major movement is vertical, so set the sequence for up and down, - // and set the delta Y depending on the direction - if (_walkDest.y < (_data[PLAYER]->_position.y / FIXED_INT_MULTIPLIER)) { - _data[PLAYER]->_sequenceNumber = Scalpel::WALK_UP; - _data[PLAYER]->_delta.y = speed.y * -FIXED_INT_MULTIPLIER; - } else { - _data[PLAYER]->_sequenceNumber = Scalpel::WALK_DOWN; - _data[PLAYER]->_delta.y = speed.y * FIXED_INT_MULTIPLIER; - } - - // If we're on the overhead map, set the sequence so we keep moving - // in the same direction - if (map._active) - _data[PLAYER]->_sequenceNumber = (oldDirection == -1) ? MAP_RIGHT : oldDirection; - - // Set the delta x - _data[PLAYER]->_delta.x = (delta.x * FIXED_INT_MULTIPLIER) / (delta.y / speed.y); - if (_walkDest.x < (_data[PLAYER]->_position.x / FIXED_INT_MULTIPLIER)) - _data[PLAYER]->_delta.x = -_data[PLAYER]->_delta.x; - - _data[PLAYER]->_walkCount = delta.y / speed.y; - } - } - - // See if the new walk sequence is the same as the old. If it's a new one, - // we need to reset the frame number to zero so it's animation starts at - // it's beginning. Otherwise, if it's the same sequence, we can leave it - // as is, so it keeps the animation going at wherever it was up to - if (_data[PLAYER]->_sequenceNumber != _oldWalkSequence) - _data[PLAYER]->_frameNumber = 0; - _oldWalkSequence = _data[PLAYER]->_sequenceNumber; - - if (!_data[PLAYER]->_walkCount) - _data[PLAYER]->gotoStand(); - - // If the sequence is the same as when we started, then Holmes was - // standing still and we're trying to re-stand him, so reset Holmes' - // rame to the old frame number from before it was reset to 0 - if (_data[PLAYER]->_sequenceNumber == oldDirection) - _data[PLAYER]->_frameNumber = oldFrame; -} - void People::walkToCoords(const Point32 &destPos, int destDir) { Events &events = *_vm->_events; Scene &scene = *_vm->_scene; @@ -442,7 +377,7 @@ void People::walkToCoords(const Point32 &destPos, int destDir) { _walkDest = Common::Point(destPos.x / FIXED_INT_MULTIPLIER + 10, destPos.y / FIXED_INT_MULTIPLIER); _allowWalkAbort = true; - goAllTheWay(); + _data[PLAYER]->goAllTheWay(); // Keep calling doBgAnim until the walk is done do { @@ -466,93 +401,6 @@ assert(_data[PLAYER]->_position.y >= 10000);/***DEBUG****/ } } -void People::goAllTheWay() { - Scene &scene = *_vm->_scene; - Common::Point srcPt(_data[PLAYER]->_position.x / FIXED_INT_MULTIPLIER + _data[PLAYER]->frameWidth() / 2, - _data[PLAYER]->_position.y / FIXED_INT_MULTIPLIER); - - // Get the zone the player is currently in - _srcZone = scene.whichZone(srcPt); - if (_srcZone == -1) - _srcZone = scene.closestZone(srcPt); - - // Get the zone of the destination - _destZone = scene.whichZone(_walkDest); - if (_destZone == -1) { - _destZone = scene.closestZone(_walkDest); - - // The destination isn't in a zone - if (_walkDest.x >= (SHERLOCK_SCREEN_WIDTH - 1)) - _walkDest.x = SHERLOCK_SCREEN_WIDTH - 2; - - // Trace a line between the centroid of the found closest zone to - // the destination, to find the point at which the zone will be left - const Common::Rect &destRect = scene._zones[_destZone]; - const Common::Point destCenter((destRect.left + destRect.right) / 2, - (destRect.top + destRect.bottom) / 2); - const Common::Point delta = _walkDest - destCenter; - Point32 pt(destCenter.x * FIXED_INT_MULTIPLIER, destCenter.y * FIXED_INT_MULTIPLIER); - - // Move along the line until the zone is left - do { - pt += delta; - } while (destRect.contains(pt.x / FIXED_INT_MULTIPLIER, pt.y / FIXED_INT_MULTIPLIER)); - - // Set the new walk destination to the last point that was in the - // zone just before it was left - _walkDest = Common::Point((pt.x - delta.x * 2) / FIXED_INT_MULTIPLIER, - (pt.y - delta.y * 2) / FIXED_INT_MULTIPLIER); - } - - // Only do a walk if both zones are acceptable - if (_srcZone == -2 || _destZone == -2) - return; - - // If the start and dest zones are the same, walk directly to the dest point - if (_srcZone == _destZone) { - setWalking(); - } else { - // Otherwise a path needs to be formed from the path information - int i = scene._walkDirectory[_srcZone][_destZone]; - - // See if we need to use a reverse path - if (i == -1) - i = scene._walkDirectory[_destZone][_srcZone]; - - int count = scene._walkData[i]; - ++i; - - // See how many points there are between the src and dest zones - if (!count || count == -1) { - // There are none, so just walk to the new zone - setWalking(); - } else { - // There are points, so set up a multi-step path between points - // to reach the given destination - _walkTo.clear(); - - if (scene._walkDirectory[_srcZone][_destZone] != -1) { - i += 3 * (count - 1); - for (int idx = 0; idx < count; ++idx, i -= 3) { - _walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]), - scene._walkData[i + 2])); - } - } else { - for (int idx = 0; idx < count; ++idx, i += 3) { - _walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]), scene._walkData[i + 2])); - } - } - - // Final position - _walkTo.push(_walkDest); - - // Start walking - _walkDest = _walkTo.pop(); - setWalking(); - } - } -} - int People::findSpeaker(int speaker) { Scene &scene = *_vm->_scene; const char *portrait = _characters[speaker]._portrait; diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 6d8389d9eb..2b99091671 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -59,6 +59,7 @@ struct PersonData { class Person : public Sprite { public: Common::Queue<Common::Point> _walkTo; + int _srcZone, _destZone; bool _walkLoaded; Common::String _portrait; @@ -83,6 +84,13 @@ public: virtual ~Person() {} /** + * Called to set the character walking to the current cursor location. + * It uses the zones and the inter-zone points to determine a series + * of steps to walk to get to that position. + */ + void goAllTheWay(); + + /** * Clear the NPC related data */ void clearNPC(); @@ -99,8 +107,6 @@ class People { protected: SherlockEngine *_vm; Common::Array<Person *> _data; - int _oldWalkSequence; - int _srcZone, _destZone; People(SherlockEngine *vm); public: @@ -109,7 +115,6 @@ public: Common::Point _walkDest; Point32 _hSavedPos; int _hSavedFacing; - Common::Queue<Common::Point> _walkTo; bool _holmesOn; bool _portraitLoaded; bool _portraitsOn; @@ -147,25 +152,11 @@ public: bool freeWalk(); /** - * Set the variables for moving a character from one poisition to another - * in a straight line - goAllTheWay must have been previously called to - * check for any obstacles in the path. - */ - void setWalking(); - - /** * Walk to the co-ordinates passed, and then face the given direction */ void walkToCoords(const Point32 &destPos, int destDir); /** - * Called to set the character walking to the current cursor location. - * It uses the zones and the inter-zone points to determine a series - * of steps to walk to get to that position. - */ - void goAllTheWay(); - - /** * Finds the scene background object corresponding to a specified speaker */ int findSpeaker(int speaker); diff --git a/engines/sherlock/scalpel/scalpel_map.cpp b/engines/sherlock/scalpel/scalpel_map.cpp index 3957f27457..a9e566f73c 100644 --- a/engines/sherlock/scalpel/scalpel_map.cpp +++ b/engines/sherlock/scalpel/scalpel_map.cpp @@ -428,7 +428,7 @@ void ScalpelMap::walkTheStreets() { const byte *path = _paths.getPath(start, dest); // Add in destination position - people._walkTo.clear(); + people[PLAYER]._walkTo.clear(); Common::Point destPos = people._walkDest; // Check for any intermediate points between the two locations @@ -436,7 +436,7 @@ void ScalpelMap::walkTheStreets() { people[PLAYER]._sequenceNumber = -1; if (_charPoint == 51 || _oldCharPoint == 51) { - people.setWalking(); + people[PLAYER].setWalking(); } else { bool reversePath = false; @@ -453,25 +453,25 @@ void ScalpelMap::walkTheStreets() { } while (*path != 254); // Load up the path to use - people._walkTo.clear(); + people[PLAYER]._walkTo.clear(); if (reversePath) { for (int idx = (int)tempPath.size() - 1; idx >= 0; --idx) - people._walkTo.push(tempPath[idx]); + people[PLAYER]._walkTo.push(tempPath[idx]); } else { for (int idx = 0; idx < (int)tempPath.size(); ++idx) - people._walkTo.push(tempPath[idx]); + people[PLAYER]._walkTo.push(tempPath[idx]); } - people._walkDest = people._walkTo.pop() + Common::Point(12, 6); - people.setWalking(); + people._walkDest = people[PLAYER]._walkTo.pop() + Common::Point(12, 6); + people[PLAYER].setWalking(); } } else { people[PLAYER]._walkCount = 0; } // Store the final destination icon position - people._walkTo.push(destPos); + people[PLAYER]._walkTo.push(destPos); } void ScalpelMap::saveIcon(ImageFrame *src, const Common::Point &pt) { diff --git a/engines/sherlock/scalpel/scalpel_people.cpp b/engines/sherlock/scalpel/scalpel_people.cpp index 4fcdff086a..e3cd1e5a6c 100644 --- a/engines/sherlock/scalpel/scalpel_people.cpp +++ b/engines/sherlock/scalpel/scalpel_people.cpp @@ -28,6 +28,13 @@ namespace Sherlock { namespace Scalpel { +// Walk speeds +#define MWALK_SPEED 2 +#define XWALK_SPEED 4 +#define YWALK_SPEED 1 + +/*----------------------------------------------------------------*/ + void ScalpelPerson::adjustSprite() { Map &map = *_vm->_map; People &people = *_vm->_people; @@ -45,9 +52,9 @@ void ScalpelPerson::adjustSprite() { if (!_walkCount) { // If there any points left for the character to walk to along the // route to a destination, then move to the next point - if (!people._walkTo.empty()) { - people._walkDest = people._walkTo.pop(); - people.setWalking(); + if (!people[PLAYER]._walkTo.empty()) { + people._walkDest = people[PLAYER]._walkTo.pop(); + setWalking(); } else { gotoStand(); } @@ -129,7 +136,6 @@ void ScalpelPerson::adjustSprite() { } } - void ScalpelPerson::gotoStand() { ScalpelMap &map = *(ScalpelMap *)_vm->_map; People &people = *_vm->_people; @@ -181,6 +187,153 @@ void ScalpelPerson::gotoStand() { people._allowWalkAbort = true; } +void ScalpelPerson::setWalking() { + Map &map = *_vm->_map; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + int oldDirection, oldFrame; + Common::Point speed, delta; + + // Flag that player has now walked in the scene + scene._walkedInScene = true; + + // Stop any previous walking, since a new dest is being set + _walkCount = 0; + oldDirection = _sequenceNumber; + oldFrame = _frameNumber; + + // Set speed to use horizontal and vertical movement + if (map._active) { + speed = Common::Point(MWALK_SPEED, MWALK_SPEED); + } else { + speed = Common::Point(XWALK_SPEED, YWALK_SPEED); + } + + // If the player is already close to the given destination that no + // walking is needed, move to the next straight line segment in the + // overall walking route, if there is one + for (;;) { + // Since we want the player to be centered on the destination they + // clicked, but characters draw positions start at their left, move + // the destination half the character width to draw him centered + int temp; + if (people._walkDest.x >= (temp = _imageFrame->_frame.w / 2)) + people._walkDest.x -= temp; + + delta = Common::Point( + ABS(_position.x / FIXED_INT_MULTIPLIER - people._walkDest.x), + ABS(_position.y / FIXED_INT_MULTIPLIER - people._walkDest.y) + ); + + // If we're ready to move a sufficient distance, that's it. Otherwise, + // move onto the next portion of the walk path, if there is one + if ((delta.x > 3 || delta.y > 0) || _walkTo.empty()) + break; + + // Pop next walk segment off the walk route stack + people._walkDest = _walkTo.pop(); + } + + // If a sufficient move is being done, then start the move + if (delta.x > 3 || delta.y) { + // See whether the major movement is horizontal or vertical + if (delta.x >= delta.y) { + // Set the initial frame sequence for the left and right, as well + // as setting the delta x depending on direction + if (people._walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) { + _sequenceNumber = (map._active ? (int)MAP_LEFT : (int)Scalpel::WALK_LEFT); + _delta.x = speed.x * -FIXED_INT_MULTIPLIER; + } else { + _sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)Scalpel::WALK_RIGHT); + _delta.x = speed.x * FIXED_INT_MULTIPLIER; + } + + // See if the x delta is too small to be divided by the speed, since + // this would cause a divide by zero error + if (delta.x >= speed.x) { + // Det the delta y + _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x / speed.x); + if (people._walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) + _delta.y = -_delta.y; + + // Set how many times we should add the delta to the player's position + _walkCount = delta.x / speed.x; + } else { + // The delta x was less than the speed (ie. we're really close to + // the destination). So set delta to 0 so the player won't move + _delta = Point32(0, 0); + _position = Point32(people._walkDest.x * FIXED_INT_MULTIPLIER, people._walkDest.y * FIXED_INT_MULTIPLIER); + + _walkCount = 1; + } + + // See if the sequence needs to be changed for diagonal walking + if (_delta.y > 150) { + if (!map._active) { + switch (_sequenceNumber) { + case Scalpel::WALK_LEFT: + _sequenceNumber = Scalpel::WALK_DOWNLEFT; + break; + case Scalpel::WALK_RIGHT: + _sequenceNumber = Scalpel::WALK_DOWNRIGHT; + break; + } + } + } else if (_delta.y < -150) { + if (!map._active) { + switch (_sequenceNumber) { + case Scalpel::WALK_LEFT: + _sequenceNumber = Scalpel::WALK_UPLEFT; + break; + case Scalpel::WALK_RIGHT: + _sequenceNumber = Scalpel::WALK_UPRIGHT; + break; + } + } + } + } else { + // Major movement is vertical, so set the sequence for up and down, + // and set the delta Y depending on the direction + if (people._walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) { + _sequenceNumber = Scalpel::WALK_UP; + _delta.y = speed.y * -FIXED_INT_MULTIPLIER; + } else { + _sequenceNumber = Scalpel::WALK_DOWN; + _delta.y = speed.y * FIXED_INT_MULTIPLIER; + } + + // If we're on the overhead map, set the sequence so we keep moving + // in the same direction + if (map._active) + _sequenceNumber = (oldDirection == -1) ? MAP_RIGHT : oldDirection; + + // Set the delta x + _delta.x = (delta.x * FIXED_INT_MULTIPLIER) / (delta.y / speed.y); + if (people._walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) + _delta.x = -_delta.x; + + _walkCount = delta.y / speed.y; + } + } + + // See if the new walk sequence is the same as the old. If it's a new one, + // we need to reset the frame number to zero so it's animation starts at + // it's beginning. Otherwise, if it's the same sequence, we can leave it + // as is, so it keeps the animation going at wherever it was up to + if (_sequenceNumber != _oldWalkSequence) + _frameNumber = 0; + _oldWalkSequence = _sequenceNumber; + + if (!_walkCount) + gotoStand(); + + // If the sequence is the same as when we started, then Holmes was + // standing still and we're trying to re-stand him, so reset Holmes' + // rame to the old frame number from before it was reset to 0 + if (_sequenceNumber == oldDirection) + _frameNumber = oldFrame; +} + /*----------------------------------------------------------------*/ ScalpelPeople::ScalpelPeople(SherlockEngine *vm) : People(vm) { diff --git a/engines/sherlock/scalpel/scalpel_people.h b/engines/sherlock/scalpel/scalpel_people.h index cc4e6b6605..cd6deac909 100644 --- a/engines/sherlock/scalpel/scalpel_people.h +++ b/engines/sherlock/scalpel/scalpel_people.h @@ -55,6 +55,12 @@ public: * Bring a moving character to a standing position */ virtual void gotoStand(); + + /** + * Set the variables for moving a character from one poisition to another + * in a straight line + */ + virtual void setWalking(); }; class ScalpelPeople : public People { diff --git a/engines/sherlock/scalpel/scalpel_user_interface.cpp b/engines/sherlock/scalpel/scalpel_user_interface.cpp index a334632b25..2f89dce3b4 100644 --- a/engines/sherlock/scalpel/scalpel_user_interface.cpp +++ b/engines/sherlock/scalpel/scalpel_user_interface.cpp @@ -319,7 +319,7 @@ void ScalpelUserInterface::handleInput() { } else { people._walkDest = pt; people._allowWalkAbort = false; - people.goAllTheWay(); + people[PLAYER].goAllTheWay(); } if (_oldKey != -1) { diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 60ab53cfa0..17e7333055 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -167,7 +167,7 @@ void Talk::talkTo(const Common::String &filename) { // Turn on the Exit option ui._endKeyActive = true; - if (people[PLAYER]._walkCount || people._walkTo.size() > 0) { + if (people[PLAYER]._walkCount || people[PLAYER]._walkTo.size() > 0) { // Only interrupt if an action if trying to do an action, and not just // if the player is walking around the scene if (people._allowWalkAbort) diff --git a/engines/sherlock/tattoo/tattoo_people.h b/engines/sherlock/tattoo/tattoo_people.h index 773f00be53..9022c42929 100644 --- a/engines/sherlock/tattoo/tattoo_people.h +++ b/engines/sherlock/tattoo/tattoo_people.h @@ -92,7 +92,7 @@ public: * Set the variables for moving a character from one poisition to another * in a straight line */ - void setWalking(); + virtual void setWalking(); }; class TattooPeople : public People { |