diff options
author | Nicola Mettifogo | 2009-02-23 11:55:25 +0000 |
---|---|---|
committer | Nicola Mettifogo | 2009-02-23 11:55:25 +0000 |
commit | 9bef5a0cfc5dcc0708d9f7d10e63b0b550d3243b (patch) | |
tree | e5822ffebb754d1c726712051f9f576f1326f3f6 | |
parent | edaf382d2fb46403fa437e6113c90754230dc2e9 (diff) | |
download | scummvm-rg350-9bef5a0cfc5dcc0708d9f7d10e63b0b550d3243b.tar.gz scummvm-rg350-9bef5a0cfc5dcc0708d9f7d10e63b0b550d3243b.tar.bz2 scummvm-rg350-9bef5a0cfc5dcc0708d9f7d10e63b0b550d3243b.zip |
Rewrote the sarcophagus puzzle in Nippon Safes, since I finally understood how it was implemented in the original!
svn-id: r38816
-rw-r--r-- | engines/parallaction/callables_ns.cpp | 132 | ||||
-rw-r--r-- | engines/parallaction/objects.cpp | 6 | ||||
-rw-r--r-- | engines/parallaction/objects.h | 7 | ||||
-rw-r--r-- | engines/parallaction/parallaction.h | 16 | ||||
-rw-r--r-- | engines/parallaction/parallaction_ns.cpp | 12 |
5 files changed, 105 insertions, 68 deletions
diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp index 517d33a8e2..de19ccc2dc 100644 --- a/engines/parallaction/callables_ns.cpp +++ b/engines/parallaction/callables_ns.cpp @@ -178,75 +178,95 @@ void Parallaction_ns::_c_fade(void *parm) { } - -void Parallaction_ns::_c_moveSarc(void *parm) { - - AnimationPtr a; - - if (_introSarcData2 != 0) { - - _introSarcData2 = 0; - if (!_moveSarcZones[0]) { - - _moveSarcZones[0] = _location.findZone("sarc1"); - _moveSarcZones[1] = _location.findZone("sarc2"); - _moveSarcZones[2] = _location.findZone("sarc3"); - _moveSarcZones[3] = _location.findZone("sarc4"); - _moveSarcZones[4] = _location.findZone("sarc5"); - - _moveSarcExaZones[0] = _location.findZone("sarc1exa"); - _moveSarcExaZones[1] = _location.findZone("sarc2exa"); - _moveSarcExaZones[2] = _location.findZone("sarc3exa"); - _moveSarcExaZones[3] = _location.findZone("sarc4exa"); - _moveSarcExaZones[4] = _location.findZone("sarc5exa"); - - } - - a = _location.findAnimation("sposta"); - - _moveSarcZone1 = *(ZonePtr*)parm; - - for (uint16 _si = 0; _si < 5; _si++) { - if (_moveSarcZones[_si] == _moveSarcZone1) { - _moveSarcZone0 = _moveSarcExaZones[_si]; - } +void Parallaction_ns::startMovingSarcophagus(ZonePtr sarc) { + if (!_moveSarcGetZones[0]) { + // bind sarcophagi zones + _moveSarcGetZones[0] = _location.findZone("sarc1"); + _moveSarcGetZones[1] = _location.findZone("sarc2"); + _moveSarcGetZones[2] = _location.findZone("sarc3"); + _moveSarcGetZones[3] = _location.findZone("sarc4"); + _moveSarcGetZones[4] = _location.findZone("sarc5"); + + _moveSarcExaZones[0] = _location.findZone("sarc1exa"); + _moveSarcExaZones[1] = _location.findZone("sarc2exa"); + _moveSarcExaZones[2] = _location.findZone("sarc3exa"); + _moveSarcExaZones[3] = _location.findZone("sarc4exa"); + _moveSarcExaZones[4] = _location.findZone("sarc5exa"); + } + /* + Each sarcophagus is made of 2 visible zones: one responds to + 'get' actions, the other to 'examine'. We need to find out + both so they can be moved. + */ + for (uint16 i = 0; i < 5; i++) { + if (_moveSarcGetZones[i] == sarc) { + _moveSarcExaZone = _moveSarcExaZones[i]; + _moveSarcGetZone = _moveSarcGetZones[i]; } + } - _introSarcData1 = _introSarcData3 - _moveSarcZone1->getX(); - a->setZ(_introSarcData3); - a->setF(_moveSarcZone1->getY() - (_introSarcData1 / 20)); - _introSarcData3 = _moveSarcZone1->getX(); - - if (_introSarcData1 > 0) { - a->setX(_introSarcData1 / 2); - a->setY(2); - } else { - a->setX(-_introSarcData1 / 2); - a->setY(-2); - } + // calculate destination for the sarcophagus + int16 destX = _freeSarcophagusSlotX; + _sarcophagusDeltaX = destX - _moveSarcGetZone->getX(); // x movement delta + int16 destY = _moveSarcGetZone->getY() - (_sarcophagusDeltaX / 20); // gently degrade y when moving sideways + + // set the new empty position (maybe this should be done on stopMovingSarcophagus?) + _freeSarcophagusSlotX = _moveSarcGetZone->getX(); + + // calculate which way and how many steps the character should move + int16 numSteps = _sarcophagusDeltaX / 2; // default to right + int16 delta = 2; // default to right + if (_sarcophagusDeltaX < 0) { + // move left + numSteps = -numSteps; // keep numSteps positive + delta = -delta; // make delta negative if moving to left + } - return; + // GROSS HACK: since there is no obvious way to provide additional parameters to a script, + // the game packs the data needed to calculate the position of the 'sposta' animation in + // the coordinate fields of the animation itself, which are accessible from the scripts. + // In detail: the sarcophagus destination coords are stored into Z and F, while the number + // of calculated steps and step length in X and Y. See any of the sarc#.script files in + // disk2 for details about unpacking. + AnimationPtr a = _location.findAnimation("sposta"); + a->forceXYZF(numSteps, delta, destX, destY); + + // start moving + _movingSarcophagus = true; +} - } +void Parallaction_ns::stopMovingSarcophagus() { - _introSarcData2 = 1; - _moveSarcZone1->translate(_introSarcData1, -_introSarcData1 / 20); - _moveSarcZone0->translate(_introSarcData1, -_introSarcData1 / 20); + // moves both sarcophagus zones at the destination, so that the user + // can interact with them + _moveSarcGetZone->translate(_sarcophagusDeltaX, -_sarcophagusDeltaX / 20); + _moveSarcExaZone->translate(_sarcophagusDeltaX, -_sarcophagusDeltaX / 20); - if (_moveSarcZones[0]->getX() == 35 && - _moveSarcZones[1]->getX() == 68 && - _moveSarcZones[2]->getX() == 101 && - _moveSarcZones[3]->getX() == 134 && - _moveSarcZones[4]->getX() == 167) { + _zonesToUpdate.push_back(_moveSarcGetZone); - a = _location.findAnimation("finito"); + // check if the puzzle has been completed, by verifying the position of + // the sarcophagi + if (_moveSarcGetZones[0]->getX() == 35 && + _moveSarcGetZones[1]->getX() == 68 && + _moveSarcGetZones[2]->getX() == 101 && + _moveSarcGetZones[3]->getX() == 134 && + _moveSarcGetZones[4]->getX() == 167) { + AnimationPtr a = _location.findAnimation("finito"); a->_flags |= (kFlagsActive | kFlagsActing); setLocationFlags(0x20); // GROSS HACK: activates 'finito' flag in dinoit_museo.loc } - return; + // stop moving + _movingSarcophagus = false; +} +void Parallaction_ns::_c_moveSarc(void *parm) { + if (!_movingSarcophagus) { + startMovingSarcophagus(*(ZonePtr*)parm); + } else { + stopMovingSarcophagus(); + } } diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp index 1016ddd670..8a3ae135ab 100644 --- a/engines/parallaction/objects.cpp +++ b/engines/parallaction/objects.cpp @@ -105,6 +105,12 @@ void Animation::setF(int16 value) { _frame = CLIP(value, min, max); } +void Animation::forceXYZF(int16 x, int16 y, int16 z, int16 f) { + _left = x; + _top = y; + _z = z; + _frame = f; +} #define NUM_LOCALS 10 char _localNames[NUM_LOCALS][10]; diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h index 26255d7519..029c498948 100644 --- a/engines/parallaction/objects.h +++ b/engines/parallaction/objects.h @@ -515,6 +515,13 @@ public: void getFrameRect(Common::Rect &r) const; int16 getBottom() const; + // HACK: this routine is only used to download initialisation + // parameter to a script used when moving sarcophagi around in + // the museum. It bypasses all the consistency checks that + // can be performed by the individual setters. See the comment + // in startMovingSarcophagus() in callables_ns.cpp + void forceXYZF(int16 x, int16 y, int16 z, int16 f); + // getters/setters used by scripts int16 getX() { return _left; } void setX(int16 value) { _left = value; } diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index 319313c475..d106a1829a 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -409,19 +409,21 @@ private: void loadProgram(AnimationPtr a, const char *filename); void freeLocation(bool removeAll); void freeCharacter(); + void startMovingSarcophagus(ZonePtr sarc); + void stopMovingSarcophagus(); // callables data typedef void (Parallaction_ns::*Callable)(void*); const Callable *_callables; - ZonePtr _moveSarcZone0; - ZonePtr _moveSarcZone1; - uint16 num_foglie; - int16 _introSarcData1; - uint16 _introSarcData2; // sarcophagus stuff to be saved - uint16 _introSarcData3; // sarcophagus stuff to be saved - ZonePtr _moveSarcZones[5]; + ZonePtr _moveSarcGetZone; + ZonePtr _moveSarcExaZone; + ZonePtr _moveSarcGetZones[5]; ZonePtr _moveSarcExaZones[5]; + uint16 num_foglie; + int16 _sarcophagusDeltaX; + bool _movingSarcophagus; // sarcophagus stuff to be saved + uint16 _freeSarcophagusSlotX; // sarcophagus stuff to be saved AnimationPtr _rightHandAnim; bool _intro; static const Callable _dosCallables[25]; diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp index f1ce4fccce..40be52c211 100644 --- a/engines/parallaction/parallaction_ns.cpp +++ b/engines/parallaction/parallaction_ns.cpp @@ -35,6 +35,8 @@ namespace Parallaction { +#define INITIAL_FREE_SARCOPHAGUS_SLOT_X 200 + class LocationName { @@ -182,9 +184,9 @@ Common::Error Parallaction_ns::init() { _programExec = new ProgramExec_ns(this); _programExec->init(); - _introSarcData1 = 0; - _introSarcData2 = 1; - _introSarcData3 = 200; + _sarcophagusDeltaX = 0; + _movingSarcophagus = false; + _freeSarcophagusSlotX = INITIAL_FREE_SARCOPHAGUS_SLOT_X; num_foglie = 0; @@ -479,8 +481,8 @@ void Parallaction_ns::cleanupGame() { freeLocation(true); _score = 0; - _introSarcData3 = 200; - _introSarcData2 = 1; + _freeSarcophagusSlotX = INITIAL_FREE_SARCOPHAGUS_SLOT_X; + _movingSarcophagus = false; } } // namespace Parallaction |