mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-05 01:38:36 +00:00
Rewrote the sarcophagus puzzle in Nippon Safes, since I finally understood how it was implemented in the original!
svn-id: r38816
This commit is contained in:
parent
edaf382d2f
commit
9bef5a0cfc
@ -178,75 +178,95 @@ void Parallaction_ns::_c_fade(void *parm) {
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
|
||||
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");
|
||||
|
||||
_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];
|
||||
}
|
||||
|
||||
a = _location.findAnimation("sposta");
|
||||
|
||||
_moveSarcZone1 = *(ZonePtr*)parm;
|
||||
|
||||
for (uint16 _si = 0; _si < 5; _si++) {
|
||||
if (_moveSarcZones[_si] == _moveSarcZone1) {
|
||||
_moveSarcZone0 = _moveSarcExaZones[_si];
|
||||
}
|
||||
}
|
||||
|
||||
_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);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
_introSarcData2 = 1;
|
||||
_moveSarcZone1->translate(_introSarcData1, -_introSarcData1 / 20);
|
||||
_moveSarcZone0->translate(_introSarcData1, -_introSarcData1 / 20);
|
||||
// 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
|
||||
|
||||
if (_moveSarcZones[0]->getX() == 35 &&
|
||||
_moveSarcZones[1]->getX() == 68 &&
|
||||
_moveSarcZones[2]->getX() == 101 &&
|
||||
_moveSarcZones[3]->getX() == 134 &&
|
||||
_moveSarcZones[4]->getX() == 167) {
|
||||
// set the new empty position (maybe this should be done on stopMovingSarcophagus?)
|
||||
_freeSarcophagusSlotX = _moveSarcGetZone->getX();
|
||||
|
||||
a = _location.findAnimation("finito");
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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() {
|
||||
|
||||
// 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);
|
||||
|
||||
_zonesToUpdate.push_back(_moveSarcGetZone);
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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; }
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user