aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicola Mettifogo2009-02-23 11:55:25 +0000
committerNicola Mettifogo2009-02-23 11:55:25 +0000
commit9bef5a0cfc5dcc0708d9f7d10e63b0b550d3243b (patch)
treee5822ffebb754d1c726712051f9f576f1326f3f6
parentedaf382d2fb46403fa437e6113c90754230dc2e9 (diff)
downloadscummvm-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.cpp132
-rw-r--r--engines/parallaction/objects.cpp6
-rw-r--r--engines/parallaction/objects.h7
-rw-r--r--engines/parallaction/parallaction.h16
-rw-r--r--engines/parallaction/parallaction_ns.cpp12
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