Skip to content

Commit

Permalink
SHERLOCK: RT: Implement setWalking
Browse files Browse the repository at this point in the history
  • Loading branch information
dreammaster committed Jun 13, 2015
1 parent 864dc6a commit 02f582d
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 20 deletions.
24 changes: 12 additions & 12 deletions engines/sherlock/scalpel/scalpel_people.cpp
Expand Up @@ -241,10 +241,10 @@ void ScalpelPerson::setWalking() {
// 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);
_sequenceNumber = (map._active ? (int)MAP_LEFT : (int)WALK_LEFT);
_delta.x = speed.x * -FIXED_INT_MULTIPLIER;
} else {
_sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)Scalpel::WALK_RIGHT);
_sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)WALK_RIGHT);
_delta.x = speed.x * FIXED_INT_MULTIPLIER;
}

Expand All @@ -271,22 +271,22 @@ void ScalpelPerson::setWalking() {
if (_delta.y > 150) {
if (!map._active) {
switch (_sequenceNumber) {
case Scalpel::WALK_LEFT:
_sequenceNumber = Scalpel::WALK_DOWNLEFT;
case WALK_LEFT:
_sequenceNumber = WALK_DOWNLEFT;
break;
case Scalpel::WALK_RIGHT:
_sequenceNumber = Scalpel::WALK_DOWNRIGHT;
case WALK_RIGHT:
_sequenceNumber = WALK_DOWNRIGHT;
break;
}
}
} else if (_delta.y < -150) {
if (!map._active) {
switch (_sequenceNumber) {
case Scalpel::WALK_LEFT:
_sequenceNumber = Scalpel::WALK_UPLEFT;
case WALK_LEFT:
_sequenceNumber = WALK_UPLEFT;
break;
case Scalpel::WALK_RIGHT:
_sequenceNumber = Scalpel::WALK_UPRIGHT;
case WALK_RIGHT:
_sequenceNumber = WALK_UPRIGHT;
break;
}
}
Expand All @@ -295,10 +295,10 @@ void ScalpelPerson::setWalking() {
// 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;
_sequenceNumber = WALK_UP;
_delta.y = speed.y * -FIXED_INT_MULTIPLIER;
} else {
_sequenceNumber = Scalpel::WALK_DOWN;
_sequenceNumber = WALK_DOWN;
_delta.y = speed.y * FIXED_INT_MULTIPLIER;
}

Expand Down
177 changes: 176 additions & 1 deletion engines/sherlock/tattoo/tattoo_people.cpp
Expand Up @@ -31,6 +31,32 @@ namespace Tattoo {

#define FACING_PLAYER 16

static const int WALK_SPEED_X[99] = {
90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 98, 90, 90, 90, 90, 90, 91, 90, 90,
90, 90,100, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,100, 90,
90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,103, 90, 90, 90, 90, 90, 90, 90,
90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90
};

static const int WALK_SPEED_Y[99] = {
28, 28, 28, 28, 28, 28, 28, 28, 28, 32, 32, 32, 28, 28, 28, 28, 28, 26, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
32, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 31, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28
};

static const int WALK_SPEED_DIAG_X[99] = {
50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 90, 50, 50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50
};

/*----------------------------------------------------------------*/

TattooPerson::TattooPerson() : Person() {
Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0);
_tempX = _tempScaleVal = 0;
Expand Down Expand Up @@ -243,7 +269,156 @@ void TattooPerson::gotoStand() {
}

void TattooPerson::setWalking() {
warning("TODO: setWalking");
People &people = *_vm->_people;
TattooScene &scene = *(TattooScene *)_vm->_scene;
int oldDirection, oldFrame;
Common::Point 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
int scaleVal = scene.getScaleVal(_position);
Common::Point speed(MAX(WALK_SPEED_X[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2),
MAX(WALK_SPEED_Y[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2));
Common::Point diagSpeed(MAX((WALK_SPEED_Y[scene._currentScene - 1] - 2) * SCALE_THRESHOLD / scaleVal, 2),
MAX(WALK_SPEED_DIAG_X[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2));

// 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 = WALK_LEFT;
_delta.x = speed.x * -FIXED_INT_MULTIPLIER;
} else {
_sequenceNumber = 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 > 1500) {
if (_sequenceNumber == WALK_LEFT || _sequenceNumber == WALK_RIGHT) {
_delta.x = _delta.x / speed.x * diagSpeed.x;
_delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x * 10 / diagSpeed.x);
}

switch (_sequenceNumber) {
case WALK_LEFT:
_sequenceNumber = WALK_DOWNLEFT;
break;
case WALK_RIGHT:
_sequenceNumber = WALK_DOWNRIGHT;
break;
}
} else if (_delta.y < -1500) {
if (_sequenceNumber == WALK_LEFT || _sequenceNumber == WALK_RIGHT) {
_delta.x = _delta.x / speed.x * diagSpeed.x;
_delta.y = -1 * (delta.y * FIXED_INT_MULTIPLIER) / (delta.x * 10 / diagSpeed.x);
}

switch (_sequenceNumber) {
case WALK_LEFT:
_sequenceNumber = WALK_UPLEFT;
break;
case WALK_RIGHT:
_sequenceNumber = 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 = WALK_UP;
_delta.y = speed.y * -FIXED_INT_MULTIPLIER;
} else {
_sequenceNumber = WALK_DOWN;
_delta.y = speed.y * FIXED_INT_MULTIPLIER;
}

// 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) {
if (_seqTo) {
// Reset to previous value
_walkSequences[oldDirection]._sequences[_frameNumber] = _seqTo;
_seqTo = 0;
}
_frameNumber = 0;
}

checkWalkGraphics();
_oldWalkSequence = _sequenceNumber;

if (!_walkCount && _walkTo.empty())
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;
}

void TattooPerson::clearNPC() {
Expand Down
12 changes: 6 additions & 6 deletions engines/sherlock/tattoo/tattoo_scene.h
Expand Up @@ -63,12 +63,6 @@ class TattooScene : public Scene {

void doBgAnimDrawSprites();

/**
* Returns the scale value for the passed co-ordinates. This is taken from the scene's
* scale zones, interpolating inbetween the top and bottom values of the zones as needed
*/
int getScaleVal(const Common::Point &pt);

/**
* Makes a greyscale translation table for each palette entry in the table
*/
Expand Down Expand Up @@ -121,6 +115,12 @@ class TattooScene : public Scene {
public:
TattooScene(SherlockEngine *vm);

/**
* Returns the scale value for the passed co-ordinates. This is taken from the scene's
* scale zones, interpolating inbetween the top and bottom values of the zones as needed
*/
int getScaleVal(const Common::Point &pt);

/**
* Draw all objects and characters.
*/
Expand Down
2 changes: 1 addition & 1 deletion engines/sherlock/tattoo/tattoo_user_interface.cpp
Expand Up @@ -370,7 +370,7 @@ void TattooUserInterface::doStandardControl() {
if (events._rightReleased) {
// Show the verbs menu for the highlighted object
activateVerbMenu(!noDesc);
} else if (_personFound || (_bgFound < 1000 && _bgShape->_aType == PERSON)) {
} else if (_personFound || (_bgFound != -1 && _bgFound < 1000 && _bgShape->_aType == PERSON)) {
// The object found is a person (the default for people is TALK)
talk.talk(_bgFound);
_activeObj = -1;
Expand Down

0 comments on commit 02f582d

Please sign in to comment.