aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock/tattoo
diff options
context:
space:
mode:
authorPaul Gilbert2015-06-17 22:04:52 -0400
committerPaul Gilbert2015-06-17 22:04:52 -0400
commit94d7928dbc7ea1d2de0e82f69a3b5d255f2319fd (patch)
treeca08be388ea7f197a4a317c23d6b6cdf666d5911 /engines/sherlock/tattoo
parent65b794a7505aeb5ab1667e8fd9ac5de687478757 (diff)
downloadscummvm-rg350-94d7928dbc7ea1d2de0e82f69a3b5d255f2319fd.tar.gz
scummvm-rg350-94d7928dbc7ea1d2de0e82f69a3b5d255f2319fd.tar.bz2
scummvm-rg350-94d7928dbc7ea1d2de0e82f69a3b5d255f2319fd.zip
SHERLOCK: RT: Implemented pullNPCPath
Diffstat (limited to 'engines/sherlock/tattoo')
-rw-r--r--engines/sherlock/tattoo/tattoo_people.cpp56
-rw-r--r--engines/sherlock/tattoo/tattoo_people.h30
-rw-r--r--engines/sherlock/tattoo/tattoo_talk.cpp8
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;