diff options
-rw-r--r-- | engines/sherlock/tattoo/tattoo_people.cpp | 56 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_people.h | 30 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_talk.cpp | 8 |
3 files changed, 86 insertions, 8 deletions
diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 6c1e064916..3895f43831 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -89,11 +89,26 @@ static const int WALK_SPEED_DIAG_X[99] = { /*----------------------------------------------------------------*/ +SavedNPCPath::SavedNPCPath() { + Common::fill(&_path[0], &_path[MAX_NPC_PATH], 0); + _npcIndex = 0; + _npcPause = 0; + _npcFacing = 0; + _lookHolmes = false; +} + +SavedNPCPath::SavedNPCPath(byte path[MAX_NPC_PATH], int npcIndex, int npcPause, const Common::Point &walkDest, + int npcFacing, bool lookHolmes) : _npcIndex(npcIndex), _npcPause(npcPause), _walkDest(walkDest), + _npcFacing(npcFacing), _lookHolmes(lookHolmes) { + Common::copy(&path[0], &path[MAX_NPC_PATH], &_path[0]); +} + +/*----------------------------------------------------------------*/ + TattooPerson::TattooPerson() : Person() { Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0); _tempX = _tempScaleVal = 0; _npcIndex = 0; - _npcStack = 0; _npcMoved = false; _npcFacing = -1; _resetNPCPath = true; @@ -573,7 +588,8 @@ void TattooPerson::walkToCoords(const Point32 &destPos, int destDir) { void TattooPerson::clearNPC() { Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0); - _npcIndex = _npcStack = 0; + _npcIndex = 0; + _pathStack.clear(); _npcName = ""; } @@ -796,7 +812,41 @@ void TattooPerson::updateNPC() { } void TattooPerson::pushNPCPath() { - warning("TODO: pushNPCPath"); + assert(_pathStack.size() < 2); + SavedNPCPath savedPath(_npcPath, _npcIndex, _npcPause, _position, _sequenceNumber, _lookHolmes); + _pathStack.push(savedPath); +} + +void TattooPerson::pullNPCPath() { + // Pop the stack entry and restore the fields + SavedNPCPath path = _pathStack.pop(); + Common::copy(&path._path[0], &path._path[MAX_NPC_PATH], &_npcPath[0]); + _npcIndex = path._npcIndex; + _npcPause = path._npcPause; + + // Handle the first case if the NPC was paused + if (_npcPause) { + _walkDest = Common::Point(path._walkDest.x / FIXED_INT_MULTIPLIER, path._walkDest.y / FIXED_INT_MULTIPLIER); + _npcFacing = path._npcFacing; + _lookHolmes = path._lookHolmes; + + // See if the NPC was moved + if (_walkDest.x != (_position.x / FIXED_INT_MULTIPLIER) || + _walkDest.y != (_position.y / FIXED_INT_MULTIPLIER)) { + goAllTheWay(); + _npcPause = 0; + _npcIndex -= 3; + } else { + // See if we need to set the old walk sequence so the NPC will put his arms up if he turns another way + if (_npcFacing != _sequenceNumber) + _oldWalkSequence = _sequenceNumber; + + gotoStand(); + } + } else { + // Handle the second case if the NPC was in motion + _npcIndex -= 6; + } } Common::Point TattooPerson::getSourcePoint() const { diff --git a/engines/sherlock/tattoo/tattoo_people.h b/engines/sherlock/tattoo/tattoo_people.h index 36027fd9cb..1abf2d5350 100644 --- a/engines/sherlock/tattoo/tattoo_people.h +++ b/engines/sherlock/tattoo/tattoo_people.h @@ -24,6 +24,7 @@ #define SHERLOCK_TATTOO_PEOPLE_H #include "common/scummsys.h" +#include "common/stack.h" #include "sherlock/people.h" namespace Sherlock { @@ -83,6 +84,19 @@ enum NpcPath { NPCPATH_IFFLAG_GOTO_LABEL = 9 }; +struct SavedNPCPath { + byte _path[MAX_NPC_PATH]; + int _npcIndex; + int _npcPause; + Common::Point _walkDest; + int _npcFacing; + bool _lookHolmes; + + SavedNPCPath(); + SavedNPCPath(byte path[MAX_NPC_PATH], int npcIndex, int npcPause, const Common::Point &walkDest, + int npcFacing, bool lookHolmes); +}; + class TattooPerson: public Person { private: Point32 _nextDest; @@ -99,8 +113,8 @@ protected: */ virtual Common::Point getSourcePoint() const; public: + Common::Stack<SavedNPCPath> _pathStack; int _npcIndex; - int _npcStack; int _npcPause; byte _npcPath[MAX_NPC_PATH]; Common::String _npcName; @@ -139,6 +153,20 @@ public: void pushNPCPath(); /** + * Pull an NPC's path data that has been previously saved on the path stack for that character. + * There are two possibilities for when the NPC was interrupted, and both are handled differently: + * 1) The NPC was paused at a position + * If the NPC didn't move, we can just restore his pause counter and exit. But if he did move, + * he must return to that position, and the path index must be reset to the pause he was executing. + * This means that the index must be decremented by 3 + * 2) The NPC was in route to a position + * He must be set to walk to that position again. This is done by moving the path index + * so that it points to the code that set the NPC walking there in the first place. + * The regular calls to updateNPC will handle the rest + */ + void pullNPCPath(); + + /** * Checks a sprite associated with an NPC to see if the frame sequence specified * in the sequence number uses alternate graphics, and if so if they need to be loaded */ diff --git a/engines/sherlock/tattoo/tattoo_talk.cpp b/engines/sherlock/tattoo/tattoo_talk.cpp index c64ae2e805..ef00c3c35a 100644 --- a/engines/sherlock/tattoo/tattoo_talk.cpp +++ b/engines/sherlock/tattoo/tattoo_talk.cpp @@ -704,7 +704,7 @@ OpcodeReturn TattooTalk::cmdWalkHolmesAndNPCToCAnimation(const byte *&str) { Scene &scene = *_vm->_scene; CAnim &anim = scene._cAnim[cAnimNum]; - if (person._npcStack == 0) + if (person._pathStack.empty()) person.pushNPCPath(); person._npcMoved = true; @@ -730,7 +730,7 @@ OpcodeReturn TattooTalk::cmdWalkNPCToCAnimation(const byte *&str) { Scene &scene = *_vm->_scene; CAnim &anim = scene._cAnim[cAnimNum]; - if (person._npcStack == 0) + if (person._pathStack.empty()) person.pushNPCPath(); person._npcMoved = true; @@ -752,7 +752,7 @@ OpcodeReturn TattooTalk::cmdWalkNPCToCoords(const byte *&str) { TattooPeople &people = *(TattooPeople *)_vm->_people; TattooPerson &person = people[npcNum]; - if (person._npcStack == 0) + if (person._pathStack.empty()) person.pushNPCPath(); person._npcMoved = true; @@ -779,7 +779,7 @@ OpcodeReturn TattooTalk::cmdWalkHomesAndNPCToCoords(const byte *&str) { TattooPeople &people = *(TattooPeople *)_vm->_people; TattooPerson &person = people[npcNum]; - if (person._npcStack == 0) + if (person._pathStack.empty()) person.pushNPCPath(); person._npcMoved = true; |