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 "ngi/ngi.h"
24 
25 #include "ngi/objectnames.h"
26 #include "ngi/constants.h"
27 #include "ngi/utils.h"
28 #include "ngi/gfx.h"
29 #include "ngi/messages.h"
30 #include "ngi/motion.h"
31 #include "ngi/scenes.h"
32 #include "ngi/statics.h"
33 #include "ngi/scene.h"
34 #include "ngi/interaction.h"
35 #include "ngi/gameloader.h"
36 #include "ngi/behavior.h"
37 
38 #include "audio/mixer.h"
39 
40 namespace NGI {
41 
42 static const int scene04_speakerPhases[] = {
43 	0, 1,  2,  3, -1, -1,
44 	0, 2,  3, -1, -1, -1,
45 	0, 2, -1, -1, -1, -1
46 };
47 
48 void sceneHandler04_putKozyawkaBack(StaticANIObject *ani);
49 
scene04_speakerCallback(int * phase)50 void scene04_speakerCallback(int *phase) {
51 	if (g_vars->scene04_soundPlaying) {
52 		if (g_vars->scene04_speakerPhase >= 0) {
53 			*phase = scene04_speakerPhases[g_vars->scene04_speakerPhase + 6 * g_vars->scene04_speakerVariant];
54 
55 			g_vars->scene04_speakerPhase++;
56 
57 			if (scene04_speakerPhases[g_vars->scene04_speakerPhase + 6 * g_vars->scene04_speakerVariant] < 0) {
58 				g_vars->scene04_speakerPhase = 0;
59 				g_vars->scene04_speakerVariant = g_nmi->_rnd.getRandomNumber(2);
60 			}
61 		} else {
62 			++g_vars->scene04_speakerPhase;
63 		}
64 	}
65 }
66 
scene04_springCallback(int * phase)67 void scene04_springCallback(int *phase) {
68 	// do nothing
69 }
70 
scene04_initScene(Scene * sc)71 void scene04_initScene(Scene *sc) {
72 	debugC(1, kDebugSceneLogic, "scene04_initScene()");
73 
74 #if 0
75 	Inventory2 *inv = getGameLoaderInventory();
76 	inv->addItem(ANI_INV_COIN, 1);
77 	inv->rebuildItemRects();
78 #endif
79 
80 	g_vars->scene04_dudeOnLadder = false;
81 	g_vars->scene04_bottle = sc->getPictureObjectById(PIC_SC4_BOTTLE, 0);
82 	g_vars->scene04_hand = sc->getStaticANIObject1ById(ANI_HAND, -1);
83 	g_vars->scene04_plank = sc->getStaticANIObject1ById(ANI_PLANK, -1);
84 	g_vars->scene04_clock = sc->getStaticANIObject1ById(ANI_CLOCK, -1);
85 	g_vars->scene04_spring = sc->getStaticANIObject1ById(ANI_SPRING, -1);
86 	g_vars->scene04_mamasha = sc->getStaticANIObject1ById(ANI_MAMASHA_4, -1);
87 	g_vars->scene04_boot = sc->getStaticANIObject1ById(ANI_SC4_BOOT, -1);
88 	g_vars->scene04_ladder = 0;
89 
90 	StaticANIObject *koz = sc->getStaticANIObject1ById(ANI_KOZAWKA, -1);
91 
92 	if (koz) {
93 		Movement *kozmov = koz->getMovementById(MV_KZW_JUMP);
94 		if (kozmov) {
95 			uint kozsize = kozmov->_currMovement ? kozmov->_currMovement->_dynamicPhases.size() : kozmov->_dynamicPhases.size();
96 
97 			for (uint i = 0; i < kozsize; i++) {
98 				kozmov->setDynamicPhaseIndex(i);
99 
100 				if (kozmov->_framePosOffsets.size()) {
101 					g_vars->scene04_jumpingKozyawki[i] = kozmov->_framePosOffsets[kozmov->_currDynamicPhaseIndex];
102 				} else {
103 					kozmov->_somePoint.x = 0;
104 					kozmov->_somePoint.y = 0;
105 					g_vars->scene04_jumpingKozyawki[i] = kozmov->_somePoint;
106 				}
107 			}
108 		}
109 
110 		kozmov = koz->getMovementById(MV_KZW_JUMPROTATE);
111 		if (kozmov) {
112 			uint kozsize = kozmov->_currMovement ? kozmov->_currMovement->_dynamicPhases.size() : kozmov->_dynamicPhases.size();
113 
114 			for (uint i = 0; i < kozsize; i++) {
115 				kozmov->setDynamicPhaseIndex(i);
116 
117 				if (kozmov->_framePosOffsets.size()) {
118 					g_vars->scene04_jumpRotateKozyawki[i] = kozmov->_framePosOffsets[kozmov->_currDynamicPhaseIndex];
119 				} else {
120 					kozmov->_somePoint.x = 0;
121 					kozmov->_somePoint.y = 0;
122 					g_vars->scene04_jumpRotateKozyawki[i] = kozmov->_somePoint;
123 				}
124 			}
125 		}
126 	}
127 
128 	Interaction *plank = getGameLoaderInteractionController()->getInteractionByObjectIds(ANI_PLANK, 0, 0);
129 	if (plank)
130 		plank->_flags |= 8;
131 
132 	if (g_nmi->getObjectState(sO_Jar_4) == g_nmi->getObjectEnumState(sO_Jar_4, sO_UpsideDown)) {
133 		debugC(2, kDebugSceneLogic, "scene04: Jar is upside down");
134 
135 		g_vars->scene04_bottleObjList.clear();
136 		g_vars->scene04_kozyawkiObjList.clear();
137 
138 		sc->getPictureObjectById(PIC_SC4_BOTTLE, 0)->_flags &= 0xfffb;
139 		sc->getPictureObjectById(PIC_SC4_MASK, 0)->_flags &= 0xfffb;
140 		sc->getStaticANIObject1ById(ANI_SPRING, 0)->_flags &= 0xfffb;
141 
142 		g_vars->scene04_clockCanGo = false;
143 		g_vars->scene04_objectIsTaken = false;
144 	} else {
145 		debugC(2, kDebugSceneLogic, "scene04: Jar is NOT upside down");
146 
147 		StaticANIObject *spring = sc->getStaticANIObject1ById(ANI_SPRING, -1);
148 
149 		if (spring)
150 			spring->_callback2 = scene04_springCallback;
151 
152 		g_vars->scene04_bottleObjList.clear();
153 		g_vars->scene04_bottleObjList.push_back(sc->getPictureObjectById(PIC_SC4_BOTTLE, 0));
154 		g_vars->scene04_bottleObjList.push_back(sc->getPictureObjectById(PIC_SC4_MASK, 0));
155 
156 		g_vars->scene04_kozyawkiObjList.clear();
157 
158 		if (koz) {
159 			debugC(2, kDebugSceneLogic, "scene04: We're in koz");
160 
161 			koz->loadMovementsPixelData();
162 
163 			koz->_statics = koz->getStaticsById(ST_KZW_EMPTY);
164 			koz->setOXY(0, 0);
165 			koz->hide();
166 
167 			g_vars->scene04_kozyawkiObjList.push_back(koz);
168 
169 			for (int i = 0; i < 6; i++) {
170 				StaticANIObject *koz1 = new StaticANIObject(koz);
171 
172 				sc->addStaticANIObject(koz1, 1);
173 				koz1->_statics = koz->getStaticsById(ST_KZW_EMPTY);
174 				koz1->setOXY(0, 0);
175 				koz1->hide();
176 				g_vars->scene04_kozyawkiObjList.push_back(koz1);
177 			}
178 		}
179 		sc->getPictureObjectById(PIC_SC4_BOTTLE2, 0)->_flags &= 0xfffb;
180 
181 		g_vars->scene04_clockCanGo = true;
182 		g_vars->scene04_objectIsTaken = true;
183 
184 		debugC(2, kDebugSceneLogic, "scene04: kozObjList size: %d", g_vars->scene04_kozyawkiObjList.size());
185 	}
186 
187 	g_vars->scene04_bottleIsTaken = false;
188 	g_vars->scene04_soundPlaying = false;
189 	g_vars->scene04_kozyawkaOnLadder = false;
190 	g_vars->scene04_walkingKozyawka = 0;
191 	g_vars->scene04_bottleWeight = 2;
192 	g_vars->scene04_dynamicPhaseIndex = 0;
193 
194 	g_vars->scene04_kozyawkiAni.clear();
195 
196 	g_nmi->setObjectState(sO_LowerPipe, g_nmi->getObjectEnumState(sO_LowerPipe, sO_IsClosed));
197 
198 	g_vars->scene04_var07 = false;
199 	g_vars->scene04_ladderClickable = false;
200 	g_vars->scene04_coinPut = false;
201 	g_vars->scene04_handIsDown = false;
202 	g_vars->scene04_dudeInBottle = false;
203 	g_vars->scene04_kozHeadRaised = false;
204 	g_vars->scene04_bottleIsDropped = false;
205 	g_vars->scene04_bigBallIn = true;
206 	g_vars->scene04_bigBallCounter = 0;
207 	g_vars->scene04_bigBallFromLeft = true;
208 
209 	if (g_nmi->getObjectState(sO_BigMumsy) != g_nmi->getObjectEnumState(sO_BigMumsy, sO_IsGone))
210 		g_vars->scene04_mamasha->hide();
211 
212 	g_vars->scene04_speaker = sc->getStaticANIObject1ById(ANI_SPEAKER_4, -1);
213 	g_vars->scene04_speaker->_callback2 = scene04_speakerCallback;
214 	g_vars->scene04_speaker->startAnim(MV_SPK4_PLAY, 0, -1);
215 
216 	g_vars->scene04_speakerVariant = 0;
217 	g_vars->scene04_speakerPhase = 0;
218 
219 	g_vars->scene04_musicStage = 0;
220 
221 	g_nmi->initArcadeKeys("SC_4");
222 }
223 
sceneHandler04_friesAreWalking()224 bool sceneHandler04_friesAreWalking() {
225 	if (g_vars->scene04_dudeOnLadder && g_nmi->_aniMan->isIdle() && !(g_nmi->_aniMan->_flags & 0x100)) {
226 		int col = g_vars->scene04_ladder->collisionDetection(g_nmi->_aniMan);
227 		if (col >= 3 && col <= 6 ) {
228 			Movement *koz;
229 
230 			if (!g_vars->scene04_walkingKozyawka
231 				 || (koz = g_vars->scene04_walkingKozyawka->_movement) == 0
232 				 || koz->_id != MV_KZW_WALKPLANK
233 				 || koz->_currDynamicPhaseIndex < 10
234 				 || koz->_currDynamicPhaseIndex > 41)
235 				return true;
236 		}
237 	}
238 
239 	return false;
240 }
241 
scene04_updateCursor()242 int scene04_updateCursor() {
243 	g_nmi->updateCursorCommon();
244 
245 	if (g_nmi->_objectIdAtCursor == PIC_SC4_LRTRUBA) {
246 		if (!g_vars->scene04_objectIsTaken) {
247 			g_nmi->_cursorId = PIC_CSR_DEFAULT;
248 
249 			return g_nmi->_cursorId;
250 		}
251 	} else if (g_nmi->_objectIdAtCursor == ANI_PLANK || g_nmi->_objectIdAtCursor == PIC_SC4_PLANK) {
252 		if (g_nmi->_objectIdAtCursor == ANI_PLANK && g_nmi->_cursorId != PIC_CSR_ITN)
253 			return g_nmi->_cursorId;
254 
255 		if (g_nmi->_objectIdAtCursor == ANI_PLANK || (g_nmi->_objectIdAtCursor == PIC_SC4_PLANK && g_nmi->_cursorId == PIC_CSR_DEFAULT)) {
256 			if (sceneHandler04_friesAreWalking()) {
257 				g_nmi->_cursorId = PIC_CSR_ARCADE1;
258 				return g_nmi->_cursorId;
259 			}
260 			if (g_vars->scene04_soundPlaying) {
261 				g_nmi->_cursorId = PIC_CSR_DEFAULT;
262 				return g_nmi->_cursorId;
263 			}
264 		}
265 	}
266 
267 	if (g_nmi->_cursorId == PIC_CSR_ITN && g_nmi->_objectIdAtCursor == PIC_SC4_DOWNTRUBA)
268 		g_nmi->_cursorId = PIC_CSR_GOD;
269 
270 	return g_nmi->_cursorId;
271 }
272 
sceneHandler04_checkBigBallClick()273 void sceneHandler04_checkBigBallClick() {
274 	StaticANIObject *ball = g_nmi->_currentScene->getStaticANIObject1ById(ANI_BIGBALL, -1);
275 
276 	if (ball)
277 		for (uint i = 0; i < ball->_movements.size(); i++)
278 			ball->_movements[i]->_counterMax = 73;
279 
280 	g_vars->scene04_bigBallIn = true;
281 }
282 
sceneHandler04_clickBottle()283 void sceneHandler04_clickBottle() {
284 	if (!g_vars->scene04_bottleIsTaken)
285 		g_vars->scene04_springOffset += 5;
286 }
287 
sceneHandler04_clickButton()288 void sceneHandler04_clickButton() {
289 	StaticANIObject *but = g_nmi->_currentScene->getStaticANIObject1ById(ANI_BUTTON, -1);
290 
291 	if (but) {
292 		if (!g_vars->scene04_clock->_movement ||
293 			(g_vars->scene04_clock->_movement->_id == MV_CLK_GO && g_vars->scene04_clock->_movement->_currDynamicPhaseIndex > 3 &&
294 			 g_vars->scene04_clock->_movement->_currDynamicPhaseIndex < 105)) {
295 			if (!g_vars->scene04_hand->_movement && !g_vars->scene04_bottleIsTaken) {
296 				but->startAnim(MV_BTN_CLICK, 0, -1);
297 				g_vars->scene04_hand->startAnim(MV_HND_POINT, 0, -1);
298 			}
299 		}
300 	}
301 }
302 
sceneHandler04_downLadder(int x,int y)303 void sceneHandler04_downLadder(int x, int y) {
304 	g_vars->scene04_ladder->startMove(g_nmi->_aniMan, x + g_vars->scene04_ladder->_ladder_field_20, y + g_vars->scene04_ladder->_ladder_field_24, 0, 0);
305 }
306 
sceneHandler04_walkClimbLadder(ExCommand * ex)307 void sceneHandler04_walkClimbLadder(ExCommand *ex) {
308 	MessageQueue *mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
309 
310 	ExCommand *ex1 = new ExCommand(ANI_MAN, 1, MV_MAN_TOLADDER, 0, 0, 0, 1, 0, 0, 0);
311 
312 	ex1->_param = g_nmi->_aniMan->_odelay;
313 	ex1->_excFlags |= 2;
314 
315 	mq->addExCommandToEnd(ex1);
316 
317 	ExCommand *ex2 = new ExCommand(ANI_MAN, 1, MV_MAN_STOPLADDER, 0, 0, 0, 1, 0, 0, 0);
318 
319 	ex2->_param = g_nmi->_aniMan->_odelay;
320 	ex2->_excFlags |= 2;
321 
322 	mq->addExCommandToEnd(ex2);
323 
324 	ExCommand *ex3;
325 
326 	if (ex) {
327 		ex3 = ex->createClone();
328 	} else {
329 		ex3 = new ExCommand(0, 17, MSG_SC4_CLICKLADDER, 0, 0, 0, 1, 0, 0, 0);
330 		ex3->_excFlags |= 3;
331 	}
332 
333 	mq->addExCommandToEnd(ex3);
334 
335 	mq->setFlags(mq->getFlags() | 1);
336 
337 	mq->chain(0);
338 
339 	g_vars->scene04_dudeOnLadder = 1;
340 
341 	g_vars->scene04_ladder = new MctlLadder;
342 	g_vars->scene04_ladder->_ladderX = 1089;
343 	g_vars->scene04_ladder->_ladderY = 406;
344 	g_vars->scene04_ladder->_ladder_field_14 = 12;
345 	g_vars->scene04_ladder->_width = 0;
346 	g_vars->scene04_ladder->_height = -40;
347 	g_vars->scene04_ladder->_ladder_field_20 = 0;
348 	g_vars->scene04_ladder->_ladder_field_24 = -60;
349 
350 	g_vars->scene04_ladder->attachObject(g_nmi->_aniMan);
351 
352 	if (g_vars->scene04_soundPlaying) {
353 		g_vars->scene04_ladder->_ladmovements.front()->movVars->varUpStart = MV_MAN_STARTLADDER2;
354 		g_vars->scene04_ladder->_ladmovements.front()->movVars->varUpGo = MV_MAN_GOLADDER2;
355 		g_vars->scene04_ladder->_ladmovements.front()->movVars->varUpStop = MV_MAN_STOPLADDER2;
356 		g_vars->scene04_ladder->_ladmovements.front()->staticIds[2] = ST_MAN_GOLADDER2;
357 	} else {
358 		g_vars->scene04_ladder->_ladmovements.front()->movVars->varUpStart = MV_MAN_STARTLADDER;
359 		g_vars->scene04_ladder->_ladmovements.front()->movVars->varUpGo = MV_MAN_GOLADDER;
360 		g_vars->scene04_ladder->_ladmovements.front()->movVars->varUpStop = MV_MAN_STOPLADDER;
361 		g_vars->scene04_ladder->_ladmovements.front()->staticIds[2] = ST_MAN_GOLADDER;
362 	}
363 
364 	g_nmi->_aniMan->_priority = 12;
365 
366 	getSc2MctlCompoundBySceneId(g_nmi->_currentScene->_sceneId)->deactivate();
367 	getGameLoaderInteractionController()->disableFlag24();
368 }
369 
sceneHandler04_clickLadder()370 void sceneHandler04_clickLadder() {
371 	g_vars->scene04_dudePosX = g_nmi->_aniMan->_ox;
372 	g_vars->scene04_dudePosY = g_nmi->_aniMan->_oy;
373 
374 	if (g_vars->scene04_dudeOnLadder) {
375 		if (!g_nmi->_aniMan->isIdle() || (g_nmi->_aniMan->_flags & 0x100)) {
376 			g_vars->scene04_ladderClickable = true;
377 		} else {
378 			int h3 = 3 * g_vars->scene04_ladder->_height;
379 			int half = abs(g_vars->scene04_ladder->_height) / 2;
380 			int start = g_vars->scene04_ladder->_ladderY - g_vars->scene04_ladder->_ladder_field_24;
381 			int min = 2 * h3 + start + half + 1;
382 			int max =     h3 + start - half - 1;
383 
384 			if (g_vars->scene04_sceneClickY > max)
385 				g_vars->scene04_sceneClickY = max;
386 
387 			if (g_vars->scene04_sceneClickY < min)
388 				g_vars->scene04_sceneClickY = min;
389 
390 			sceneHandler04_downLadder(g_vars->scene04_sceneClickX, g_vars->scene04_sceneClickY);
391 
392 			g_vars->scene04_ladderClickable = false;
393 		}
394 	} else {
395 		if (g_nmi->_aniMan->isIdle() && !(g_nmi->_aniMan->_flags & 0x100)) {
396 			if (abs(1095 - g_vars->scene04_dudePosX) > 1 || abs(434 - g_vars->scene04_dudePosY) > 1) {
397 				MessageQueue *mq = getSc2MctlCompoundBySceneId(g_nmi->_currentScene->_sceneId)->startMove(g_nmi->_aniMan, 1095, 434, 1, ST_MAN_UP);
398 				if (mq) {
399 					ExCommand *ex = new ExCommand(0, 17, MSG_SC4_CLICKLADDER, 0, 0, 0, 1, 0, 0, 0);
400 
401 					ex->_excFlags = 3;
402 					mq->addExCommandToEnd(ex);
403 
404 					postExCommand(g_nmi->_aniMan->_id, 2, 1095, 434, 0, -1);
405 				}
406 			} else {
407 				sceneHandler04_walkClimbLadder(0);
408 			}
409 		}
410 	}
411 }
412 
sceneHandler04_jumpOnLadder()413 void sceneHandler04_jumpOnLadder() {
414 	if (g_nmi->_aniMan->_movement && g_nmi->_aniMan->_movement->_id != MV_MAN_LOOKLADDER)
415 		return;
416 
417 	if (g_nmi->_aniMan->_statics->_staticsId != ST_MAN_STANDLADDER && g_nmi->_aniMan->_statics->_staticsId != ST_MAN_LADDERDOWN)
418 		return;
419 
420 	g_nmi->_aniMan->changeStatics2(ST_MAN_LADDERDOWN);
421 
422 	g_nmi->_aniMan->_flags |= 0x100;
423 
424 	AniHandler aniHandler;
425 	MakeQueueStruct mkQueue;
426 
427 	aniHandler.attachObject(ANI_MAN);
428 
429 	mkQueue.ani = g_nmi->_aniMan;
430 	mkQueue.staticsId2 = ST_MAN_ONPLANK;
431 	mkQueue.x1 = 938;
432 	mkQueue.y1 = 442;
433 	mkQueue.field_1C = 10;
434 	mkQueue.field_10 = 1;
435 	mkQueue.flags = 78;
436 	mkQueue.movementId = MV_MAN_JUMPONPLANK;
437 
438 	MessageQueue *mq = aniHandler.makeRunQueue(&mkQueue);
439 
440 	if (mq) {
441 		mq->_flags |= 1;
442 
443 		if (!mq->chain(g_nmi->_aniMan))
444 			delete mq;
445 
446 		g_nmi->_aniMan->_priority = 10;
447 	}
448 
449 	g_vars->scene04_ladderOffset = g_vars->scene04_ladder->collisionDetection(g_nmi->_aniMan);
450 }
451 
sceneHandler04_clickPlank()452 void sceneHandler04_clickPlank() {
453 	if (sceneHandler04_friesAreWalking())
454 		sceneHandler04_jumpOnLadder();
455 	else if (g_vars->scene04_dudeOnLadder)
456 		g_nmi->playSound(SND_4_033, 0);
457 	else if (!g_vars->scene04_soundPlaying)
458 		chainQueue(QU_PNK_CLICK, 0);
459 }
460 
sceneHandler04_dropBottle()461 void sceneHandler04_dropBottle() {
462 	g_vars->scene04_bottleIsDropped = true;
463 	g_vars->scene04_bottleY = 10;
464 	g_vars->scene04_bottleWeight = 0;
465 
466 	while (g_vars->scene04_kozyawkiAni.size()) {
467 		StaticANIObject *koz = g_vars->scene04_kozyawkiAni.front();
468 		g_vars->scene04_kozyawkiAni.pop_front();
469 
470 		for (Common::List<GameObject *>::iterator it = g_vars->scene04_bottleObjList.begin(); it != g_vars->scene04_bottleObjList.end(); ++it)
471 			if (*it == koz) {
472 				g_vars->scene04_bottleObjList.erase(it);
473 				break;
474 			}
475 
476 		koz->queueMessageQueue(0);
477 		koz->hide();
478 
479 		g_vars->scene04_kozyawkiObjList.push_back(koz);
480 	}
481 
482 	g_vars->scene04_hand->changeStatics2(ST_HND_EMPTY);
483 
484 	g_vars->scene04_hand->setOXY(429, 21);
485 	g_vars->scene04_hand->_priority = 15;
486 }
487 
sceneHandler04_gotoLadder(ExCommand * ex)488 void sceneHandler04_gotoLadder(ExCommand *ex) {
489 	AniHandler aniHandler;
490 	MakeQueueStruct mkQueue;
491 
492 	aniHandler.attachObject(ANI_MAN);
493 
494 	mkQueue.ani = g_nmi->_aniMan;
495 	mkQueue.staticsId2 = ST_MAN_UP;
496 	mkQueue.x1 = 1095;
497 	mkQueue.y1 = 434;
498 	mkQueue.field_1C = 12;
499 	mkQueue.field_10 = 1;
500 	mkQueue.flags = 78;
501 	mkQueue.movementId = MV_MAN_PLANKTOLADDER;
502 
503 	MessageQueue *mq = aniHandler.makeRunQueue(&mkQueue);
504 
505 	if (mq) {
506 		mq->deleteExCommandByIndex(mq->getCount() - 1, 1);
507 
508 		ExCommand *ex1 = new ExCommand(ANI_MAN, 1, MV_MAN_TOLADDER, 0, 0, 0, 1, 0, 0, 0);
509 		ex1->_excFlags = 2;
510 		ex1->_field_24 = 1;
511 		ex1->_param = -1;
512 		mq->addExCommandToEnd(ex1);
513 
514 		ExCommand *ex2 = new ExCommand(ANI_MAN, 1, MV_MAN_STOPLADDER, 0, 0, 0, 1, 0, 0, 0);
515 		ex2->_excFlags = 2;
516 		ex2->_field_24 = 1;
517 		ex2->_param = -1;
518 		mq->addExCommandToEnd(ex2);
519 
520 		ExCommand *ex3 = new ExCommand(g_nmi->_aniMan->_id, 34, 256, 0, 0, 0, 1, 0, 0, 0);
521 		ex3->_z = 256;
522 		ex3->_messageNum = 0;
523 		ex3->_excFlags |= 3;
524 		mq->addExCommandToEnd(ex3);
525 
526 		if (ex) {
527 			ExCommand *ex4 = ex->createClone();
528 
529 			mq->addExCommandToEnd(ex4);
530 		}
531 
532 		mq->setFlags(mq->getFlags() | 1);
533 
534 		if (mq->chain(g_nmi->_aniMan)) {
535 			g_nmi->_aniMan->_priority = 12;
536 			g_nmi->_aniMan->_flags |= 0x100;
537 		} else {
538 			delete mq;
539 		}
540 	}
541 
542 	g_vars->scene04_kozyawkaOnLadder = false;
543 }
544 
sceneHandler04_lowerPlank()545 void sceneHandler04_lowerPlank() {
546 	g_vars->scene04_plank->startAnim(MV_PNK_WEIGHTRIGHT, 0, -1);
547 }
548 
sceneHandler04_manFromBottle()549 void sceneHandler04_manFromBottle() {
550 	for (Common::List<GameObject *>::iterator it = g_vars->scene04_bottleObjList.begin(); it != g_vars->scene04_bottleObjList.end(); ++it)
551 		if (*it == g_nmi->_aniMan) {
552 			g_vars->scene04_bottleObjList.erase(it);
553 			g_vars->scene04_bottleWeight -= 9;
554 			break;
555 		}
556 
557 	if (g_vars->scene04_ladder)
558 		delete g_vars->scene04_ladder;
559 
560 	g_vars->scene04_ladder = 0;
561 
562 	getSc2MctlCompoundBySceneId(g_nmi->_currentScene->_sceneId)->activate();
563 	getGameLoaderInteractionController()->enableFlag24();
564 }
565 
sceneHandler04_manToBottle()566 void sceneHandler04_manToBottle() {
567 	g_vars->scene04_bottleObjList.push_back(g_nmi->_aniMan);
568 	g_vars->scene04_springOffset = 5;
569 	g_vars->scene04_bottleWeight += 9;
570 	g_nmi->_aniMan2 = g_nmi->_aniMan;
571 	g_vars->scene04_dudeInBottle = 1;
572 }
573 
sceneHandler04_raisePlank()574 void sceneHandler04_raisePlank() {
575 	g_vars->scene04_plank->startAnim(MV_PNK_WEIGHTLEFT, 0, -1);
576 }
577 
sceneHandler04_kozFly3(StaticANIObject * ani,double phase)578 MessageQueue *sceneHandler04_kozFly3(StaticANIObject *ani, double phase) {
579 	AniHandler aniHandler;
580 	MakeQueueStruct mkQueue;
581 
582 	debugC(2, kDebugSceneLogic, "scene04: kozFly3 (OK)");
583 
584 	aniHandler.attachObject(ANI_KOZAWKA);
585 
586 	mkQueue.ani = ani;
587 	mkQueue.staticsId2 = ST_KZW_SIT;
588 	mkQueue.x1 = (int)(723.0 - phase * 185.0);
589 	mkQueue.y1 = 486;
590 	mkQueue.field_1C = 10;
591 	mkQueue.field_10 = 1;
592 	mkQueue.flags = 78;
593 	mkQueue.movementId = MV_KZW_JUMP;
594 
595 	MessageQueue *mq = aniHandler.makeRunQueue(&mkQueue);
596 
597 	if (mq) {
598 		ExCommand *ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_STANDUP, 0, 0, 0, 1, 0, 0, 0);
599 		ex->_excFlags |= 2;
600 		ex->_param = ani->_odelay;
601 		mq->addExCommandToEnd(ex);
602 
603 		ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_TURN, 0, 0, 0, 1, 0, 0, 0);
604 		ex->_excFlags |= 2;
605 		ex->_param = ani->_odelay;
606 		mq->addExCommandToEnd(ex);
607 
608 		for (int i = 0; i < 5; i++) {
609 			ex = new ExCommand(ANI_KOZAWKA, 1, rMV_KZW_GOR, 0, 0, 0, 1, 0, 0, 0);
610 			ex->_excFlags |= 2;
611 			ex->_param = ani->_odelay;
612 			mq->addExCommandToEnd(ex);
613 		}
614 
615 		ex = new ExCommand(ANI_KOZAWKA, 6, 0, 0, 0, 0, 1, 0, 0, 0);
616 		ex->_excFlags |= 3;
617 		ex->_param = ani->_odelay;
618 		mq->addExCommandToEnd(ex);
619 
620 		ex = new ExCommand(ANI_KOZAWKA, 17, MSG_KOZAWRESTART, 0, 0, 0, 1, 0, 0, 0);
621 		ex->_excFlags |= 3;
622 		ex->_param = ani->_odelay;
623 		mq->addExCommandToEnd(ex);
624 	}
625 
626 	return mq;
627 }
628 
sceneHandler04_kozFly5(StaticANIObject * ani,double phase)629 MessageQueue *sceneHandler04_kozFly5(StaticANIObject *ani, double phase) {
630 	AniHandler aniHandler;
631 	MakeQueueStruct mkQueue;
632 
633 	debugC(2, kDebugSceneLogic, "scene04: kozFly5 (OK)");
634 
635 	aniHandler.attachObject(ANI_KOZAWKA);
636 
637 	mkQueue.ani = ani;
638 	mkQueue.staticsId2 = ST_KZW_JUMPOUT;
639 	mkQueue.x1 = 525;
640 	mkQueue.y1 = (int)(344.0 - (double)(320 - g_vars->scene04_bottle->_oy) * phase);
641 	mkQueue.field_1C = 10;
642 	mkQueue.field_10 = 1;
643 	mkQueue.flags = 78;
644 	mkQueue.movementId = MV_KZW_JUMPHIT;
645 
646 	MessageQueue *mq1 = aniHandler.makeRunQueue(&mkQueue);
647 
648 	mkQueue.reset();
649 	mkQueue.ani = ani;
650 	mkQueue.staticsId1 = ST_KZW_JUMPOUT;
651 	mkQueue.staticsId2 = ST_KZW_SIT;
652 	mkQueue.x2 = 525;
653 	mkQueue.y2 = (int)(344.0 - (double)(320 - g_vars->scene04_bottle->_oy) * phase);
654 	mkQueue.y1 = 486;
655 	mkQueue.field_1C = 10;
656 	mkQueue.field_10 = 1;
657 	mkQueue.flags = 117;
658 	mkQueue.movementId = MV_KZW_JUMPOUT;
659 
660 	MessageQueue *mq2 = aniHandler.makeRunQueue(&mkQueue);
661 
662 	if (mq1 && mq2) {
663 		mq1->addExCommandToEnd(mq2->getExCommandByIndex(0)->createClone());
664 
665 		delete mq2;
666 		mq2 = 0;
667 
668 		ExCommand *ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_STANDUP, 0, 0, 0, 1, 0, 0, 0);
669 		ex->_excFlags |= 2;
670 		ex->_param = ani->_odelay;
671 		mq1->addExCommandToEnd(ex);
672 
673 		ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_TURN, 0, 0, 0, 1, 0, 0, 0);
674 		ex->_excFlags |= 2;
675 		ex->_param = ani->_odelay;
676 		mq1->addExCommandToEnd(ex);
677 
678 		for (int i = 0; i < 5; i++) {
679 			ex = new ExCommand(ANI_KOZAWKA, 1, rMV_KZW_GOR, 0, 0, 0, 1, 0, 0, 0);
680 			ex->_excFlags |= 2;
681 			ex->_param = ani->_odelay;
682 			mq1->addExCommandToEnd(ex);
683 		}
684 
685 		ex = new ExCommand(ANI_KOZAWKA, 6, 0, 0, 0, 0, 1, 0, 0, 0);
686 		ex->_excFlags |= 3;
687 		ex->_param = ani->_odelay;
688 		mq1->addExCommandToEnd(ex);
689 
690 		ex = new ExCommand(ANI_KOZAWKA, 17, MSG_KOZAWRESTART, 0, 0, 0, 1, 0, 0, 0);
691 		ex->_excFlags |= 3;
692 		ex->_param = ani->_odelay;
693 		mq1->addExCommandToEnd(ex);
694 	}
695 
696 	if (mq2)
697 		delete mq2;
698 
699 	return mq1;
700 }
701 
sceneHandler04_kozFly6(StaticANIObject * ani)702 MessageQueue *sceneHandler04_kozFly6(StaticANIObject *ani) {
703 	AniHandler aniHandler;
704 	MakeQueueStruct mkQueue;
705 
706 	debugC(2, kDebugSceneLogic, "scene04: kozFly6 (OK)");
707 
708 	aniHandler.attachObject(ANI_KOZAWKA);
709 
710 	mkQueue.ani = ani;
711 	mkQueue.staticsId2 = ST_KZW_SIT;
712 	mkQueue.x1 = 397 - 4 * g_nmi->_rnd.getRandomNumber(1);
713 	mkQueue.field_1C = ani->_priority;
714 	mkQueue.y1 = g_vars->scene04_bottle->_oy - 4 * g_nmi->_rnd.getRandomNumber(1) + 109;
715 	mkQueue.field_10 = 1;
716 	mkQueue.flags = 78;
717 	mkQueue.movementId = MV_KZW_JUMPROTATE;
718 
719 	MessageQueue *mq = aniHandler.makeRunQueue(&mkQueue);
720 
721 	if (mq) {
722 		mq->deleteExCommandByIndex(mq->getCount() - 1, 1);
723 
724 		ExCommand *ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_STANDUP, 0, 0, 0, 1, 0, 0, 0);
725 		ex->_excFlags |= 2;
726 		ex->_param = ani->_odelay;
727 		mq->addExCommandToEnd(ex);
728 
729 		ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_GOR, 0, 0, 0, 1, 0, 0, 0);
730 		ex->_excFlags |= 2;
731 		ex->_param = ani->_odelay;
732 		mq->addExCommandToEnd(ex);
733 
734 		ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_RAISEHEAD, 0, 0, 0, 1, 0, 0, 0);
735 		ex->_excFlags |= 2;
736 		ex->_param = ani->_odelay;
737 		mq->addExCommandToEnd(ex);
738 
739 		g_vars->scene04_kozHeadRaised = true;
740 	}
741 
742 	return mq;
743 }
744 
sceneHandler04_kozMove(Movement * mov,int from,int to,Common::Point * points,double phase)745 void sceneHandler04_kozMove(Movement *mov, int from, int to, Common::Point *points, double phase) {
746 	for (int i = from; i < to; i++) {
747 		mov->setDynamicPhaseIndex(i);
748 
749 		Common::Point *p;
750 		if (mov->_framePosOffsets.size()) {
751 			p = &mov->_framePosOffsets[mov->_currDynamicPhaseIndex];
752 		} else {
753 			p = &mov->_somePoint;
754 			p->x = 0;
755 			p->y = 0;
756 		}
757 
758 		p->y = (int)((double)points[i].y * phase);
759 	}
760 }
761 
sceneHandler04_kozFly7(StaticANIObject * ani,double phase)762 MessageQueue *sceneHandler04_kozFly7(StaticANIObject *ani, double phase) {
763 	AniHandler aniHandler;
764 	MakeQueueStruct mkQueue;
765 
766 	debugC(2, kDebugSceneLogic, "scene04: kozFly7");
767 
768 	aniHandler.attachObject(ANI_KOZAWKA);
769 
770 	mkQueue.ani = ani;
771 	mkQueue.staticsId2 = 560;
772 	mkQueue.x1 = (int)(250.0 - phase * 100.0);
773 	mkQueue.y1 = 455;
774 	mkQueue.field_1C = 10;
775 	mkQueue.field_10 = 1;
776 	mkQueue.flags = 78;
777 	mkQueue.movementId = MV_KZW_JUMPROTATE;
778 
779 	MessageQueue *mq = aniHandler.makeRunQueue(&mkQueue);
780 
781 	if (mq) {
782 		sceneHandler04_kozMove(ani->getMovementById(MV_KZW_JUMPROTATE), 1, 9, g_vars->scene04_jumpRotateKozyawki, phase * 0.5 + 1.5);
783 
784 		ani->_priority = 10;
785 
786 		ExCommand *ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_STANDUP, 0, 0, 0, 1, 0, 0, 0);
787 		ex->_excFlags |= 2;
788 		ex->_param = ani->_odelay;
789 		mq->addExCommandToEnd(ex);
790 
791 		ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_TURN, 0, 0, 0, 1, 0, 0, 0);
792 		ex->_excFlags |= 2;
793 		ex->_param = ani->_odelay;
794 		mq->addExCommandToEnd(ex);
795 
796 		for (int i = 0; i < 2; i++) {
797 			ex = new ExCommand(ANI_KOZAWKA, 1, rMV_KZW_GOR, 0, 0, 0, 1, 0, 0, 0);
798 			ex->_excFlags |= 2;
799 			ex->_param = ani->_odelay;
800 			mq->addExCommandToEnd(ex);
801 		}
802 
803 		ex = new ExCommand(ANI_KOZAWKA, 6, 0, 0, 0, 0, 1, 0, 0, 0);
804 		ex->_excFlags |= 3;
805 		ex->_param = ani->_odelay;
806 		mq->addExCommandToEnd(ex);
807 
808 		ex = new ExCommand(ANI_KOZAWKA, 17, MSG_KOZAWRESTART, 0, 0, 0, 1, 0, 0, 0);
809 		ex->_excFlags |= 3;
810 		ex->_param = ani->_odelay;
811 		mq->addExCommandToEnd(ex);
812 	}
813 
814 	return mq;
815 }
816 
817 static const int kozTrajectory3[] = {
818 	3, 2, 0,
819 	3, 2, 0,
820 	3, 2, 0
821 };
822 
823 static const int kozTrajectory4[] = {
824 	5, 3, 1,
825 	5, 4, 1,
826 	5, 3, 1
827 };
828 
829 static const int kozTrajectory5[] = {
830 	6, 5, 4,
831 	6, 5, 4,
832 	6, 5, 4
833 };
834 
835 static const int kozTrajectory6[] = {
836 	7, 6, 5,
837 	7, 6, 5,
838 	7, 6, 5
839 };
840 
sceneHandler04_shootKozyawka()841 void sceneHandler04_shootKozyawka() {
842 	g_vars->scene04_plank->changeStatics2(ST_PNK_WEIGHTRIGHT);
843 
844 	if (!g_vars->scene04_walkingKozyawka)
845 		return;
846 
847 	if (g_vars->scene04_walkingKozyawka->_movement) {
848 		if (g_vars->scene04_walkingKozyawka->_movement->_id == MV_KZW_WALKPLANK) {
849 			int dphase = g_vars->scene04_walkingKozyawka->_movement->_currDynamicPhaseIndex;
850 
851 			if (dphase < 41) {
852 				int col = 3 * dphase / 15;
853 				if (col > 2)
854 					col = 2;
855 
856 				int row = g_vars->scene04_kozyawkiAni.size();
857 				if (row > 2)
858 					row = 2;
859 
860 				int idx = 3 * row + col;
861 				int phase;
862 
863 				if (g_vars->scene04_ladderOffset == 3) {
864 					phase = kozTrajectory3[idx];
865 				} else if (g_vars->scene04_ladderOffset == 4) {
866 					phase = kozTrajectory4[idx];
867 				} else {
868 					if (g_vars->scene04_ladderOffset == 5)
869 						phase = kozTrajectory5[idx];
870 					else
871 						phase = kozTrajectory6[idx];
872 				}
873 
874 				g_vars->scene04_walkingKozyawka->queueMessageQueue(0);
875 				g_vars->scene04_walkingKozyawka->_movement = 0;
876 				g_vars->scene04_walkingKozyawka->_statics = g_vars->scene04_walkingKozyawka->getStaticsById(ST_KZW_RIGHT);
877 
878 				MessageQueue *mq;
879 
880 				if (phase > 2) {
881 					if (phase > 5) {
882 						if (phase == 6)
883 							mq = sceneHandler04_kozFly6(g_vars->scene04_walkingKozyawka);
884 						else
885 							mq = sceneHandler04_kozFly7(g_vars->scene04_walkingKozyawka, (double)(phase - 6) * 0.3333333333333333);
886 					} else {
887 						mq = sceneHandler04_kozFly5(g_vars->scene04_walkingKozyawka, (double)(phase - 2) * 0.3333333333333333);
888 					}
889 				} else {
890 					mq = sceneHandler04_kozFly3(g_vars->scene04_walkingKozyawka, (double)phase * 0.5);
891 				}
892 
893 				if (mq) {
894 					g_vars->scene04_lastKozyawka = g_vars->scene04_walkingKozyawka;
895 
896 					if (!mq->chain(g_vars->scene04_walkingKozyawka) )
897 						delete mq;
898 				}
899 			}
900 		}
901 	}
902 
903 	if (g_vars->scene04_ladderOffset > 3)
904 		g_nmi->_aniMan->changeStatics1(ST_MAN_LOOKPLANK);
905 
906 	g_vars->scene04_kozyawkaOnLadder = true;
907 }
908 
sceneHandler04_showCoin()909 void sceneHandler04_showCoin() {
910 	StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_SC4_COIN, -1);
911 
912 	if (ani) {
913 		ani->show1(MV_BDG_OPEN, MV_MAN_GOU, MV_SC4_COIN_default, 0);
914 
915 		ani->_priority = 40;
916 	}
917 }
918 
sceneHandler04_stopSound()919 void sceneHandler04_stopSound() {
920 	g_vars->scene04_soundPlaying = false;
921 
922 	g_nmi->stopSoundStream2();
923 }
924 
sceneHandler04_animOutOfBottle(ExCommand * ex)925 void sceneHandler04_animOutOfBottle(ExCommand *ex) {
926 	g_nmi->_aniMan->changeStatics2(ST_MAN_SIT);
927 
928 	MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC4_MANFROMBOTTLE), 0, 0);
929 
930 	if (ex) {
931 		ExCommand *newex = ex->createClone();
932 
933 		mq->addExCommandToEnd(newex);
934 	  }
935 
936 	mq->_flags |= 1;
937 	mq->chain(0);
938 
939 	g_vars->scene04_dudeInBottle = false;
940 	g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 1);
941 }
942 
sceneHandler04_walkKozyawka()943 void sceneHandler04_walkKozyawka() {
944 	debugC(1, kDebugSceneLogic, "scene04: walkKozyawka");
945 
946 	if (g_vars->scene04_kozyawkiObjList.size()) {
947 		debugC(1, kDebugSceneLogic, "scene04: walkKozyawka: getting one");
948 
949 		g_vars->scene04_walkingKozyawka = g_vars->scene04_kozyawkiObjList.front();
950 		g_vars->scene04_kozyawkiObjList.pop_front();
951 
952 		MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_KOZAW_WALK), 0, 1);
953 		mq->setParamInt(-1, g_vars->scene04_walkingKozyawka->_odelay);
954 		mq->chain(0);
955 	}
956 }
957 
sceneHandler04_bottleUpdateObjects(int off)958 void sceneHandler04_bottleUpdateObjects(int off) {
959 	for (Common::List<GameObject *>::iterator it = g_vars->scene04_bottleObjList.begin(); it != g_vars->scene04_bottleObjList.end(); ++it) {
960 		if ((*it)->_objtype == kObjTypeStaticANIObject) {
961 			StaticANIObject *st = static_cast<StaticANIObject *>(*it);
962 
963 			st->setOXY(st->_ox, off + st->_oy);
964 		} else {
965 			GameObject *obj = *it;
966 
967 			obj->setOXY(obj->_ox, off + obj->_oy);
968 		}
969 	}
970 }
971 
sceneHandler04_springWobble()972 void sceneHandler04_springWobble() {
973 	int oldDynIndex = g_vars->scene04_dynamicPhaseIndex;
974 	int newdelta = g_vars->scene04_springOffset + g_vars->scene04_dynamicPhaseIndex;
975 
976 	g_vars->scene04_dynamicPhaseIndex += g_vars->scene04_springOffset;
977 
978 	if (newdelta < 0) {
979 		newdelta = 0;
980 		g_vars->scene04_dynamicPhaseIndex = 0;
981 		g_vars->scene04_springOffset = 0;
982 	}
983 
984 	if (newdelta > 14) {
985 		newdelta = 14;
986 		g_vars->scene04_dynamicPhaseIndex = 14;
987 		g_vars->scene04_springOffset = 0;
988 	}
989 
990 	if (g_vars->scene04_bottleWeight > newdelta)
991 		g_vars->scene04_springOffset++;
992 
993 	if (g_vars->scene04_bottleWeight < newdelta)
994 		g_vars->scene04_springOffset--;
995 
996 	if ((oldDynIndex <= g_vars->scene04_bottleWeight && newdelta > g_vars->scene04_bottleWeight)
997 		|| (oldDynIndex > g_vars->scene04_bottleWeight && newdelta <= g_vars->scene04_bottleWeight)) {
998 		g_vars->scene04_springDelay++;
999 
1000 		if (g_vars->scene04_springOffset && g_vars->scene04_springDelay > 1) {
1001 			g_vars->scene04_springDelay = 0;
1002 			g_vars->scene04_springOffset = g_vars->scene04_springOffset - g_vars->scene04_springOffset / abs(g_vars->scene04_springOffset);
1003 		}
1004 	}
1005 
1006 	int oldpos = g_vars->scene04_spring->getCurrDimensions().y - oldDynIndex;
1007 
1008 	if (g_vars->scene04_dynamicPhaseIndex) {
1009 		if (!g_vars->scene04_spring->_movement)
1010 			g_vars->scene04_spring->startAnim(MV_SPR_LOWER, 0, -1);
1011 
1012 		g_vars->scene04_spring->_movement->setDynamicPhaseIndex(g_vars->scene04_dynamicPhaseIndex);
1013 	} else {
1014 		g_vars->scene04_spring->changeStatics2(ST_SPR_UP);
1015 	}
1016 
1017 	if (g_vars->scene04_dynamicPhaseIndex != oldDynIndex) {
1018 		sceneHandler04_bottleUpdateObjects(oldpos - (g_vars->scene04_spring->getCurrDimensions().y - g_vars->scene04_dynamicPhaseIndex));
1019 	}
1020 }
1021 
sceneHandler04_leaveScene()1022 void sceneHandler04_leaveScene() {
1023 	g_nmi->_aniMan2 = 0;
1024 
1025 	MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC4_MANTOBOTTLE), 0, 0);
1026 	ExCommand *ex = 0;
1027 
1028 	for (uint i = 0; i < mq->getCount(); i++) {
1029 		if (mq->getExCommandByIndex(i)->_messageKind == 27) {
1030 			ex = mq->getExCommandByIndex(i);
1031 			break;
1032 		}
1033 	}
1034 
1035 	if (!ex) {
1036 		error("sceneHandler04_leaveScene(): Cannot find exit");
1037 	}
1038 
1039 	ex->_y = g_vars->scene04_bottle->_oy - 304;
1040 
1041 	mq->chain(0);
1042 
1043 	g_vars->scene04_var07 = false;
1044 	g_vars->scene04_dudeOnLadder = 0;
1045 
1046 	g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 0);
1047 
1048 	g_nmi->updateMapPiece(PIC_MAP_P03, 1);
1049 }
1050 
sceneHandler04_liftBottle()1051 void sceneHandler04_liftBottle() {
1052 	int newy = g_vars->scene04_bottleY + g_vars->scene04_spring->_oy;
1053 
1054 	g_vars->scene04_bottleY += 5;
1055 
1056 	sceneHandler04_bottleUpdateObjects(newy - g_vars->scene04_spring->_oy);
1057 
1058 	g_vars->scene04_spring->setOXY(g_vars->scene04_spring->_ox, newy);
1059 
1060 	if (g_vars->scene04_bottle->_oy >= 226) {
1061 		sceneHandler04_bottleUpdateObjects(226 - g_vars->scene04_bottle->_oy);
1062 
1063 		g_vars->scene04_spring->setOXY(g_vars->scene04_spring->_ox, 437);
1064 		g_vars->scene04_bottleIsDropped = false;
1065 		g_vars->scene04_handIsDown = false;
1066 		g_vars->scene04_objectIsTaken = true;
1067 		g_vars->scene04_bottleWeight = 2;
1068 		g_vars->scene04_springOffset = 10;
1069 		g_vars->scene04_bottleIsTaken = false;
1070 
1071 		g_nmi->setObjectState(sO_LowerPipe, g_nmi->getObjectEnumState(sO_LowerPipe, sO_IsClosed));
1072 	}
1073 }
1074 
sceneHandler04_startSounds(const char * snd1,const char * snd2,const char * snd3)1075 void sceneHandler04_startSounds(const char *snd1, const char *snd2, const char *snd3) {
1076 	g_nmi->playOggSound(snd1, g_nmi->_soundStream2);
1077 
1078 	g_nmi->_stream2playing = true;
1079 
1080 	g_vars->scene04_musicStage = 1;
1081 }
1082 
updateSound()1083 void updateSound() {
1084 	switch (g_vars->scene04_musicStage) {
1085 	case 0:
1086 	default:
1087 		break;
1088 	case 1:
1089 		if (!g_nmi->_mixer->isSoundHandleActive(g_nmi->_soundStream2)) {
1090 			g_nmi->playOggSound("sc4_loop.ogg", g_nmi->_soundStream3);
1091 			g_vars->scene04_musicStage = 2;
1092 		}
1093 		break;
1094 	case 2:
1095 		if (!g_nmi->_mixer->isSoundHandleActive(g_nmi->_soundStream3)) {
1096 			if (g_nmi->_stream2playing) { // Looop it
1097 				g_nmi->playOggSound("sc4_loop.ogg", g_nmi->_soundStream3);
1098 			} else {
1099 				g_nmi->playOggSound("sc4_stop2.ogg", g_nmi->_soundStream4);
1100 				g_vars->scene04_musicStage = 3;
1101 			}
1102 		}
1103 		break;
1104 	case 3:
1105 		if (!g_nmi->_mixer->isSoundHandleActive(g_nmi->_soundStream4)) {
1106 			g_vars->scene04_musicStage = 0;
1107 		}
1108 		break;
1109 	}
1110 }
1111 
sceneHandler04_goClock()1112 void sceneHandler04_goClock() {
1113 	sceneHandler04_walkKozyawka();
1114 	chainQueue(QU_SC4_GOCLOCK, 0);
1115 	g_vars->scene04_soundPlaying = true;
1116 	g_vars->scene04_coinPut = false;
1117 
1118 	g_nmi->stopAllSoundStreams();
1119 
1120 	sceneHandler04_startSounds("sc4_start.ogg", "sc4_loop.ogg", "sc4_stop2.ogg");
1121 
1122 	g_vars->scene04_bigBallCounter = 0;
1123 }
1124 
sceneHandler04_bigBallOut()1125 void sceneHandler04_bigBallOut() {
1126 	StaticANIObject *ball =  g_nmi->_currentScene->getStaticANIObject1ById(ANI_BIGBALL, -1);
1127 
1128 	if (ball && ball->_flags & 4)
1129 		for (uint i = 0; i < ball->_movements.size(); i++)
1130 			ball->_movements[i]->_counterMax = 0;
1131 
1132 	g_vars->scene04_bigBallIn = false;
1133 }
1134 
sceneHandler04_leaveLadder(ExCommand * ex)1135 void sceneHandler04_leaveLadder(ExCommand *ex) {
1136 	if (!g_nmi->_aniMan->isIdle())
1137 		return;
1138 
1139 	if (!(g_nmi->_aniMan->_flags & 0x100)) {
1140 		if (getSc2MctlCompoundBySceneId(g_nmi->_currentScene->_sceneId)->_objtype == kObjTypeMctlCompound) {
1141 			MctlCompound *mc = static_cast<MctlCompound *>(getSc2MctlCompoundBySceneId(g_nmi->_currentScene->_sceneId));
1142 
1143 			if (mc->_motionControllers[0]->_movGraphReactObj->pointInRegion(g_nmi->_sceneRect.left + ex->_x, g_nmi->_sceneRect.top + ex->_y)) {
1144 				if (g_vars->scene04_ladder->collisionDetection(g_nmi->_aniMan)) {
1145 					MessageQueue *mq = g_vars->scene04_ladder->controllerWalkTo(g_nmi->_aniMan, 0);
1146 
1147 					if (mq) {
1148 						mq->addExCommandToEnd(ex->createClone());
1149 
1150 						if (mq->chain(g_nmi->_aniMan) )
1151 							ex->_messageKind = 0;
1152 						else
1153 							delete mq;
1154 
1155 						if (g_vars->scene04_bigBallIn) {
1156 							sceneHandler04_bigBallOut();
1157 							return;
1158 						}
1159 					}
1160 				} else {
1161 					MessageQueue *mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
1162 					ExCommand *ex1;
1163 
1164 					if (g_nmi->_aniMan->_statics->_staticsId == ST_MAN_LADDERDOWN) {
1165 						ex1 = new ExCommand(ANI_MAN, 1, MV_MAN_LOOKLADDERRV, 0, 0, 0, 1, 0, 0, 0);
1166 						ex1->_param = g_nmi->_aniMan->_odelay;
1167 						ex1->_excFlags |= 2;
1168 						mq->addExCommandToEnd(ex1);
1169 					}
1170 
1171 					ex1 = new ExCommand(ANI_MAN, 1, MV_MAN_STARTLADDERD, 0, 0, 0, 1, 0, 0, 0);
1172 					ex1->_param = g_nmi->_aniMan->_odelay;
1173 					ex1->_excFlags |= 2;
1174 					mq->addExCommandToEnd(ex1);
1175 
1176 					ex1 = new ExCommand(ANI_MAN, 1, MV_MAN_FROMLADDER, 0, 0, 0, 1, 0, 0, 0);
1177 					ex1->_param = g_nmi->_aniMan->_odelay;
1178 					ex1->_excFlags |= 2;
1179 					mq->addExCommandToEnd(ex1);
1180 
1181 					ex1 = ex->createClone();
1182 					mq->addExCommandToEnd(ex1);
1183 
1184 					mq->setFlags(mq->getFlags() | 1);
1185 
1186 					if (mq->chain(g_nmi->_aniMan)) {
1187 						if (g_vars->scene04_ladder)
1188 							delete g_vars->scene04_ladder;
1189 
1190 						g_vars->scene04_ladder = 0;
1191 						g_vars->scene04_dudeOnLadder = 0;
1192 
1193 						ex->_messageKind = 0;
1194 
1195 						mc->activate();
1196 						getGameLoaderInteractionController()->enableFlag24();
1197 					} else {
1198 						delete mq;
1199 					}
1200 
1201 					if (g_vars->scene04_bigBallIn) {
1202 						sceneHandler04_bigBallOut();
1203 						return;
1204 					}
1205 				}
1206 			}
1207 		}
1208 	}
1209 }
1210 
sceneHandler04_handTake()1211 void sceneHandler04_handTake() {
1212 	g_vars->scene04_clock->changeStatics2(ST_CLK_CLOSED);
1213 
1214 	if (g_vars->scene04_kozyawkiAni.size()) {
1215 		if (g_vars->scene04_kozyawkiAni.size() == 1) {
1216 			chainQueue(QU_HND_TAKE1, 0);
1217 			g_vars->scene04_objectIsTaken = false;
1218 		} else {
1219 			chainQueue((g_vars->scene04_kozyawkiAni.size() != 2) ? QU_HND_TAKEBOTTLE : QU_HND_TAKE2, 0);
1220 			g_vars->scene04_objectIsTaken = false;
1221 		}
1222 	} else {
1223 		chainQueue(QU_HND_TAKE0, 0);
1224 		g_vars->scene04_objectIsTaken = false;
1225 	}
1226 }
1227 
sceneHandler04_putKozyawkaBack(StaticANIObject * ani)1228 void sceneHandler04_putKozyawkaBack(StaticANIObject *ani) {
1229 	debugC(2, kDebugSceneLogic, "scene04: putKozyawkaBack");
1230 
1231 	g_vars->scene04_bottleObjList.push_back(ani);
1232 	g_vars->scene04_kozyawkiAni.push_back(ani);
1233 
1234 	g_vars->scene04_bottleWeight += 2;
1235 	g_vars->scene04_walkingKozyawka = 0;
1236 	g_vars->scene04_lastKozyawka = 0;
1237 
1238 	if (g_vars->scene04_kozyawkiAni.size() > 1 )
1239 		g_vars->scene04_objectIsTaken = false;
1240 
1241 	if (g_vars->scene04_kozyawkiAni.size() <= 2 || g_vars->scene04_hand->_movement) {
1242 		sceneHandler04_walkKozyawka();
1243 	} else {
1244 		sceneHandler04_handTake();
1245 		sceneHandler04_stopSound();
1246 	}
1247 }
1248 
sceneHandler04_bigBallWalkIn()1249 void sceneHandler04_bigBallWalkIn() {
1250 	StaticANIObject *ball =  g_nmi->_currentScene->getStaticANIObject1ById(ANI_BIGBALL, -1);
1251 
1252 	if (g_vars->scene04_dudeOnLadder
1253 		 && (!ball || !(ball->_flags & 4))
1254 		 && g_vars->scene04_ladder->collisionDetection(g_nmi->_aniMan) > 3) {
1255 
1256 		if (!g_nmi->_rnd.getRandomNumber(49)) {
1257 			if (g_vars->scene04_bigBallFromLeft)
1258 				chainQueue(QU_BALL_WALKR, 0);
1259 			else
1260 				chainQueue(QU_BALL_WALKL, 0);
1261 
1262 			g_vars->scene04_bigBallFromLeft = !g_vars->scene04_bigBallFromLeft;
1263 
1264 			sceneHandler04_checkBigBallClick();
1265 
1266 			g_vars->scene04_bigBallCounter = 0;
1267 		}
1268 	}
1269 }
1270 
sceneHandler04_takeBottle()1271 void sceneHandler04_takeBottle() {
1272 	g_vars->scene04_bottleIsTaken = true;
1273 	g_vars->scene04_hand->_priority = 5;
1274 
1275 	g_nmi->setObjectState(sO_LowerPipe, g_nmi->getObjectEnumState(sO_LowerPipe, sO_IsOpened));
1276 }
1277 
sceneHandler04_takeKozyawka()1278 void sceneHandler04_takeKozyawka() {
1279 	if (g_vars->scene04_kozyawkiAni.size() > 0) {
1280 		if (g_vars->scene04_kozyawkiAni.size() == 1)
1281 			g_vars->scene04_objectIsTaken = true;
1282 
1283 		StaticANIObject *koz = g_vars->scene04_kozyawkiAni.front();
1284 		g_vars->scene04_kozyawkiAni.pop_front();
1285 
1286 		if (koz) {
1287 			koz->queueMessageQueue(0);
1288 			koz->hide();
1289 
1290 			g_vars->scene04_kozyawkiObjList.push_back(koz);
1291 
1292 			for (Common::List<GameObject *>::iterator it = g_vars->scene04_bottleObjList.begin(); it != g_vars->scene04_bottleObjList.end(); ++it)
1293 				if (*it == koz) {
1294 					g_vars->scene04_bottleObjList.erase(it);
1295 					break;
1296 				}
1297 
1298 			g_vars->scene04_bottleWeight -= 2;
1299 		}
1300 	}
1301 }
1302 
sceneHandler04_testPlank(ExCommand * ex)1303 void sceneHandler04_testPlank(ExCommand *ex) {
1304 	MessageQueue *mq = g_nmi->_globalMessageQueueList->getMessageQueueById(ex->_parId);
1305 
1306 	if (!mq)
1307 		return;
1308 
1309 	if (g_vars->scene04_plank->_movement || !g_vars->scene04_plank->_statics || g_vars->scene04_plank->_statics->_staticsId != ST_PNK_WEIGHTLEFT) {
1310 		mq->getExCommandByIndex(0)->_messageNum = MV_KZW_TOHOLERV;
1311 	} else {
1312 		mq->getExCommandByIndex(0)->_messageNum = MV_KZW_WALKPLANK;
1313 	}
1314 }
1315 
sceneHandler04_updateBottle()1316 void sceneHandler04_updateBottle() {
1317 	int yoff;
1318 
1319 	if (g_vars->scene04_hand->_movement)
1320 		yoff = g_vars->scene04_hand->_movement->_oy;
1321 	else
1322 		yoff = g_vars->scene04_hand->_oy;
1323 
1324 	int newy = g_vars->scene04_hand->getSomeXY().y + yoff + 140;
1325 
1326 	sceneHandler04_bottleUpdateObjects(newy - g_vars->scene04_spring->_oy);
1327 
1328 	g_vars->scene04_spring->setOXY(g_vars->scene04_spring->_ox, newy);
1329 }
1330 
sceneHandler04_winArcade()1331 void sceneHandler04_winArcade() {
1332 	if (g_nmi->getObjectState(sO_LowerPipe) == g_nmi->getObjectEnumState(sO_LowerPipe, sO_IsClosed)
1333 		&& g_vars->scene04_soundPlaying) {
1334 		g_vars->scene04_clock->changeStatics2(ST_CLK_CLOSED);
1335 		g_vars->scene04_hand->changeStatics2(ST_HND_EMPTY);
1336 
1337 		chainQueue(QU_HND_TAKEBOTTLE, 1);
1338 
1339 		if (g_vars->scene04_walkingKozyawka) {
1340 			g_vars->scene04_kozyawkiObjList.push_back(g_vars->scene04_walkingKozyawka);
1341 
1342 			g_vars->scene04_walkingKozyawka->changeStatics2(ST_KZW_EMPTY);
1343 			g_vars->scene04_walkingKozyawka->hide();
1344 			g_vars->scene04_walkingKozyawka = 0;
1345 		}
1346 
1347 		g_vars->scene04_objectIsTaken = false;
1348 		g_vars->scene04_soundPlaying = false;
1349 
1350 		getSc2MctlCompoundBySceneId(g_nmi->_currentScene->_sceneId)->activate();
1351 
1352 		getGameLoaderInteractionController()->enableFlag24();
1353 
1354 		g_nmi->stopSoundStream2();
1355 	}
1356 }
1357 
sceneHandler04(ExCommand * ex)1358 int sceneHandler04(ExCommand *ex) {
1359 	if (ex->_messageKind != 17)
1360 		return 0;
1361 
1362 	switch (ex->_messageNum) {
1363 	case MSG_UPDATEBOTTLE:
1364 		sceneHandler04_updateBottle();
1365 		break;
1366 
1367 	case MSG_CLICKBOTTLE:
1368 		sceneHandler04_clickBottle();
1369 		break;
1370 
1371 	case MSG_SHOOTKOZAW:
1372 		sceneHandler04_shootKozyawka();
1373 		break;
1374 
1375 	case MSG_SHAKEBOTTLE:
1376 		if (!g_vars->scene04_bottleIsTaken)
1377 			++g_vars->scene04_springOffset;
1378 		break;
1379 
1380 	case MSG_STARTHAND:
1381 		g_vars->scene04_handIsDown = true;
1382 		g_vars->scene04_coinPut = false;
1383 
1384 		if (g_vars->scene04_dudeInBottle)
1385 			sceneHandler04_animOutOfBottle(0);
1386 
1387 		sceneHandler04_handTake();
1388 		sceneHandler04_stopSound();
1389 		break;
1390 
1391 	case MSG_TAKEKOZAW:
1392 		sceneHandler04_takeKozyawka();
1393 		break;
1394 
1395 	case MSG_CLICKBUTTON:
1396 		sceneHandler04_clickButton();
1397 		break;
1398 
1399 	case MSG_CLICKPLANK:
1400 		sceneHandler04_clickPlank();
1401 		break;
1402 
1403 	case MSG_RAISEPLANK:
1404 		sceneHandler04_raisePlank();
1405 		break;
1406 
1407 	case MSG_KOZAWRESTART:
1408 		debugC(1, kDebugSceneLogic, "scene04: kozawRestart");
1409 
1410 		if (g_vars->scene04_walkingKozyawka) {
1411 			g_vars->scene04_kozyawkiObjList.push_back(g_vars->scene04_walkingKozyawka);
1412 			g_vars->scene04_walkingKozyawka->hide();
1413 			g_vars->scene04_walkingKozyawka = 0;
1414 		}
1415 
1416 		if (g_vars->scene04_soundPlaying)
1417 			sceneHandler04_walkKozyawka();
1418 
1419 		break;
1420 
1421 	case MSG_LOWERPLANK:
1422 		sceneHandler04_lowerPlank();
1423 		break;
1424 
1425 	case MSG_TESTPLANK:
1426 		sceneHandler04_testPlank(ex);
1427 		break;
1428 
1429 	case 33:
1430 		{
1431 			g_vars->scene04_dudePosX = g_nmi->_aniMan->_ox;
1432 			g_vars->scene04_dudePosY = g_nmi->_aniMan->_oy;
1433 
1434 			int res = 0;
1435 
1436 			if (g_nmi->_aniMan2) {
1437 				if (g_nmi->_aniMan->_ox < g_nmi->_sceneRect.left + 200) {
1438 					g_nmi->_currentScene->_x = g_nmi->_aniMan->_ox - g_nmi->_sceneRect.left - 300;
1439 					g_nmi->_aniMan->_ox = g_vars->scene04_dudePosX;
1440 				}
1441 				if (g_nmi->_aniMan->_ox > g_nmi->_sceneRect.right - 200) {
1442 					g_nmi->_currentScene->_x = g_nmi->_aniMan->_ox - g_nmi->_sceneRect.right + 300;
1443 				}
1444 
1445 				res = 1;
1446 			}
1447 
1448 			g_nmi->sceneAutoScrolling();
1449 
1450 			if (g_nmi->_aniMan2) {
1451 				if (g_vars->scene04_soundPlaying) {
1452 					if (g_nmi->_aniMan->_movement) {
1453 						if (g_nmi->_aniMan->_movement->_id == MV_MAN_TOLADDER) {
1454 							g_nmi->_aniMan2 = 0;
1455 
1456 							if (g_nmi->_sceneRect.left > 380)
1457 								g_nmi->_currentScene->_x = 380 - g_nmi->_sceneRect.left;
1458 						}
1459 					}
1460 				}
1461 			} else {
1462 				if (g_nmi->_aniMan->_movement && g_nmi->_aniMan->_movement->_id == MV_MAN_GOD)
1463 					g_nmi->_aniMan2 = g_nmi->_aniMan;
1464 			}
1465 
1466 			sceneHandler04_springWobble();
1467 
1468 			if (g_vars->scene04_var07 && !g_vars->scene04_handIsDown)
1469 				sceneHandler04_leaveScene();
1470 
1471 			if (g_vars->scene04_bottleIsDropped)
1472 				sceneHandler04_liftBottle();
1473 
1474 			if (g_vars->scene04_ladderClickable)
1475 				sceneHandler04_clickLadder();
1476 
1477 			if (g_vars->scene04_dudeInBottle && g_vars->scene04_hand->_movement)
1478 				sceneHandler04_animOutOfBottle(0);
1479 
1480 			if (g_vars->scene04_coinPut && g_vars->scene04_clockCanGo && !g_vars->scene04_handIsDown && !g_vars->scene04_soundPlaying)
1481 				sceneHandler04_goClock();
1482 
1483 			if (g_vars->scene04_dudeOnLadder) {
1484 				if (!g_vars->scene04_soundPlaying) {
1485 					g_nmi->startSceneTrack();
1486 
1487 					g_nmi->_behaviorManager->updateBehaviors();
1488 					return res;
1489 				}
1490 
1491 				g_vars->scene04_bigBallCounter++;
1492 
1493 				if (g_vars->scene04_bigBallCounter > 600)
1494 					sceneHandler04_bigBallWalkIn();
1495 			}
1496 
1497 			if (g_vars->scene04_soundPlaying) {
1498 				g_nmi->_behaviorManager->updateBehaviors();
1499 
1500 				return res;
1501 			}
1502 
1503 			g_nmi->startSceneTrack();
1504 
1505 			g_nmi->_behaviorManager->updateBehaviors();
1506 
1507 			return res;
1508 		}
1509 		break;
1510 
1511 	case 29:
1512 		{
1513 			int picid = g_nmi->_currentScene->getPictureObjectIdAtPos(ex->_sceneClickX, ex->_sceneClickY);
1514 
1515 			if (g_vars->scene04_dudeInBottle) {
1516 				sceneHandler04_animOutOfBottle(ex);
1517 
1518 				break;
1519 			}
1520 
1521 			if (picid == PIC_SC4_LADDER) {
1522 				if (!g_vars->scene04_kozyawkaOnLadder) {
1523 					g_vars->scene04_sceneClickX = ex->_sceneClickX;
1524 					g_vars->scene04_sceneClickY = ex->_sceneClickY;
1525 
1526 					sceneHandler04_clickLadder();
1527 
1528 					ex->_messageKind = 0;
1529 
1530 					break;
1531 				}
1532 
1533 				sceneHandler04_gotoLadder(0);
1534 
1535 				break;
1536 			}
1537 
1538 			StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(ex->_sceneClickX, ex->_sceneClickY);
1539 
1540 			if ((ani && ani->_id == ANI_PLANK) || picid == PIC_SC4_PLANK) {
1541 				sceneHandler04_clickPlank();
1542 
1543 				ex->_messageKind = 0;
1544 			} else if (g_vars->scene04_dudeOnLadder) {
1545 				sceneHandler04_leaveLadder(ex);
1546 			} else if (!ani || !canInteractAny(g_nmi->_aniMan, ani, ex->_param)) {
1547 				PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picid, 0);
1548 
1549 				if (!pic || !canInteractAny(g_nmi->_aniMan, pic,ex->_param)) {
1550 					if ((g_nmi->_sceneRect.right - ex->_sceneClickX < 47 && g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1)
1551 						|| (ex->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0))
1552 						g_nmi->processArcade(ex);
1553 				}
1554 			}
1555 		}
1556 		break;
1557 
1558 	case MSG_SC4_HIDEBOOT:
1559 		g_vars->scene04_boot->_flags &= 0xfffb;
1560 		break;
1561 
1562 	case MSG_CMN_WINARCADE:
1563 		sceneHandler04_winArcade();
1564 		break;
1565 
1566 	case MSG_SC4_HANDOVER:
1567 		g_vars->scene04_handIsDown = false;
1568 		g_vars->scene04_objectIsTaken = true;
1569 		break;
1570 
1571 	case MSG_SC4_DROPBOTTLE:
1572 		sceneHandler04_dropBottle();
1573 		break;
1574 
1575 	case MSG_SC4_COINOUT:
1576 		g_vars->scene04_clock->changeStatics2(ST_CLK_CLOSED);
1577 		g_vars->scene04_coinPut = false;
1578 		sceneHandler04_stopSound();
1579 
1580 		if (g_vars->scene04_kozyawkiAni.size() && !g_vars->scene04_bottleIsTaken) {
1581 			g_vars->scene04_handIsDown = true;
1582 
1583 			if (g_vars->scene04_dudeInBottle)
1584 				sceneHandler04_animOutOfBottle(0);
1585 
1586 			sceneHandler04_handTake();
1587 		}
1588 		break;
1589 
1590 	case MSG_SC4_KOZAWFALL:
1591 		{
1592 			ExCommand *exnew;
1593 
1594 			if (g_vars->scene04_kozHeadRaised) {
1595 				sceneHandler04_putKozyawkaBack(g_vars->scene04_lastKozyawka);
1596 
1597 				g_vars->scene04_kozHeadRaised = 0;
1598 
1599 				exnew = new ExCommand(0, 35, SND_4_010, 0, 0, 0, 1, 0, 0, 0);
1600 			} else {
1601 				exnew = new ExCommand(0, 35, SND_4_012, 0, 0, 0, 1, 0, 0, 0);
1602 			}
1603 
1604 			exnew->_z = 5;
1605 			exnew->_excFlags |= 2;
1606 			exnew->postMessage();
1607 		}
1608 		break;
1609 
1610 	case MSG_SC4_MANFROMBOTTLE:
1611 		sceneHandler04_manFromBottle();
1612 		break;
1613 
1614 	case MSG_SC4_CLICKLADDER:
1615 		sceneHandler04_clickLadder();
1616 		break;
1617 
1618 	case MSG_SC4_MANTOBOTTLE:
1619 		sceneHandler04_manToBottle();
1620 		break;
1621 
1622 	case MSG_SHOWCOIN:
1623 		sceneHandler04_showCoin();
1624 		break;
1625 
1626 	case MSG_TAKEBOTTLE:
1627 		sceneHandler04_takeBottle();
1628 		break;
1629 
1630 	case MSG_GOTOLADDER:
1631 		sceneHandler04_gotoLadder(0);
1632 		break;
1633 
1634 	case MSG_SC4_COINPUT:
1635 		g_vars->scene04_coinPut = true;
1636 		break;
1637 
1638 	default:
1639 		break;
1640 	}
1641 
1642 	updateSound();
1643 
1644 	return 0;
1645 }
1646 
1647 } // End of namespace NGI
1648