/* 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 "mohawk/riven_stacks/bspit.h" #include "mohawk/cursors.h" #include "mohawk/riven.h" #include "mohawk/riven_card.h" #include "mohawk/riven_graphics.h" #include "mohawk/riven_video.h" namespace Mohawk { namespace RivenStacks { BSpit::BSpit(MohawkEngine_Riven *vm) : DomeSpit(vm, kStackBspit, "bSliders.190", "bSliderBG.190") { REGISTER_COMMAND(BSpit, xblabopenbook); REGISTER_COMMAND(BSpit, xblabbookprevpage); REGISTER_COMMAND(BSpit, xblabbooknextpage); REGISTER_COMMAND(BSpit, xsoundplug); REGISTER_COMMAND(BSpit, xbchangeboiler); REGISTER_COMMAND(BSpit, xbupdateboiler); REGISTER_COMMAND(BSpit, xbsettrap); REGISTER_COMMAND(BSpit, xbcheckcatch); REGISTER_COMMAND(BSpit, xbait); REGISTER_COMMAND(BSpit, xbfreeytram); REGISTER_COMMAND(BSpit, xbaitplate); REGISTER_COMMAND(BSpit, xbisland190_opencard); REGISTER_COMMAND(BSpit, xbisland190_resetsliders); REGISTER_COMMAND(BSpit, xbisland190_slidermd); REGISTER_COMMAND(BSpit, xbisland190_slidermw); REGISTER_COMMAND(BSpit, xbscpbtn); REGISTER_COMMAND(BSpit, xbisland_domecheck); REGISTER_COMMAND(BSpit, xvalvecontrol); REGISTER_COMMAND(BSpit, xbchipper); } void BSpit::xblabopenbook(const ArgumentArray &args) { // Get the variable uint32 page = _vm->_vars["blabpage"]; // Draw the image of the page based on the blabbook variable _vm->getCard()->drawPicture(page); if (page == 14) { labBookDrawDomeCombination(); } } void BSpit::labBookDrawDomeCombination() const { // Draw the dome combination // The images for the numbers are tBMP's 364 through 368 // The start point is at (240, 82) uint32 domeCombo = _vm->_vars["adomecombo"]; static const uint16 kNumberWidth = 32; static const uint16 kNumberHeight = 24; static const uint16 kDstX = 240; static const uint16 kDstY = 82; byte numCount = 0; for (int bitPos = 24; bitPos >= 0; bitPos--) { if (domeCombo & (1 << bitPos)) { uint16 offset = (24 - bitPos) * kNumberWidth; Common::Rect srcRect = Common::Rect(offset, 0, offset + kNumberWidth, kNumberHeight); Common::Rect dstRect = Common::Rect(numCount * kNumberWidth + kDstX, kDstY, (numCount + 1) * kNumberWidth + kDstX, kDstY + kNumberHeight); _vm->_gfx->drawImageRect(numCount + 364, srcRect, dstRect); numCount++; } } assert(numCount == 5); // Sanity check } void BSpit::xblabbookprevpage(const ArgumentArray &args) { // Get the page variable uint32 &page = _vm->_vars["blabpage"]; // Keep turning pages while the mouse is pressed while (keepTurningPages()) { // Check for the first page if (page == 1) return; // Update the page number page--; pageTurn(kRivenTransitionWipeRight); _vm->getCard()->drawPicture(page); if (page == 14) { labBookDrawDomeCombination(); } _vm->doFrame(); waitForPageTurnSound(); } } void BSpit::xblabbooknextpage(const ArgumentArray &args) { // Get the page variable uint32 &page = _vm->_vars["blabpage"]; // Keep turning pages while the mouse is pressed while (keepTurningPages()) { // Check for the last page if (page == 22) return; // Update the page number page++; pageTurn(kRivenTransitionWipeLeft); _vm->getCard()->drawPicture(page); if (page == 14) { labBookDrawDomeCombination(); } _vm->doFrame(); waitForPageTurnSound(); } } void BSpit::xsoundplug(const ArgumentArray &args) { if (_vm->_vars["bcratergg"] == 0) { if (_vm->_vars["bblrwtr"] == 0) { _vm->getCard()->overrideSound(0, 2); } else { _vm->getCard()->overrideSound(0, 3); } } else { _vm->getCard()->overrideSound(0, 1); } } void BSpit::xbchangeboiler(const ArgumentArray &args) { uint32 heat = _vm->_vars["bheat"]; uint32 water = _vm->_vars["bblrwtr"]; uint32 platform = _vm->_vars["bblrgrt"]; // Stop any background videos _vm->_video->closeVideos(); if (args[0] == 1) { // Water is filling/draining from the boiler if (water == 0) { if (platform == 1) _vm->getCard()->playMovie(12); else _vm->getCard()->playMovie(10); } else if (heat == 1) { if (platform == 1) _vm->getCard()->playMovie(22); else _vm->getCard()->playMovie(19); } else { if (platform == 1) _vm->getCard()->playMovie(16); else _vm->getCard()->playMovie(13); } } else if (args[0] == 2 && water != 0) { if (heat == 1) { // Turning on the heat if (platform == 1) _vm->getCard()->playMovie(23); else _vm->getCard()->playMovie(20); } else { // Turning off the heat if (platform == 1) _vm->getCard()->playMovie(18); else _vm->getCard()->playMovie(15); } } else if (args[0] == 3) { if (platform == 1) { // Lowering the platform if (water == 1) { if (heat == 1) _vm->getCard()->playMovie(24); else _vm->getCard()->playMovie(17); } else { _vm->getCard()->playMovie(11); } } else { // Raising the platform if (water == 1) { if (heat == 1) _vm->getCard()->playMovie(21); else _vm->getCard()->playMovie(14); } else { _vm->getCard()->playMovie(9); } } } if (args.size() > 1) _vm->getCard()->playSound(args[1]); else if (args[0] == 2) _vm->getCard()->playSound(1); RivenVideo *video = _vm->_video->openSlot(11); video->playBlocking(); } void BSpit::xbupdateboiler(const ArgumentArray &args) { if (_vm->_vars["bheat"] != 0) { if (_vm->_vars["bblrgrt"] == 0) { _vm->getCard()->playMovie(8); } else { _vm->getCard()->playMovie(7); } } else { RivenVideo *video = _vm->_video->getSlot(7); if (video) { video->disable(); video->stop(); } video = _vm->_video->getSlot(8); if (video) { video->disable(); video->stop(); } } } void BSpit::ytramTrapTimer() { // Remove this timer removeTimer(); // Check if we've caught a Ytram checkYtramCatch(true); } void BSpit::xbsettrap(const ArgumentArray &args) { // Set the Ytram trap // We can catch the Ytram between 10 seconds and 3 minutes from now uint32 timeUntilCatch = _vm->_rnd->getRandomNumberRng(10, 60 * 3) * 1000; _vm->_vars["bytramtime"] = timeUntilCatch + _vm->getTotalPlayTime(); // And set the timer too installTimer(TIMER(BSpit, ytramTrapTimer), timeUntilCatch); } void BSpit::checkYtramCatch(bool playSound) { // Check if we've caught a Ytram uint32 &ytramTime = _vm->_vars["bytramtime"]; // The trap has been moved back up. // You can't catch those sneaky Ytrams that way. if (ytramTime == 0) { return; } // If the trap still has not gone off, reinstall our timer // This is in case you set the trap, walked away, and returned if (_vm->getTotalPlayTime() < ytramTime) { installTimer(TIMER(BSpit, ytramTrapTimer), ytramTime - _vm->getTotalPlayTime()); return; } // Increment the movie per catch (max = 3) uint32 &ytramMovie = _vm->_vars["bytram"]; ytramMovie++; if (ytramMovie > 3) ytramMovie = 3; // Reset variables _vm->_vars["bytrapped"] = 1; _vm->_vars["bbait"] = 0; _vm->_vars["bytrap"] = 0; ytramTime = 0; // Play the capture sound, if requested if (playSound) _vm->_sound->playSound(33); } void BSpit::xbcheckcatch(const ArgumentArray &args) { // Just pass our parameter along... checkYtramCatch(args[0] != 0); } void BSpit::xbait(const ArgumentArray &args) { // Set the cursor to the pellet _vm->_cursor->setCursor(kRivenPelletCursor); // Loop until the player lets go (or quits) while (mouseIsDown() && !_vm->hasGameEnded()) { _vm->doFrame(); } // Set back the cursor _vm->_cursor->setCursor(kRivenMainCursor); RivenHotspot *bait = _vm->getCard()->getHotspotByBlstId(9); RivenHotspot *baitPlate = _vm->getCard()->getHotspotByBlstId(16); // Set the bait if we put it on the plate if (baitPlate->containsPoint(getMousePosition())) { _vm->_vars["bbait"] = 1; _vm->getCard()->drawPicture(4); bait->enable(false); // Disable bait hotspot baitPlate->enable(true); // Enable baitplate hotspot } } void BSpit::xbfreeytram(const ArgumentArray &args) { // Play a random Ytram movie after freeing it uint16 mlstId; switch (_vm->_vars["bytram"]) { case 1: mlstId = 11; break; case 2: mlstId = 12; break; default: // The original did rand(13, 14) mlstId = _vm->_rnd->getRandomNumberRng(13, 15); break; } // Play the video _vm->getCard()->playMovie(mlstId); RivenVideo *first = _vm->_video->openSlot(11); first->playBlocking(); // Now play the second movie _vm->getCard()->playMovie(mlstId + 5); RivenVideo *second = _vm->_video->openSlot(12); second->playBlocking(); _vm->getCard()->drawPicture(4); } void BSpit::xbaitplate(const ArgumentArray &args) { // Remove the pellet from the plate and put it in your hand _vm->_cursor->setCursor(kRivenPelletCursor); _vm->getCard()->drawPicture(3); // Loop until the player lets go (or quits) while (mouseIsDown() && !_vm->hasGameEnded()) { _vm->doFrame(); } // Set back the cursor _vm->_cursor->setCursor(kRivenMainCursor); RivenHotspot *bait = _vm->getCard()->getHotspotByBlstId(9); RivenHotspot *baitPlate = _vm->getCard()->getHotspotByBlstId(16); // Set the bait if we put it on the plate, remove otherwise if (baitPlate->containsPoint(getMousePosition())) { _vm->_vars["bbait"] = 1; _vm->getCard()->drawPicture(4); bait->enable(false); // Disable bait hotspot baitPlate->enable(true); // Enable baitplate hotspot } else { _vm->_vars["bbait"] = 0; bait->enable(true); // Enable bait hotspot baitPlate->enable(false); // Disable baitplate hotspot } } void BSpit::xbisland190_opencard(const ArgumentArray &args) { checkDomeSliders(); } void BSpit::xbisland190_resetsliders(const ArgumentArray &args) { resetDomeSliders(9); } void BSpit::xbisland190_slidermd(const ArgumentArray &args) { dragDomeSlider(9); } void BSpit::xbisland190_slidermw(const ArgumentArray &args) { checkSliderCursorChange(9); } void BSpit::xbscpbtn(const ArgumentArray &args) { runDomeButtonMovie(); } void BSpit::xbisland_domecheck(const ArgumentArray &args) { runDomeCheck(); } void BSpit::xvalvecontrol(const ArgumentArray &args) { Common::Point startPos = getMouseDragStartPosition(); // Set the cursor to the closed position _vm->_cursor->setCursor(kRivenClosedHandCursor); while (mouseIsDown()) { Common::Point mousePos = getMousePosition(); int changeX = mousePos.x - startPos.x; int changeY = startPos.y - mousePos.y; // Get the variable for the valve uint32 valve = _vm->_vars["bvalve"]; // FIXME: These values for changes in x/y could be tweaked. if (valve == 0 && changeY <= -10) { valveChangePosition(1, 2, 2); } else if (valve == 1) { if (changeX >= 0 && changeY >= 10) { valveChangePosition(0, 3, 1); } else if (changeX <= -10 && changeY <= 10) { valveChangePosition(2, 1, 3); } } else if (valve == 2 && changeX >= 10) { valveChangePosition(1, 4, 2); } _vm->doFrame(); } } void BSpit::valveChangePosition(uint32 valvePosition, uint16 videoId, uint16 pictureId) { RivenVideo *video = _vm->_video->openSlot(videoId); video->seek(0); video->playBlocking(); _vm->getCard()->drawPicture(pictureId); // If we changed state and the new state is that the valve is flowing to // the boiler, we need to update the boiler state. if (valvePosition == 1) { // Check which way the water is going at the boiler if (_vm->_vars["bidvlv"] == 1) { if (_vm->_vars["bblrarm"] == 1 && _vm->_vars["bblrwtr"] == 1) { // If the pipe is open, make sure the water is drained out _vm->_vars["bheat"] = 0; _vm->_vars["bblrwtr"] = 0; _vm->_sound->playCardSound("bBlrFar"); } if (_vm->_vars["bblrarm"] == 0 && _vm->_vars["bblrwtr"] == 0) { // If the pipe is closed, fill the boiler again _vm->_vars["bheat"] = _vm->_vars["bblrvalve"]; _vm->_vars["bblrwtr"] = 1; _vm->_sound->playCardSound("bBlrFar"); } } else { // Have the grating inside the boiler match the switch outside _vm->_vars["bblrgrt"] = (_vm->_vars["bblrsw"] == 1) ? 0 : 1; } } _vm->_vars["bvalve"] = valvePosition; } void BSpit::xbchipper(const ArgumentArray &args) { Common::Point startPos = getMouseDragStartPosition(); bool pulledLever = false; while (mouseIsDown() && !_vm->hasGameEnded()) { Common::Point pos = getMousePosition(); if (pos.y > startPos.y) { pulledLever = true; break; } _vm->doFrame(); } if (pulledLever) { RivenVideo *video = _vm->_video->openSlot(2); video->seek(0); video->playBlocking(); } } } // End of namespace RivenStacks } // End of namespace Mohawk