diff options
Diffstat (limited to 'engines/access/amazon/amazon_logic.cpp')
-rw-r--r-- | engines/access/amazon/amazon_logic.cpp | 1832 |
1 files changed, 1832 insertions, 0 deletions
diff --git a/engines/access/amazon/amazon_logic.cpp b/engines/access/amazon/amazon_logic.cpp new file mode 100644 index 0000000000..cae3373ea8 --- /dev/null +++ b/engines/access/amazon/amazon_logic.cpp @@ -0,0 +1,1832 @@ +/* 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. + * + */ + +#include "common/scummsys.h" +#include "access/access.h" +#include "access/resources.h" +#include "access/screen.h" +#include "access/amazon/amazon_game.h" +#include "access/amazon/amazon_logic.h" + +namespace Access { + +namespace Amazon { + +PannedScene::PannedScene(AmazonEngine *vm): AmazonManager(vm) { + for (int i = 0; i < PAN_SIZE; ++i) { + _pan[i]._pObject = nullptr; + _pan[i]._pImgNum = 0; + _pan[i]._pObjX = _pan[i]._pObjY = _pan[i]._pObjZ = 0; + _pan[i]._pObjXl = _pan[i]._pObjYl = 0; + } + + _xCount = 0; + _xTrack = _yTrack = _zTrack = 0; + _xCam = _yCam = _zCam = 0; + _pNumObj = 0; + _screenVertX = 0; +} + +void PannedScene::pan() { + _zCam += _zTrack; + _xCam += _xTrack; + int tx = (_xTrack << 8) / _zCam; + _yCam += _yTrack; + int ty = (_yTrack << 8) / _zCam; + + if (_vm->_timers[24]._flag != 1) { + ++_vm->_timers[24]._flag; + for (int i = 0; i < _pNumObj; i++) { + _pan[i]._pObjZ += _zTrack; + _pan[i]._pObjXl += (_pan[i]._pObjZ * tx) & 0xff; + _pan[i]._pObjX += ((_pan[i]._pObjZ * tx) >> 8) + (_pan[i]._pObjXl >> 8); + _pan[i]._pObjXl &= 0xff; + + _pan[i]._pObjYl += (_pan[i]._pObjZ * ty) & 0xff; + _pan[i]._pObjY += ((_pan[i]._pObjZ * ty) >> 8) + (_pan[i]._pObjYl >> 8); + _pan[i]._pObjYl &= 0xff; + } + } + + for (int i = 0; i < _pNumObj; i++) { + ImageEntry ie; + ie._flags = IMGFLAG_UNSCALED; + ie._position = Common::Point(_pan[i]._pObjX, _pan[i]._pObjY); + ie._offsetY = 255; + ie._spritesPtr = _pan[i]._pObject; + ie._frameNumber = _pan[i]._pImgNum; + + _vm->_images.addToList(ie); + } +} + +/*------------------------------------------------------------------------*/ + +Opening::Opening(AmazonEngine *vm) : PannedScene(vm) { +} + +void Opening::mWhileDoOpen() { + Screen &screen = *_vm->_screen; + EventsManager &events = *_vm->_events; + + screen.setBufferScan(); + events.hideCursor(); + screen.forceFadeOut(); + _vm->_skipStart = false; + if (_vm->_conversation != 2) { + // Cutscene at start of chapter 1 + screen.setPanel(3); + _vm->startChapter(1); + _vm->establishCenter(0, 1); + } + + Resource *data = _vm->_files->loadFile(1, 0); + _vm->_objectsTable[1] = new SpriteResource(_vm, data); + delete data; + + _vm->_files->_setPaletteFlag = false; + _vm->_files->loadScreen(1, 2); + _vm->_buffer2.copyFrom(*_vm->_screen); + _vm->_buffer1.copyFrom(*_vm->_screen); + + // Load animation data + _vm->_animation->freeAnimationData(); + Resource *animResource = _vm->_files->loadFile(1, 1); + _vm->_animation->loadAnimations(animResource); + delete animResource; + + _xTrack = 8; + _yTrack = -3; + _zTrack = 0; + _xCam = _yCam = 0; + _zCam = 270; + _vm->_timers[24]._timer = _vm->_timers[24]._initTm = 1; + ++_vm->_timers[24]._flag; + _vm->_timers.updateTimers(); + + _pNumObj = 10; + for (int i = 0; i < _pNumObj; i++) { + _pan[i]._pObject = _vm->_objectsTable[1]; + _pan[i]._pImgNum = OPENING_OBJS[i][0]; + _pan[i]._pObjX = OPENING_OBJS[i][1]; + _pan[i]._pObjY = OPENING_OBJS[i][2]; + _pan[i]._pObjZ = OPENING_OBJS[i][3]; + _pan[i]._pObjXl = _pan[i]._pObjYl = 0; + } + + _vm->_oldRects.clear(); + _vm->_newRects.clear(); + Animation *anim = _vm->_animation->setAnimation(0); + _vm->_animation->setAnimTimer(anim); + anim = _vm->_animation->setAnimation(1); + _vm->_animation->setAnimTimer(anim); + _vm->_sound->newMusic(10, 0); + + bool startFl = false; + while (!_vm->shouldQuit()) { + _vm->_images.clear(); + _vm->_animation->animate(0); + _vm->_animation->animate(1); + pan(); + _vm->_buffer2.copyFrom(_vm->_buffer1); + _vm->_newRects.clear(); + _vm->plotList(); + _vm->copyBlocks(); + if (!startFl) { + startFl = true; + screen.forceFadeIn(); + } + + events.pollEventsAndWait(); + + if (events._leftButton || events._rightButton || events._keypresses.size() > 0) { + _vm->_skipStart = true; + _vm->_sound->newMusic(10, 1); + + events.debounceLeft(); + events.zeroKeys(); + break; + } + + if (_xCam > 680) { + events._vbCount = 125; + + while (!_vm->shouldQuit() && !events.isKeyMousePressed() && events._vbCount > 0) { + events.pollEventsAndWait(); + } + break; + } + } + + events.showCursor(); + _vm->_buffer2.copyFrom(*_vm->_screen); + _vm->_buffer1.copyFrom(*_vm->_screen); + + _vm->freeCells(); + _vm->_oldRects.clear(); + _vm->_newRects.clear(); + _vm->_numAnimTimers = 0; + _vm->_images.clear(); + + if (_vm->_conversation == 2) { + // Cutscene at end of Chapter 6 + Resource *spriteData = _vm->_files->loadFile(28, 37); + _vm->_objectsTable[28] = new SpriteResource(_vm, spriteData); + delete spriteData; + + _vm->_animation->freeAnimationData(); + animResource = _vm->_files->loadFile(28, 38); + _vm->_animation->loadAnimations(animResource); + delete animResource; + } +} + +/*------------------------------------------------------------------------*/ + +Plane::Plane(AmazonEngine *vm): PannedScene(vm) { + _pCount = 0; + _planeCount = 0; + _propCount = 0; +} + + +void Plane::doFlyCell() { + SpriteResource *sprites = _vm->_objectsTable[15]; + + if (_pCount <= 40) { + _vm->_buffer2.plotImage(sprites, 3, Common::Point(70, 74)); + } else if (_pCount <= 80) { + _vm->_buffer2.plotImage(sprites, 6, Common::Point(70, 74)); + } else if (_pCount <= 120) { + _vm->_buffer2.plotImage(sprites, 2, Common::Point(50, 76)); + } else if (_pCount <= 160) { + _vm->_buffer2.plotImage(sprites, 14, Common::Point(63, 78)); + } else if (_pCount <= 200) { + _vm->_buffer2.plotImage(sprites, 5, Common::Point(86, 74)); + } else if (_pCount <= 240) { + _vm->_buffer2.plotImage(sprites, 0, Common::Point(103, 76)); + } else if (_pCount <= 280) { + _vm->_buffer2.plotImage(sprites, 4, Common::Point(119, 77)); + } else { + _vm->_buffer2.plotImage(sprites, 1, Common::Point(111, 77)); + } + + if (_planeCount == 11 || _planeCount == 12) + ++_position.y; + else if (_planeCount >= 28) + --_position.y; + + _vm->_buffer2.plotImage(sprites, 7, _position); + _vm->_buffer2.plotImage(sprites, 8 + _propCount, Common::Point( + _position.x + 99, _position.y + 10)); + _vm->_buffer2.plotImage(sprites, 11 + _propCount, Common::Point( + _position.x + 104, _position.y + 18)); + + if (++_planeCount >= 30) + _planeCount = 0; + if (++_propCount >= 3) + _propCount = 0; + + ++_xCount; + if (_xCount == 1) + ++_position.x; + else + _xCount = 0; +} + +void Plane::doFallCell() { + if (_vm->_scaleI <= 20) + return; + + SpriteFrame *frame = _vm->_objectsTable[20]->getFrame(_planeCount / 6); + Common::Rect r(115, 11, 115 + _vm->_screen->_scaleTable1[frame->w], + 11 + _vm->_screen->_scaleTable1[frame->h]); + _vm->_buffer2.sPlotF(frame, r); + + _vm->_scaleI -= 3; + _vm->_scale = _vm->_scaleI; + _vm->_screen->setScaleTable(_vm->_scale); + ++_xCount; + if (_xCount == 5) + return; + _xCount = 0; + if (_planeCount == 18) + _planeCount = 0; + else + _planeCount += 6; +} + +void Plane::scrollFly() { + _vm->copyBF1BF2(); + _vm->_newRects.clear(); + doFlyCell(); + _vm->copyRects(); + _vm->copyBF2Vid(); +} + +void Plane::scrollFall() { + _vm->copyBF1BF2(); + _vm->_newRects.clear(); + doFallCell(); + _vm->copyRects(); + _vm->copyBF2Vid(); +} + +void Plane::mWhileFly() { + Screen &screen = *_vm->_screen; + Player &player = *_vm->_player; + EventsManager &events = *_vm->_events; + + events.hideCursor(); + screen.clearScreen(); + screen.setBufferScan(); + screen.fadeOut(); + screen._scrollX = 0; + + _vm->_room->buildScreen(); + _vm->copyBF2Vid(); + screen.fadeIn(); + _vm->_oldRects.clear(); + _vm->_newRects.clear(); + + // KEYFLG = 0; + + screen._scrollRow = screen._scrollCol = 0; + screen._scrollX = screen._scrollY = 0; + player._rawPlayer = Common::Point(0, 0); + player._scrollAmount = 1; + + _pCount = 0; + _planeCount = 0; + _propCount = 0; + _xCount = 0; + _position = Common::Point(20, 29); + + while (!_vm->shouldQuit() && !events.isKeyMousePressed() && + ((screen._scrollCol + screen._vWindowWidth) != _vm->_room->_playFieldWidth)) { + events._vbCount = 4; + screen._scrollX += player._scrollAmount; + + while (screen._scrollX >= TILE_WIDTH) { + screen._scrollX -= TILE_WIDTH; + ++screen._scrollCol; + + _vm->_buffer1.moveBufferLeft(); + _vm->_room->buildColumn(screen._scrollCol + screen._vWindowWidth, screen._vWindowBytesWide); + } + + scrollFly(); + ++_pCount; + + while (!_vm->shouldQuit() && events._vbCount > 0) { + // To be rewritten when NEWTIMER is done + events.checkForNextFrameCounter(); + _vm->_sound->playSound(0); + + events.pollEventsAndWait(); + } + } + + events.showCursor(); +} + +void Plane::mWhileFall() { + Screen &screen = *_vm->_screen; + EventsManager &events = *_vm->_events; + + events.hideCursor(); + screen.clearScreen(); + screen.setBufferScan(); + screen.fadeOut(); + screen._scrollX = 0; + + _vm->_room->buildScreen(); + _vm->copyBF2Vid(); + screen.fadeIn(); + _vm->_oldRects.clear(); + _vm->_newRects.clear(); + + // KEYFLG = 0; + + screen._scrollRow = screen._scrollCol = 0; + screen._scrollX = screen._scrollY = 0; + _vm->_player->_scrollAmount = 3; + _vm->_scaleI = 255; + + _xCount = 0; + _planeCount = 0; + + while (!_vm->shouldQuit() && !events.isKeyMousePressed() && + (screen._scrollCol + screen._vWindowWidth != _vm->_room->_playFieldWidth)) { + events._vbCount = 4; + screen._scrollX += _vm->_player->_scrollAmount; + + while (screen._scrollX >= TILE_WIDTH) { + screen._scrollX -= TILE_WIDTH; + ++screen._scrollCol; + + _vm->_buffer1.moveBufferLeft(); + _vm->_room->buildColumn(screen._scrollCol + screen._vWindowWidth, screen._vWindowBytesWide); + } + + scrollFall(); + + while (!_vm->shouldQuit() && events._vbCount > 0) { + events.pollEventsAndWait(); + } + } + + events.showCursor(); +} + +/*------------------------------------------------------------------------*/ + +Jungle::Jungle(AmazonEngine *vm) : PannedScene(vm) { + for (int i = 0; i < JUNGLE_SIZE; ++i) { + _jCnt[i] = _jungleX[i] = -1; + } +} + +void Jungle::jungleMove() { + const static int jungleY[3] = { 27, 30, 29 }; + int count = 1; + int frameOffset = 0; + + if (!_vm->_timers[0]._flag) { + ++_vm->_timers[0]._flag; + _vm->_screen->_scrollX += _vm->_player->_scrollAmount; + + for (int i = 0; i < 3; ++i) { + int newJCnt = (_jCnt[i] + 1) % 8; + _jCnt[i] = newJCnt; + _jungleX[i] += 5; + } + + frameOffset = 4; + count = (_vm->_allenFlag != 1) ? 2 : 3; + } + + for (int i = 0; i < count; ++i) { + ImageEntry ie; + ie._flags = IMGFLAG_UNSCALED; + ie._spritesPtr = _vm->_objectsTable[24]; + ie._frameNumber = _jCnt[i] + frameOffset; + ie._position = Common::Point(_jungleX[i], jungleY[i]); + ie._offsetY = jungleY[i]; + + _vm->_images.addToList(ie); + frameOffset += 8; + } +} + +void Jungle::initJWalk2() { + const int JUNGLE1OBJ[7][4] = { + { 2, 470, 0, 20 }, + { 0, 290, 0, 50 }, + { 1, 210, 0, 40 }, + { 0, 500, 0, 30 }, + { 1, 550, 0, 20 }, + { 0, 580, 0, 60 }, + { 1, 650, 0, 30 } + }; + _vm->_screen->fadeOut(); + _vm->_events->hideCursor(); + _vm->_screen->clearScreen(); + _vm->_buffer2.clearBuffer(); + _vm->_screen->setBufferScan(); + + _vm->_screen->_scrollX = _vm->_screen->_scrollY; + _vm->_screen->_scrollCol = _vm->_screen->_scrollRow; + _vm->_room->buildScreen(); + _vm->copyBF2Vid(); + _vm->_screen->fadeIn(); + // KEYFL = 0; + + _xCount = 2; + _vm->_player->_scrollAmount = 5; + _xTrack = -10; + _yTrack = _zTrack = 0; + _xCam = 480; + _yCam = 0; + _zCam = 80; + + _vm->_timers[24]._timer = 1; + _vm->_timers[24]._initTm = 1; + ++_vm->_timers[24]._flag; + + _pNumObj = 7; + for (int i = 0; i < _pNumObj; i++) { + _pan[i]._pObject = _vm->_objectsTable[24]; + _pan[i]._pImgNum = JUNGLE1OBJ[i][0]; + _pan[i]._pObjX = JUNGLE1OBJ[i][1]; + _pan[i]._pObjY = JUNGLE1OBJ[i][2]; + _pan[i]._pObjZ = JUNGLE1OBJ[i][3]; + _pan[i]._pObjXl = _pan[i]._pObjYl = 0; + } + + _jCnt[0] = 0; + _jCnt[1] = 3; + _jCnt[2] = 5; + + _jungleX[0] = 50; + _jungleX[1] = 16; + _jungleX[2] = 93; +} + +void Jungle::mWhileJWalk() { + Screen &screen = *_vm->_screen; + EventsManager &events = *_vm->_events; + Player &player = *_vm->_player; + + static const int JUNGLE_OBJ[7][4] = { + { 2, 77, 0, 40 }, + { 0, 290, 0, 50 }, + { 1, 210, 0, 70 }, + { 0, 50, 0, 30 }, + { 1, 70, 0, 20 }, + { 0, -280, 0, 60 }, + { 1, -150, 0, 30 }, + }; + + screen.fadeOut(); + events.hideCursor(); + screen.clearScreen(); + _vm->_buffer2.clearBuffer(); + screen.setBufferScan(); + screen._scrollX = 0; + + // Build the initial jungle scene and fade it in + _vm->_room->buildScreen(); + _vm->copyBF2Vid(); + screen.fadeIn(); + + // Set up the player to walk horizontally + player._xFlag = 1; + player._yFlag = 0; + player._moveTo.x = 160; + player._playerMove = true; + + _xCount = 2; + _xTrack = 10; + _yTrack = _zTrack = 0; + _xCam = 480; + _yCam = 0; + _zCam = 80; + + TimerEntry *te = &_vm->_timers[24]; + te->_initTm = te->_timer = 1; + te->_flag++; + + _pNumObj = 7; + for (int i = 0; i < _pNumObj; i++) { + _pan[i]._pObject = _vm->_objectsTable[24]; + _pan[i]._pImgNum = JUNGLE_OBJ[i][0]; + _pan[i]._pObjX = JUNGLE_OBJ[i][1]; + _pan[i]._pObjY = JUNGLE_OBJ[i][2]; + _pan[i]._pObjZ = JUNGLE_OBJ[i][3]; + _pan[i]._pObjXl = _pan[i]._pObjYl = 0; + } + + while (!_vm->shouldQuit() && !events.isKeyMousePressed() && (player._xFlag != 2)) { + _vm->_images.clear(); + events._vbCount = 6; + + _pan[0]._pImgNum = _xCount; + if (_xCount == 2) + ++_xCount; + else + --_xCount; + + player.checkMove(); + player.checkScroll(); + pan(); + scrollJWalk(); + + while (!_vm->shouldQuit() && events._vbCount > 0) { + events.pollEventsAndWait(); + } + } + + _vm->_images.clear(); + events.showCursor(); +} + +void Jungle::mWhileJWalk2() { + Screen &screen = *_vm->_screen; + + initJWalk2(); + + while (!_vm->shouldQuit() && !_vm->_events->isKeyMousePressed() && + (screen._scrollCol + screen._vWindowWidth) != _vm->_room->_playFieldWidth) { + _vm->_images.clear(); + _vm->_events->_vbCount = 6; + _pan[0]._pImgNum = _xCount; + + jungleMove(); + while (screen._scrollX >= TILE_WIDTH) { + screen._scrollX -= TILE_WIDTH; + ++screen._scrollCol; + _vm->_buffer1.moveBufferLeft(); + _vm->_room->buildColumn(screen._scrollCol + screen._vWindowWidth, screen._vWindowBytesWide); + } + + if (_xCount == 2) + ++_xCount; + else + --_xCount; + + pan(); + scrollJWalk(); + + while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0) { + _vm->_events->pollEventsAndWait(); + } + } + + _vm->_events->showCursor(); +} + +void Jungle::scrollJWalk() { + _vm->copyBF1BF2(); + _vm->_newRects.clear(); + _vm->plotList(); + _vm->copyRects(); + _vm->copyBF2Vid(); +} + +/*------------------------------------------------------------------------*/ + +Guard::Guard(AmazonEngine *vm): PannedScene(vm) { + _vm = nullptr; + _guardCel = 0; + _gCode1 = _gCode2 = 0; + _xMid = _yMid = 0; +} + +void Guard::setVerticalCode() { + _gCode1 = 0; + _gCode2 = 0; + if (_topLeft.x < _vm->_screen->_orgX1) + _gCode1 |= 8; + else if (_topLeft.x == _vm->_screen->_orgX1) { + _gCode1 |= 8; + _gCode1 |= 2; + } + else + _gCode1 |= 2; + + if (_bottomRight.x < _vm->_screen->_orgX1) + _gCode2 |= 8; + else if (_bottomRight.x == _vm->_screen->_orgX1) { + _gCode2 |= 8; + _gCode2 |= 2; + } + else + _gCode2 |= 2; + + if (_topLeft.y < _vm->_screen->_orgY1) + _gCode1 |= 4; + else if (_topLeft.y > _vm->_screen->_orgY2) + _gCode1 |= 1; + + if (_bottomRight.y < _vm->_screen->_orgY1) + _gCode2 |= 4; + else if (_bottomRight.y > _vm->_screen->_orgY2) + _gCode2 |= 1; +} + +void Guard::setHorizontalCode() { + _gCode1 = 0; + _gCode2 = 0; + + if (_topLeft.y < _vm->_screen->_orgY1) + _gCode1 |= 4; + else if (_topLeft.x == _vm->_screen->_orgX1) { + _gCode1 |= 4; + _gCode1 |= 1; + } + else + _gCode1 |= 1; + + if (_bottomRight.y < _vm->_screen->_orgY1) + _gCode2 |= 4; + else if (_bottomRight.x == _vm->_screen->_orgX1) { + _gCode2 |= 4; + _gCode2 |= 1; + } + else + _gCode2 |= 1; + + if (_topLeft.x < _vm->_screen->_orgX1) + _gCode1 |= 8; + else if (_topLeft.x > _vm->_screen->_orgX2) + _gCode1 |= 2; + + if (_bottomRight.x < _vm->_screen->_orgX1) + _gCode2 |= 8; + else if (_bottomRight.y > _vm->_screen->_orgX2) + _gCode2 |= 2; +} + +void Guard::chkVLine() { + if (_position.x > _vm->_player->_rawPlayer.x) { + _topLeft = _vm->_player->_rawPlayer; + _bottomRight = _position; + } + else { + _topLeft = _position; + _bottomRight = _vm->_player->_rawPlayer; + } + + if (_vm->_screen->_orgY1 > _vm->_screen->_orgY2) + SWAP(_vm->_screen->_orgY1, _vm->_screen->_orgY2); + + for (;;) { + setVerticalCode(); + int code = _gCode1 | _gCode2; + if (code == 10) { + _vm->_guardFind = 0; + return; + } + + int code2 = _gCode1 & _gCode2; + code2 &= 5; + if (((code & 10) == 8) || ((code & 10) == 2) || (code2 != 0)) + return; + + int midX = (_topLeft.x + _bottomRight.x) / 2; + int midY = (_topLeft.y + _bottomRight.y) / 2; + + if (midX < _vm->_screen->_orgX1) { + if ((midX == _topLeft.x) && (midY == _topLeft.y)) + return; + + _topLeft.x = midX; + _topLeft.y = midY; + } + else { + if ((midX == _bottomRight.x) && (midY == _bottomRight.y)) + return; + + _bottomRight.x = midX; + _bottomRight.y = midY; + } + } +} + +void Guard::chkHLine() { + if (_position.y > _vm->_player->_rawPlayer.y) { + _topLeft = _vm->_player->_rawPlayer; + _bottomRight = _position; + } + else { + _topLeft = _position; + _bottomRight = _vm->_player->_rawPlayer; + } + + if (_vm->_screen->_orgX1 > _vm->_screen->_orgX2) + SWAP(_vm->_screen->_orgX1, _vm->_screen->_orgX2); + + while (true) { + setHorizontalCode(); + int code = _gCode1 | _gCode2; + if (code == 5) { + _vm->_guardFind = 0; + return; + } + + int code2 = _gCode1 & _gCode2; + code2 &= 10; + if (((code & 5) == 4) || ((code & 5) == 1) || (code2 != 0)) + return; + + int midX = (_topLeft.x + _bottomRight.x) / 2; + int midY = (_topLeft.y + _bottomRight.y) / 2; + + if (midY < _vm->_screen->_orgY1) { + if ((midX == _topLeft.x) && (midY == _topLeft.y)) + return; + + _topLeft.x = midX; + _topLeft.y = midY; + } + else { + if ((midX == _bottomRight.x) && (midY == _bottomRight.y)) + return; + + _bottomRight.x = midX; + _bottomRight.y = midY; + } + } +} + +void Guard::guardSee() { + int tmpY = (_vm->_screen->_scrollRow << 4) + _vm->_screen->_scrollY; + _vm->_flags[140] = 0; + if (tmpY > _position.y) + return; + + tmpY += _vm->_screen->_vWindowLinesTall; + tmpY -= 11; + + if (tmpY < _position.y) + return; + + _vm->_guardFind = 1; + _vm->_flags[140] = 1; + + for (uint16 idx = 0; idx < _vm->_room->_plotter._walls.size(); idx++) { + _vm->_screen->_orgX1 = _vm->_room->_plotter._walls[idx].left; + _vm->_screen->_orgY1 = _vm->_room->_plotter._walls[idx].top; + _vm->_screen->_orgX2 = _vm->_room->_plotter._walls[idx].right; + _vm->_screen->_orgY2 = _vm->_room->_plotter._walls[idx].bottom; + if (_vm->_screen->_orgX1 == _vm->_screen->_orgX2) { + chkVLine(); + if (_vm->_guardFind == 0) + return; + } + else if (_vm->_screen->_orgY1 == _vm->_screen->_orgY2) { + chkHLine(); + if (_vm->_guardFind == 0) + return; + } + } +} + +void Guard::setGuardFrame() { + ImageEntry ie; + ie._flags = IMGFLAG_UNSCALED; + + if (_vm->_guardLocation == 4) + ie._flags |= IMGFLAG_BACKWARDS; + ie._spritesPtr = _vm->_objectsTable[37]; + ie._frameNumber = _guardCel; + ie._position = _position; + ie._offsetY = 10; + _vm->_images.addToList(ie); +} + +void Guard::doGuard() { + if (_vm->_timers[8]._flag) { + setGuardFrame(); + return; + } + + ++_vm->_timers[8]._flag; + ++_guardCel; + int curCel = _guardCel; + + switch (_vm->_guardLocation) { + case 1: + // Guard walking down + if (curCel <= 8 || curCel > 13) + _guardCel = curCel = 8; + + _position.y += _vm->_player->_walkOffDown[curCel - 8]; + guardSee(); + if (_position.y >= 272) { + _position.y = 272; + _vm->_guardLocation = 2; + } + break; + case 2: + // Guard walking left + if (curCel <= 43 || curCel > 48) + _guardCel = curCel = 43; + + _position.x -= _vm->_player->_walkOffLeft[curCel - 43]; + guardSee(); + if (_position.x <= 56) { + _position.x = 56; + _vm->_guardLocation = 3; + } + break; + case 3: + // Guard walking up + if (curCel <= 0 || curCel > 5) + _guardCel = curCel = 0; + + _position.y -= _vm->_player->_walkOffUp[curCel]; + guardSee(); + if (_position.y <= 89) { + _position.y = 89; + _vm->_guardLocation = 4; + if (_vm->_flags[121] == 1) + _vm->_guardLocation = 5; + } + break; + default: + // Guard walking right + if (curCel <= 43 || curCel > 48) + _guardCel = curCel = 43; + + _position.x += _vm->_player->_walkOffRight[curCel - 43]; + guardSee(); + if (_position.x >= 127) { + _position.x = 127; + _vm->_guardLocation = 1; + } + break; + } + + setGuardFrame(); +} + +void Guard::setPosition(const Common::Point &pt) { + _position = pt; +} + +/*------------------------------------------------------------------------*/ + +Cast::Cast(AmazonEngine *vm) : PannedScene(vm) { +} + +void Cast::doCast(int param1) { + _vm->_screen->setDisplayScan(); + _vm->_events->hideCursor(); + _vm->_screen->forceFadeOut(); + _vm->_screen->_clipHeight = 173; + _vm->_screen->clearScreen(); + _vm->_chapter = 16; + _vm->tileScreen(); + _vm->updateSummary(param1); + _vm->_screen->setPanel(3); + _vm->_chapter = 14; + + Resource *spriteData = _vm->_files->loadFile(91, 0); + _vm->_objectsTable[0] = new SpriteResource(_vm, spriteData); + delete spriteData; + spriteData = _vm->_files->loadFile(91, 1); + _vm->_objectsTable[1] = new SpriteResource(_vm, spriteData); + delete spriteData; + + _vm->_files->_setPaletteFlag = false; + _vm->_files->loadScreen(58, 1); + _vm->_buffer2.copyFrom(*_vm->_screen); + _vm->_buffer1.copyFrom(*_vm->_screen); + + _xTrack = 0; + _yTrack = -6; + _zTrack = 0; + _xCam = _yCam = 0; + _zCam = 60; + + _vm->_timers[24]._timer = 1; + _vm->_timers[24]._initTm = 1; + ++_vm->_timers[24]._flag; + + _pNumObj = 26; + for (int i = 0; i < _pNumObj; i++) { + _pan[i]._pObject = _vm->_objectsTable[0]; + _pan[i]._pImgNum = CAST_END_OBJ[i][0]; + _pan[i]._pObjX = CAST_END_OBJ[i][1]; + _pan[i]._pObjY = CAST_END_OBJ[i][2]; + _pan[i]._pObjZ = CAST_END_OBJ[i][3]; + _pan[i]._pObjXl = _pan[i]._pObjYl = 0; + } + + _pNumObj = 4; + for (int i = 0; i < _pNumObj; i++) { + _pan[26 + i]._pObject = _vm->_objectsTable[1]; + _pan[26 + i]._pImgNum = CAST_END_OBJ1[i][0]; + _pan[26 + i]._pObjX = CAST_END_OBJ1[i][1]; + _pan[26 + i]._pObjY = CAST_END_OBJ1[i][2]; + _pan[26 + i]._pObjZ = CAST_END_OBJ1[i][3]; + _pan[26 + i]._pObjXl = _pan[26 + i]._pObjYl = 0; + } + + _vm->_oldRects.clear(); + _vm->_newRects.clear(); + _vm->_numAnimTimers = 0; + + _vm->_sound->newMusic(58, 0); + _vm->_screen->forceFadeIn(); + + while (!_vm->shouldQuit()) { + _vm->_images.clear(); + pan(); + _vm->_buffer2.copyFrom(_vm->_buffer1); + _vm->_newRects.clear(); + _vm->plotList(); + _vm->copyBlocks(); + + _vm->_events->pollEvents(); + if (_vm->_events->isKeyMousePressed()) + break; + + if (_yCam < -7550) { + _vm->_events->_vbCount = 50; + + while (!_vm->shouldQuit() && !_vm->_events->isKeyMousePressed() && _vm->_events->_vbCount > 0) { + _vm->_events->pollEventsAndWait(); + } + + while (!_vm->shouldQuit() && !_vm->_sound->checkMidiDone()) + _vm->_events->pollEventsAndWait(); + + break; + } + } + + _vm->_sound->newMusic(58, 1); + _vm->_events->showCursor(); + + _vm->freeCells(); + _vm->_oldRects.clear(); + _vm->_newRects.clear(); + _vm->_numAnimTimers = 0; + _vm->_images.clear(); + _vm->_screen->forceFadeOut(); + + _vm->quitGame(); + _vm->_events->pollEvents(); +} + +/*------------------------------------------------------------------------*/ + +River::River(AmazonEngine *vm): PannedScene(vm) { + _vm = nullptr; + _CHICKENOUTFLG = false; + _rScrollRow = 0; + _rScrollCol = 0; + _rScrollX = 0; + _rScrollY = 0; + _rOldRectCount = 0; + _rNewRectCount = 0; + _rKeyFlag = 0; + _mapOffset = 0; + _screenVirtX = 0; +} + +void River::setRiverPan() { + int delta = (_vm->_screen->_scrollCol * 16) + _vm->_screen->_scrollX; + + _xTrack = 9; + _yTrack = _zTrack = 0; + _xCam = 160; + _yCam = 0; + _zCam = 80; + + _vm->_timers[24]._timer = 1; + _vm->_timers[24]._initTm = 1; + ++_vm->_timers[24]._flag; + + _pNumObj = 23; + for (int i = 0; i < _pNumObj; i++) { + _pan[i]._pObject = _vm->_objectsTable[45]; + _pan[i]._pImgNum = RIVER1OBJ[i][0]; + _pan[i]._pObjX = RIVER1OBJ[i][1] + delta; + _pan[i]._pObjY = RIVER1OBJ[i][2]; + _pan[i]._pObjZ = RIVER1OBJ[i][3]; + _pan[i]._pObjXl = _pan[i]._pObjYl = 0; + } +} + +void River::initRiver() { + static const int RIVERVXTBL[3] = { 6719, 7039, 8319 }; + + _vm->_events->centerMousePos(); + _vm->_events->restrictMouse(); + _vm->_screen->setDisplayScan(); + _vm->_screen->clearScreen(); + _vm->_screen->savePalette(); + _vm->_screen->forceFadeOut(); + + _vm->_files->_setPaletteFlag = false; + _vm->_files->loadScreen(95, 4); + _vm->_buffer2.copyFrom(*_vm->_screen); + + _vm->_screen->restorePalette(); + _vm->_screen->setBufferScan(); + _vm->_destIn = &_vm->_buffer2; + _vm->_room->roomMenu(); + + if (_vm->_saveRiver) { + // Restoring a savegame, so set properties from saved fields + _vm->_screen->_scrollRow = _rScrollRow; + _vm->_screen->_scrollCol = _rScrollCol; + _vm->_screen->_scrollX = _rScrollX; + _vm->_screen->_scrollY = _rScrollY; + } else { + // Set initial scene state + _vm->_screen->_scrollRow = 0; + _vm->_screen->_scrollCol = 140; + _vm->_screen->_scrollX = 0; + _vm->_screen->_scrollY = 0; + } + + _vm->_room->buildScreen(); + _vm->copyBF2Vid(); + _vm->_screen->forceFadeIn(); + + if (_vm->_saveRiver) { + // Restore draw rects from savegame + _vm->_oldRects.resize(_rOldRectCount); + _vm->_newRects.resize(_rNewRectCount); + // KEYFLG = _vm->_rKeyFlag + } else { + // Reset draw rects + _vm->_oldRects.clear(); + _vm->_newRects.clear(); + // KEYFLG = 0 + } + + _vm->_player->_scrollAmount = 2; + setRiverPan(); + _vm->_timers[3]._timer = 1; + _vm->_timers[3]._initTm = 1; + ++_vm->_timers[3]._flag; + + _canoeFrame = 0; + _mapPtr = (const byte *)MAPTBL[_vm->_riverFlag] + 1; + if (_vm->_saveRiver) { + _mapPtr--; + _mapPtr += _mapOffset; + } else { + _screenVertX = RIVERVXTBL[_vm->_riverFlag] - 320; + _canoeLane = 3; + _hitCount = 0; + _hitSafe = 0; + _canoeYPos = 71; + } + + _riverIndex = _vm->_riverFlag; + _topList = RIVEROBJECTTBL[_riverIndex]; + updateObstacles(); + riverSetPhysX(); + _canoeDir = 0; + _vm->_deathFlag = 0; + _vm->_deathCount = 0; + + _vm->_timers[11]._timer = 1200; + _vm->_timers[11]._initTm = 1200; + ++_vm->_timers[11]._flag; + _vm->_timers[12]._timer = 1500; + _vm->_timers[12]._initTm = 1500; + ++_vm->_timers[12]._flag; + + _vm->_maxHits = 2 - _vm->_riverFlag; + _vm->_saveRiver = false; +} + +void River::resetPositions() { + riverSetPhysX(); + int val = (_vm->_screen->_scrollCol + 1 - _vm->_oldScrollCol) * 16; + if (val > 256) { + val &= 0x7F; + val |= 0x80; + } + + for (int i = 0; i < _pNumObj; i++) + _pan[i]._pObjX += val; +} + +void River::checkRiverPan() { + int val = (_vm->_screen->_scrollCol + 20) * 16; + + for (int i = 0; i < _pNumObj; i++) { + if (_pan[i]._pObjX < val) + return; + } + + setRiverPan(); +} + +bool River::riverJumpTest() { + if (_vm->_screen->_scrollCol == 120 || _vm->_screen->_scrollCol == 60 || _vm->_screen->_scrollCol == 0) { + int val = _mapPtr[0]; + ++_mapPtr; + if (val == 0xFF) + return true; + _vm->_oldScrollCol = _vm->_screen->_scrollCol; + + if (val == 0) { + _vm->_screen->_scrollCol = 139; + _vm->_screen->_scrollX = 14; + _vm->_room->buildScreen(); + resetPositions(); + return false; + } + } else if (_vm->_screen->_scrollCol == 105) { + int val1 = _mapPtr[1]; + int val2 = _mapPtr[2]; + _mapPtr += 3; + if (_canoeLane < 3) { + if (val1 != 0) { + _vm->_deathFlag = true; + _vm->_deathCount = 300; + _vm->_deathType = val2; + } + } else { + if (val1 != 1) { + _vm->_deathFlag = true; + _vm->_deathCount = 300; + _vm->_deathType = val2; + } + _vm->_oldScrollCol = _vm->_screen->_scrollCol; + _vm->_screen->_scrollCol = 44; + _vm->_screen->_scrollX = 14; + _vm->_room->buildScreen(); + resetPositions(); + return false; + } + } + + _vm->_screen->_scrollX = 14; + --_vm->_screen->_scrollCol; + _vm->_buffer1.moveBufferRight(); + _vm->_room->buildColumn(_vm->_screen->_scrollCol, 0); + checkRiverPan(); + return false; +} + +void River::riverSound() { + if (_vm->_timers[11]._flag == 0) { + ++_vm->_timers[11]._flag; + _vm->_sound->playSound(2); + } + + if (_vm->_timers[12]._flag == 0) { + ++_vm->_timers[12]._flag; + _vm->_sound->playSound(3); + } + + if ((_xCam >= 1300) && (_xCam <= 1320)) + _vm->_sound->playSound(1); +} + +void River::moveCanoe() { + Screen &screen = *_vm->_screen; + EventsManager &events = *_vm->_events; + Common::Point pt = events.calcRawMouse(); + + // Do an event polling + _vm->_canSaveLoad = true; + events.pollEvents(); + _vm->_canSaveLoad = false; + if (_vm->_room->_function == FN_CLEAR1) + return; + + if (_canoeDir) { + // Canoe movement in progress + moveCanoe2(); + } else { + if (events._leftButton && pt.y >= 140) { + if (pt.x < RMOUSE[8][0]) { + // Disk icon wasn't clicked + _vm->_scripts->printString(BAR_MESSAGE); + } else { + // Clicked on the Disc icon + _vm->_saveRiver = true; + _rScrollRow = screen._scrollRow; + _rScrollCol = screen._scrollCol; + _rScrollX = screen._scrollX; + _rScrollY = screen._scrollY; + _mapOffset = _mapPtr - MAPTBL[_vm->_riverFlag]; + + // Show the ScummVM menu + _vm->_room->handleCommand(9); + + if (_vm->_room->_function != FN_CLEAR1) { + _vm->_saveRiver = false; + _vm->_room->buildScreen(); + _vm->copyBF2Vid(); + } + } + } + else if ((events._leftButton && pt.y <= _canoeYPos) || + (!events._leftButton && _vm->_player->_move == UP)) { + // Move canoe up + if (_canoeLane > 0) { + _canoeDir = -1; + _canoeMoveCount = 0; + + moveCanoe2(); + } + } + else if (events._leftButton || _vm->_player->_move == DOWN) { + // Move canoe down + if (_canoeLane < 7) { + _canoeDir = 1; + _canoeMoveCount = 0; + + moveCanoe2(); + } + } + } +} + +void River::moveCanoe2() { + _canoeYPos += _canoeDir; + + if (++_canoeMoveCount == 5) { + _canoeLane += _canoeDir; + _canoeDir = 0; + } +} + +void River::updateObstacles() { + RiverStruct *cur; + for (cur = _topList; cur < RIVEROBJECTTBL[_riverIndex + 1]; ++cur) { + int val = cur->_field1 + cur->_field3 - 1; + if (val < _screenVertX) + break; + + if (cur->_field3 < (_screenVirtX + 319)) { + _topList = cur; + _botList = cur; + + while (cur < RIVEROBJECTTBL[_riverIndex + 1]) { + ++cur; + val = cur->_field1 + cur->_field3 - 1; + if (val < _screenVertX || (cur->_field3 >= (_screenVirtX + 319))) + break; + + _botList = cur; + } + + return; + } + } + + cur = _topList; + cur--; + _botList = cur; +} + +void River::riverSetPhysX() { + int val = (_vm->_screen->_scrollCol * 16) + _vm->_screen->_scrollX; + RiverStruct *cur = _topList; + while (cur <= _botList) { + cur[0]._field5 = val - (_screenVertX - cur[0]._field3); + ++cur; + } +} + +bool River::checkRiverCollide() { + if (_hitSafe) + return false; + + _canoeVXPos = _screenVertX + 170; + + for (RiverStruct *si = _topList; si <= _botList; ++si) { + if (si[0]._lane < _canoeLane) + continue; + + if ((si[0]._lane == _canoeLane) || (si[0]._lane == _canoeLane + 1)) { + if (si[0]._field1 + si[0]._field3 - 1 >= _canoeVXPos) { + if (_canoeVXPos + 124 >= si[0]._field3) { + _vm->_sound->playSound(4); + return true; + } + } + } + } + return false; +} + +void River::plotRiver() { + if (_vm->_timers[3]._flag == 0) { + ++_vm->_timers[3]._flag; + if (_canoeFrame == 12) + _canoeFrame = 0; + else + ++_canoeFrame; + } + + ImageEntry ie; + ie._flags = IMGFLAG_UNSCALED; + ie._spritesPtr = _vm->_objectsTable[45]; + ie._frameNumber = _canoeFrame; + ie._position.x = (_vm->_screen->_scrollCol * 16) + _vm->_screen->_scrollX + 160; + ie._position.y = _canoeYPos - 41; + ie._offsetY = 41; + _vm->_images.addToList(ie); + + RiverStruct *cur = _topList; + while (cur <= _botList) { + if (cur[0]._id != -1) { + ie._flags = IMGFLAG_UNSCALED; + ie._spritesPtr = _vm->_objectsTable[45]; + ie._frameNumber = 0; + ie._position.x = cur[0]._field5; + int val = (cur[0]._lane * 5) + 56; + ie._position.y = val - cur[0]._field8; + ie._offsetY = cur[0]._field8; + _vm->_images.addToList(ie); + } + ++cur; + } +} + +void River::mWhileDownRiver() { + _vm->_events->hideCursor(); + _vm->_screen->setDisplayScan(); + _vm->_screen->clearScreen(); + _vm->_screen->savePalette(); + + _vm->_files->loadScreen(95, 4); + _vm->_buffer2.copyFrom(*_vm->_screen); + _vm->_screen->restorePalette(); + _vm->_screen->setPalette(); + _vm->_screen->setBufferScan(); + _vm->_screen->_scrollX = 0; + _vm->_room->buildScreen(); + _vm->copyBF2Vid(); + + _vm->_player->_scrollAmount = 2; + _vm->_destIn = &_vm->_buffer2; + _xTrack = -7; + _yTrack = _zTrack = 0; + _xCam = _yCam = 0; + _zCam = 80; + + _vm->_timers[24]._timer = 1; + _vm->_timers[24]._initTm = 1; + ++_vm->_timers[24]._flag; + + _pNumObj = 14; + for (int i = 0; i <_pNumObj; i++) { + _pan[i]._pObject = _vm->_objectsTable[33]; + _pan[i]._pImgNum = DOWNRIVEROBJ[i][0]; + _pan[i]._pObjX = DOWNRIVEROBJ[i][1]; + _pan[i]._pObjY = DOWNRIVEROBJ[i][2]; + _pan[i]._pObjZ = DOWNRIVEROBJ[i][3]; + _pan[i]._pObjXl = _pan[i]._pObjYl = 0; + } + + _vm->_timers[3]._timer = 200; + _vm->_timers[3]._initTm = 200; + ++_vm->_timers[3]._flag; + _vm->_timers[4]._timer = 350; + _vm->_timers[4]._initTm = 350; + ++_vm->_timers[4]._flag; + + while (!_vm->shouldQuit() && !_vm->_events->isKeyMousePressed() && + (_vm->_screen->_scrollCol + _vm->_screen->_vWindowWidth != _vm->_room->_playFieldWidth)) { + _vm->_images.clear(); + _vm->_events->_vbCount = 6; + + _vm->_screen->_scrollX += _vm->_player->_scrollAmount; + while (_vm->_screen->_scrollX >= TILE_WIDTH) { + _vm->_screen->_scrollX -= TILE_WIDTH; + ++_vm->_screen->_scrollCol; + _vm->_buffer1.moveBufferLeft(); + _vm->_room->buildColumn(_vm->_screen->_scrollCol + _vm->_screen->_vWindowWidth, _vm->_screen->_vWindowBytesWide); + } + + pan(); + scrollRiver(); + + if (!_vm->_timers[3]._flag) { + ++_vm->_timers[3]._flag; + _vm->_sound->playSound(1); + } + else if (!_vm->_timers[4]._flag) { + ++_vm->_timers[4]._flag; + _vm->_sound->playSound(0); + } + + while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0) { + _vm->_events->pollEventsAndWait(); + } + } + + _vm->_events->showCursor(); +} + +void River::scrollRiver() { + _vm->copyBF1BF2(); + _vm->_newRects.clear(); + _vm->_buffer2.plotImage(_vm->_objectsTable[33], 0, Common::Point(66, 30)); + _vm->plotList(); + _vm->copyRects(); + _vm->copyBF2Vid(); +} + +void River::scrollRiver1() { + _vm->copyBF1BF2(); + _vm->_newRects.clear(); + plotRiver(); + _vm->plotList(); + _vm->copyRects(); + _vm->copyBF2Vid(); +} + +void River::river() { + static const int RIVERDEATH[5] = { 22, 23, 24, 25, 26 }; + + initRiver(); + _vm->_events->showCursor(); + + while (!_vm->shouldQuit()) { + _vm->_events->_vbCount = 4; + + // int bx = _vm->_player->_scrollAmount - _screenVertX; + if (_vm->_screen->_scrollX == 0) { + _vm->_sound->midiRepeat(); + if (riverJumpTest()) { + _CHICKENOUTFLG = false; + return; + } + } + else { + _vm->_screen->_scrollX -= _vm->_player->_scrollAmount; + } + + if (_CHICKENOUTFLG) { + _CHICKENOUTFLG = false; + return; + } + + _vm->_images.clear(); + _vm->_animation->animate(0); + + riverSound(); + pan(); + moveCanoe(); + + if (_vm->_room->_function != FN_CLEAR1) { + updateObstacles(); + riverSetPhysX(); + bool checkCollide = checkRiverCollide(); + if (_hitSafe != 0) + _hitSafe -= 2; + + if (checkCollide) { + _vm->dead(RIVERDEATH[0]); + return; + } + + if (_vm->_deathFlag) { + _vm->_deathCount--; + if (_vm->_deathCount == 0) { + _vm->dead(RIVERDEATH[_vm->_deathType]); + return; + } + } + + // Scroll the river + scrollRiver1(); + + // Allow time for new scrolled river position to be shown + _vm->_canSaveLoad = true; + while (!_vm->shouldQuit() && _vm->_room->_function == FN_NONE && + _vm->_events->_vbCount > 0) { + _vm->_events->pollEventsAndWait(); + } + _vm->_canSaveLoad = false; + } + + if (_vm->_room->_function == FN_CLEAR1) { + _vm->_scripts->_endFlag = true; + _vm->_scripts->_returnCode = 0; + _CHICKENOUTFLG = false; + break; + } + } +} +void River::synchronize(Common::Serializer &s) { + s.syncAsSint16LE(_canoeLane); + s.syncAsSint16LE(_canoeYPos); + s.syncAsSint16LE(_hitCount); + s.syncAsSint16LE(_riverIndex); + s.syncAsSint16LE(_hitSafe); + s.syncAsUint16LE(_rScrollRow); + s.syncAsUint16LE(_rScrollCol); + s.syncAsSint16LE(_rScrollX); + s.syncAsSint16LE(_rScrollY); + s.syncAsUint16LE(_rOldRectCount); + s.syncAsUint16LE(_rNewRectCount); + s.syncAsUint16LE(_rKeyFlag); + s.syncAsUint16LE(_mapOffset); + s.syncAsUint16LE(_screenVirtX); + warning("TODO: s.syncAsSint16LE(_topList);"); + warning("TODO: s.syncAsSint16LE(_botList);"); +} + +/*------------------------------------------------------------------------*/ + +Ant::Ant(AmazonEngine *vm) : AmazonManager(vm) { + _antDirection = NONE; + _pitDirection = NONE; + _antCel = 0; + _torchCel = 0; + _pitCel = 0; + _stabCel = 0; + _antPos = Common::Point(0, 0); + _antDieFl = _antEatFl = false; + _stabFl = false; + _pitPos = Common::Point(0, 0); +} + +void Ant::plotTorchSpear(int indx, const int *&buf) { + int idx = indx; + + ImageEntry ie; + ie._flags = IMGFLAG_UNSCALED; + ie._spritesPtr = _vm->_objectsTable[62]; + ie._frameNumber = buf[(idx / 2)]; + ie._position = Common::Point(_pitPos.x + buf[(idx / 2) + 1], _pitPos.y + buf[(idx / 2) + 2]); + ie._offsetY = 255; + _vm->_images.addToList(ie); +} + +void Ant::plotPit(int indx, const int *&buf) { + int idx = indx; + ImageEntry ie; + ie._flags = IMGFLAG_UNSCALED; + ie._spritesPtr = _vm->_objectsTable[62]; + ie._frameNumber = buf[(idx / 2)]; + ie._position = Common::Point(_pitPos.x, _pitPos.y); + ie._offsetY = _pitPos.y; + _vm->_images.addToList(ie); + + _vm->_player->_rawPlayer = _pitPos; + if (_vm->_inventory->_inv[76]._value == 1) { + idx = _torchCel; + buf = Amazon::TORCH; + _vm->_timers[14]._flag = 1; + idx += 6; + if (buf[idx / 2] == -1) + idx = 0; + _torchCel = idx; + plotTorchSpear(idx, buf); + } + else if (!_stabFl && (_vm->_inventory->_inv[78]._value == 1)) { + idx = 0; + buf = Amazon::SPEAR; + plotTorchSpear(idx, buf); + } +} + +int Ant::antHandleRight(int indx, const int *&buf) { + int retval = indx; + if (_pitDirection == NONE) { + _pitDirection = UP; + _pitPos.y = 127; + } + retval = _pitCel; + buf = Amazon::PITWALK; + if (_pitPos.x < 230) { + if (retval == 0) { + retval = 48; + _pitPos.y = 127; + } + retval -= 6; + _pitPos.x -= buf[(retval / 2) + 1]; + _pitPos.y -= buf[(retval / 2) + 2]; + _pitCel = retval; + } + return retval; +} + +int Ant::antHandleLeft(int indx, const int *&buf) { + int retval = indx; + if (_pitDirection == UP) { + _pitDirection = NONE; + _pitPos.y = 127; + } + retval = _pitCel; + buf = Amazon::PITWALK; + retval += 6; + if (buf[retval / 2] == -1) { + retval = 0; + _pitPos.y = 127; + } + _pitPos.x += buf[(retval / 2) + 1]; + _pitPos.y += buf[(retval / 2) + 2]; + _pitCel = retval; + + return retval; +} + +int Ant::antHandleStab(int indx, const int *&buf) { + int retval = indx; + if (_vm->_inventory->_inv[78]._value != 1) { + if (_stabFl) { + buf = Amazon::PITSTAB; + retval = _stabCel; + if (_vm->_timers[13]._flag == 0) { + _vm->_timers[13]._flag = 1; + retval += 6; + if (Amazon::PITSTAB[retval] == -1) { + _stabFl = false; + _pitCel = 0; + _pitPos.y = 127; + retval = 0; + buf = Amazon::PITWALK; + } + else { + _pitPos.x += buf[(retval / 2) + 1]; + _pitPos.y += buf[(retval / 2) + 2]; + _pitCel = retval; + } + } + } + else { + _stabFl = true; + _pitCel = 0; + retval = 0; + _stabCel = 0; + int dist = _pitPos.x - _antPos.x; + if (_antEatFl && !_antDieFl && (dist <= 80)) { + _antDieFl = true; + _antCel = 0; + _antPos.y = 123; + _vm->_sound->playSound(1); + } + } + } + return retval; +} + +void Ant::doAnt() { + _antDirection = NONE; + if (_vm->_aniFlag != 1) { + _vm->_aniFlag = 1; + _antCel = 0; + _torchCel = 0; + _pitCel = 0; + + _vm->_timers[15]._timer = 16; + _vm->_timers[15]._initTm = 16; + _vm->_timers[15]._flag = 1; + + _vm->_timers[13]._timer = 5; + _vm->_timers[13]._initTm = 5; + _vm->_timers[13]._flag = 1; + + _vm->_timers[14]._timer = 10; + _vm->_timers[14]._initTm = 10; + _vm->_timers[14]._flag = 1; + + _antPos = Common::Point(-40, 123); + _antDieFl = _antEatFl = false; + _stabFl = false; + _pitPos = Common::Point(_vm->_player->_rawPlayer.x, 127); + } + + const int *buf = nullptr; + if (_antDieFl) { + buf = Amazon::ANTDIE; + } + else if (_antEatFl) { + buf = Amazon::ANTEAT; + } + else if (_antPos.x > 120 && _vm->_flags[198] == 1) { + _antEatFl = true; + _vm->_flags[235] = 1; + _antCel = 0; + buf = Amazon::ANTEAT; + } + else { + buf = Amazon::ANTWALK; + if (_vm->_inventory->_inv[76]._value == 1) + _antDirection = UP; + } + + int idx = _antCel; + if (_vm->_timers[15]._flag == 0) { + _vm->_timers[15]._flag = 1; + if (_antDirection == UP) { + if (_antPos.x > 10) { + if (idx == 0) + idx = 36; + else + idx -= 6; + + _antPos = Common::Point(buf[(idx / 2) + 1], buf[(idx / 2) + 2]); + _antCel = idx; + } + } + else { + idx += 6; + if (buf[(idx / 2)] != -1) { + _antPos = Common::Point(buf[(idx / 2) + 1], buf[(idx / 2) + 2]); + _antCel = idx; + } + else if (!_antDieFl) { + idx = 0; + _antPos = Common::Point(buf[(idx / 2) + 1], buf[(idx / 2) + 2]); + _antCel = idx; + } + else { + idx -= 6; + if (_vm->_flags[200] == 0) + _vm->_flags[200] = 1; + } + } + } + + ImageEntry ie; + ie._flags = IMGFLAG_UNSCALED; + ie._spritesPtr = _vm->_objectsTable[61]; + ie._frameNumber = buf[(idx / 2)]; + ie._position = Common::Point(_antPos.x, _antPos.y); + ie._offsetY = _antPos.y - 70; + _vm->_images.addToList(ie); + _antCel = idx; + + if (_vm->_flags[196] != 1) { + idx = _pitCel; + if (_stabFl == 1) { + idx = antHandleStab(idx, buf); + } + else { + buf = Amazon::PITWALK; + if (_vm->_timers[13]._flag == 0) { + _vm->_timers[13]._flag = 1; + _vm->_events->pollEvents(); + if (_vm->_events->_leftButton) { + Common::Point pt = _vm->_events->calcRawMouse(); + if (pt.x < _pitPos.x) + idx = antHandleLeft(idx, buf); + else if (pt.x > _pitPos.x) + idx = antHandleRight(idx, buf); + } + else { + buf = Amazon::PITWALK; + if (_vm->_player->_playerDirection == UP) + idx = antHandleStab(idx, buf); + else if (_vm->_player->_playerDirection == LEFT) + idx = antHandleLeft(idx, buf); + else if (_vm->_player->_playerDirection == RIGHT) + idx = antHandleRight(idx, buf); + } + } + } + plotPit(idx, buf); + } + + if (!_antDieFl) { + int dist = _pitPos.x - _antPos.x; + if ((_antEatFl && (dist <= 45)) || (!_antEatFl && (dist <= 80))) { + _vm->_flags[199] = 1; + _vm->_aniFlag = 0; + } + } +} + +} // End of namespace Amazon + +} // End of namespace Access |