1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "mohawk/riven_stacks/ospit.h"
24
25 #include "mohawk/cursors.h"
26 #include "mohawk/riven.h"
27 #include "mohawk/riven_card.h"
28 #include "mohawk/riven_graphics.h"
29 #include "mohawk/riven_inventory.h"
30 #include "mohawk/riven_video.h"
31
32 namespace Mohawk {
33 namespace RivenStacks {
34
OSpit(MohawkEngine_Riven * vm)35 OSpit::OSpit(MohawkEngine_Riven *vm) :
36 RivenStack(vm, kStackOspit) {
37
38 REGISTER_COMMAND(OSpit, xorollcredittime);
39 REGISTER_COMMAND(OSpit, xbookclick);
40 REGISTER_COMMAND(OSpit, xooffice30_closebook);
41 REGISTER_COMMAND(OSpit, xobedroom5_closedrawer);
42 REGISTER_COMMAND(OSpit, xogehnopenbook);
43 REGISTER_COMMAND(OSpit, xogehnbookprevpage);
44 REGISTER_COMMAND(OSpit, xogehnbooknextpage);
45 REGISTER_COMMAND(OSpit, xgwatch);
46 }
47
xorollcredittime(const ArgumentArray & args)48 void OSpit::xorollcredittime(const ArgumentArray &args) {
49 // WORKAROUND: The special change stuff only handles one destination and it would
50 // be messy to modify the way that currently works. If we use the trap book on Tay,
51 // we should be using the Tay end game sequences.
52 if (_vm->_vars["returnstackid"] == kStackRspit) {
53 RivenScriptPtr script = _vm->_scriptMan->createScriptWithCommand(
54 new RivenStackChangeCommand(_vm, kStackRspit, 0x3338, true, false));
55 _vm->_scriptMan->runScript(script, false);
56 return;
57 }
58
59 // You used the trap book... why? What were you thinking?
60 uint32 gehnState = _vm->_vars["agehn"];
61
62 if (gehnState == 0) // Gehn who?
63 runEndGame(1, 9500, 1225);
64 else if (gehnState == 4) // You freed him? Are you kidding me?
65 runEndGame(2, 12000, 558);
66 else // You already spoke with Gehn. What were you thinking?
67 runEndGame(3, 8000, 857);
68 }
69
xbookclick(const ArgumentArray & args)70 void OSpit::xbookclick(const ArgumentArray &args) {
71 // Let's hook onto our video
72 RivenVideo *video = _vm->_video->getSlot(args[0]);
73
74 // Convert from the standard QuickTime base time to milliseconds
75 // The values are in terms of 1/600 of a second.
76 // Have I said how much I just *love* QuickTime? </sarcasm>
77 uint32 startTime = args[1] * 1000 / 600;
78 uint32 endTime = args[2] * 1000 / 600;
79
80 // Track down our hotspot
81 Common::String hotspotName = Common::String::format("touchBook%d", args[3]);
82 RivenHotspot *hotspot = _vm->getCard()->getHotspotByName(hotspotName);
83 Common::Rect hotspotRect = hotspot->getRect();
84
85 debug(0, "xbookclick:");
86 debug(0, "\tVideo Code = %d", args[0]);
87 debug(0, "\tStart Time = %dms", startTime);
88 debug(0, "\tEnd Time = %dms", endTime);
89 debug(0, "\tHotspot = %d -> %s", args[3], hotspotName.c_str());
90
91 // Just let the video play while we wait until Gehn opens the trap book for us
92 while (video->getTime() < startTime && !_vm->hasGameEnded()) {
93 _vm->doFrame();
94 }
95
96 // Break out if we're quitting
97 if (_vm->hasGameEnded())
98 return;
99
100 // OK, Gehn has opened the trap book and has asked us to go in. Let's watch
101 // and see what the player will do...
102 while (video->getTime() < endTime && !_vm->hasGameEnded()) {
103 if (hotspotRect.contains(getMousePosition()))
104 _vm->_cursor->setCursor(kRivenOpenHandCursor);
105 else
106 _vm->_cursor->setCursor(kRivenMainCursor);
107
108 if (mouseIsDown()) {
109 if (hotspotRect.contains(getMousePosition())) {
110 // OK, we've used the trap book! We go for ride lady!
111 _vm->_video->closeVideos(); // Stop all videos
112 _vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor
113 _vm->_gfx->scheduleTransition(kRivenTransitionBlend);
114 _vm->getCard()->drawPicture(3); // Black out the screen
115 _vm->_sound->playSound(0); // Play the link sound
116 _vm->delay(12000);
117 _vm->getCard()->playMovie(7); // Activate Gehn Link Video
118 RivenVideo *linkVideo = _vm->_video->openSlot(1); // Play Gehn Link Video
119 linkVideo->playBlocking();
120 _vm->_vars["ocage"] = 1;
121 _vm->_vars["agehn"] = 4; // Set Gehn to the trapped state
122 _vm->_vars["atrapbook"] = 1; // We've got the trap book again
123 _vm->_sound->playSound(0); // Play the link sound again
124 _vm->_gfx->scheduleTransition(kRivenTransitionBlend);
125 _vm->changeToCard(_vm->getStack()->getCardStackId(0x2885)); // Link out!
126 _vm->_inventory->forceVisible(true);
127 _vm->delay(2000);
128 _vm->_inventory->forceVisible(false);
129 _vm->_scriptMan->stopAllScripts(); // Stop all running scripts (so we don't remain in the cage)
130 return;
131 }
132 }
133
134 _vm->doFrame();
135 }
136
137 // Break out if we're quitting
138 if (_vm->hasGameEnded())
139 return;
140
141 // If there was no click and this is the third time Gehn asks us to
142 // use the trap book, he will shoot the player. Dead on arrival.
143 // Run the credits from here.
144 if (_vm->_vars["agehn"] == 3) {
145 runCredits(args[0], 5000, 995);
146 return;
147 }
148
149 // There was no click, so just play the rest of the video.
150 video->playBlocking();
151 }
152
xooffice30_closebook(const ArgumentArray & args)153 void OSpit::xooffice30_closebook(const ArgumentArray &args) {
154 // Close the blank linking book if it's open
155 uint32 &book = _vm->_vars["odeskbook"];
156 if (book != 1)
157 return;
158
159 // Set the variable to be "closed"
160 book = 0;
161
162 // Play the movie
163 RivenVideo *video = _vm->_video->openSlot(1);
164 video->seek(0);
165 video->playBlocking();
166
167 // Set the hotspots into their correct states
168 RivenHotspot *closeBook = _vm->getCard()->getHotspotByName("closeBook");
169 RivenHotspot *nullHotspot = _vm->getCard()->getHotspotByName("null");
170 RivenHotspot *openBook = _vm->getCard()->getHotspotByName("openBook");
171
172 closeBook->enable(false);
173 nullHotspot->enable(false);
174 openBook->enable(true);
175
176 _vm->getCard()->drawPicture(1);
177 }
178
xobedroom5_closedrawer(const ArgumentArray & args)179 void OSpit::xobedroom5_closedrawer(const ArgumentArray &args) {
180 // Close the drawer if open when clicking on the journal.
181 RivenVideo *video = _vm->_video->openSlot(2);
182 video->playBlocking();
183 _vm->_vars["ostanddrawer"] = 0;
184 }
185
xogehnopenbook(const ArgumentArray & args)186 void OSpit::xogehnopenbook(const ArgumentArray &args) {
187 _vm->getCard()->drawPicture(_vm->_vars["ogehnpage"]);
188 }
189
xogehnbookprevpage(const ArgumentArray & args)190 void OSpit::xogehnbookprevpage(const ArgumentArray &args) {
191 // Get the page variable
192 uint32 &page = _vm->_vars["ogehnpage"];
193
194 // Keep turning pages while the mouse is pressed
195 while (keepTurningPages()) {
196 // Check for the first page
197 if (page == 1)
198 return;
199
200 // Update the page number
201 page--;
202
203 pageTurn(kRivenTransitionWipeRight);
204 _vm->getCard()->drawPicture(page);
205 _vm->doFrame();
206
207 waitForPageTurnSound();
208 }
209 }
210
xogehnbooknextpage(const ArgumentArray & args)211 void OSpit::xogehnbooknextpage(const ArgumentArray &args) {
212 // Get the page variable
213 uint32 &page = _vm->_vars["ogehnpage"];
214
215 // Keep turning pages while the mouse is pressed
216 while (keepTurningPages()) {
217 // Check for the last page
218 if (page == 13)
219 return;
220
221 // Update the page number
222 page++;
223
224 pageTurn(kRivenTransitionWipeLeft);
225 _vm->getCard()->drawPicture(page);
226 _vm->doFrame();
227
228 waitForPageTurnSound();
229 }
230 }
231
xgwatch(const ArgumentArray & args)232 void OSpit::xgwatch(const ArgumentArray &args) {
233 // Hide the cursor
234 _vm->_cursor->setCursor(kRivenHideCursor);
235
236 uint32 prisonCombo = _vm->_vars["pcorrectorder"];
237
238 byte curSound = 0;
239 while (curSound < 5 && !_vm->hasGameEnded()) {
240 // Play a sound every half second
241 _vm->_sound->playSound(getComboDigit(prisonCombo, curSound) + 13);
242 _vm->delay(500);
243
244 curSound++;
245 }
246
247 // Now play the video for the watch
248 _vm->getCard()->playMovie(1);
249 RivenVideo *watchVideo = _vm->_video->openSlot(1);
250 watchVideo->playBlocking();
251 }
252
253 } // End of namespace RivenStacks
254 } // End of namespace Mohawk
255