aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/sherlock/objects.cpp8
-rw-r--r--engines/sherlock/objects.h6
-rw-r--r--engines/sherlock/people.cpp338
-rw-r--r--engines/sherlock/people.h25
-rw-r--r--engines/sherlock/scalpel/scalpel_map.cpp16
-rw-r--r--engines/sherlock/scalpel/scalpel_people.cpp161
-rw-r--r--engines/sherlock/scalpel/scalpel_people.h6
-rw-r--r--engines/sherlock/scalpel/scalpel_user_interface.cpp2
-rw-r--r--engines/sherlock/talk.cpp2
-rw-r--r--engines/sherlock/tattoo/tattoo_people.h2
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 {