From a97715f9dcca2022a8f502ded4e4843f076b4687 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 11 Jun 2015 22:55:36 -0400 Subject: SHERLOCK: Refactor gotoStand into Person classes --- engines/sherlock/objects.cpp | 6 +- engines/sherlock/objects.h | 5 + engines/sherlock/people.cpp | 4 +- engines/sherlock/people.h | 7 +- engines/sherlock/scalpel/scalpel_people.cpp | 119 +++++++++++---------- engines/sherlock/scalpel/scalpel_people.h | 11 +- engines/sherlock/scalpel/scalpel_scene.cpp | 4 +- .../sherlock/scalpel/scalpel_user_interface.cpp | 2 +- engines/sherlock/scene.cpp | 6 +- engines/sherlock/scene.h | 4 +- engines/sherlock/talk.cpp | 4 +- engines/sherlock/tattoo/tattoo_people.cpp | 84 +++++++++++++-- engines/sherlock/tattoo/tattoo_people.h | 19 ++-- engines/sherlock/tattoo/tattoo_scene.cpp | 14 +-- 14 files changed, 184 insertions(+), 105 deletions(-) diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 6a0aa5b9ad..120fb997da 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -301,7 +301,7 @@ void Sprite::checkSprite() { obj.setFlagsAndToggles(); talk.talkTo(obj._use[0]._target); } else { - people.gotoStand(*this); + gotoStand(); } break; @@ -311,7 +311,7 @@ void Sprite::checkSprite() { obj.setFlagsAndToggles(); talk.talkTo(obj._use[0]._target); } else { - people.gotoStand(*this); + gotoStand(); } break; @@ -323,7 +323,7 @@ void Sprite::checkSprite() { case WALK_AROUND: if (objBounds.contains(people._walkTo.front())) { // Reached zone - people.gotoStand(*this); + gotoStand(); } else { // Destination not within box, walk to best corner Common::Point walkPos; diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 3c690e960f..b9911c7946 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -304,6 +304,11 @@ public: * This adjusts the sprites position, as well as it's animation sequence: */ virtual void adjustSprite() = 0; + + /** + * Bring a moving character using the sprite to a standing position + */ + virtual void gotoStand() = 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 a7434ae3b7..bb95c51f0f 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -423,7 +423,7 @@ assert(_data[PLAYER]->_position.y >= 10000);/***DEBUG****/ _oldWalkSequence = _data[PLAYER]->_sequenceNumber; if (!_data[PLAYER]->_walkCount) - gotoStand(*_data[PLAYER]); + _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' @@ -456,7 +456,7 @@ void People::walkToCoords(const Point32 &destPos, int destDir) { assert(_data[PLAYER]->_position.y >= 10000);/***DEBUG****/ _data[PLAYER]->_sequenceNumber = destDir; - gotoStand(*_data[PLAYER]); + _data[PLAYER]->gotoStand(); // Draw Holmes facing the new direction scene.doBgAnim(); diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index b45f7b4929..6d8389d9eb 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -58,6 +58,7 @@ struct PersonData { class Person : public Sprite { public: + Common::Queue _walkTo; bool _walkLoaded; Common::String _portrait; @@ -183,12 +184,6 @@ public: * Change the sequence of the scene background object associated with the current speaker. */ virtual void setTalkSequence(int speaker, int sequenceNum = 1) = 0; - - /** - * Bring a moving character to a standing position. If the Scalpel chessboard - * is being displayed, then the chraracter will always face down. - */ - virtual void gotoStand(Sprite &sprite) = 0; }; } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel_people.cpp b/engines/sherlock/scalpel/scalpel_people.cpp index 82840b22a4..4fcdff086a 100644 --- a/engines/sherlock/scalpel/scalpel_people.cpp +++ b/engines/sherlock/scalpel/scalpel_people.cpp @@ -49,7 +49,7 @@ void ScalpelPerson::adjustSprite() { people._walkDest = people._walkTo.pop(); people.setWalking(); } else { - people.gotoStand(*this); + gotoStand(); } } } @@ -57,22 +57,22 @@ void ScalpelPerson::adjustSprite() { if (_type == CHARACTER && !map._active) { if ((_position.y / FIXED_INT_MULTIPLIER) > LOWER_LIMIT) { _position.y = LOWER_LIMIT * FIXED_INT_MULTIPLIER; - people.gotoStand(*this); + gotoStand(); } if ((_position.y / FIXED_INT_MULTIPLIER) < UPPER_LIMIT) { _position.y = UPPER_LIMIT * FIXED_INT_MULTIPLIER; - people.gotoStand(*this); + gotoStand(); } if ((_position.x / FIXED_INT_MULTIPLIER) < LEFT_LIMIT) { _position.x = LEFT_LIMIT * FIXED_INT_MULTIPLIER; - people.gotoStand(*this); + gotoStand(); } if ((_position.x / FIXED_INT_MULTIPLIER) > RIGHT_LIMIT) { _position.x = RIGHT_LIMIT * FIXED_INT_MULTIPLIER; - people.gotoStand(*this); + gotoStand(); } } else if (!map._active) { _position.y = CLIP((int)_position.y, (int)UPPER_LIMIT, (int)LOWER_LIMIT); @@ -118,9 +118,9 @@ void ScalpelPerson::adjustSprite() { if (exit) { scene._goToScene = exit->_scene; - if (exit->_people.x != 0) { - people._hSavedPos = exit->_people; - people._hSavedFacing = exit->_peopleDir; + if (exit->_newPosition.x != 0) { + people._hSavedPos = exit->_newPosition; + people._hSavedFacing = exit->_newFacing; if (people._hSavedFacing > 100 && people._hSavedPos.x < 1) people._hSavedPos.x = 100; @@ -129,6 +129,58 @@ void ScalpelPerson::adjustSprite() { } } + +void ScalpelPerson::gotoStand() { + ScalpelMap &map = *(ScalpelMap *)_vm->_map; + People &people = *_vm->_people; + _walkTo.clear(); + _walkCount = 0; + + switch (_sequenceNumber) { + case Scalpel::WALK_UP: + _sequenceNumber = STOP_UP; + break; + case WALK_DOWN: + _sequenceNumber = STOP_DOWN; + break; + case TALK_LEFT: + case WALK_LEFT: + _sequenceNumber = STOP_LEFT; + break; + case TALK_RIGHT: + case WALK_RIGHT: + _sequenceNumber = STOP_RIGHT; + break; + case WALK_UPRIGHT: + _sequenceNumber = STOP_UPRIGHT; + break; + case WALK_UPLEFT: + _sequenceNumber = STOP_UPLEFT; + break; + case WALK_DOWNRIGHT: + _sequenceNumber = STOP_DOWNRIGHT; + break; + case WALK_DOWNLEFT: + _sequenceNumber = STOP_DOWNLEFT; + break; + default: + break; + } + + // Only restart frame at 0 if the sequence number has changed + if (_oldWalkSequence != -1 || _sequenceNumber == Scalpel::STOP_UP) + _frameNumber = 0; + + if (map._active) { + _sequenceNumber = 0; + people[PLAYER]._position.x = (map[map._charPoint].x - 6) * FIXED_INT_MULTIPLIER; + people[PLAYER]._position.y = (map[map._charPoint].y + 10) * FIXED_INT_MULTIPLIER; + } + + _oldWalkSequence = -1; + people._allowWalkAbort = true; +} + /*----------------------------------------------------------------*/ ScalpelPeople::ScalpelPeople(SherlockEngine *vm) : People(vm) { @@ -237,57 +289,6 @@ void ScalpelPeople::setTalkSequence(int speaker, int sequenceNum) { } } -void ScalpelPeople::gotoStand(Sprite &sprite) { - ScalpelMap &map = *(ScalpelMap *)_vm->_map; - _walkTo.clear(); - sprite._walkCount = 0; - - switch (sprite._sequenceNumber) { - case Scalpel::WALK_UP: - sprite._sequenceNumber = STOP_UP; - break; - case WALK_DOWN: - sprite._sequenceNumber = STOP_DOWN; - break; - case TALK_LEFT: - case WALK_LEFT: - sprite._sequenceNumber = STOP_LEFT; - break; - case TALK_RIGHT: - case WALK_RIGHT: - sprite._sequenceNumber = STOP_RIGHT; - break; - case WALK_UPRIGHT: - sprite._sequenceNumber = STOP_UPRIGHT; - break; - case WALK_UPLEFT: - sprite._sequenceNumber = STOP_UPLEFT; - break; - case WALK_DOWNRIGHT: - sprite._sequenceNumber = STOP_DOWNRIGHT; - break; - case WALK_DOWNLEFT: - sprite._sequenceNumber = STOP_DOWNLEFT; - break; - default: - break; - } - - // Only restart frame at 0 if the sequence number has changed - if (_oldWalkSequence != -1 || sprite._sequenceNumber == Scalpel::STOP_UP) - sprite._frameNumber = 0; - - if (map._active) { - sprite._sequenceNumber = 0; - _data[PLAYER]->_position.x = (map[map._charPoint].x - 6) * FIXED_INT_MULTIPLIER; - _data[PLAYER]->_position.y = (map[map._charPoint].y + 10) * FIXED_INT_MULTIPLIER; - } - - _oldWalkSequence = -1; - _allowWalkAbort = true; -} - - } // End of namespace Scalpel } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel_people.h b/engines/sherlock/scalpel/scalpel_people.h index dac685b26c..cc4e6b6605 100644 --- a/engines/sherlock/scalpel/scalpel_people.h +++ b/engines/sherlock/scalpel/scalpel_people.h @@ -50,6 +50,11 @@ public: * This adjusts the sprites position, as well as it's animation sequence: */ virtual void adjustSprite(); + + /** + * Bring a moving character to a standing position + */ + virtual void gotoStand(); }; class ScalpelPeople : public People { @@ -71,12 +76,6 @@ public: * Change the sequence of the scene background object associated with the specified speaker. */ virtual void setTalkSequence(int speaker, int sequenceNum = 1); - - /** - * Bring a moving character to a standing position. If the Scalpel chessboard - * is being displayed, then the chraracter will always face down. - */ - virtual void gotoStand(Sprite &sprite); }; } // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/scalpel_scene.cpp b/engines/sherlock/scalpel/scalpel_scene.cpp index e3bc6483eb..47ec639559 100644 --- a/engines/sherlock/scalpel/scalpel_scene.cpp +++ b/engines/sherlock/scalpel/scalpel_scene.cpp @@ -660,7 +660,7 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) { if (tpPos.x != -1) { people[PLAYER]._position = tpPos; // Place the player people[PLAYER]._sequenceNumber = tpDir; - people.gotoStand(people[PLAYER]); + people[PLAYER].gotoStand(); } if (playRate < 0) @@ -689,7 +689,7 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) { people[PLAYER]._position = tpPos; people[PLAYER]._sequenceNumber = tpDir; - people.gotoStand(people[PLAYER]); + people[PLAYER].gotoStand(); } events.setCursor(oldCursor); diff --git a/engines/sherlock/scalpel/scalpel_user_interface.cpp b/engines/sherlock/scalpel/scalpel_user_interface.cpp index 31399b0ad9..a334632b25 100644 --- a/engines/sherlock/scalpel/scalpel_user_interface.cpp +++ b/engines/sherlock/scalpel/scalpel_user_interface.cpp @@ -2232,7 +2232,7 @@ void ScalpelUserInterface::checkAction(ActionType &action, const char *const mes // Ensure Holmes is on the exact intended location people[PLAYER]._position = pt; people[PLAYER]._sequenceNumber = dir; - people.gotoStand(people[PLAYER]); + people[PLAYER].gotoStand(); talk.talkTo(action._names[nameIdx].c_str() + 2); if (ch == 'T') diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index b52dfc172a..385c75174a 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -114,9 +114,9 @@ void Exit::load(Common::SeekableReadStream &s, bool isRoseTattoo) { if (!isRoseTattoo) _allow = s.readSint16LE(); - _people.x = s.readSint16LE(); - _people.y = s.readSint16LE(); - _peopleDir = s.readUint16LE(); + _newPosition.x = s.readSint16LE(); + _newPosition.y = s.readSint16LE(); + _newFacing = s.readUint16LE(); if (isRoseTattoo) _allow = s.readSint16LE(); diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 8051d45c2d..f6e9ce1b77 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -79,8 +79,8 @@ class Exit: public Common::Rect { public: int _scene; int _allow; - Common::Point _people; - int _peopleDir; + Common::Point _newPosition; + int _newFacing; Common::String _dest; int _image; // Arrow image to use diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index a968f9fea6..60ab53cfa0 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -173,7 +173,7 @@ void Talk::talkTo(const Common::String &filename) { if (people._allowWalkAbort) abortFlag = true; - people.gotoStand(people[PLAYER]); + people[PLAYER].gotoStand(); } if (_talkToAbort) @@ -965,7 +965,7 @@ void Talk::doScript(const Common::String &script) { _yp = (_talkTo == -1) ? 5 : screen.fontHeight() + 11; if (IS_ROSE_TATTOO) { - for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) { + for (int idx = 0; idx < MAX_CHARACTERS; ++idx) { Person &p = people[idx]; p._savedNpcSequence = p._sequenceNumber; p._savedNpcFrame = p._frameNumber; diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index cc50a32b7b..0e08eb5fd7 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -21,6 +21,7 @@ */ #include "sherlock/tattoo/tattoo_people.h" +#include "sherlock/tattoo/tattoo_scene.h" #include "sherlock/tattoo/tattoo_talk.h" #include "sherlock/sherlock.h" @@ -29,8 +30,83 @@ namespace Sherlock { namespace Tattoo { void TattooPerson::adjustSprite() { - // TODO - warning("TODO: TattooPerson::adjustSprite"); + People &people = *_vm->_people; + TattooScene &scene = *(TattooScene *)_vm->_scene; + + if (_type == INVALID) + return; + + if (_type == CHARACTER && _status) { + // Sprite waiting to move, so restart walk + _walkCount = _status; + _status = 0; + + people._walkDest = _walkTo.front(); + setWalking(); + } else if (_type == CHARACTER && _walkCount) { + if (_walkCount > 10) { + people._walkDest = _walkTo.front(); + setWalking(); + } + + _position += _delta; + if (_walkCount) + --_walkCount; + + if (!_walkCount) { + // If there are remaining points to walk, move to the next one + people._walkDest = _walkTo.pop(); + setWalking(); + } else { + gotoStand(); + } + } + + if (_type != CHARACTER) { + if (_position.y > SHERLOCK_SCREEN_HEIGHT) + _position.y = SHERLOCK_SCREEN_HEIGHT; + + if (_position.y < UPPER_LIMIT) + _position.y = UPPER_LIMIT; + + if (_position.x < LEFT_LIMIT) + _position.x = LEFT_LIMIT; + + if (_position.x > RIGHT_LIMIT) + _position.x = RIGHT_LIMIT; + } + + int frameNum = _frameNumber; + if (frameNum == -1) + frameNum = 0; + int idx = _walkSequences[_sequenceNumber][frameNum]; + if (idx > _maxFrames) + idx = 1; + + // Set the image frame + if (_altSeq) + _imageFrame = &(*_altImages)[idx - 1]; + else + _imageFrame = &(*_images)[idx - 1]; + + // See if the player has come to a stop after clicking on an Arrow zone to leave the scene. + // If so, this will set up the exit information for the scene transition + if (!_walkCount && scene._exitZone != -1 && scene._walkedInScene && scene._goToScene != -1 && + !_description.compareToIgnoreCase(people[PLAYER]._description)) { + people._hSavedPos = scene._exits[scene._exitZone]._newPosition; + people._hSavedFacing = scene._exits[scene._exitZone]._newFacing; + + if (people._hSavedFacing > 100 && people._hSavedPos.x < 1) + people._hSavedPos.x = 100; + } +} + +void TattooPerson::gotoStand() { + error("TODO: gotoStand"); +} + +void TattooPerson::setWalking() { + error("TODO: setWalking"); } /*----------------------------------------------------------------*/ @@ -236,10 +312,6 @@ void TattooPeople::synchronize(Serializer &s) { } } -void TattooPeople::gotoStand(Sprite &sprite) { - error("TODO: gotoStand"); -} - } // End of namespace Tattoo } // End of namespace Sherlock diff --git a/engines/sherlock/tattoo/tattoo_people.h b/engines/sherlock/tattoo/tattoo_people.h index 455b9489e4..773f00be53 100644 --- a/engines/sherlock/tattoo/tattoo_people.h +++ b/engines/sherlock/tattoo/tattoo_people.h @@ -72,6 +72,8 @@ enum TattooSequences { }; class TattooPerson: public Person { +private: + bool checkCollision() const; public: TattooPerson() : Person() {} virtual ~TattooPerson() {} @@ -80,6 +82,17 @@ public: * This adjusts the sprites position, as well as it's animation sequence: */ virtual void adjustSprite(); + + /** + * 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 + */ + void setWalking(); }; class TattooPeople : public People { @@ -107,12 +120,6 @@ public: * Change the sequence of the scene background object associated with the specified speaker. */ virtual void setTalkSequence(int speaker, int sequenceNum = 1); - - /** - * Bring a moving character to a standing position. If the Scalpel chessboard - * is being displayed, then the chraracter will always face down. - */ - virtual void gotoStand(Sprite &sprite); }; } // End of namespace Scalpel diff --git a/engines/sherlock/tattoo/tattoo_scene.cpp b/engines/sherlock/tattoo/tattoo_scene.cpp index 20b690f016..7ac2c18aea 100644 --- a/engines/sherlock/tattoo/tattoo_scene.cpp +++ b/engines/sherlock/tattoo/tattoo_scene.cpp @@ -157,7 +157,7 @@ void TattooScene::drawAllShapes() { } // Queue all active characters for drawing - for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) { + for (int idx = 0; idx < MAX_CHARACTERS; ++idx) { if (people[idx]._type == CHARACTER && people[idx]._walkLoaded) shapeList.push_back(ShapeEntry(&people[idx], people[idx]._position.y / FIXED_INT_MULTIPLIER)); } @@ -364,7 +364,7 @@ void TattooScene::doBgAnimEraseBackground() { ui.doBgAnimRestoreUI(); // Restore background for any areas covered by characters and shapes - for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) + for (int idx = 0; idx < MAX_CHARACTERS; ++idx) screen.restoreBackground(Common::Rect(people[idx]._oldPosition.x, people[idx]._oldPosition.y, people[idx]._oldPosition.x + people[idx]._oldSize.x, people[idx]._oldPosition.y + people[idx]._oldSize.y)); @@ -428,7 +428,7 @@ void TattooScene::doBgAnim() { talk._talkToAbort = false; // Check the characters and sprites for updates - for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) { + for (int idx = 0; idx < MAX_CHARACTERS; ++idx) { if (people[idx]._type == CHARACTER) people[idx].checkSprite(); } @@ -461,7 +461,7 @@ void TattooScene::doBgAnim() { _doBgAnimDone = false; ui._drawMenu = false; - for (uint idx = 1; idx < MAX_CHARACTERS; ++idx) { + for (int idx = 1; idx < MAX_CHARACTERS; ++idx) { if (people[idx]._updateNPCPath) people[idx].updateNPC(); } @@ -478,7 +478,7 @@ void TattooScene::doBgAnimUpdateBgObjectsAndAnim() { obj.adjustObject(); } - for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) { + for (int idx = 0; idx < MAX_CHARACTERS; ++idx) { if (people[idx]._type == CHARACTER) people[idx].adjustSprite(); } @@ -572,7 +572,7 @@ void TattooScene::updateBackground() { screen._flushScreen = true; - for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) { + for (int idx = 0; idx < MAX_CHARACTERS; ++idx) { Person &p = people[idx]; if (p._type != INVALID) { @@ -640,7 +640,7 @@ void TattooScene::doBgAnimDrawSprites() { Screen &screen = *_vm->_screen; TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui; - for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) { + for (int idx = 0; idx < MAX_CHARACTERS; ++idx) { Person &person = people[idx]; if (person._type != INVALID) { -- cgit v1.2.3