void TSpit::xtakeit(const ArgumentArray &args) { // Pick up and move a marble // First, let's figure out what marble we're now holding uint32 &marble = _vm->_vars["themarble"]; marble = 0; for (uint32 i = 0; i < kMarbleCount; i++) { RivenHotspot *marbleHotspot = _vm->getCard()->getHotspotByName(s_marbleNames[i]); if (marbleHotspot->containsPoint(getMousePosition())) { marble = i + 1; break; } } // xtakeit() shouldn't be called if we're not on a marble hotspot assert(marble != 0); // Redraw the background _vm->getCard()->drawPicture(1); // Loop until the player lets go (or quits) while (mouseIsDown() && !_vm->hasGameEnded()) { _vm->doFrame(); } // Check if we landed in a valid location and no other marble has that location uint32 &marblePos = _vm->_vars[s_marbleNames[marble - 1]]; bool foundMatch = false; for (int y = 0; y < 25 && !foundMatch; y++) { for (int x = 0; x < 25 && !foundMatch; x++) { Common::Rect testHotspot = generateMarbleGridRect(x, y); // Let's try to place the marble! if (testHotspot.contains(getMousePosition())) { // Set this as the position setMarbleX(marblePos, x); setMarbleY(marblePos, y); // Let's make sure no other marble is in this spot... for (uint16 i = 0; i < kMarbleCount; i++) if (i != marble - 1 && _vm->_vars[s_marbleNames[i]] == marblePos) marblePos = 0; // We have a match foundMatch = true; } } } // If we still don't have a match, reset it to the original location if (!foundMatch) marblePos = 0; // Check the new hotspots and refresh everything marble = 0; setMarbleHotspots(); drawMarbles(); }
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 PSpit::xpisland990_elevcombo(const ArgumentArray &args) { // Play button sound based on args[0] _vm->_sound->playSound(args[0] + 5); _vm->_cursor->hideCursor(); _vm->delay(500); _vm->_cursor->showCursor(); // If the user released the mouse button during the wait time, the mouse up event // is not forwarded to the game script handler. The button appears to be down // until the user moves the mouse outside of the button hotspot. // This happens with the original engine as well. // To work around this issue we run the mouse up script if the mouse is not // pressed anymore at this point. if (!mouseIsDown()) { Common::String buttonName = Common::String::format("combo%d", args[0]); RivenHotspot *button = _vm->getCard()->getHotspotByName(buttonName); RivenScriptPtr mouseUpScript = button->getScript(kMouseUpScript); _vm->_scriptMan->runScript(mouseUpScript, false); } // It is impossible to get here if Gehn is not trapped. However, // the original also disallows brute forcing the ending if you have // not yet trapped Gehn. if (_vm->_vars["agehn"] != 4) return; uint32 &correctDigits = _vm->_vars["pelevcombo"]; // pelevcombo keeps count of how many buttons we have pressed in the correct order. // When pelevcombo is 5, clicking the handle will show the video freeing Catherine. if (correctDigits < 5 && args[0] == getComboDigit(_vm->_vars["pcorrectorder"], correctDigits)) correctDigits++; else correctDigits = 0; }
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::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(); } }
void ASpit::xaatrusbooknextpage(const ArgumentArray &args) { // Get the page variable uint32 &page = _vm->_vars["aatrusbook"]; // Keep turning pages while the mouse is pressed bool firstPageTurn = true; while ((mouseIsDown() || firstPageTurn) && !_vm->hasGameEnded()) { // Check for the last page if (((_vm->getFeatures() & GF_DEMO) && page == 6) || page == 10) return; if (!pageTurn(kRivenTransitionWipeLeft)) { return; } // Update the page number page++; firstPageTurn = false; _vm->getCard()->drawPicture(page); _vm->doFrame(); } }
void ASpit::xaatrusbookprevpage(const ArgumentArray &args) { // Get the page variable uint32 &page = _vm->_vars["aatrusbook"]; // Keep turning pages while the mouse is pressed bool firstPageTurn = true; while (mouseIsDown() || firstPageTurn) { // Check for the first page if (page == 1) return; if (!pageTurn(kRivenTransitionWipeRight)) { return; } // Update the page number page--; firstPageTurn = false; _vm->getCard()->drawPicture(page); _vm->doFrame(); } }
void ASpit::xacathbooknextpage(const ArgumentArray &args) { // Get the variable uint32 &page = _vm->_vars["acathbook"]; // Keep turning pages while the mouse is pressed bool firstPageTurn = true; while ((mouseIsDown() || firstPageTurn) && !_vm->hasGameEnded()) { // Check for the last page if (page == 49) return; if (!pageTurn(kRivenTransitionWipeUp)) { return; } // Update the page number page++; firstPageTurn = false; cathBookDrawPage(page); _vm->doFrame(); } }
void OSpit::xbookclick(const ArgumentArray &args) { // Let's hook onto our video RivenVideo *video = _vm->_video->getSlot(args[0]); // Convert from the standard QuickTime base time to milliseconds // The values are in terms of 1/600 of a second. // Have I said how much I just *love* QuickTime? </sarcasm> uint32 startTime = args[1] * 1000 / 600; uint32 endTime = args[2] * 1000 / 600; // Track down our hotspot Common::String hotspotName = Common::String::format("touchBook%d", args[3]); RivenHotspot *hotspot = _vm->getCard()->getHotspotByName(hotspotName); Common::Rect hotspotRect = hotspot->getRect(); debug(0, "xbookclick:"); debug(0, "\tVideo Code = %d", args[0]); debug(0, "\tStart Time = %dms", startTime); debug(0, "\tEnd Time = %dms", endTime); debug(0, "\tHotspot = %d -> %s", args[3], hotspotName.c_str()); // Just let the video play while we wait until Gehn opens the trap book for us while (video->getTime() < startTime && !_vm->hasGameEnded()) { _vm->doFrame(); } // Break out if we're quitting if (_vm->hasGameEnded()) return; // OK, Gehn has opened the trap book and has asked us to go in. Let's watch // and see what the player will do... while (video->getTime() < endTime && !_vm->hasGameEnded()) { if (hotspotRect.contains(getMousePosition())) _vm->_cursor->setCursor(kRivenOpenHandCursor); else _vm->_cursor->setCursor(kRivenMainCursor); if (mouseIsDown()) { if (hotspotRect.contains(getMousePosition())) { // OK, we've used the trap book! We go for ride lady! _vm->_video->closeVideos(); // Stop all videos _vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor _vm->_gfx->scheduleTransition(kRivenTransitionBlend); _vm->getCard()->drawPicture(3); // Black out the screen _vm->_sound->playSound(0); // Play the link sound _vm->delay(12000); _vm->getCard()->playMovie(7); // Activate Gehn Link Video RivenVideo *linkVideo = _vm->_video->openSlot(1); // Play Gehn Link Video linkVideo->playBlocking(); _vm->_vars["ocage"] = 1; _vm->_vars["agehn"] = 4; // Set Gehn to the trapped state _vm->_vars["atrapbook"] = 1; // We've got the trap book again _vm->_sound->playSound(0); // Play the link sound again _vm->_gfx->scheduleTransition(kRivenTransitionBlend); _vm->changeToCard(_vm->getStack()->getCardStackId(0x2885)); // Link out! _vm->_inventory->forceVisible(true); _vm->delay(2000); _vm->_inventory->forceVisible(false); _vm->_scriptMan->stopAllScripts(); // Stop all running scripts (so we don't remain in the cage) return; } } _vm->doFrame(); } // Break out if we're quitting if (_vm->hasGameEnded()) return; // If there was no click and this is the third time Gehn asks us to // use the trap book, he will shoot the player. Dead on arrival. // Run the credits from here. if (_vm->_vars["agehn"] == 3) { runCredits(args[0], 5000, 995); return; } // There was no click, so just play the rest of the video. video->playBlocking(); }