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 "fullpipe/fullpipe.h"
24 
25 #include "fullpipe/objectnames.h"
26 #include "fullpipe/constants.h"
27 
28 #include "fullpipe/gameloader.h"
29 #include "fullpipe/motion.h"
30 #include "fullpipe/scenes.h"
31 #include "fullpipe/statics.h"
32 
33 #include "fullpipe/interaction.h"
34 #include "fullpipe/behavior.h"
35 
36 
37 namespace Fullpipe {
38 
scene16_initScene(Scene * sc)39 void scene16_initScene(Scene *sc) {
40 	g_vars->scene16_figures.clear();
41 	g_vars->scene16_walkingBoy = 0;
42 	g_vars->scene16_walkingGirl = 0;
43 	g_vars->scene16_walkingCount = 200;
44 	g_vars->scene16_wire = sc->getStaticANIObject1ById(ANI_WIRE16, -1);
45 	g_vars->scene16_mug = sc->getStaticANIObject1ById(ANI_MUG, -1);
46 	g_vars->scene16_jettie = sc->getStaticANIObject1ById(ANI_JETTIE, -1);
47 	g_vars->scene16_boot = sc->getStaticANIObject1ById(ANI_BOOT_16, -1);
48 	g_vars->scene16_girlIsLaughing = false;
49 	g_vars->scene16_sound = SND_16_034;
50 
51 	if (g_fp->getObjectState(sO_Bridge) == g_fp->getObjectEnumState(sO_Bridge, sO_Convoluted)) {
52 		g_vars->scene16_placeIsOccupied = true;
53 
54 		StaticANIObject *boy[2];
55 		boy[0] = sc->getStaticANIObject1ById(ANI_BOY, -1);
56 		boy[0]->loadMovementsPixelData();
57 
58 		boy[1] = new StaticANIObject(boy[0]);
59 		sc->addStaticANIObject(boy[1], 1);
60 
61 		int idx = 0;
62 
63 		for (int i = 0; i < 3; i++) {
64 			g_vars->scene16_figures.push_back(boy[idx]);
65 
66 			idx++;
67 
68 			if (idx > 1)
69 				idx = 0;
70 		}
71 
72 		g_vars->scene16_figures.push_back(sc->getStaticANIObject1ById(ANI_GIRL, -1));
73 
74 		for (int i = 0; i < 4; i++) {
75 			g_vars->scene16_figures.push_back(boy[idx]);
76 
77 			idx++;
78 
79 			if (idx > 1)
80 				idx = 0;
81 		}
82 	} else {
83 		g_fp->setObjectState(sO_Girl, g_fp->getObjectEnumState(sO_Girl, sO_IsSwinging));
84 
85 		g_vars->scene16_placeIsOccupied = false;
86 
87 		StaticANIObject *ani = new StaticANIObject(g_fp->accessScene(SC_COMMON)->getStaticANIObject1ById(ANI_BEARDED_CMN, -1));
88 		ani->_movement = 0;
89 		ani->_statics = ani->_staticsList[0];
90 		sc->addStaticANIObject(ani, 1);
91 	}
92 
93 	if (g_fp->getObjectState(sO_Girl) == g_fp->getObjectEnumState(sO_Girl, sO_IsLaughing)) {
94 		StaticANIObject *girl = sc->getStaticANIObject1ById(ANI_GIRL, -1);
95 
96 		girl->show1(554, 432, MV_GRL_LAUGH_POPA, 0);
97 		girl->_priority = 20;
98 	}
99 
100 	if (g_fp->getObjectState(sO_Cup) == g_fp->getObjectEnumState(sO_Cup, sO_In_16)) {
101 		g_vars->scene16_mug->_statics = g_vars->scene16_mug->getStaticsById(ST_MUG_EMPTY);
102 		g_vars->scene16_mug->_movement = 0;
103 		g_vars->scene16_mug->setOXY(409, 459);
104 		g_vars->scene16_mug->_priority = 5;
105 		g_vars->scene16_mug->_flags |= 4;
106 	}
107 }
108 
scene16_updateCursor()109 int scene16_updateCursor() {
110 	g_fp->updateCursorCommon();
111 
112 	if (g_fp->_objectIdAtCursor == PIC_SC16_TUMBA) {
113 		if (g_fp->_cursorId == PIC_CSR_DEFAULT)
114 			g_fp->_cursorId = PIC_CSR_ITN;
115 	} else {
116 		if (g_fp->_objectIdAtCursor == ANI_MUG && g_fp->_cursorId == PIC_CSR_ITN && g_vars->scene16_mug->_statics->_staticsId == ST_MUG_FULL)
117 			g_fp->_cursorId = PIC_CSR_ITN_GREEN;
118 	}
119 
120 	return g_fp->_cursorId;
121 }
122 
sceneHandler16_laughSound()123 void sceneHandler16_laughSound() {
124 	int snd = SND_16_035;
125 
126 	switch (g_vars->scene16_sound) {
127 	case SND_16_034:
128 		snd = SND_16_035;
129 		break;
130 
131 	case SND_16_035:
132 		snd = SND_16_037;
133 		break;
134 
135 	case SND_16_037:
136 		snd = SND_16_034;
137 		break;
138 	}
139 
140 	g_vars->scene16_sound = snd;
141 
142 	g_fp->playSound(snd, 0);
143 }
144 
sceneHandler16_showBearded()145 void sceneHandler16_showBearded() {
146 	if (g_fp->getObjectState(sO_Bridge) == g_fp->getObjectEnumState(sO_Bridge, sO_Unconvoluted)) {
147 		StaticANIObject *brd = g_fp->_currentScene->getStaticANIObject1ById(ANI_BEARDED_CMN, -1);
148 
149 		if (!brd || !(brd->_flags & 4))
150 			chainQueue(QU_BRD16_STARTBEARDED, 0);
151 	}
152 }
153 
sceneHandler16_showMugFull()154 void sceneHandler16_showMugFull() {
155 	g_vars->scene16_mug->changeStatics2(ST_MUG_FULL);
156 }
157 
sceneHandler16_fillMug()158 void sceneHandler16_fillMug() {
159 	if (g_vars->scene16_mug->_flags & 4) {
160 		g_vars->scene16_jettie->_priority = 2;
161 		g_vars->scene16_jettie->startAnim(MV_JTI_FLOWIN, 0, -1);
162 
163 		if (g_fp->_aniMan->_movement) {
164 			if (g_fp->_aniMan->_movement->_id == MV_MAN16_TAKEMUG) {
165 				g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT);
166 
167 				g_vars->scene16_mug->show1(-1, -1, -1, 0);
168 
169 				g_fp->setObjectState(sO_Cup, g_fp->getObjectEnumState(sO_Cup, sO_DudeHas));
170 			}
171 		}
172 		return;
173 	}
174 
175 	MessageQueue *mq;
176 
177 	if (!(g_vars->scene16_boot->_flags & 4)) {
178 		g_vars->scene16_jettie->_priority = 15;
179 		g_vars->scene16_jettie->startAnim(MV_JTI_FLOWBY, 0, -1);
180 
181 		if (g_vars->scene16_walkingBoy) {
182 			mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_BOYOUT), 0, 1);
183 
184 			mq->setParamInt(-1, g_vars->scene16_walkingBoy->_odelay);
185 			if (mq->chain(g_vars->scene16_walkingBoy))
186 				return;
187 		} else {
188 			if (!g_vars->scene16_walkingGirl)
189 				return;
190 
191 			mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_GIRLOUT), 0, 1);
192 
193 			mq->setParamInt(-1, g_vars->scene16_walkingGirl->_odelay);
194 			if (mq->chain(g_vars->scene16_walkingGirl))
195 				return;
196 		}
197 		delete mq;
198 
199 		return;
200 	}
201 
202 	g_vars->scene16_jettie->_priority = 15;
203 
204 	g_vars->scene16_boot->startAnim(MV_BT16_FILL, 0, -1);
205 
206 	StaticANIObject *ani;
207 
208 	if (g_vars->scene16_walkingBoy) {
209 		mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_BOYOUT), 0, 1);
210 
211 		mq->setParamInt(-1, g_vars->scene16_walkingBoy->_odelay);
212 
213 		ani = g_vars->scene16_walkingBoy;
214 	} else {
215 		if (!g_vars->scene16_walkingGirl)
216 			return;
217 
218 		mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_GIRLOUT), 0, 1);
219 
220 		mq->setParamInt(-1, g_vars->scene16_walkingGirl->_odelay);
221 		ani = g_vars->scene16_walkingGirl;
222 	}
223 
224 	if (!mq->chain(ani))
225 		delete mq;
226 }
227 
sceneHandler16_startLaugh()228 void sceneHandler16_startLaugh() {
229 	StaticANIObject *girl = g_fp->_currentScene->getStaticANIObject1ById(ANI_GIRL, -1);
230 
231 	girl->changeStatics2(ST_GRL_STAND);
232 
233 	MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_GIRLLAUGH), 0, 1);
234 
235 	mq->setParamInt(-1, girl->_odelay);
236 	mq->setFlags(mq->getFlags() | 1);
237 	mq->chain(0);
238 
239 	g_fp->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->setSubVarAsInt(sO_DudeSwinged, 0);
240 
241 	g_vars->scene16_girlIsLaughing = true;
242 }
243 
sceneHandler16_drink()244 void sceneHandler16_drink() {
245 	if (g_vars->scene16_mug->_flags & 4) {
246 		if (!g_vars->scene16_jettie->_movement) {
247 			if (!g_vars->scene16_walkingBoy || !g_vars->scene16_walkingBoy->_movement || g_vars->scene16_walkingBoy->_movement->_id != MV_BOY_DRINK) {
248 				if (!g_vars->scene16_walkingGirl || !g_vars->scene16_walkingGirl->_movement || g_vars->scene16_walkingGirl->_movement->_id != MV_GRL_DRINK) {
249 					if (g_vars->scene16_mug->_statics->_staticsId == ST_MUG_FULL) {
250 						MessageQueue *mq;
251 						ExCommand *ex;
252 
253 						if (g_vars->scene16_walkingBoy) {
254 							g_fp->_aniMan->_flags |= 0x180;
255 
256 							g_vars->scene16_walkingBoy->changeStatics2(ST_BOY_STAND);
257 							g_vars->scene16_walkingBoy->queueMessageQueue(0);
258 
259 							mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_BOYKICK), 0, 1);
260 
261 							mq->setParamInt(-1, g_vars->scene16_walkingBoy->_odelay);
262 
263 							ex = new ExCommand(ANI_MAN, 34, 384, 0, 0, 0, 1, 0, 0, 0);
264 							ex->_excFlags |= 3u;
265 							ex->_z = 384;
266 							ex->_messageNum = 0;
267 
268 							mq->insertExCommandAt(2, ex);
269 							mq->setFlags(mq->getFlags() | 1);
270 							mq->chain(0);
271 						} else {
272 							g_fp->_aniMan->_flags |= 0x100;
273 
274 							mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_MANDRINK), 0, 1);
275 
276 							ex = new ExCommand(ANI_MAN, 34, 256, 0, 0, 0, 1, 0, 0, 0);
277 							ex->_excFlags |= 3u;
278 							ex->_z = 256;
279 							ex->_messageNum = 0;
280 
281 							mq->addExCommandToEnd(ex);
282 							mq->setFlags(mq->getFlags() | 1);
283 							mq->chain(0);
284 
285 							g_fp->_currentScene->getStaticANIObject1ById(ANI_GIRL, -1)->changeStatics2(ST_GRL_STAND);
286 						}
287 
288 						g_fp->_currentScene->getStaticANIObject1ById(ANI_WIRE16, -1)->show1(-1, -1, -1, 0);
289 					} else {
290 						chainObjQueue(g_fp->_aniMan, QU_SC16_TAKEMUG, 1);
291 					}
292 				}
293 			}
294 		}
295 	}
296 }
297 
sceneHandler16_mugClick()298 void sceneHandler16_mugClick() {
299 	if (abs(310 - g_fp->_aniMan->_ox) >= 1 || abs(449 - g_fp->_aniMan->_oy) >= 1
300 		|| g_fp->_aniMan->_movement || g_fp->_aniMan->_statics->_staticsId != ST_MAN_RIGHT) {
301 		MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_fp->_aniMan, 310, 449, 1, ST_MAN_RIGHT);
302 
303 		if (mq) {
304 			ExCommand *ex = new ExCommand(0, 17, MSG_SC16_MUGCLICK, 0, 0, 0, 1, 0, 0, 0);
305 			ex->_excFlags = 2;
306 			mq->addExCommandToEnd(ex);
307 
308 			postExCommand(g_fp->_aniMan->_id, 2, 310, 449, 0, -1);
309 		}
310 	} else {
311 		sceneHandler16_drink();
312 	}
313 }
314 
sceneHandler16_showMan()315 void sceneHandler16_showMan() {
316 	g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT);
317 	g_fp->_aniMan->show1(-1, -1, -1, 0);
318 
319 	g_vars->scene16_mug->show1(-1, -1, -1, 0);
320 }
321 
sceneHandler16_showMug()322 void sceneHandler16_showMug() {
323 	chainQueue(QU_SC16_SHOWMUG, 0);
324 }
325 
sceneHandler16_hideMan()326 void sceneHandler16_hideMan() {
327 	g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT);
328 	g_fp->_aniMan->hide();
329 
330 	g_vars->scene16_mug->hide();
331 }
332 
sceneHandler16_hideMug()333 void sceneHandler16_hideMug() {
334 	g_vars->scene16_mug->hide();
335 }
336 
sceneHandler16_hideWire()337 void sceneHandler16_hideWire() {
338 	g_vars->scene16_wire->hide();
339 }
340 
sceneHandler16_showWire()341 void sceneHandler16_showWire() {
342 	g_vars->scene16_wire->show1(-1, -1, -1, 0);
343 }
344 
sceneHandler16_putOnWheel()345 void sceneHandler16_putOnWheel() {
346 	StaticANIObject *ani = g_vars->scene16_walkingBoy;
347 
348 	if (!ani)
349 		ani = g_vars->scene16_walkingGirl;
350 
351 	if (ani)
352 		g_vars->scene16_figures.push_back(ani);
353 
354 	ani = g_vars->scene16_figures.front();
355 
356 	g_vars->scene16_figures.pop_front();
357 
358 	if (ani) {
359 		MessageQueue *mq;
360 
361 		if (ani->_id == ANI_BOY) {
362 			mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_GOBOY), 0, 1);
363 
364 			mq->setParamInt(-1, ani->_odelay);
365 			mq->chain(0);
366 
367 			g_vars->scene16_walkingBoy = ani;
368 			g_vars->scene16_walkingGirl = 0;
369 		} else if (ani->_id == ANI_GIRL) {
370 			if (g_fp->getObjectState(sO_Girl) == g_fp->getObjectEnumState(sO_Girl, sO_IsSwinging)) {
371 				mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_GOGIRL), 0, 1);
372 
373 				mq->setParamInt(-1, ani->_odelay);
374 				mq->chain(0);
375 
376 				g_vars->scene16_walkingBoy = 0;
377 				g_vars->scene16_walkingGirl = ani;
378 			}
379 		}
380 	}
381 }
382 
sceneHandler16_girlROTFL()383 void sceneHandler16_girlROTFL() {
384 	StaticANIObject *girl = g_fp->_currentScene->getStaticANIObject1ById(ANI_GIRL, -1);
385 
386 	girl->changeStatics2(ST_GRL_LAUGH);
387 	girl->startAnim(MV_GRL_FALL, 0, -1);
388 
389 	g_vars->scene16_girlIsLaughing = false;
390 }
391 
sceneHandler16(ExCommand * cmd)392 int sceneHandler16(ExCommand *cmd) {
393 	if (cmd->_messageKind != 17)
394 		return 0;
395 
396 	switch(cmd->_messageNum) {
397 	case MSG_SC16_LAUGHSOUND:
398 		sceneHandler16_laughSound();
399 		break;
400 
401 	case MSG_SC16_SHOWBEARDED:
402 		sceneHandler16_showBearded();
403 		break;
404 
405 	case MSG_SC16_SHOWMUGFULL:
406 		sceneHandler16_showMugFull();
407 		break;
408 
409 	case MSG_SC16_FILLMUG:
410 		sceneHandler16_fillMug();
411 		break;
412 
413 	case MSG_SC16_STARTLAUGH:
414 		sceneHandler16_startLaugh();
415 		break;
416 
417 	case MSG_SC16_MUGCLICK:
418 		if (!g_fp->_aniMan->isIdle() || g_fp->_aniMan->_flags & 0x100)
419 			cmd->_messageKind = 0;
420 		else
421 			sceneHandler16_mugClick();
422 
423 		break;
424 
425 	case MSG_SC16_SHOWMAN:
426 		sceneHandler16_showMan();
427 		break;
428 
429 	case MSG_SC16_SHOWMUG:
430 		sceneHandler16_showMug();
431 		break;
432 
433 	case MSG_SC16_HIDEMAN:
434 		sceneHandler16_hideMan();
435 		break;
436 
437 	case MSG_SC16_HIDEMUG:
438 		sceneHandler16_hideMug();
439 		break;
440 
441 	case MSG_SC16_HIDEWIRE:
442 		sceneHandler16_hideWire();
443 		break;
444 
445 	case MSG_SC16_SHOWWIRE:
446 		sceneHandler16_showWire();
447 		break;
448 
449 	case 33:
450 		if (g_fp->_aniMan2) {
451 			int x = g_fp->_aniMan2->_ox;
452 
453 			if (x < g_fp->_sceneRect.left + 200)
454 				g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
455 
456 			if (x > g_fp->_sceneRect.right - 200)
457 				g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
458 		}
459 
460 		if (g_vars->scene16_placeIsOccupied) {
461 			g_vars->scene16_walkingCount++;
462 
463 			if (g_vars->scene16_walkingCount >= 280) {
464 				sceneHandler16_putOnWheel();
465 
466 				g_vars->scene16_walkingCount = 0;
467 			}
468 		}
469 
470 		if (g_vars->scene16_girlIsLaughing) {
471 			if (g_fp->_aniMan->_movement)
472 				if (g_fp->_aniMan->_movement->_id == MV_MAN_TURN_RL)
473 					sceneHandler16_girlROTFL();
474 		}
475 
476 		g_fp->_behaviorManager->updateBehaviors();
477 		g_fp->startSceneTrack();
478 
479 	}
480 
481 	return 0;
482 }
483 
484 } // End of namespace Fullpipe
485