scummvm/engines/avalanche/trip6.cpp

1639 lines
45 KiB
C++
Raw Normal View History

2013-06-27 12:13:00 +02:00
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
/*
* This code is based on the original source code of Lord Avalot d'Argent version 1.3.
* Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
*/
/* TRIP5 Trippancy V - the sprite animation subsystem */
2013-06-27 12:13:00 +02:00
#include "avalanche/avalanche.h"
2013-06-29 16:36:40 +02:00
#include "avalanche/trip6.h"
2013-06-27 12:13:00 +02:00
#include "avalanche/scrolls2.h"
#include "avalanche/lucerna2.h"
#include "avalanche/visa2.h"
#include "avalanche/gyro2.h"
#include "avalanche/celer2.h"
#include "avalanche/sequence2.h"
#include "avalanche/timeout2.h"
#include "avalanche/enid2.h"
2013-06-29 16:36:40 +02:00
#include "common/scummsys.h"
#include "common/textconsole.h"
#include "common/file.h"
2013-06-29 16:36:40 +02:00
2013-06-27 12:13:00 +02:00
namespace Avalanche {
void triptype::init(byte spritenum, bool do_check, Trip *tr) {
_tr = tr;
const int32 idshould = -1317732048;
2013-09-04 12:02:01 +02:00
byte fv;
int32 id;
Common::File inf;
if (spritenum == 177)
return; // Already running!
Common::String filename;
filename = filename.format("sprite%d.avd", spritenum);
if (!inf.open(filename)) {
warning("AVALANCHE: Trip: File not found: %s", filename.c_str());
return;
}
inf.seek(177);
id = inf.readSint32LE();
if (id != idshould) {
//output << '\7';
inf.close();
return;
}
inf.skip(2); // Replace variable named 'soa' in the original code.
if (!a.name.empty())
a.name.clear();
byte nameSize = inf.readByte();
for (byte i = 0; i < nameSize; i++)
a.name += inf.readByte();
inf.skip(12 - nameSize);
//inf.skip(1); // Same as above.
byte commentSize = inf.readByte();
for (byte i = 0; i < commentSize; i++)
a.comment += inf.readByte();
inf.skip(16 - commentSize);
a.num = inf.readByte();
_info._xLength = inf.readByte();
_info._yLength = inf.readByte();
a.seq = inf.readByte();
_info._size = inf.readUint16LE();
a.fgc = inf.readByte();
a.bgc = inf.readByte();
a.accinum = inf.readByte();
totalnum = 0; // = 1;
_info._xWidth = _info._xLength / 8;
if ((_info._xLength % 8) > 0)
_info._xWidth++;
for (byte aa = 0; aa < /*nds*seq*/a.num; aa++) {
_info._sil[totalnum] = new SilType[11 * (_info._yLength + 1)];
//getmem(sil[totalnum-1], 11 * (a.yl + 1));
_info._mani[totalnum] = new ManiType[_info._size - 6];
//getmem(mani[totalnum-1], a.size - 6);
for (fv = 0; fv <= _info._yLength; fv++)
inf.read((*_info._sil[totalnum])[fv], _info._xWidth);
//blockread(inf, (*sil[totalnum-1])[fv], xw);
inf.read(*_info._mani[totalnum], _info._size - 6);
//blockread(inf, *mani[totalnum-1], a.size - 6);
totalnum++;
}
totalnum++;
// on;
x = 0;
y = 0;
quick = true;
visible = false;
xs = 3;
ys = 1;
if (spritenum == 1)
_tr->newspeed(); // Just for the lights.
homing = false;
ix = 0;
iy = 0;
step = 0;
check_me = do_check;
count = 0;
whichsprite = spritenum;
vanishifstill = false;
call_eachstep = false;
inf.close();
}
void triptype::original() {
quick = false;
whichsprite = 177;
}
void triptype::andexor() {
if ((vanishifstill) && (ix == 0) && (iy == 0))
return;
byte picnum = face * a.seq + step; // There'll maybe problem because of the different array indexes in Pascal (starting from 1).
_tr->_vm->_graphics->drawSprite(_info, picnum, x, y);
}
void triptype::turn(byte whichway) {
2013-06-30 14:10:33 +02:00
if (whichway == 8)
face = 0;
else
face = whichway;
}
void triptype::appear(int16 wx, int16 wy, byte wf) {
x = (wx / 8) * 8;
y = wy;
2013-09-06 16:23:57 +02:00
ox[_tr->_vm->_gyro->_cp] = wx;
oy[_tr->_vm->_gyro->_cp] = wy;
turn(wf);
visible = true;
ix = 0;
iy = 0;
}
bool triptype::collision_check() {
2013-07-24 17:02:38 +02:00
for (byte fv = 0; fv < _tr->numtr; fv++)
if (_tr->tr[fv].quick && (_tr->tr[fv].whichsprite != whichsprite) &&
((x + _info._xLength) > _tr->tr[fv].x) &&
(x < (_tr->tr[fv].x + _tr->tr[fv]._info._xLength)) &&
2013-07-03 14:05:06 +02:00
(_tr->tr[fv].y == y))
return true;
return false;
}
void triptype::walk() {
2013-07-24 17:02:38 +02:00
byte tc;
2013-09-06 16:23:57 +02:00
ByteField r;
2013-07-24 17:02:38 +02:00
if (visible) {
2013-09-06 16:23:57 +02:00
r._x1 = (x / 8) - 1;
if (r._x1 == 255)
r._x1 = 0;
r._y1 = y - 2;
r._x2 = ((x + _info._xLength) / 8) + 1;
r._y2 = y + _info._yLength + 2;
2013-09-06 16:23:57 +02:00
_tr->getset[1 - _tr->_vm->_gyro->_cp].remember(r);
2013-07-24 17:02:38 +02:00
}
2013-09-06 16:23:57 +02:00
if (!_tr->_vm->_gyro->_doingSpriteRun) {
ox[_tr->_vm->_gyro->_cp] = x;
oy[_tr->_vm->_gyro->_cp] = y;
if (homing)
homestep();
2013-07-24 17:02:38 +02:00
x = x + ix;
y = y + iy;
}
if (check_me) {
if (collision_check()) {
bounce();
return;
}
2013-09-06 16:23:57 +02:00
tc = _tr->checkfeet(x, x + _info._xLength, oy[_tr->_vm->_gyro->_cp], y, _info._yLength) - 1;
// -1 is because the modified array indexes of magics[] compared to Pascal .
2013-07-24 17:02:38 +02:00
2013-09-06 16:23:57 +02:00
if ((tc != 255) & (!_tr->_vm->_gyro->_doingSpriteRun)) {
switch (_tr->_vm->_gyro->_magics[tc]._operation) {
2013-09-05 23:57:58 +02:00
case Gyro::kMagicExclaim: {
2013-07-24 17:02:38 +02:00
bounce();
_tr->mustexclaim = true;
2013-09-06 16:23:57 +02:00
_tr->saywhat = _tr->_vm->_gyro->_magics[tc]._data;
2013-07-24 17:02:38 +02:00
}
break;
2013-09-05 23:57:58 +02:00
case Gyro::kMagicBounce:
2013-07-24 17:02:38 +02:00
bounce();
break;
2013-09-05 23:57:58 +02:00
case Gyro::kMagicTransport:
2013-09-06 16:23:57 +02:00
_tr->fliproom(_tr->_vm->_gyro->_magics[tc]._data >> 8, _tr->_vm->_gyro->_magics[tc]._data & 0xff);
2013-07-24 17:02:38 +02:00
break;
2013-09-05 23:57:58 +02:00
case Gyro::kMagicUnfinished: {
2013-07-24 17:02:38 +02:00
bounce();
_tr->_vm->_scrolls->display("\7Sorry.\3\rThis place is not available yet!");
2013-07-24 17:02:38 +02:00
}
break;
2013-09-05 23:57:58 +02:00
case Gyro::kMagicSpecial:
2013-09-06 16:23:57 +02:00
_tr->call_special(_tr->_vm->_gyro->_magics[tc]._data);
2013-07-24 17:02:38 +02:00
break;
2013-09-05 23:57:58 +02:00
case Gyro::kMagicOpenDoor:
2013-09-06 16:23:57 +02:00
_tr->open_the_door(_tr->_vm->_gyro->_magics[tc]._data >> 8, _tr->_vm->_gyro->_magics[tc]._data & 0xff, tc);
2013-07-24 17:02:38 +02:00
break;
}
}
}
2013-09-06 16:23:57 +02:00
if (!_tr->_vm->_gyro->_doingSpriteRun) {
count++;
2013-07-24 17:02:38 +02:00
if (((ix != 0) || (iy != 0)) && (count > 1)) {
step++;
if (step == a.seq)
step = 0;
2013-07-24 17:02:38 +02:00
count = 0;
}
}
}
void triptype::bounce() {
2013-09-06 16:23:57 +02:00
x = ox[_tr->_vm->_gyro->_cp];
y = oy[_tr->_vm->_gyro->_cp];
2013-06-30 14:10:33 +02:00
if (check_me)
_tr->stopwalking();
else
stopwalk();
2013-09-05 23:57:58 +02:00
_tr->_vm->_gyro->_onCanDoPageSwap = false;
_tr->_vm->_lucerna->showrw();
2013-09-05 23:57:58 +02:00
_tr->_vm->_gyro->_onCanDoPageSwap = true;
}
2013-09-04 17:54:08 +02:00
int8 triptype::sgn(int16 val) {
if (val > 0)
return 1;
2013-09-04 17:54:08 +02:00
else if (val < 0)
return -1;
else
return 0;
}
void triptype::walkto(byte pednum) {
pednum--; // Pascal -> C conversion: different array indexes.
2013-09-06 16:23:57 +02:00
speed(sgn(_tr->_vm->_gyro->_peds[pednum]._x - x) * 4, sgn(_tr->_vm->_gyro->_peds[pednum]._y - y));
hx = _tr->_vm->_gyro->_peds[pednum]._x - _info._xLength / 2;
hy = _tr->_vm->_gyro->_peds[pednum]._y - _info._yLength;
homing = true;
}
void triptype::stophoming() {
homing = false;
}
void triptype::homestep() {
int16 temp;
if ((hx == x) && (hy == y)) {
// touching the target
stopwalk();
return;
2013-06-27 12:13:00 +02:00
}
ix = 0;
iy = 0;
if (hy != y) {
temp = hy - y;
2013-06-30 14:10:33 +02:00
if (temp > 4)
iy = 4;
else if (temp < -4)
iy = -4;
else
iy = temp;
2013-06-27 12:13:00 +02:00
}
if (hx != x) {
temp = hx - x;
2013-06-30 14:10:33 +02:00
if (temp > 4)
ix = 4;
else if (temp < -4)
ix = -4;
else
ix = temp;
}
}
void triptype::speed(int8 xx, int8 yy) {
ix = xx;
iy = yy;
2013-06-30 14:10:33 +02:00
if ((ix == 0) && (iy == 0))
return; // no movement
if (ix == 0) {
// No horz movement
2013-06-30 14:10:33 +02:00
if (iy < 0)
turn(_tr->up);
else
turn(_tr->down);
} else {
2013-06-30 14:10:33 +02:00
if (ix < 0)
turn(_tr->left);
else
turn(_tr->right);
}
}
void triptype::stopwalk() {
ix = 0;
iy = 0;
homing = false;
}
void triptype::chatter() {
2013-09-06 16:23:57 +02:00
_tr->_vm->_gyro->_talkX = x + _info._xLength / 2;
_tr->_vm->_gyro->_talkY = y;
_tr->_vm->_gyro->_talkFontColor = a.fgc;
_tr->_vm->_gyro->_talkBackgroundColor = a.bgc;
}
void triptype::set_up_saver(trip_saver_type &v) {
v.whichsprite = whichsprite;
v.face = face;
v.step = step;
v.x = x;
v.y = y;
v.ix = ix;
v.iy = iy;
v.visible = visible;
v.homing = homing;
v.check_me = check_me;
v.count = count;
v.xw = _info._xWidth;
v.xs = xs;
v.ys = ys;
v.totalnum = totalnum;
v.hx = hx;
v.hy = hy;
v.call_eachstep = call_eachstep;
v.eachstep = eachstep;
v.vanishifstill = vanishifstill;
}
void triptype::unload_saver(trip_saver_type v) {
whichsprite = v.whichsprite;
face = v.face;
step = v.step;
x = v.x;
y = v.y;
ix = v.ix;
iy = v.iy;
visible = v.visible;
homing = v.homing;
check_me = v.check_me;
count = v.count;
_info._xWidth = v.xw;
xs = v.xs;
ys = v.ys;
totalnum = v.totalnum;
hx = v.hx;
hy = v.hy;
call_eachstep = v.call_eachstep;
eachstep = v.eachstep;
vanishifstill = v.vanishifstill;
}
void triptype::savedata(Common::File &f) {
warning("STUB: triptype::savedata()");
}
void triptype::loaddata(Common::File &f) {
warning("STUB: triptype::loaddata()");
}
void triptype::save_data_to_mem(uint16 &where) {
warning("STUB: triptype::save_data_to_mem()");
}
void triptype::load_data_from_mem(uint16 &where) {
warning("STUB: triptype::load_data_from_mem()");
}
triptype *triptype::done() {
Common::String xx;
2013-06-27 12:13:00 +02:00
// nds:=num div seq;
totalnum--;
_info._xWidth = _info._xLength / 8;
if ((_info._xLength % 8) > 0)
_info._xWidth++;
2013-09-04 12:02:01 +02:00
for (byte aa = 0; aa < /*nds*seq*/ a.num; aa++) {
totalnum--;
delete[] _info._mani[totalnum];
delete[] _info._sil[totalnum];
2013-06-27 12:13:00 +02:00
}
quick = false;
whichsprite = 177;
return this;
}
2013-06-27 12:13:00 +02:00
getsettype *getsettype::init() {
numleft = 0; // initialize array pointer
return this;
}
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
void getsettype::remember(ByteField r) {
numleft++;
//if (numleft > maxgetset)
// error("Trip::remember() : runerr_Getset_Overflow");
gs[numleft] = r;
}
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
void getsettype::recall(ByteField &r) {
r = gs[numleft];
numleft--;
}
2013-06-27 12:13:00 +02:00
Trip::Trip(AvalancheEngine *vm) {
_vm = vm;
getsetclear();
mustexclaim = false;
}
2013-06-27 12:13:00 +02:00
2013-09-05 15:48:30 +02:00
Trip::~Trip() {
for (byte i = 0; i < numtr; i++) {
if (tr[i].quick)
tr[i].done();
}
}
void Trip::loadtrip() {
2013-09-04 17:54:08 +02:00
for (int16 gm = 0; gm < numtr; gm++)
2013-06-30 14:10:33 +02:00
tr[gm].original();
2013-07-03 14:05:06 +02:00
2013-09-04 17:54:08 +02:00
for (uint16 i = 0; i < sizeof(aa); i++)
aa[i] = 0;
}
2013-06-27 12:13:00 +02:00
byte Trip::checkfeet(int16 x1, int16 x2, int16 oy, int16 y, byte yl) {
byte a, c;
int16 fv, ff;
// if not alive then begin checkfeet:=0; exit; end;
a = 0;
//setactivepage(2);
if (x1 < 0)
x1 = 0;
if (x2 > 639)
x2 = 639;
if (oy < y) {
for (fv = x1; fv <= x2; fv++) {
for (ff = oy + yl; ff <= y + yl; ff++) {
c = *(byte *)_vm->_graphics->_magics.getBasePtr(fv, ff);
if (c > a)
a = c;
}
}
} else {
for (fv = x1; fv <= x2; fv++) {
for (ff = y + yl; ff <= oy + yl; ff++) {
c = *(byte *)_vm->_graphics->_magics.getBasePtr(fv, ff);
if (c > a)
a = c;
}
}
}
//setactivepage(1 - cp);
return a;
}
byte Trip::geida_ped(byte which) {
switch (which) {
case 1:
2013-08-29 23:38:47 +02:00
return 7;
case 2:
case 6:
2013-08-29 23:38:47 +02:00
return 8;
case 3:
case 5:
2013-08-29 23:38:47 +02:00
return 9;
case 4:
2013-08-29 23:38:47 +02:00
return 10;
2013-09-04 12:02:01 +02:00
default:
return 0;
}
}
2013-06-27 12:13:00 +02:00
void Trip::catamove(byte ped) {
/* When you enter a new position in the catacombs, this procedure should
be called. It changes the Also codes so that they may match the picture
on the screen. (Coming soon: It draws up the screen, too.) */
2013-06-27 12:13:00 +02:00
int32 here;
uint16 xy_uint16;
2013-09-04 12:02:01 +02:00
byte fv;
2013-06-27 12:13:00 +02:00
// XY_uint16 is cat_x+cat_y*256. Thus, every room in the
// catacombs has a different number for it.
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
xy_uint16 = _vm->_gyro->_dna._catacombX + _vm->_gyro->_dna._catacombY * 256;
_vm->_gyro->_dna._geidaSpin = 0;
switch (xy_uint16) {
case 1801: // Exit catacombs
fliproom(r__lustiesroom, 4);
_vm->_scrolls->display("Phew! Nice to be out of there!");
return;
case 1033: // Oubliette
fliproom(r__oubliette, 1);
2013-08-29 23:38:47 +02:00
_vm->_scrolls->display(Common::String("Oh, NO!") + _vm->_scrolls->kControlRegister + '1' + _vm->_scrolls->kControlSpeechBubble);
return;
2013-06-30 14:10:33 +02:00
case 4:
fliproom(r__geidas, 1);
return;
2013-06-30 14:10:33 +02:00
case 2307:
fliproom(r__lusties, 5);
_vm->_scrolls->display("Oh no... here we go again...");
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._userMovesAvvy = false;
tr[0].iy = 1;
tr[0].ix = 0;
return;
}
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
if (!_vm->_gyro->_dna._enterCatacombsFromLustiesRoom)
_vm->_lucerna->load(29);
2013-09-06 16:23:57 +02:00
here = _vm->_gyro->kCatacombMap[_vm->_gyro->_dna._catacombY - 1][_vm->_gyro->_dna._catacombX - 1];
2013-06-27 12:13:00 +02:00
switch (here & 0xf) { // West.
case 0: // no connection (wall)
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicNothing; // Door.
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 28);
2013-06-30 14:10:33 +02:00
break;
case 0x1: // no connection (wall + shield),
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicNothing; // Door.
_vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
_vm->_celer->drawBackgroundSprite(-1, -1, 29); // ...shield.
2013-06-30 14:10:33 +02:00
break;
case 0x2: // wall with door
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicSpecial; // Door.
_vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
_vm->_celer->drawBackgroundSprite(-1, -1, 30); // ...door.
2013-06-30 14:10:33 +02:00
break;
case 0x3: // wall with door and shield
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicSpecial; // Door.
_vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
_vm->_celer->drawBackgroundSprite(-1, -1, 30); // ...door, and...
_vm->_celer->drawBackgroundSprite(-1, -1, 29); // ...shield.
2013-06-30 14:10:33 +02:00
break;
case 0x4: // no connection (wall + window),
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicNothing; // Door.
_vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
_vm->_celer->drawBackgroundSprite(-1, -1, 5); // ...window.
2013-06-30 14:10:33 +02:00
break;
case 0x5: // wall with door and window
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicSpecial; // Door.
_vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
_vm->_celer->drawBackgroundSprite(-1, -1, 30); // ...door, and...
_vm->_celer->drawBackgroundSprite(-1, -1, 5); // ...window.
2013-06-30 14:10:33 +02:00
break;
case 0x6: // no connection (wall + torches),
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicNothing; // No door.
_vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
_vm->_celer->drawBackgroundSprite(-1, -1, 7); // ...torches.
2013-06-30 14:10:33 +02:00
break;
case 0x7: // wall with door and torches
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicSpecial; // Door.
_vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
_vm->_celer->drawBackgroundSprite(-1, -1, 30); // ...door, and...
_vm->_celer->drawBackgroundSprite(-1, -1, 7); // ...torches.
2013-06-30 14:10:33 +02:00
break;
case 0xf: // straight-through corridor.
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicNothing; // Sloping wall.
_vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicSpecial; // Straight wall.
2013-06-30 14:10:33 +02:00
break;
2013-06-27 12:13:00 +02:00
}
/* ---- */
2013-06-27 12:13:00 +02:00
switch ((here & 0xf0) >> 4) { // East
case 0: // no connection (wall)
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicNothing; // Door.
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 19);
2013-06-30 14:10:33 +02:00
break;
case 0x1: // no connection (wall + window),
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicNothing; // Door.
_vm->_celer->drawBackgroundSprite(-1, -1, 19); // Wall, plus...
_vm->_celer->drawBackgroundSprite(-1, -1, 20); // ...window.
2013-06-30 14:10:33 +02:00
break;
case 0x2: // wall with door
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicSpecial; // Door.
_vm->_celer->drawBackgroundSprite(-1, -1, 19); // Wall, plus...
_vm->_celer->drawBackgroundSprite(-1, -1, 21); // ...door.
2013-06-30 14:10:33 +02:00
break;
case 0x3: // wall with door and window
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicSpecial; // Door.
_vm->_celer->drawBackgroundSprite(-1, -1, 19); // Wall, plus...
_vm->_celer->drawBackgroundSprite(-1, -1, 20); // ...door, and...
_vm->_celer->drawBackgroundSprite(-1, -1, 21); // ...window.
2013-06-30 14:10:33 +02:00
break;
case 0x6: // no connection (wall + torches),
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicNothing; // No door.
_vm->_celer->drawBackgroundSprite(-1, -1, 19); // Wall, plus...
_vm->_celer->drawBackgroundSprite(-1, -1, 18); // ...torches.
2013-06-30 14:10:33 +02:00
break;
case 0x7: // wall with door and torches
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
_vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
_vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicSpecial; // Door.
_vm->_celer->drawBackgroundSprite(-1, -1, 19); // Wall, plus...
_vm->_celer->drawBackgroundSprite(-1, -1, 21); // ...door, and...
_vm->_celer->drawBackgroundSprite(-1, -1, 18); // ...torches.
2013-06-30 14:10:33 +02:00
break;
case 0xf: // straight-through corridor.
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicNothing; // Sloping wall.
_vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicSpecial; // Straight wall.
_vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicNothing; // Door.
2013-06-30 14:10:33 +02:00
break;
}
2013-06-27 12:13:00 +02:00
/* ---- */
2013-06-27 12:13:00 +02:00
switch ((here & 0xf00) >> 8) { // South
case 0: // No connection.
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[6]._operation = _vm->_gyro->kMagicBounce;
_vm->_gyro->_magics[11]._operation = _vm->_gyro->kMagicBounce;
_vm->_gyro->_magics[12]._operation = _vm->_gyro->kMagicBounce;
2013-06-30 14:10:33 +02:00
break;
case 0x1:
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 22);
2013-09-06 16:23:57 +02:00
if ((xy_uint16 == 2051) && (_vm->_gyro->_dna._geidaFollows))
_vm->_gyro->_magics[12]._operation = _vm->_gyro->kMagicExclaim;
else
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[12]._operation = _vm->_gyro->kMagicSpecial; // Right exit south.
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[6]._operation = _vm->_gyro->kMagicBounce;
_vm->_gyro->_magics[11]._operation = _vm->_gyro->kMagicBounce;
2013-06-30 14:10:33 +02:00
break;
case 0x2:
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 23);
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[6]._operation = _vm->_gyro->kMagicSpecial; // Middle exit south.
_vm->_gyro->_magics[11]._operation = _vm->_gyro->kMagicBounce;
_vm->_gyro->_magics[12]._operation = _vm->_gyro->kMagicBounce;
2013-06-30 14:10:33 +02:00
break;
case 0x3:
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 24);
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[11]._operation = _vm->_gyro->kMagicSpecial; // Left exit south.
_vm->_gyro->_magics[6]._operation = _vm->_gyro->kMagicBounce;
_vm->_gyro->_magics[12]._operation = _vm->_gyro->kMagicBounce;
2013-06-30 14:10:33 +02:00
break;
2013-06-27 12:13:00 +02:00
}
switch ((here & 0xf000) >> 12) { // North
case 0: // No connection
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicBounce;
_vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicNothing; // Door.
2013-06-30 14:10:33 +02:00
break;
// LEFT handles:
#if 0
2013-06-30 14:10:33 +02:00
case 0x1:
_vm->_celer->show_one(-1, -1, 4);
_vm->_gyro->magics[1].op = _vm->_gyro->bounces; // { Left exit north. } { Change magic number! }
_vm->_gyro->portals[12].op = _vm->_gyro->special; // { Door. }
2013-06-30 14:10:33 +02:00
break;
#endif
2013-06-30 14:10:33 +02:00
case 0x2:
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 4);
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicBounce; // Middle exit north.
_vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicSpecial; // Door.
2013-06-30 14:10:33 +02:00
break;
#if 0
case 0x3:
_vm->_celer->show_one(-1, -1, 4);
_vm->_gyro->magics[1].op = _vm->_gyro->bounces; // { Right exit north. } { Change magic number! }
_vm->_gyro->portals[12].op = _vm->_gyro->special; // { Door. }
2013-06-30 14:10:33 +02:00
break;
// RIGHT handles:
case 0x4:
_vm->_celer->show_one(-1, -1, 3);
_vm->_gyro->magics[1].op = _vm->_gyro->bounces; // { Left exit north. } { Change magic number! }
_vm->_gyro->portals[12].op = _vm->_gyro->special; // { Door. }
2013-06-30 14:10:33 +02:00
break;
#endif
2013-06-30 14:10:33 +02:00
case 0x5:
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 3);
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicBounce; // Middle exit north.
_vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicSpecial; // Door.
2013-06-30 14:10:33 +02:00
break;
#if 0
2013-06-30 14:10:33 +02:00
case 0x6:
_vm->_celer->show_one(-1, -1, 3);
_vm->_gyro->magics[1].op = _vm->_gyro->bounces; // { Right exit north. }
_vm->_gyro->portals[12].op = _vm->_gyro->special; // { Door. }
2013-06-30 14:10:33 +02:00
break;
#endif
2013-06-30 14:10:33 +02:00
// ARCHWAYS:
case 0x7:
case 0x8:
case 0x9: {
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 6);
2013-06-30 14:10:33 +02:00
if (((here & 0xf000) >> 12) > 0x7)
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 31);
2013-06-30 14:10:33 +02:00
if (((here & 0xf000) >> 12) == 0x9)
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 32);
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicSpecial; // Middle arch north.
_vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicNothing; // Door.
}
break;
// DECORATIONS:
case 0xd: // No connection + WINDOW
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicBounce;
_vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicNothing; // Door.
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 14);
2013-06-30 14:10:33 +02:00
break;
case 0xe: // No connection + TORCH
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicBounce;
_vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicNothing; // Door.
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 8);
2013-06-30 14:10:33 +02:00
break;
// Recessed door:
2013-06-30 14:10:33 +02:00
case 0xf:
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicNothing; // Door to Geida's room.
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 1);
2013-09-06 16:23:57 +02:00
_vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicSpecial; // Door.
2013-06-30 14:10:33 +02:00
break;
2013-06-27 12:13:00 +02:00
}
switch (xy_uint16) {
case 514:
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 17);
break; // [2,2] : "Art Gallery" sign over door.
case 264:
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 9);
break; // [8,1] : "The Wrong Way!" sign.
case 1797:
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 2);
break; // [5,7] : "Ite Mingite" sign.
case 258:
for (fv = 0; fv <= 2; fv++) { // [2,1] : Art gallery - pictures
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(130 + fv * 120, 70, 15);
_vm->_celer->drawBackgroundSprite(184 + fv * 120, 78, 16);
}
break;
case 1287:
for (fv = 10; fv <= 13; fv++)
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, fv);
break; // [7,5] : 4 candles.
case 776:
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 10);
break; // [8,3] : 1 candle.
case 2049:
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 11);
break; // [1,8] : another candle.
2013-06-30 14:10:33 +02:00
case 257:
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 12);
_vm->_celer->drawBackgroundSprite(-1, -1, 13);
break; // [1,1] : the other two.
2013-06-27 12:13:00 +02:00
}
2013-09-06 16:23:57 +02:00
if ((_vm->_gyro->_dna._geidaFollows) && (ped > 0)) {
if (!tr[1].quick) // If we don't already have her...
tr[1].init(5, true, this); // ...Load Geida.
apped(2, geida_ped(ped));
tr[1].call_eachstep = true;
tr[1].eachstep = procgeida_procs;
}
}
// This proc gets called whenever you touch a line defined as _vm->_gyro->special.
void Trip::dawndelay() {
_vm->_timeout->set_up_timer(2, _vm->_timeout->procdawn_delay, _vm->_timeout->reason_dawndelay);
}
void Trip::call_special(uint16 which) {
switch (which) {
case 1: // _vm->_gyro->special 1: Room 22: top of stairs.
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 1);
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._brummieStairs = 1;
_vm->_gyro->_magics[9]._operation = _vm->_gyro->kMagicNothing;
_vm->_timeout->set_up_timer(10, _vm->_timeout->procstairs, _vm->_timeout->reason_brummiestairs);
stopwalking();
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._userMovesAvvy = false;
break;
case 2: // _vm->_gyro->special 2: Room 22: bottom of stairs.
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._brummieStairs = 3;
_vm->_gyro->_magics[10]._operation = _vm->_gyro->kMagicNothing;
_vm->_gyro->_magics[11]._operation = _vm->_gyro->kMagicExclaim;
_vm->_gyro->_magics[11]._data = 5;
_vm->_gyro->_magics[3]._operation = _vm->_gyro->kMagicBounce; // Now works as planned!
stopwalking();
_vm->_visa->dixi('q', 26);
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._userMovesAvvy = true;
2013-06-30 14:10:33 +02:00
break;
case 3: // _vm->_gyro->special 3: Room 71: triggers dart.
tr[0].bounce(); // Must include that.
2013-09-06 16:23:57 +02:00
if (!_vm->_gyro->_dna._arrowTriggered) {
_vm->_gyro->_dna._arrowTriggered = true;
apped(2, 4); // The dart starts at ped 4, and...
tr[1].walkto(5); // flies to ped 5.
tr[1].face = 0; // Only face.
// Should call some kind of Eachstep procedure which will deallocate
// the sprite when it hits the wall, and replace it with the chunk
// graphic of the arrow buried in the plaster. */
// OK!
tr[1].call_eachstep = true;
tr[1].eachstep = procarrow_procs;
2013-06-27 12:13:00 +02:00
}
2013-06-30 14:10:33 +02:00
break;
case 4: // This is the ghost room link.
_vm->_lucerna->dusk();
tr[0].turn(right); // you'll see this after we get back from bootstrap
_vm->_timeout->set_up_timer(1, _vm->_timeout->procghost_room_phew, _vm->_timeout->reason_ghost_room_phew);
_vm->_enid->backToBootstrap(3);
2013-06-30 14:10:33 +02:00
break;
case 5:
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._friarWillTieYouUp) {
// _vm->_gyro->special 5: Room 42: touched tree, and get tied up.
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Boundary effect is now working again.
_vm->_visa->dixi('q', 35);
tr[0].done();
//tr[1].vanishifstill:=true;
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 2);
_vm->_visa->dixi('q', 36);
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._tiedUp = true;
_vm->_gyro->_dna._friarWillTieYouUp = false;
tr[1].walkto(3);
tr[1].vanishifstill = true;
tr[1].check_me = true; // One of them must have Check_Me switched on.
2013-09-06 16:23:57 +02:00
_vm->_gyro->_whereIs[_vm->_gyro->kPeopleFriarTuck - 150] = 177; // Not here, then.
_vm->_timeout->set_up_timer(364, _vm->_timeout->prochang_around, _vm->_timeout->reason_hanging_around);
2013-06-27 12:13:00 +02:00
}
break;
case 6: // _vm->_gyro->special 6: fall down oubliette.
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._userMovesAvvy = false;
tr[0].ix = 3;
tr[0].iy = 0;
tr[0].face = right;
_vm->_timeout->set_up_timer(1, _vm->_timeout->procfall_down_oubliette, _vm->_timeout->reason_falling_down_oubliette);
2013-06-30 14:10:33 +02:00
break;
case 7: // _vm->_gyro->special 7: stop falling down oubliette.
tr[0].visible = false;
2013-09-06 16:23:57 +02:00
_vm->_gyro->_magics[9]._operation = _vm->_gyro->kMagicNothing;
stopwalking();
_vm->_timeout->lose_timer(_vm->_timeout->reason_falling_down_oubliette);
//_vm->_lucerna->mblit(12, 80, 38, 160, 3, 0);
//_vm->_lucerna->mblit(12, 80, 38, 160, 3, 1);
_vm->_scrolls->display("Oh dear, you seem to be down the bottom of an oubliette.");
_vm->_timeout->set_up_timer(200, _vm->_timeout->procmeet_avaroid, _vm->_timeout->reason_meeting_avaroid);
2013-06-30 14:10:33 +02:00
break;
case 8: // _vm->_gyro->special 8: leave du Lustie's room.
2013-09-06 16:23:57 +02:00
if ((_vm->_gyro->_dna._geidaFollows) && (!_vm->_gyro->_dna._lustieIsAsleep)) {
_vm->_visa->dixi('q', 63);
tr[1].turn(down);
tr[1].stopwalk();
tr[1].call_eachstep = false; // Geida
_vm->_lucerna->gameover();
2013-06-27 12:13:00 +02:00
}
break;
case 9: // _vm->_gyro->special 9: lose Geida to Robin Hood...
2013-09-06 16:23:57 +02:00
if (!_vm->_gyro->_dna._geidaFollows)
return; // DOESN'T COUNT: no Geida.
tr[1].call_eachstep = false; // She no longer follows Avvy around.
tr[1].walkto(4); // She walks to somewhere...
tr[0].done(); // Lose Avvy.
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._userMovesAvvy = false;
_vm->_timeout->set_up_timer(40, _vm->_timeout->procrobin_hood_and_geida, _vm->_timeout->reason_robin_hood_and_geida);
2013-06-30 14:10:33 +02:00
break;
case 10: // _vm->_gyro->special 10: transfer north in catacombs.
2013-09-06 16:23:57 +02:00
if ((_vm->_gyro->_dna._catacombX == 4) && (_vm->_gyro->_dna._catacombY == 1)) {
// Into Geida's room.
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._objects[_vm->_gyro->kObjectKey - 1])
_vm->_visa->dixi('q', 62);
else {
_vm->_visa->dixi('q', 61);
return;
}
}
_vm->_lucerna->dusk();
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._catacombY--;
catamove(4);
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._room != r__catacombs)
2013-06-30 14:10:33 +02:00
return;
_vm->_lucerna->delavvy();
2013-09-06 16:23:57 +02:00
switch ((_vm->_gyro->kCatacombMap[_vm->_gyro->_dna._catacombY - 1][_vm->_gyro->_dna._catacombX - 1] & 0xf00) >> 8) {
case 0x1:
apped(1, 12);
break;
case 0x3:
apped(1, 11);
break;
default:
apped(1, 4);
}
getback();
dawndelay();
2013-06-30 14:10:33 +02:00
break;
case 11: // _vm->_gyro->special 11: transfer east in catacombs.
_vm->_lucerna->dusk();
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._catacombX++;
catamove(1);
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._room != r__catacombs)
2013-06-30 14:10:33 +02:00
return;
_vm->_lucerna->delavvy();
apped(1, 1);
getback();
dawndelay();
2013-06-30 14:10:33 +02:00
break;
case 12: // _vm->_gyro->special 12: transfer south in catacombs.
_vm->_lucerna->dusk();
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._catacombY += 1;
catamove(2);
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._room != r__catacombs)
2013-06-30 14:10:33 +02:00
return;
_vm->_lucerna->delavvy();
apped(1, 2);
getback();
dawndelay();
2013-06-30 14:10:33 +02:00
break;
case 13: // _vm->_gyro->special 13: transfer west in catacombs.
_vm->_lucerna->dusk();
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._catacombX--;
catamove(3);
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._room != r__catacombs)
2013-06-30 14:10:33 +02:00
return;
_vm->_lucerna->delavvy();
apped(1, 3);
getback();
dawndelay();
2013-06-30 14:10:33 +02:00
break;
}
}
2013-06-30 14:10:33 +02:00
void Trip::open_the_door(byte whither, byte ped, byte magicnum) {
// This slides the door open. (The data really ought to be saved in
// the Also file, and will be next time. However, for now, they're
// here.)
2013-09-06 16:23:57 +02:00
switch (_vm->_gyro->_dna._room) {
case r__outsideyours:
case r__outsidenottspub:
2013-06-30 14:10:33 +02:00
case r__outsideducks:
_vm->_sequence->first_show(1);
_vm->_sequence->then_show(2);
_vm->_sequence->then_show(3);
2013-06-30 14:10:33 +02:00
break;
case r__insidecardiffcastle:
_vm->_sequence->first_show(1);
_vm->_sequence->then_show(5);
2013-06-30 14:10:33 +02:00
break;
case r__avvysgarden:
case r__entrancehall:
2013-06-30 14:10:33 +02:00
case r__insideabbey:
case r__yourhall:
_vm->_sequence->first_show(1);
_vm->_sequence->then_show(2);
2013-06-30 14:10:33 +02:00
break;
case r__musicroom:
2013-06-30 14:10:33 +02:00
case r__outsideargentpub:
_vm->_sequence->first_show(5);
_vm->_sequence->then_show(6);
2013-06-30 14:10:33 +02:00
break;
case r__lusties:
switch (magicnum) {
case 14:
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._avvysInTheCupboard) {
hide_in_the_cupboard();
_vm->_sequence->first_show(8);
_vm->_sequence->then_show(7);
_vm->_sequence->start_to_close();
return;
} else {
apped(1, 6);
tr[0].face = right; // added by TT 12/3/1995
_vm->_sequence->first_show(8);
_vm->_sequence->then_show(9);
2013-06-27 12:13:00 +02:00
}
break;
2013-06-30 14:10:33 +02:00
case 12:
_vm->_sequence->first_show(4);
_vm->_sequence->then_show(5);
_vm->_sequence->then_show(6);
2013-06-30 14:10:33 +02:00
break;
2013-06-27 12:13:00 +02:00
}
break;
2013-06-27 12:13:00 +02:00
}
_vm->_sequence->then_flip(whither, ped);
_vm->_sequence->start_to_open();
}
2013-06-27 12:13:00 +02:00
void Trip::newspeed() {
2013-08-17 17:14:00 +02:00
// Given that you've just changed the speed in triptype.xs, this adjusts ix.
2013-09-06 16:23:57 +02:00
const ByteField lightspace = {40, 199, 47, 199};
2013-08-17 17:14:00 +02:00
byte page_;
tr[0].ix = (tr[0].ix / 3) * tr[0].xs;
2013-08-17 17:14:00 +02:00
//setactivepage(3);
2013-09-05 23:57:58 +02:00
if (tr[0].xs == _vm->_gyro->kRun)
2013-09-05 23:07:08 +02:00
_vm->_graphics->_surface.drawLine(371, 199, 373, 199, kColorYellow);
2013-08-17 17:14:00 +02:00
else
2013-09-05 23:07:08 +02:00
_vm->_graphics->_surface.drawLine(336, 199, 338, 199, kColorYellow);
2013-08-17 17:14:00 +02:00
2013-09-05 23:57:58 +02:00
if (tr[0].xs == _vm->_gyro->kRun)
2013-09-05 23:07:08 +02:00
_vm->_graphics->_surface.drawLine(336, 199, 338, 199, kColorLightblue);
2013-08-17 17:14:00 +02:00
else
2013-09-05 23:07:08 +02:00
_vm->_graphics->_surface.drawLine(371, 199, 373, 199, kColorLightblue);
2013-08-17 17:14:00 +02:00
//setactivepage(1 - cp);
2013-09-04 13:34:58 +02:00
for (page_ = 0; page_ <= 1; page_++)
2013-08-17 17:14:00 +02:00
getset[page_].remember(lightspace);
}
2013-06-27 12:13:00 +02:00
2013-09-04 17:54:08 +02:00
void Trip::rwsp(byte t, byte dir) {
switch (dir) {
2013-06-30 14:10:33 +02:00
case up:
tr[t].speed(0, -tr[t].ys);
break;
case down:
tr[t].speed(0, tr[t].ys);
break;
case left:
tr[t].speed(-tr[t].xs, 0);
break;
case right:
tr[t].speed(tr[t].xs, 0);
break;
case ul:
tr[t].speed(-tr[t].xs, -tr[t].ys);
break;
case ur:
tr[t].speed(tr[t].xs, -tr[t].ys);
break;
case dl:
tr[t].speed(-tr[t].xs, tr[t].ys);
break;
case dr:
tr[t].speed(tr[t].xs, tr[t].ys);
break;
}
}
2013-06-27 12:13:00 +02:00
void Trip::apped(byte trn, byte np) {
trn--;
np--;
2013-09-06 16:23:57 +02:00
tr[trn].appear(_vm->_gyro->_peds[np]._x - tr[trn]._info._xLength / 2, _vm->_gyro->_peds[np]._y - tr[trn]._info._yLength, _vm->_gyro->_peds[np]._direction);
rwsp(trn, _vm->_gyro->_peds[np]._direction);
}
2013-06-27 12:13:00 +02:00
#if 0
function overlap(x1,y1,x2,y2,x3,y3,x4,y4:uint16):bool;
begin // By De Morgan's law:
overlap:=(x2>=x3) and (x4>=x1) and (y2>=y3) and (y4>=y1);
end;
#endif
//x1,x2 - as _vm->_gyro->bytefield, but *8. y1,y2 - as _vm->_gyro->bytefield.
//x3,y3 = mx,my. x4,y4 = mx+16,my+16.
2013-06-27 12:13:00 +02:00
void Trip::getback() {
// Super_Off;
2013-09-06 16:23:57 +02:00
#if 0
while (getset[1 - _vm->_gyro->cp].numleft > 0) {
getset[1 - _vm->_gyro->cp].recall(r);
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
2013-09-05 01:27:51 +02:00
bool endangered = false;
if overlaps_with_mouse and not endangered then
2013-06-30 14:10:33 +02:00
begin
endangered:=true;
blitfix;
Super_Off;
end;
2013-06-27 12:13:00 +02:00
//_vm->_lucerna->mblit(r.x1, r.y1, r.x2, r.y2, 3, 1 - _vm->_gyro->cp);
2013-06-27 12:13:00 +02:00
}
if endangered then
Super_On;
#endif
}
// Eachstep procedures:
void Trip::follow_avvy_y(byte tripnum) {
if (tr[0].face == left)
return;
if (tr[tripnum].homing)
tr[tripnum].hy = tr[1].y;
else {
if (tr[tripnum].y < tr[1].y)
tr[tripnum].y += 1;
else if (tr[tripnum].y > tr[1].y)
tr[tripnum].y -= 1;
else
2013-06-27 12:13:00 +02:00
return;
if (tr[tripnum].ix == 0) {
tr[tripnum].step += 1;
2013-06-30 14:10:33 +02:00
if (tr[tripnum].step == tr[tripnum].a.seq)
tr[tripnum].step = 0;
tr[tripnum].count = 0;
2013-06-27 12:13:00 +02:00
}
}
}
2013-06-27 12:13:00 +02:00
void Trip::back_and_forth(byte tripnum) {
if (!tr[tripnum].homing) {
if (tr[tripnum].face == right)
tr[tripnum].walkto(4);
else
tr[tripnum].walkto(5);
2013-06-27 12:13:00 +02:00
}
}
2013-06-27 12:13:00 +02:00
void Trip::face_avvy(byte tripnum) {
if (!tr[tripnum].homing) {
if (tr[0].x >= tr[tripnum].x)
2013-06-30 14:10:33 +02:00
tr[tripnum].face = right;
else
tr[tripnum].face = left;
2013-06-27 12:13:00 +02:00
}
}
2013-06-27 12:13:00 +02:00
void Trip::arrow_procs(byte tripnum) {
if (tr[tripnum].homing) {
// Arrow is still in flight.
// We must check whether or not the arrow has collided tr[tripnum] Avvy's head.
// This is so if: a) the bottom of the arrow is below Avvy's head,
// b) the left of the arrow is left of the right of Avvy's head, and
// c) the right of the arrow is right of the left of Avvy's head.
if (((tr[tripnum].y + tr[tripnum]._info._yLength) >= tr[0].y) // A
&& (tr[tripnum].x <= (tr[0].x + tr[0]._info._xLength)) // B
&& ((tr[tripnum].x + tr[tripnum]._info._xLength) >= tr[0].x)) { // C
// OK, it's hit him... what now?
tr[1].call_eachstep = false; // prevent recursion.
_vm->_visa->dixi('Q', 47); // Complaint!
tr[tripnum].done(); // Deallocate the arrow.
#if 0
tr[1].done; { Deallocate normal pic of Avvy. }
off;
for byte fv:=0 to 1 do
begin
cp:=1-cp;
getback;
end;
on;
#endif
_vm->_lucerna->gameover();
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._userMovesAvvy = false; // Stop the user from moving him.
_vm->_timeout->set_up_timer(55, _vm->_timeout->procnaughty_duke, _vm->_timeout->reason_naughty_duke);
2013-06-27 12:13:00 +02:00
}
} else { // Arrow has hit the wall!
tr[tripnum].done(); // Deallocate the arrow.
_vm->_celer->drawBackgroundSprite(-1, -1, 3); // Show pic of arrow stuck into the door.
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._arrowInTheDoor = true; // So that we can pick it up.
2013-06-27 12:13:00 +02:00
}
}
#if 0
procedure Spludwick_procs(tripnum:byte);
var fv:byte;
begin
with tr[tripnum] do
if not homing then { We only need to do anything if Spludwick *stops*
walking. }
with _vm->_gyro->dna do
2013-06-27 12:13:00 +02:00
begin
inc(DogfoodPos);
if DogfoodPos=8 then DogfoodPos:=1;
walkto(DogfoodPos);
end;
end;
#endif
void Trip::grab_avvy(byte tripnum) { // For Friar Tuck, in Nottingham.
2013-09-04 12:02:01 +02:00
int16 tox = tr[0].x + 17;
int16 toy = tr[0].y - 1;
if ((tr[tripnum].x == tox) && (tr[tripnum].y == toy)) {
tr[tripnum].call_eachstep = false;
tr[tripnum].face = left;
tr[tripnum].stopwalk();
// ... whatever ...
} else {
// Still some way to go.
if (tr[tripnum].x < tox) {
tr[tripnum].x += 5;
2013-06-30 14:10:33 +02:00
if (tr[tripnum].x > tox)
tr[tripnum].x = tox;
}
2013-06-30 14:10:33 +02:00
if (tr[tripnum].y < toy)
tr[tripnum].y++;
tr[tripnum].step++;
2013-06-30 14:10:33 +02:00
if (tr[tripnum].step == tr[tripnum].a.seq)
tr[tripnum].step = 0;
2013-06-27 12:13:00 +02:00
}
}
2013-06-27 12:13:00 +02:00
void Trip::take_a_step(byte &tripnum) {
if (tr[tripnum].ix == 0) {
tr[tripnum].step++;
2013-06-30 14:10:33 +02:00
if (tr[tripnum].step == tr[tripnum].a.seq)
tr[tripnum].step = 0;
tr[tripnum].count = 0;
2013-06-27 12:13:00 +02:00
}
}
2013-06-27 12:13:00 +02:00
void Trip::spin(byte whichway, byte &tripnum) {
if (tr[tripnum].face != whichway) {
tr[tripnum].face = whichway;
2013-06-30 14:10:33 +02:00
if (tr[tripnum].whichsprite == 2)
return; // Not for Spludwick
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._geidaSpin += 1;
_vm->_gyro->_dna._geidaTime = 20;
if (_vm->_gyro->_dna._geidaSpin == 5) {
_vm->_scrolls->display("Steady on, Avvy, you'll make the poor girl dizzy!");
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._geidaSpin = 0;
_vm->_gyro->_dna._geidaTime = 0; // knock out records
2013-06-27 12:13:00 +02:00
}
}
}
2013-06-27 12:13:00 +02:00
void Trip::geida_procs(byte tripnum) {
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._geidaTime > 0) {
_vm->_gyro->_dna._geidaTime--;
if (_vm->_gyro->_dna._geidaTime == 0)
_vm->_gyro->_dna._geidaSpin = 0;
}
2013-06-27 12:13:00 +02:00
if (tr[tripnum].y < (tr[0].y - 2)) {
// Geida is further from the screen than Avvy.
spin(down, tripnum);
tr[tripnum].iy = 1;
tr[tripnum].ix = 0;
take_a_step(tripnum);
return;
} else if (tr[tripnum].y > (tr[0].y + 2)) {
// Avvy is further from the screen than Geida.
spin(up, tripnum);
tr[tripnum].iy = -1;
tr[tripnum].ix = 0;
take_a_step(tripnum);
return;
2013-06-27 12:13:00 +02:00
}
tr[tripnum].iy = 0;
// These 12-s are not in the original, I added them to make the following method more "smooth".
// Now the NPC which is following Avvy won't block his way and will walk next to him properly.
if (tr[tripnum].x < tr[0].x - tr[0].xs * 8 - 12) {
tr[tripnum].ix = tr[0].xs;
spin(right, tripnum);
take_a_step(tripnum);
} else if (tr[tripnum].x > tr[0].x + tr[0].xs * 8 + 12) {
tr[tripnum].ix = -tr[0].xs;
spin(left, tripnum);
take_a_step(tripnum);
2013-06-30 14:10:33 +02:00
} else
tr[tripnum].ix = 0;
}
// That's all...
void Trip::call_andexors() {
int8 order[5];
byte fv, temp;
bool ok;
for (int i = 0; i < 5; i++)
order[i] = -1;
for (fv = 0; fv < numtr; fv++) {
if (tr[fv].quick && tr[fv].visible)
order[fv] = fv;
}
2013-06-27 12:13:00 +02:00
do {
ok = true;
for (fv = 0; fv < 4; fv++) {
if (((order[fv] != -1) && (order[fv + 1] != -1))
&& (tr[order[fv]].y > tr[order[fv + 1]].y)) {
// Swap them!
temp = order[fv];
order[fv] = order[fv + 1];
order[fv + 1] = temp;
ok = false;
}
2013-06-30 14:10:33 +02:00
}
} while (!ok);
2013-06-27 12:13:00 +02:00
_vm->_graphics->refreshBackground();
for (fv = 0; fv < 5; fv++) {
if (order[fv] > -1)
tr[order[fv]].andexor();
2013-06-30 14:10:33 +02:00
}
}
2013-06-27 12:13:00 +02:00
void Trip::trippancy_link() {
byte fv;
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dropdownActive | _vm->_gyro->_onToolbar | _vm->_gyro->_seeScroll)
2013-06-30 14:10:33 +02:00
return;
for (fv = 0; fv < numtr; fv++) {
if (tr[fv].quick && tr[fv].visible)
tr[fv].walk();
}
2013-06-27 12:13:00 +02:00
call_andexors();
for (fv = 0; fv < numtr; fv++) {
if (tr[fv].quick && tr[fv].call_eachstep) {
switch (tr[fv].eachstep) {
case procfollow_avvy_y :
follow_avvy_y(fv);
break;
case procback_and_forth :
back_and_forth(fv);
break;
case procface_avvy :
face_avvy(fv);
break;
case procarrow_procs :
arrow_procs(fv);
break;
// PROCSpludwick_procs : spludwick_procs(fv);
case procgrab_avvy :
grab_avvy(fv);
break;
case procgeida_procs :
geida_procs(fv);
break;
2013-06-27 12:13:00 +02:00
}
}
}
if (mustexclaim) {
mustexclaim = false;
_vm->_visa->dixi('x', saywhat);
2013-06-27 12:13:00 +02:00
}
}
2013-06-27 12:13:00 +02:00
void Trip::get_back_loretta() {
byte fv;
2013-06-27 12:13:00 +02:00
for (fv = 0; fv < numtr; fv++) {
if (tr[fv].quick) {
getback();
return;
}
2013-06-30 14:10:33 +02:00
}
// for fv:=0 to 1 do begin cp:=1-cp; getback; end;
}
void Trip::stopwalking() {
tr[0].stopwalk();
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._direction = stopped;
if (_vm->_gyro->_alive)
tr[0].step = 1;
}
void Trip::tripkey(char dir) {
warning("Replaced by Trip::handleMoveKey!");
}
2013-06-27 12:13:00 +02:00
void Trip::readstick() {
warning("STUB: Trip::readstick()");
}
2013-06-27 12:13:00 +02:00
void Trip::getsetclear() {
for (byte fv = 0; fv <= 1; fv++)
getset[fv].init();
}
2013-06-27 12:13:00 +02:00
void Trip::hide_in_the_cupboard() {
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._avvysInTheCupboard) {
if (_vm->_gyro->_dna._wearing == Acci::kNothing)
_vm->_scrolls->display(Common::String(_vm->_scrolls->kControlItalic) + "AVVY!" + _vm->_scrolls->kControlRoman + "Get dressed first!");
else {
tr[0].visible = true;
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._userMovesAvvy = true;
apped(1, 3); // Walk out of the cupboard.
_vm->_scrolls->display("You leave the cupboard. Nice to be out of there!");
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._avvysInTheCupboard = false;
_vm->_sequence->first_show(8);
_vm->_sequence->then_show(7);
_vm->_sequence->start_to_close();
}
} else {
// Not hiding in the cupboard
tr[0].visible = false;
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._userMovesAvvy = false;
_vm->_scrolls->display(Common::String("You walk into the room...") + _vm->_scrolls->kControlParagraph
+ "It seems to be an empty, but dusty, cupboard. Hmmmm... you leave the door slightly open to avoid suffocation.");
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._avvysInTheCupboard = true;
2013-09-03 22:22:42 +02:00
_vm->_celer->drawBackgroundSprite(-1, -1, 8);
2013-06-27 12:13:00 +02:00
}
}
2013-06-27 12:13:00 +02:00
void Trip::fliproom(byte room, byte ped) {
byte fv;
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
if (!_vm->_gyro->_alive) {
// You can't leave the room if you're dead.
tr[0].ix = 0;
tr[0].iy = 0; // Stop him from moving.
return;
}
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
if ((room == 177) && (_vm->_gyro->_dna._room == r__lusties)) {
hide_in_the_cupboard();
return;
}
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
if ((_vm->_gyro->_dna._jumpStatus > 0) && (_vm->_gyro->_dna._room == r__insidecardiffcastle)) {
// You can't *jump* out of Cardiff Castle!
tr[0].ix = 0;
return;
}
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
_vm->_lucerna->exitroom(_vm->_gyro->_dna._room);
_vm->_lucerna->dusk();
getsetclear();
2013-06-27 12:13:00 +02:00
for (fv = 1; fv < numtr; fv++) {
if (tr[fv].quick)
tr[fv].done();
} // Deallocate sprite
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._room == r__lustiesroom)
_vm->_gyro->_dna._enterCatacombsFromLustiesRoom = true;
2013-06-27 12:13:00 +02:00
_vm->_lucerna->enterroom(room, ped);
apped(1, ped);
2013-09-06 16:23:57 +02:00
_vm->_gyro->_dna._enterCatacombsFromLustiesRoom = false;
_vm->_gyro->_oldDirection = _vm->_gyro->_dna._direction;
_vm->_gyro->_dna._direction = tr[0].face;
_vm->_lucerna->showrw();
2013-06-27 12:13:00 +02:00
for (fv = 0; fv <= 1; fv++) {
2013-09-06 16:23:57 +02:00
_vm->_gyro->_cp = 1 - _vm->_gyro->_cp;
getback();
2013-06-27 12:13:00 +02:00
}
_vm->_lucerna->dawn();
2013-06-27 12:13:00 +02:00
// Tidy up after mouse. I know it's a kludge...
// tidy_after_mouse;
}
2013-06-27 12:13:00 +02:00
bool Trip::infield(byte which) {
which--; // Pascal -> C: different array indexes.
int16 yy = tr[0].y + tr[0]._info._yLength;
2013-06-27 12:13:00 +02:00
2013-09-06 16:23:57 +02:00
return (tr[0].x >= _vm->_gyro->_fields[which]._x1) && (tr[0].x <= _vm->_gyro->_fields[which]._x2)
&& (yy >= _vm->_gyro->_fields[which]._y1) && (yy <= _vm->_gyro->_fields[which]._y2);
2013-06-27 12:13:00 +02:00
}
bool Trip::neardoor() {
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_fieldNum < 8) {
// there ARE no doors here!
return false;
2013-06-27 12:13:00 +02:00
}
int16 ux = tr[0].x;
int16 uy = tr[0].y + tr[0]._info._yLength;
bool nd = false;
2013-09-06 16:23:57 +02:00
for (byte fv = 8; fv < _vm->_gyro->_fieldNum; fv++)
if ((ux >= _vm->_gyro->_fields[fv]._x1) && (ux <= _vm->_gyro->_fields[fv]._x2)
&& (uy >= _vm->_gyro->_fields[fv]._y1) && (uy <= _vm->_gyro->_fields[fv]._y2))
2013-06-30 14:10:33 +02:00
nd = true;
return nd;
}
2013-06-27 12:13:00 +02:00
void Trip::new_game_for_trippancy() { // Called by gyro.newgame
tr[0].visible = false;
}
2013-06-27 12:13:00 +02:00
void Trip::handleMoveKey(const Common::Event &event) {
2013-09-06 16:23:57 +02:00
if (!_vm->_gyro->_dna._userMovesAvvy)
return;
if (_vm->_dropdown->_activeMenuItem._activeNow)
_vm->_parser->tryDropdown();
else {
switch (event.kbd.keycode) {
case Common::KEYCODE_UP:
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._direction != up) {
_vm->_gyro->_dna._direction = up;
rwsp(0, _vm->_gyro->_dna._direction);
} else
stopwalking();
break;
case Common::KEYCODE_DOWN:
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._direction != down) {
_vm->_gyro->_dna._direction = down;
rwsp(0, _vm->_gyro->_dna._direction);
} else
stopwalking();
break;
case Common::KEYCODE_LEFT:
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._direction != left) {
_vm->_gyro->_dna._direction = left;
rwsp(0, _vm->_gyro->_dna._direction);
} else
stopwalking();
break;
case Common::KEYCODE_RIGHT:
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._direction != right) {
_vm->_gyro->_dna._direction = right;
rwsp(0, _vm->_gyro->_dna._direction);
} else
stopwalking();
break;
case Common::KEYCODE_PAGEUP:
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._direction != ur) {
_vm->_gyro->_dna._direction = ur;
rwsp(0, _vm->_gyro->_dna._direction);
} else
stopwalking();
break;
case Common::KEYCODE_PAGEDOWN:
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._direction != dr) {
_vm->_gyro->_dna._direction = dr;
rwsp(0, _vm->_gyro->_dna._direction);
} else
stopwalking();
break;
case Common::KEYCODE_END:
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._direction != dl) {
_vm->_gyro->_dna._direction = dl;
rwsp(0, _vm->_gyro->_dna._direction);
} else
stopwalking();
break;
case Common::KEYCODE_HOME:
2013-09-06 16:23:57 +02:00
if (_vm->_gyro->_dna._direction != ul) {
_vm->_gyro->_dna._direction = ul;
rwsp(0, _vm->_gyro->_dna._direction);
} else
stopwalking();
break;
case Common::KEYCODE_KP5:
stopwalking();
break;
2013-09-04 17:15:33 +02:00
default:
break;
}
}
}
2013-06-27 12:13:00 +02:00
} // End of namespace Avalanche.