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 "neverhood/modules/module1000_sprites.h"
24
25 namespace Neverhood {
26
AsScene1001Door(NeverhoodEngine * vm)27 AsScene1001Door::AsScene1001Door(NeverhoodEngine *vm)
28 : AnimatedSprite(vm, 1100) {
29
30 createSurface(800, 137, 242);
31 _x = 726;
32 _y = 440;
33 stShowIdleDoor();
34 loadSound(1, 0xED403E03);
35 SetUpdateHandler(&AnimatedSprite::update);
36 SetMessageHandler(&AsScene1001Door::handleMessage);
37 }
38
handleMessage(int messageNum,const MessageParam & param,Entity * sender)39 uint32 AsScene1001Door::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
40 Sprite::handleMessage(messageNum, param, sender);
41 switch (messageNum) {
42 case NM_ANIMATION_UPDATE:
43 hammerHitsDoor();
44 break;
45 case NM_ANIMATION_STOP:
46 gotoNextState();
47 break;
48 default:
49 break;
50 }
51 return 0;
52 }
53
hammerHitsDoor()54 void AsScene1001Door::hammerHitsDoor() {
55 switch (getGlobalVar(V_DOOR_STATUS)) {
56 case 0:
57 case 1:
58 playSound(0, 0x65482F03);
59 startAnimation(0x624C0498, 1, 3);
60 NextState(&AsScene1001Door::stShowIdleDoor);
61 break;
62 case 2:
63 playSound(1);
64 startAnimation(0x624C0498, 6, 6);
65 NextState(&AsScene1001Door::stBustedDoorMove);
66 break;
67 default:
68 // Nothing
69 break;
70 }
71 incGlobalVar(V_DOOR_STATUS, 1);
72 }
73
stShowIdleDoor()74 void AsScene1001Door::stShowIdleDoor() {
75 switch (getGlobalVar(V_DOOR_STATUS)) {
76 case 1:
77 startAnimation(0x624C0498, 4, -1);
78 _newStickFrameIndex = 4;
79 break;
80 case 2:
81 startAnimation(0x624C0498, 1, -1);
82 _newStickFrameIndex = 1;
83 break;
84 case 3:
85 stopAnimation();
86 setVisible(false);
87 break;
88 default:
89 startAnimation(0x624C0498, 0, -1);
90 _newStickFrameIndex = 0;
91 break;
92 }
93 }
94
stBustedDoorMove()95 void AsScene1001Door::stBustedDoorMove() {
96 setGlobalVar(V_DOOR_BUSTED, 1);
97 startAnimation(0x624C0498, 6, 6);
98 NextState(&AsScene1001Door::stBustedDoorGone);
99 _x = 30;
100 }
101
stBustedDoorGone()102 void AsScene1001Door::stBustedDoorGone() {
103 playSound(0);
104 stopAnimation();
105 setVisible(false);
106 }
107
AsScene1001Hammer(NeverhoodEngine * vm,Sprite * asDoor)108 AsScene1001Hammer::AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor)
109 : AnimatedSprite(vm, 1100), _asDoor(asDoor) {
110
111 _x = 547;
112 _y = 206;
113 createSurface(900, 177, 192);
114 startAnimation(0x022C90D4, -1, -1);
115 _newStickFrameIndex = STICK_LAST_FRAME;
116 SetUpdateHandler(&AnimatedSprite::update);
117 SetMessageHandler(&AsScene1001Hammer::handleMessage);
118 }
119
handleMessage(int messageNum,const MessageParam & param,Entity * sender)120 uint32 AsScene1001Hammer::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
121 Sprite::handleMessage(messageNum, param, sender);
122 switch (messageNum) {
123 case NM_ANIMATION_START:
124 if (param.asInteger() == 0x00352100)
125 sendMessage(_asDoor, 0x2000, 0);
126 else if (param.asInteger() == 0x0A1A0109)
127 playSound(0, 0x66410886);
128 break;
129 case NM_ANIMATION_UPDATE:
130 startAnimation(0x022C90D4, 1, -1);
131 playSound(0, 0xE741020A);
132 _newStickFrameIndex = STICK_LAST_FRAME;
133 break;
134 default:
135 break;
136 }
137 return 0;
138 }
139
AsScene1001Window(NeverhoodEngine * vm)140 AsScene1001Window::AsScene1001Window(NeverhoodEngine *vm)
141 : AnimatedSprite(vm, 1200) {
142
143 _x = 320;
144 _y = 240;
145 createSurface(100, 66, 129);
146 startAnimation(0xC68C2299, 0, -1);
147 _newStickFrameIndex = 0;
148 SetUpdateHandler(&AnimatedSprite::update);
149 SetMessageHandler(&AsScene1001Window::handleMessage);
150 }
151
handleMessage(int messageNum,const MessageParam & param,Entity * sender)152 uint32 AsScene1001Window::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
153 Sprite::handleMessage(messageNum, param, sender);
154 switch (messageNum) {
155 case NM_ANIMATION_START:
156 if (param.asInteger() == 0x0E0A1410)
157 playSound(0, 0x60803F10);
158 break;
159 case 0x2001:
160 startAnimation(0xC68C2299, 0, -1);
161 break;
162 case NM_ANIMATION_STOP:
163 SetMessageHandler(NULL);
164 setGlobalVar(V_WINDOW_OPEN, 1);
165 setVisible(false);
166 break;
167 default:
168 break;
169 }
170 return 0;
171 }
172
AsScene1001Lever(NeverhoodEngine * vm,Scene * parentScene,int16 x,int16 y,int deltaXType)173 AsScene1001Lever::AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType)
174 : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
175
176 createSurface(1010, 71, 73);
177 setDoDeltaX(deltaXType);
178 startAnimation(0x04A98C36, 0, -1);
179 _newStickFrameIndex = 0;
180 _x = x;
181 _y = y;
182 SetUpdateHandler(&AnimatedSprite::update);
183 SetMessageHandler(&AsScene1001Lever::handleMessage);
184 }
185
handleMessage(int messageNum,const MessageParam & param,Entity * sender)186 uint32 AsScene1001Lever::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
187 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
188 switch (messageNum) {
189 case NM_ANIMATION_START:
190 if (param.asInteger() == 0x00C0C444)
191 sendMessage(_parentScene, NM_KLAYMEN_LOWER_LEVER, 0);
192 else if (param.asInteger() == 0xC41A02C0)
193 playSound(0, 0x40581882);
194 break;
195 case 0x1011:
196 sendMessage(_parentScene, 0x4826, 0);
197 messageResult = 1;
198 break;
199 case NM_ANIMATION_STOP:
200 startAnimation(0x04A98C36, 0, -1);
201 _newStickFrameIndex = 0;
202 break;
203 case NM_KLAYMEN_LOWER_LEVER:
204 startAnimation(0x04A98C36, 0, -1);
205 break;
206 case NM_MOVE_TO_BACK:
207 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
208 break;
209 case NM_MOVE_TO_FRONT:
210 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
211 break;
212 default:
213 break;
214 }
215 return messageResult;
216 }
217
SsCommonButtonSprite(NeverhoodEngine * vm,Scene * parentScene,uint32 fileHash,int surfacePriority,uint32 soundFileHash)218 SsCommonButtonSprite::SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash)
219 : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene), _countdown(0) {
220
221 _priority = 1100;
222 _soundFileHash = soundFileHash ? soundFileHash : 0x44141000;
223 setVisible(false);
224 SetUpdateHandler(&SsCommonButtonSprite::update);
225 SetMessageHandler(&SsCommonButtonSprite::handleMessage);
226 }
227
update()228 void SsCommonButtonSprite::update() {
229 if (_countdown != 0 && (--_countdown) == 0)
230 setVisible(false);
231 }
232
handleMessage(int messageNum,const MessageParam & param,Entity * sender)233 uint32 SsCommonButtonSprite::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
234 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
235 switch (messageNum) {
236 case 0x480B:
237 sendMessage(_parentScene, 0x480B, 0);
238 setVisible(true);
239 _countdown = 8;
240 playSound(0, _soundFileHash);
241 break;
242 default:
243 break;
244 }
245 return messageResult;
246 }
247
AsScene1002Ring(NeverhoodEngine * vm,Scene * parentScene,bool isSpecial,int16 x,int16 y,int16 clipY1,bool isRingLow)248 AsScene1002Ring::AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow)
249 : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isSpecial(isSpecial) {
250
251 SetUpdateHandler(&AsScene1002Ring::update);
252
253 if (_isSpecial) {
254 createSurface(990, 68, 314);
255 if (isRingLow) {
256 startAnimation(0x04103090, 0, -1);
257 SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
258 } else {
259 startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
260 SetMessageHandler(&AsScene1002Ring::hmRingIdle);
261 }
262 } else {
263 createSurface(990, 68, 138);
264 startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
265 SetMessageHandler(&AsScene1002Ring::hmRingIdle);
266 }
267
268 setClipRect(0, clipY1, 640, 480);
269
270 _x = x;
271 _y = y;
272
273 setDoDeltaX(_vm->_rnd->getRandomNumber(1));
274
275 }
276
update()277 void AsScene1002Ring::update() {
278 updateAnim();
279 updatePosition();
280 }
281
hmRingIdle(int messageNum,const MessageParam & param,Entity * sender)282 uint32 AsScene1002Ring::hmRingIdle(int messageNum, const MessageParam ¶m, Entity *sender) {
283 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
284 switch (messageNum) {
285 case NM_KLAYMEN_USE_OBJECT:
286 setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
287 sendMessage(_parentScene, NM_KLAYMEN_USE_OBJECT, 0);
288 SetMessageHandler(&AsScene1002Ring::hmRingPulled1);
289 startAnimation(_isSpecial ? 0x87502558 : 0x80DD4010, 0, -1);
290 break;
291 case NM_KLAYMEN_LOWER_LEVER:
292 setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
293 sendMessage(_parentScene, NM_KLAYMEN_LOWER_LEVER, 0);
294 SetMessageHandler(&AsScene1002Ring::hmRingPulled2);
295 startAnimation(0x861A2020, 0, -1);
296 break;
297 case NM_MOVE_TO_BACK:
298 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
299 break;
300 case NM_MOVE_TO_FRONT:
301 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
302 break;
303 default:
304 break;
305 }
306 return messageResult;
307 }
308
hmRingPulled1(int messageNum,const MessageParam & param,Entity * sender)309 uint32 AsScene1002Ring::hmRingPulled1(int messageNum, const MessageParam ¶m, Entity *sender) {
310 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
311 switch (messageNum) {
312 case NM_ANIMATION_STOP:
313 startAnimation(_isSpecial ? 0x78D0A812 : 0xB85D2A10, 0, -1);
314 SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
315 break;
316 case NM_KLAYMEN_RAISE_LEVER:
317 sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 0);
318 setDoDeltaX(_vm->_rnd->getRandomNumber(1));
319 startAnimation(0x8258A030, 0, -1);
320 SetMessageHandler(&AsScene1002Ring::hmRingReleased);
321 break;
322 case NM_MOVE_TO_BACK:
323 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
324 break;
325 case NM_MOVE_TO_FRONT:
326 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
327 break;
328 default:
329 break;
330 }
331 return messageResult;
332 }
333
hmRingPulled2(int messageNum,const MessageParam & param,Entity * sender)334 uint32 AsScene1002Ring::hmRingPulled2(int messageNum, const MessageParam ¶m, Entity *sender) {
335 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
336 switch (messageNum) {
337 case NM_ANIMATION_STOP:
338 startAnimation(0x04103090, 0, -1);
339 SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
340 break;
341 case NM_MOVE_TO_BACK:
342 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
343 break;
344 case NM_MOVE_TO_FRONT:
345 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
346 break;
347 default:
348 break;
349 }
350 return messageResult;
351 }
352
hmRingHangingLow(int messageNum,const MessageParam & param,Entity * sender)353 uint32 AsScene1002Ring::hmRingHangingLow(int messageNum, const MessageParam ¶m, Entity *sender) {
354 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
355 switch (messageNum) {
356 case NM_KLAYMEN_RAISE_LEVER:
357 sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 0);
358 setDoDeltaX(_vm->_rnd->getRandomNumber(1));
359 startAnimation(0x8258A030, 0, -1);
360 SetMessageHandler(&AsScene1002Ring::hmRingReleased);
361 break;
362 case NM_MOVE_TO_BACK:
363 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
364 break;
365 case NM_MOVE_TO_FRONT:
366 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
367 break;
368 default:
369 break;
370 }
371 return messageResult;
372 }
373
hmRingReleased(int messageNum,const MessageParam & param,Entity * sender)374 uint32 AsScene1002Ring::hmRingReleased(int messageNum, const MessageParam ¶m, Entity *sender) {
375 uint32 messageResult = hmRingIdle(messageNum, param, sender);
376 switch (messageNum) {
377 case NM_ANIMATION_START:
378 if (param.asInteger() == 0x05410F72)
379 playSound(0, 0x21EE40A9);
380 break;
381 case NM_ANIMATION_STOP:
382 startAnimation(0xA85C4011, 0, -1);
383 break;
384 case NM_MOVE_TO_BACK:
385 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
386 break;
387 case NM_MOVE_TO_FRONT:
388 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
389 break;
390 default:
391 break;
392 }
393 return messageResult;
394 }
395
AsScene1002Door(NeverhoodEngine * vm,NRect & clipRect)396 AsScene1002Door::AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect)
397 : StaticSprite(vm, 1200) {
398
399 loadSprite(0x1052370F, kSLFDefDrawOffset | kSLFSetPosition, 800, 526, getGlobalVar(V_FLYTRAP_RING_DOOR) ? 49 : 239);
400 setClipRect(clipRect);
401 SetUpdateHandler(&AsScene1002Door::update);
402 SetMessageHandler(&AsScene1002Door::handleMessage);
403 SetSpriteUpdate(NULL);
404 }
405
update()406 void AsScene1002Door::update() {
407 handleSpriteUpdate();
408 updatePosition();
409 }
410
handleMessage(int messageNum,const MessageParam & param,Entity * sender)411 uint32 AsScene1002Door::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
412 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
413 switch (messageNum) {
414 case NM_KLAYMEN_OPEN_DOOR:
415 setGlobalVar(V_FLYTRAP_RING_DOOR, 1);
416 SetSpriteUpdate(&AsScene1002Door::suOpenDoor);
417 break;
418 case NM_KLAYMEN_CLOSE_DOOR:
419 setGlobalVar(V_FLYTRAP_RING_DOOR, 0);
420 SetSpriteUpdate(&AsScene1002Door::suCloseDoor);
421 break;
422 default:
423 break;
424 }
425 return messageResult;
426 }
427
suOpenDoor()428 void AsScene1002Door::suOpenDoor() {
429 if (_y > 49) {
430 _y -= 8;
431 if (_y < 49) {
432 SetSpriteUpdate(NULL);
433 _y = 49;
434 }
435 _needRefresh = true;
436 }
437 }
438
suCloseDoor()439 void AsScene1002Door::suCloseDoor() {
440 if (_y < 239) {
441 _y += 8;
442 if (_y > 239) {
443 SetSpriteUpdate(NULL);
444 _y = 239;
445 }
446 _needRefresh = true;
447 }
448 }
449
AsScene1002BoxingGloveHitEffect(NeverhoodEngine * vm)450 AsScene1002BoxingGloveHitEffect::AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm)
451 : AnimatedSprite(vm, 1400) {
452
453 createSurface(1025, 88, 165);
454 setVisible(false);
455 SetUpdateHandler(&AnimatedSprite::update);
456 SetMessageHandler(&AsScene1002BoxingGloveHitEffect::handleMessage);
457 }
458
handleMessage(int messageNum,const MessageParam & param,Entity * sender)459 uint32 AsScene1002BoxingGloveHitEffect::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
460 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
461 switch (messageNum) {
462 case 0x2004:
463 _x = ((Sprite*)sender)->getX() - 98;
464 _y = ((Sprite*)sender)->getY() - 111;
465 startAnimation(0x0422255A, 0, -1);
466 setVisible(true);
467 break;
468 case NM_ANIMATION_STOP:
469 stopAnimation();
470 setVisible(false);
471 break;
472 default:
473 break;
474 }
475 return messageResult;
476 }
477
AsScene1002DoorSpy(NeverhoodEngine * vm,NRect & clipRect,Scene * parentScene,Sprite * asDoor,Sprite * asScene1002BoxingGloveHitEffect)478 AsScene1002DoorSpy::AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect)
479 : AnimatedSprite(vm, 1300), _clipRect(clipRect), _parentScene(parentScene), _asDoor(asDoor), _asBoxingGloveHitEffect(asScene1002BoxingGloveHitEffect) {
480
481 createSurface(800, 136, 147);
482 setClipRect(clipRect);
483 suDoorSpy();
484 loadSound(0, 0xC0C40298);
485 startAnimation(0x586C1D48, 0, 0);
486 SetUpdateHandler(&AnimatedSprite::update);
487 SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
488 SetSpriteUpdate(&AsScene1002DoorSpy::suDoorSpy);
489 }
490
handleMessage(int messageNum,const MessageParam & param,Entity * sender)491 uint32 AsScene1002DoorSpy::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
492 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
493 switch (messageNum) {
494 case NM_ANIMATION_START:
495 if (param.asInteger() == 0xA61CA1C2)
496 sendMessage(_asBoxingGloveHitEffect, 0x2004, 0);
497 else if (param.asInteger() == 0x14CE0620)
498 playSound(0);
499 break;
500 case 0x2003:
501 stDoorSpyBoxingGlove();
502 break;
503 default:
504 break;
505 }
506 return messageResult;
507 }
508
hmDoorSpyAnimation(int messageNum,const MessageParam & param,Entity * sender)509 uint32 AsScene1002DoorSpy::hmDoorSpyAnimation(int messageNum, const MessageParam ¶m, Entity *sender) {
510 uint32 messageResult = handleMessage(messageNum, param, sender);
511 switch (messageNum) {
512 case NM_ANIMATION_STOP:
513 gotoNextState();
514 break;
515 default:
516 break;
517 }
518 return messageResult;
519 }
520
suDoorSpy()521 void AsScene1002DoorSpy::suDoorSpy() {
522 _x = _asDoor->getX() + 34;
523 _y = _asDoor->getY() + 175;
524 }
525
stDoorSpyIdle()526 void AsScene1002DoorSpy::stDoorSpyIdle() {
527 setClipRect(_clipRect);
528 _parentScene->setSurfacePriority(getSurface(), 800);
529 startAnimation(0x586C1D48, 0, 0);
530 SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
531 }
532
stDoorSpyBoxingGlove()533 void AsScene1002DoorSpy::stDoorSpyBoxingGlove() {
534 setClipRect(0, 0, 640, 480);
535 _parentScene->setSurfacePriority(getSurface(), 1200);
536 startAnimation(0x586C1D48, 1, -1);
537 SetMessageHandler(&AsScene1002DoorSpy::hmDoorSpyAnimation);
538 NextState(&AsScene1002DoorSpy::stDoorSpyIdle);
539 }
540
SsCommonPressButton(NeverhoodEngine * vm,Scene * parentScene,uint32 fileHash1,uint32 fileHash2,int surfacePriority,uint32 soundFileHash)541 SsCommonPressButton::SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
542 : StaticSprite(vm, 1100), _parentScene(parentScene), _status(0), _countdown(0) {
543
544 _soundFileHash = soundFileHash != 0 ? soundFileHash : 0x44141000;
545 _fileHashes[0] = fileHash1;
546 _fileHashes[1] = fileHash2;
547 createSurface(surfacePriority, 40, 40);
548 loadSprite(fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
549 setVisible(false);
550 SetUpdateHandler(&SsCommonPressButton::update);
551 SetMessageHandler(&SsCommonPressButton::handleMessage);
552 }
553
setFileHashes(uint32 fileHash1,uint32 fileHash2)554 void SsCommonPressButton::setFileHashes(uint32 fileHash1, uint32 fileHash2) {
555 _fileHashes[0] = fileHash1;
556 _fileHashes[1] = fileHash2;
557 loadSprite(_status == 2 ? fileHash2 : fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
558 }
559
update()560 void SsCommonPressButton::update() {
561 if (_countdown != 0 && (--_countdown) == 0) {
562 if (_status == 1) {
563 _status = 2;
564 loadSprite(_fileHashes[1], kSLFDefDrawOffset | kSLFDefPosition);
565 _countdown = 4;
566 } else if (_status == 2) {
567 _status = 3;
568 loadSprite(_fileHashes[0], kSLFDefDrawOffset | kSLFDefPosition);
569 _countdown = 4;
570 } else if (_status == 3) {
571 _status = 0;
572 setVisible(false);
573 }
574 }
575 }
576
handleMessage(int messageNum,const MessageParam & param,Entity * sender)577 uint32 SsCommonPressButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
578 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
579 switch (messageNum) {
580 case 0x480B:
581 sendMessage(_parentScene, 0x480B, 0);
582 _status = 1;
583 _countdown = 4;
584 setVisible(true);
585 playSound(0, _soundFileHash);
586 break;
587 default:
588 break;
589 }
590 return messageResult;
591 }
592
AsScene1002VenusFlyTrap(NeverhoodEngine * vm,Scene * parentScene,Sprite * klaymen,bool isSecond)593 AsScene1002VenusFlyTrap::AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond)
594 : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klaymen(klaymen), _isSecond(isSecond), _countdown(0) {
595
596 createSurface(995, 175, 195);
597 if (!_isSecond) {
598 if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
599 setDoDeltaX(1);
600 _x = 366;
601 _y = 435;
602 stRingGrabbed();
603 } else {
604 _x = 174 + getGlobalVar(V_FLYTRAP_POSITION_1) * 32;
605 _y = 435;
606 stIdle();
607 }
608 } else {
609 _x = 186 + getGlobalVar(V_FLYTRAP_POSITION_2) * 32;
610 _y = 364;
611 if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE)) {
612 stRingGrabbed();
613 } else {
614 stIdle();
615 }
616 }
617 _flags = 4;
618 SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
619 SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
620 SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
621 }
622
update()623 void AsScene1002VenusFlyTrap::update() {
624 if (_countdown != 0 && (--_countdown == 0))
625 gotoNextState();
626 AnimatedSprite::update();
627 }
628
upIdle()629 void AsScene1002VenusFlyTrap::upIdle() {
630 if (_countdown == 0 && _klaymen->getX() - 20 > _x)
631 setDoDeltaX(1);
632 else if (_klaymen->getX() + 20 < _x)
633 setDoDeltaX(0);
634 update();
635 }
636
handleMessage(int messageNum,const MessageParam & param,Entity * sender)637 uint32 AsScene1002VenusFlyTrap::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
638 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
639 switch (messageNum) {
640 case NM_ANIMATION_START:
641 if (param.asInteger() == 0x000890C4)
642 playSound(0, 0xC21190D8);
643 else if (param.asInteger() == 0x522200A0)
644 playSound(0, 0x931080C8);
645 break;
646 case 0x1011:
647 if (_isSecond) {
648 if (_x >= 154 && _x <= 346) {
649 sendMessage(_parentScene, 0x2000, 0);
650 messageResult = 1;
651 }
652 } else {
653 if (_x >= 174 && _x <= 430) {
654 sendMessage(_parentScene, 0x2000, 0);
655 messageResult = 1;
656 }
657 }
658 break;
659 case 0x480B:
660 setDoDeltaX(param.asInteger() != 0 ? 1 : 0);
661 if (!_isSecond) {
662 if (getGlobalVar(V_FLYTRAP_RING_DOOR))
663 stRelease();
664 else
665 stWalk();
666 } else {
667 if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE))
668 stRelease();
669 else
670 stWalk();
671 }
672 break;
673 case 0x480C:
674 if (_isSecond) {
675 if (_x >= 154 && _x <= 346)
676 messageResult = 1;
677 else
678 messageResult = 0;
679 } else {
680 if (_x >= 174 && _x <= 430)
681 messageResult = 1;
682 else
683 messageResult = 0;
684 }
685 break;
686 case 0x480E:
687 if (param.asInteger() == 1)
688 stGrabRing();
689 break;
690 case 0x4810:
691 swallowKlaymen();
692 break;
693 case NM_MOVE_TO_BACK:
694 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 995);
695 break;
696 case NM_MOVE_TO_FRONT:
697 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1015);
698 break;
699 default:
700 break;
701 }
702 return messageResult;
703 }
704
hmAnimationSimple(int messageNum,const MessageParam & param,Entity * sender)705 uint32 AsScene1002VenusFlyTrap::hmAnimationSimple(int messageNum, const MessageParam ¶m, Entity *sender) {
706 uint32 messageResult = handleMessage(messageNum, param, sender);
707 switch (messageNum) {
708 case NM_ANIMATION_STOP:
709 gotoNextState();
710 break;
711 default:
712 break;
713 }
714 return messageResult;
715 }
716
hmAnimationExt(int messageNum,const MessageParam & param,Entity * sender)717 uint32 AsScene1002VenusFlyTrap::hmAnimationExt(int messageNum, const MessageParam ¶m, Entity *sender) {
718 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
719 switch (messageNum) {
720 case NM_ANIMATION_START:
721 if (param.asInteger() == 0x000890C4)
722 playSound(0, 0xC21190D8);
723 else if (param.asInteger() == 0x41881801) {
724 if (_isSecond) {
725 if (_x > 330)
726 sendMessage(_klaymen, 0x4811, 2);
727 else
728 sendMessage(_klaymen, 0x4811, 0);
729 } else {
730 sendMessage(_klaymen, 0x4811, 0);
731 }
732 } else if (param.asInteger() == 0x522200A0)
733 playSound(0, 0x931080C8);
734 break;
735 case NM_ANIMATION_STOP:
736 gotoNextState();
737 break;
738 case NM_MOVE_TO_BACK:
739 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 995);
740 break;
741 case NM_MOVE_TO_FRONT:
742 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1015);
743 break;
744 default:
745 break;
746 }
747 return messageResult;
748 }
749
stWalkBack()750 void AsScene1002VenusFlyTrap::stWalkBack() {
751 setDoDeltaX(2);
752 startAnimation(0xC4080034, 0, -1);
753 SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
754 SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
755 NextState(&AsScene1002VenusFlyTrap::stIdle);
756 }
757
stWalk()758 void AsScene1002VenusFlyTrap::stWalk() {
759 startAnimation(0xC4080034, 0, -1);
760 SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
761 SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
762 NextState(&AsScene1002VenusFlyTrap::stIdle);
763 }
764
stRelease()765 void AsScene1002VenusFlyTrap::stRelease() {
766 sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 0);
767 startAnimation(0x82292851, 0, -1);
768 SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
769 SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
770 NextState(&AsScene1002VenusFlyTrap::stIdle);
771 }
772
stGrabRing()773 void AsScene1002VenusFlyTrap::stGrabRing() {
774 setDoDeltaX(1);
775 startAnimation(0x86A82A11, 0, -1);
776 SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
777 SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
778 NextState(&AsScene1002VenusFlyTrap::stRingGrabbed);
779 }
780
stRingGrabbed()781 void AsScene1002VenusFlyTrap::stRingGrabbed() {
782 startAnimation(0xB5A86034, 0, -1);
783 SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
784 SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
785 }
786
stKlaymenInside()787 void AsScene1002VenusFlyTrap::stKlaymenInside() {
788 startAnimation(0x31303094, 0, -1);
789 SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
790 SetMessageHandler(NULL);
791 NextState(&AsScene1002VenusFlyTrap::stKlaymenInsideMoving);
792 _countdown = 24;
793 }
794
stIdle()795 void AsScene1002VenusFlyTrap::stIdle() {
796 startAnimation(0xC8204250, 0, -1);
797 SetUpdateHandler(&AsScene1002VenusFlyTrap::upIdle);
798 SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
799 if (_isSecond) {
800 if (_x >= 154 && _x <= 346)
801 setGlobalVar(V_FLYTRAP_POSITION_2, (_x - 186) / 32);
802 else {
803 NextState(&AsScene1002VenusFlyTrap::stWalkBack);
804 _countdown = 12;
805 }
806 } else {
807 if (_x >= 174 && _x <= 430)
808 setGlobalVar(V_FLYTRAP_POSITION_1, (_x - 174) / 32);
809 else {
810 NextState(&AsScene1002VenusFlyTrap::stWalkBack);
811 _countdown = 12;
812 }
813 }
814 }
815
stKlaymenInsideMoving()816 void AsScene1002VenusFlyTrap::stKlaymenInsideMoving() {
817 startAnimation(0x152920C4, 0, -1);
818 SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
819 SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
820 NextState(&AsScene1002VenusFlyTrap::stSpitOutKlaymen);
821 }
822
stSpitOutKlaymen()823 void AsScene1002VenusFlyTrap::stSpitOutKlaymen() {
824 startAnimation(0x84001117, 0, -1);
825 SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
826 SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
827 NextState(&AsScene1002VenusFlyTrap::stIdle);
828 }
829
swallowKlaymen()830 void AsScene1002VenusFlyTrap::swallowKlaymen() {
831 if (_x - 15 < _klaymen->getX() && _x + 15 > _klaymen->getX()) {
832 if (_isSecond)
833 setDoDeltaX(_x > 265 && _x < 330 ? 1 : 0);
834 else
835 setDoDeltaX(_x > 320 ? 1 : 0);
836 sendMessage(_klaymen, 0x2001, 0);
837 startAnimation(0x8C2C80D4, 0, -1);
838 SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
839 SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
840 NextState(&AsScene1002VenusFlyTrap::stKlaymenInside);
841 }
842 }
843
AsScene1002OutsideDoorBackground(NeverhoodEngine * vm)844 AsScene1002OutsideDoorBackground::AsScene1002OutsideDoorBackground(NeverhoodEngine *vm)
845 : AnimatedSprite(vm, 1200), _countdown(0), _isDoorClosed(true) {
846
847 createSurface(850, 186, 212);
848 _x = 320;
849 _y = 240;
850 if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
851 startAnimation(0x004A4495, -1, -1);
852 _newStickFrameIndex = STICK_LAST_FRAME;
853 } else
854 setVisible(false);
855 SetUpdateHandler(&AsScene1002OutsideDoorBackground::update);
856 SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
857 }
858
update()859 void AsScene1002OutsideDoorBackground::update() {
860 if (_countdown != 0 && (--_countdown == 0)) {
861 if (_isDoorClosed)
862 stCloseDoor();
863 else
864 stOpenDoor();
865 }
866 AnimatedSprite::update();
867 }
868
handleMessage(int messageNum,const MessageParam & param,Entity * sender)869 uint32 AsScene1002OutsideDoorBackground::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
870 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
871 switch (messageResult) {
872 case NM_KLAYMEN_OPEN_DOOR:
873 _isDoorClosed = false;
874 _countdown = 2;
875 break;
876 case NM_KLAYMEN_CLOSE_DOOR:
877 _isDoorClosed = true;
878 _countdown = 2;
879 break;
880 default:
881 break;
882 }
883 return messageResult;
884 }
885
hmAnimation(int messageNum,const MessageParam & param,Entity * sender)886 uint32 AsScene1002OutsideDoorBackground::hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender) {
887 uint32 messageResult = handleMessage(messageNum, param, sender);
888 switch (messageResult) {
889 case NM_ANIMATION_STOP:
890 gotoNextState();
891 break;
892 default:
893 break;
894 }
895 return messageResult;
896 }
897
stOpenDoor()898 void AsScene1002OutsideDoorBackground::stOpenDoor() {
899 startAnimation(0x004A4495, 0, -1);
900 _newStickFrameIndex = STICK_LAST_FRAME;
901 setVisible(true);
902 SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
903 }
904
stCloseDoor()905 void AsScene1002OutsideDoorBackground::stCloseDoor() {
906 startAnimation(0x004A4495, -1, -1);
907 _playBackwards = true;
908 setVisible(true);
909 SetMessageHandler(&AsScene1002OutsideDoorBackground::hmAnimation);
910 NextState(&AsScene1002OutsideDoorBackground::stDoorClosed);
911 }
912
stDoorClosed()913 void AsScene1002OutsideDoorBackground::stDoorClosed() {
914 setVisible(false);
915 stopAnimation();
916 }
917
AsScene1002KlaymenLadderHands(NeverhoodEngine * vm,Klaymen * klaymen)918 AsScene1002KlaymenLadderHands::AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen)
919 : AnimatedSprite(vm, 1200), _klaymen(klaymen) {
920
921 createSurface(1200, 40, 163);
922 setVisible(false);
923 SetUpdateHandler(&AsScene1002KlaymenLadderHands::update);
924 SetMessageHandler(&Sprite::handleMessage);
925 }
926
update()927 void AsScene1002KlaymenLadderHands::update() {
928 if (_klaymen->getCurrAnimFileHash() == 0x3A292504) {
929 startAnimation(0xBA280522, _klaymen->getFrameIndex(), -1);
930 _newStickFrameIndex = _klaymen->getFrameIndex();
931 setVisible(true);
932 _x = _klaymen->getX();
933 _y = _klaymen->getY();
934 setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
935 } else if (_klaymen->getCurrAnimFileHash() == 0x122D1505) {
936 startAnimation(0x1319150C, _klaymen->getFrameIndex(), -1);
937 _newStickFrameIndex = _klaymen->getFrameIndex();
938 setVisible(true);
939 _x = _klaymen->getX();
940 _y = _klaymen->getY();
941 setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
942 } else
943 setVisible(false);
944 AnimatedSprite::update();
945 }
946
AsScene1002KlaymenPeekHand(NeverhoodEngine * vm,Scene * parentScene,Klaymen * klaymen)947 AsScene1002KlaymenPeekHand::AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen)
948 : AnimatedSprite(vm, 1200), _parentScene(parentScene), _klaymen(klaymen),
949 _isClipRectSaved(false) {
950
951 createSurface(1000, 33, 41);
952 setVisible(false);
953 SetUpdateHandler(&AsScene1002KlaymenPeekHand::update);
954 SetMessageHandler(&AsScene1002KlaymenPeekHand::handleMessage);
955 }
956
update()957 void AsScene1002KlaymenPeekHand::update() {
958 if (_klaymen->getCurrAnimFileHash() == 0xAC20C012 && _klaymen->getFrameIndex() < 50) {
959 startAnimation(0x9820C913, _klaymen->getFrameIndex(), -1);
960 _newStickFrameIndex = _klaymen->getFrameIndex();
961 setVisible(true);
962 _x = _klaymen->getX();
963 _y = _klaymen->getY();
964 setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
965 } else
966 setVisible(false);
967 AnimatedSprite::update();
968 }
969
handleMessage(int messageNum,const MessageParam & param,Entity * sender)970 uint32 AsScene1002KlaymenPeekHand::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
971 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
972 switch (messageNum) {
973 case NM_ANIMATION_START:
974 if (param.asInteger() == 0x4AB28209) {
975 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1200);
976 _isClipRectSaved = true;
977 _savedClipRect = _surface->getClipRect();
978 setClipRect(0, 0, 640, 480);
979 } else if (param.asInteger() == 0x88001184) {
980 sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1000);
981 if (_isClipRectSaved)
982 setClipRect(_savedClipRect);
983 }
984 break;
985 default:
986 break;
987 }
988 return messageResult;
989 }
990
AsScene1004TrashCan(NeverhoodEngine * vm)991 AsScene1004TrashCan::AsScene1004TrashCan(NeverhoodEngine *vm)
992 : AnimatedSprite(vm, 1100) {
993
994 _x = 330;
995 _y = 327;
996 createSurface(800, 56, 50);
997 setVisible(false);
998 SetUpdateHandler(&AnimatedSprite::update);
999 SetMessageHandler(&AsScene1004TrashCan::handleMessage);
1000 }
1001
handleMessage(int messageNum,const MessageParam & param,Entity * sender)1002 uint32 AsScene1004TrashCan::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
1003 Sprite::handleMessage(messageNum, param, sender);
1004 switch (messageNum) {
1005 case NM_ANIMATION_START:
1006 if (param.asInteger() == 0x225A8587)
1007 playSound(0, 0x109AFC4C);
1008 break;
1009 case NM_POSITION_CHANGE:
1010 startAnimation(0xEB312C11, 0, -1);
1011 setVisible(true);
1012 break;
1013 case NM_ANIMATION_STOP:
1014 stopAnimation();
1015 setVisible(false);
1016 break;
1017 default:
1018 break;
1019 }
1020 return 0;
1021 }
1022
1023 static const KlaymenIdleTableItem klaymenIdleTable1002[] = {
1024 {1, kIdlePickEar},
1025 {2, kIdleWonderAbout}
1026 };
1027
KmScene1001(NeverhoodEngine * vm,Scene * parentScene,int16 x,int16 y)1028 KmScene1001::KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
1029 : Klaymen(vm, parentScene, x, y) {
1030 }
1031
xHandleMessage(int messageNum,const MessageParam & param)1032 uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam ¶m) {
1033 switch (messageNum) {
1034 case 0x4001:
1035 case 0x4800:
1036 startWalkToX(param.asPoint().x, false);
1037 break;
1038 case NM_KLAYMEN_STAND_IDLE:
1039 GotoState(&Klaymen::stTryStandIdle);
1040 break;
1041 case 0x4804:
1042 if (param.asInteger() == 2)
1043 GotoState(&KmScene1001::stSleeping);
1044 break;
1045 case 0x480D:
1046 GotoState(&KmScene1001::stPullHammerLever);
1047 break;
1048 case NM_KLAYMEN_PICKUP:
1049 GotoState(&Klaymen::stPickUpGeneric);
1050 break;
1051 case NM_KLAYMEN_PRESS_BUTTON:
1052 if (param.asInteger() == 1)
1053 GotoState(&Klaymen::stPressButton);
1054 else if (param.asInteger() == 2)
1055 GotoState(&Klaymen::stPressFloorButton);
1056 else
1057 GotoState(&Klaymen::stPressButtonSide);
1058 break;
1059 case 0x4817:
1060 setDoDeltaX(param.asInteger());
1061 gotoNextStateExt();
1062 break;
1063 case 0x481B:
1064 if (param.asPoint().y != 0)
1065 startWalkToXDistance(param.asPoint().y, param.asPoint().x);
1066 else
1067 startWalkToAttachedSpriteXDistance(param.asPoint().x);
1068 break;
1069 case 0x481F:
1070 if (param.asInteger() == 0)
1071 GotoState(&Klaymen::stWonderAboutHalf);
1072 else if (param.asInteger() == 1)
1073 GotoState(&Klaymen::stWonderAboutAfter);
1074 else if (param.asInteger() == 3)
1075 GotoState(&Klaymen::stTurnToUseHalf);
1076 else if (param.asInteger() == 4)
1077 GotoState(&Klaymen::stTurnAwayFromUse);
1078 else
1079 GotoState(&Klaymen::stWonderAbout);
1080 break;
1081 case 0x482D:
1082 setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
1083 gotoNextStateExt();
1084 break;
1085 case 0x4836:
1086 if (param.asInteger() == 1) {
1087 sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
1088 GotoState(&KmScene1001::stWakeUp);
1089 }
1090 break;
1091 case 0x483F:
1092 startSpecialWalkRight(param.asInteger());
1093 break;
1094 case 0x4840:
1095 startSpecialWalkLeft(param.asInteger());
1096 break;
1097 default:
1098 break;
1099 }
1100 return 0;
1101 }
1102
stWakeUp()1103 void KmScene1001::stWakeUp() {
1104 _busyStatus = 1;
1105 _acceptInput = false;
1106 startAnimation(0x527AC970, 0, -1);
1107 SetUpdateHandler(&Klaymen::update);
1108 SetMessageHandler(&Klaymen::hmLowLevelAnimation);
1109 SetSpriteUpdate(NULL);
1110 }
1111
stSleeping()1112 void KmScene1001::stSleeping() {
1113 _busyStatus = 0;
1114 _acceptInput = true;
1115 startAnimation(0x5A38C110, 0, -1);
1116 SetUpdateHandler(&Klaymen::update);
1117 SetMessageHandler(&KmScene1001::hmSleeping);
1118 SetSpriteUpdate(NULL);
1119 }
1120
hmSleeping(int messageNum,const MessageParam & param,Entity * sender)1121 uint32 KmScene1001::hmSleeping(int messageNum, const MessageParam ¶m, Entity *sender) {
1122 uint32 messageResult = hmLowLevel(messageNum, param, sender);
1123 switch (messageNum) {
1124 case NM_ANIMATION_START:
1125 if (param.asInteger() == 0x03060012) {
1126 playSound(0, 0xC0238244);
1127 }
1128 break;
1129 default:
1130 break;
1131 }
1132 return messageResult;
1133 }
1134
stPullHammerLever()1135 void KmScene1001::stPullHammerLever() {
1136 if (!stStartAction(AnimationCallback(&KmScene1001::stPullHammerLever))) {
1137 _busyStatus = 2;
1138 _acceptInput = false;
1139 startAnimation(0x00648953, 0, -1);
1140 SetUpdateHandler(&Klaymen::update);
1141 SetMessageHandler(&KmScene1001::hmPullHammerLever);
1142 SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
1143 }
1144 }
1145
hmPullHammerLever(int messageNum,const MessageParam & param,Entity * sender)1146 uint32 KmScene1001::hmPullHammerLever(int messageNum, const MessageParam ¶m, Entity *sender) {
1147 uint32 messageResult = Klaymen::hmLever(messageNum, param, sender);
1148 switch (messageNum) {
1149 case NM_ANIMATION_START:
1150 if (param.asInteger() == 0x4AB28209)
1151 sendMessage(_attachedSprite, NM_KLAYMEN_LOWER_LEVER, 0);
1152 break;
1153 default:
1154 break;
1155 }
1156 return messageResult;
1157 }
1158
KmScene1002(NeverhoodEngine * vm,Scene * parentScene,int16 x,int16 y)1159 KmScene1002::KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
1160 : Klaymen(vm, parentScene, x, y) {
1161
1162 setKlaymenIdleTable1();
1163 }
1164
xUpdate()1165 void KmScene1002::xUpdate() {
1166 if (_x >= 250 && _x <= 435 && _y >= 420) {
1167 if (_idleTableNum == 0) {
1168 setKlaymenIdleTable(klaymenIdleTable1002, ARRAYSIZE(klaymenIdleTable1002));
1169 _idleTableNum = 1;
1170 }
1171 } else if (_idleTableNum == 1) {
1172 setKlaymenIdleTable1();
1173 _idleTableNum = 0;
1174 }
1175 }
1176
xHandleMessage(int messageNum,const MessageParam & param)1177 uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam ¶m) {
1178 switch (messageNum) {
1179 case 0x2001:
1180 GotoState(&Klaymen::stStandIdleSpecial);
1181 break;
1182 case NM_CAR_MOVE_TO_PREV_POINT:
1183 _otherSprite = (Sprite*)param.asEntity();
1184 break;
1185 case 0x4001:
1186 case 0x4800:
1187 startWalkToX(param.asPoint().x, false);
1188 break;
1189 case NM_KLAYMEN_STAND_IDLE:
1190 GotoState(&Klaymen::stTryStandIdle);
1191 break;
1192 case 0x4803:
1193 if (param.asInteger() == 1)
1194 GotoState(&KmScene1002::stJumpAndFall);
1195 else if (param.asInteger() == 2)
1196 GotoState(&KmScene1002::stDropFromRing);
1197 break;
1198 case 0x4804:
1199 GotoState(&Klaymen::stPeekWall);
1200 break;
1201 case 0x4805:
1202 switch (param.asInteger()) {
1203 case 1:
1204 GotoState(&KmScene1002::stJumpToRing1);
1205 break;
1206 case 2:
1207 GotoState(&KmScene1002::stJumpToRing2);
1208 break;
1209 case 3:
1210 GotoState(&KmScene1002::stJumpToRing3);
1211 break;
1212 case 4:
1213 GotoState(&KmScene1002::stJumpToRing4);
1214 break;
1215 default:
1216 break;
1217 }
1218 break;
1219 case NM_KLAYMEN_MOVE_OBJECT:
1220 GotoState(&KmScene1002::stMoveVenusFlyTrap);
1221 break;
1222 case 0x480D:
1223 GotoState(&KmScene1002::stJumpToRingVenusFlyTrap);
1224 break;
1225 case NM_KLAYMEN_PRESS_BUTTON:
1226 if (param.asInteger() == 0)
1227 GotoState(&KmScene1002::stPressDoorButton);
1228 break;
1229 case 0x4817:
1230 setDoDeltaX(param.asInteger());
1231 gotoNextStateExt();
1232 break;
1233 case 0x481B:
1234 startWalkToAttachedSpriteXDistance(param.asInteger());
1235 break;
1236 case 0x4820:
1237 sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
1238 GotoState(&Klaymen::stContinueClimbLadderUp);
1239 break;
1240 case 0x4821:
1241 sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
1242 _destY = param.asInteger();
1243 GotoState(&Klaymen::stStartClimbLadderDown);
1244 break;
1245 case 0x4822:
1246 sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
1247 _destY = param.asInteger();
1248 GotoState(&Klaymen::stStartClimbLadderUp);
1249 break;
1250 case 0x4823:
1251 sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
1252 GotoState(&Klaymen::stClimbLadderHalf);
1253 break;
1254 case 0x482E:
1255 if (param.asInteger() == 1)
1256 GotoState(&Klaymen::stWalkToFrontNoStep);
1257 else
1258 GotoState(&Klaymen::stWalkToFront);
1259 break;
1260 case 0x482F:
1261 if (param.asInteger() == 1)
1262 GotoState(&Klaymen::stTurnToFront);
1263 else
1264 GotoState(&Klaymen::stTurnToBack);
1265 break;
1266 case 0x483F:
1267 startSpecialWalkRight(param.asInteger());
1268 break;
1269 case 0x4840:
1270 startSpecialWalkLeft(param.asInteger());
1271 break;
1272 default:
1273 break;
1274 }
1275 return 0;
1276 }
1277
setupJumpToRing()1278 void KmScene1002::setupJumpToRing() {
1279 _acceptInput = false;
1280 SetUpdateHandler(&Klaymen::update);
1281 SetMessageHandler(&KmScene1002::hmJumpToRing);
1282 SetSpriteUpdate(&Klaymen::suUpdateDestX);
1283 NextState(&KmScene1002::stHangOnRing);
1284 sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
1285 }
1286
hmJumpToRing(int messageNum,const MessageParam & param,Entity * sender)1287 uint32 KmScene1002::hmJumpToRing(int messageNum, const MessageParam ¶m, Entity *sender) {
1288 uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
1289 switch (messageNum) {
1290 case NM_ANIMATION_START:
1291 if (param.asInteger() == 0x168050A0) {
1292 sendMessage(_attachedSprite, NM_KLAYMEN_USE_OBJECT, 0);
1293 _acceptInput = true;
1294 } else if (param.asInteger() == 0x320AC306) {
1295 playSound(0, 0x5860C640);
1296 } else if (param.asInteger() == 0x4AB28209) {
1297 sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
1298 } else if (param.asInteger() == 0x88001184) {
1299 sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
1300 }
1301 break;
1302 default:
1303 break;
1304 }
1305 return messageResult;
1306 }
1307
stHangOnRing()1308 void KmScene1002::stHangOnRing() {
1309 _busyStatus = 0;
1310 _acceptInput = true;
1311 startAnimation(0x4829E0B8, 0, -1);
1312 SetUpdateHandler(&Klaymen::update);
1313 SetMessageHandler(&Klaymen::hmLowLevel);
1314 SetSpriteUpdate(NULL);
1315 }
1316
stJumpToRing1()1317 void KmScene1002::stJumpToRing1() {
1318 if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing1))) {
1319 _busyStatus = 0;
1320 startAnimation(0xD82890BA, 0, -1);
1321 setupJumpToRing();
1322 }
1323 }
1324
stJumpToRing2()1325 void KmScene1002::stJumpToRing2() {
1326 if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing2))) {
1327 _busyStatus = 0;
1328 startAnimation(0x900980B2, 0, -1);
1329 setupJumpToRing();
1330 }
1331 }
1332
stJumpToRing3()1333 void KmScene1002::stJumpToRing3() {
1334 if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing3))) {
1335 _busyStatus = 0;
1336 _acceptInput = false;
1337 startAnimation(0xBA1910B2, 0, -1);
1338 SetUpdateHandler(&Klaymen::update);
1339 SetSpriteUpdate(&Klaymen::suUpdateDestX);
1340 SetMessageHandler(&KmScene1002::hmJumpToRing3);
1341 NextState(&KmScene1002::stHoldRing3);
1342 sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
1343 }
1344 }
1345
hmJumpToRing3(int messageNum,const MessageParam & param,Entity * sender)1346 uint32 KmScene1002::hmJumpToRing3(int messageNum, const MessageParam ¶m, Entity *sender) {
1347 uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
1348 switch (messageNum) {
1349 case NM_ANIMATION_START:
1350 if (param.asInteger() == 0x168050A0) {
1351 sendMessage(_attachedSprite, NM_KLAYMEN_USE_OBJECT, 0);
1352 } else if (param.asInteger() == 0x320AC306) {
1353 playSound(0, 0x5860C640);
1354 } else if (param.asInteger() == 0x4AB28209) {
1355 sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
1356 } else if (param.asInteger() == 0x88001184) {
1357 sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
1358 }
1359 break;
1360 default:
1361 break;
1362 }
1363 return messageResult;
1364 }
1365
stHoldRing3()1366 void KmScene1002::stHoldRing3() {
1367 _busyStatus = 0;
1368 _acceptInput = true;
1369 startAnimation(0x4A293FB0, 0, -1);
1370 SetUpdateHandler(&Klaymen::update);
1371 SetMessageHandler(&KmScene1002::hmHoldRing3);
1372 SetSpriteUpdate(NULL);
1373 }
1374
hmHoldRing3(int messageNum,const MessageParam & param,Entity * sender)1375 uint32 KmScene1002::hmHoldRing3(int messageNum, const MessageParam ¶m, Entity *sender) {
1376 if (messageNum == 0x1008) {
1377 stReleaseRing();
1378 return 0;
1379 }
1380 return hmLowLevel(messageNum, param, sender);
1381 }
1382
stJumpToRing4()1383 void KmScene1002::stJumpToRing4() {
1384 if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing4))) {
1385 _busyStatus = 0;
1386 startAnimation(0xB8699832, 0, -1);
1387 setupJumpToRing();
1388 }
1389 }
1390
stJumpToRingVenusFlyTrap()1391 void KmScene1002::stJumpToRingVenusFlyTrap() {
1392 if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRingVenusFlyTrap))) {
1393 _busyStatus = 2;
1394 _acceptInput = false;
1395 startAnimation(0x584984B4, 0, -1);
1396 SetUpdateHandler(&Klaymen::update);
1397 SetMessageHandler(&KmScene1002::hmJumpToRingVenusFlyTrap);
1398 SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
1399 NextState(&KmScene1002::stLandOnFeet);
1400 sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
1401 }
1402 }
1403
hmJumpToRingVenusFlyTrap(int messageNum,const MessageParam & param,Entity * sender)1404 uint32 KmScene1002::hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender) {
1405 uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
1406 switch (messageNum) {
1407 case NM_ANIMATION_START:
1408 if (param.asInteger() == 0x168050A0) {
1409 sendMessage(_attachedSprite, NM_KLAYMEN_LOWER_LEVER, 0);
1410 } else if (param.asInteger() == 0x586B0300) {
1411 sendMessage(_otherSprite, 0x480E, 1);
1412 } else if (param.asInteger() == 0x4AB28209) {
1413 sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
1414 } else if (param.asInteger() == 0x88001184) {
1415 sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
1416 }
1417 break;
1418 default:
1419 break;
1420 }
1421 return messageResult;
1422 }
1423
stJumpAndFall()1424 void KmScene1002::stJumpAndFall() {
1425 if (!stStartAction(AnimationCallback(&KmScene1002::stJumpAndFall))) {
1426 sendMessage(_parentScene, 0x1024, 3);
1427 _busyStatus = 2;
1428 _acceptInput = false;
1429 startAnimation(0xB93AB151, 0, -1);
1430 SetUpdateHandler(&Klaymen::update);
1431 SetMessageHandler(&KmScene1002::hmJumpAndFall);
1432 SetSpriteUpdate(&Klaymen::suFallDown);
1433 NextState(&KmScene1002::stLandOnFeet);
1434 }
1435 }
1436
stDropFromRing()1437 void KmScene1002::stDropFromRing() {
1438 if (_attachedSprite) {
1439 _x = _attachedSprite->getX();
1440 sendMessage(_attachedSprite, NM_KLAYMEN_RAISE_LEVER, 0);
1441 _attachedSprite = NULL;
1442 }
1443 _busyStatus = 2;
1444 _acceptInput = false;
1445 startAnimation(0x586984B1, 0, -1);
1446 SetUpdateHandler(&Klaymen::update);
1447 SetMessageHandler(&Klaymen::hmLowLevel);
1448 SetSpriteUpdate(&Klaymen::suFallDown);
1449 NextState(&KmScene1002::stLandOnFeet);
1450 }
1451
hmJumpAndFall(int messageNum,const MessageParam & param,Entity * sender)1452 uint32 KmScene1002::hmJumpAndFall(int messageNum, const MessageParam ¶m, Entity *sender) {
1453 uint32 messageResult = hmLowLevel(messageNum, param, sender);
1454 switch (messageNum) {
1455 case NM_ANIMATION_START:
1456 if (param.asInteger() == 0x1307050A) {
1457 playSound(0, 0x40428A09);
1458 }
1459 break;
1460 default:
1461 break;
1462 }
1463 return messageResult;
1464 }
1465
stMoveVenusFlyTrap()1466 void KmScene1002::stMoveVenusFlyTrap() {
1467 if (!stStartAction(AnimationCallback(&KmScene1002::stMoveVenusFlyTrap))) {
1468 _busyStatus = 2;
1469 _isMoveObjectRequested = false;
1470 _acceptInput = true;
1471 setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
1472 startAnimation(0x5C01A870, 0, -1);
1473 SetUpdateHandler(&Klaymen::update);
1474 SetMessageHandler(&KmScene1002::hmMoveVenusFlyTrap);
1475 SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
1476 FinalizeState(&KmScene1002::evMoveVenusFlyTrapDone);
1477 }
1478 }
1479
stContinueMovingVenusFlyTrap()1480 void KmScene1002::stContinueMovingVenusFlyTrap() {
1481 _isMoveObjectRequested = false;
1482 _acceptInput = true;
1483 startAnimationByHash(0x5C01A870, 0x01084280, 0);
1484 SetUpdateHandler(&Klaymen::update);
1485 SetMessageHandler(&KmScene1002::hmMoveVenusFlyTrap);
1486 SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
1487 FinalizeState(&KmScene1002::evMoveVenusFlyTrapDone);
1488 }
1489
evMoveVenusFlyTrapDone()1490 void KmScene1002::evMoveVenusFlyTrapDone() {
1491 sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
1492 }
1493
hmMoveVenusFlyTrap(int messageNum,const MessageParam & param,Entity * sender)1494 uint32 KmScene1002::hmMoveVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender) {
1495 switch (messageNum) {
1496 case NM_ANIMATION_START:
1497 if (param.asInteger() == 0x01084280) {
1498 sendMessage(_attachedSprite, 0x480B, (uint32)_doDeltaX);
1499 } else if (param.asInteger() == 0x02421405) {
1500 if (_isMoveObjectRequested) {
1501 if (sendMessage(_attachedSprite, 0x480C, (uint32)_doDeltaX) != 0)
1502 stContinueMovingVenusFlyTrap();
1503 } else {
1504 SetMessageHandler(&KmScene1002::hmFirstMoveVenusFlyTrap);
1505 }
1506 } else if (param.asInteger() == 0x4AB28209) {
1507 sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
1508 } else if (param.asInteger() == 0x88001184) {
1509 sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
1510 } else if (param.asInteger() == 0x32180101) {
1511 playSound(0, 0x405002D8);
1512 } else if (param.asInteger() == 0x0A2A9098) {
1513 playSound(0, 0x0460E2FA);
1514 }
1515 break;
1516 case NM_KLAYMEN_MOVE_OBJECT:
1517 _isMoveObjectRequested = true;
1518 return 0;
1519 default:
1520 break;
1521 }
1522 return hmLowLevelAnimation(messageNum, param, sender);
1523 }
1524
hmFirstMoveVenusFlyTrap(int messageNum,const MessageParam & param,Entity * sender)1525 uint32 KmScene1002::hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender) {
1526 uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
1527 switch (messageNum) {
1528 case NM_ANIMATION_START:
1529 if (param.asInteger() == 0x4AB28209) {
1530 sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
1531 } else if (param.asInteger() == 0x88001184) {
1532 sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
1533 } else if (param.asInteger() == 0x32180101) {
1534 playSound(0, 0x405002D8);
1535 } else if (param.asInteger() == 0x0A2A9098) {
1536 playSound(0, 0x0460E2FA);
1537 }
1538 break;
1539 default:
1540 break;
1541 }
1542 return messageResult;
1543 }
1544
stPressDoorButton()1545 void KmScene1002::stPressDoorButton() {
1546 _busyStatus = 2;
1547 _acceptInput = true;
1548 setDoDeltaX(0);
1549 startAnimation(0x1CD89029, 0, -1);
1550 SetUpdateHandler(&Klaymen::update);
1551 SetMessageHandler(&KmScene1002::hmPressDoorButton);
1552 SetSpriteUpdate(&Klaymen::suAction);
1553 }
1554
stHitByBoxingGlove()1555 void KmScene1002::stHitByBoxingGlove() {
1556 _busyStatus = 1;
1557 _acceptInput = false;
1558 startAnimation(0x35AA8059, 0, -1);
1559 SetUpdateHandler(&Klaymen::update);
1560 SetMessageHandler(&KmScene1002::hmHitByBoxingGlove);
1561 SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
1562 FinalizeState(&KmScene1002::evHitByBoxingGloveDone);
1563 }
1564
evHitByBoxingGloveDone()1565 void KmScene1002::evHitByBoxingGloveDone() {
1566 sendMessage(_parentScene, 0x1024, 1);
1567 }
1568
hmPressDoorButton(int messageNum,const MessageParam & param,Entity * sender)1569 uint32 KmScene1002::hmPressDoorButton(int messageNum, const MessageParam ¶m, Entity *sender) {
1570 uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
1571 switch (messageNum) {
1572 case NM_ANIMATION_START:
1573 if (param.asInteger() == 0x942D2081) {
1574 _acceptInput = false;
1575 sendMessage(_attachedSprite, 0x2003, 0);
1576 } else if (param.asInteger() == 0xDA600012) {
1577 stHitByBoxingGlove();
1578 } else if (param.asInteger() == 0x0D01B294) {
1579 _acceptInput = false;
1580 sendMessage(_attachedSprite, 0x480B, 0);
1581 }
1582 break;
1583 default:
1584 break;
1585 }
1586 return messageResult;
1587 }
1588
hmHitByBoxingGlove(int messageNum,const MessageParam & param,Entity * sender)1589 uint32 KmScene1002::hmHitByBoxingGlove(int messageNum, const MessageParam ¶m, Entity *sender) {
1590 int16 speedUpFrameIndex;
1591 uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
1592 switch (messageNum) {
1593 case 0x1008:
1594 speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
1595 if (_currFrameIndex < speedUpFrameIndex) {
1596 startAnimation(0x35AA8059, speedUpFrameIndex, -1);
1597 _y = 435;
1598 }
1599 messageResult = 0;
1600 break;
1601 case NM_ANIMATION_START:
1602 if (param.asInteger() == 0x1A1A0785) {
1603 playSound(0, 0x40F0A342);
1604 } else if (param.asInteger() == 0x60428026) {
1605 playSound(0, 0x40608A59);
1606 }
1607 break;
1608 default:
1609 break;
1610 }
1611 return messageResult;
1612 }
1613
KmScene1004(NeverhoodEngine * vm,Scene * parentScene,int16 x,int16 y)1614 KmScene1004::KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
1615 : Klaymen(vm, parentScene, x, y) {
1616
1617 _dataResource.load(0x01900A04);
1618 }
1619
xHandleMessage(int messageNum,const MessageParam & param)1620 uint32 KmScene1004::xHandleMessage(int messageNum, const MessageParam ¶m) {
1621 switch (messageNum) {
1622 case 0x4001:
1623 case 0x4800:
1624 startWalkToX(param.asPoint().x, false);
1625 break;
1626 case NM_KLAYMEN_STAND_IDLE:
1627 GotoState(&Klaymen::stTryStandIdle);
1628 break;
1629 case 0x4817:
1630 setDoDeltaX(param.asInteger());
1631 gotoNextStateExt();
1632 break;
1633 case 0x4818:
1634 startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
1635 break;
1636 case NM_KLAYMEN_RETURN_FROM_USE:
1637 GotoState(&KmScene1004::stReadNote);
1638 break;
1639 case 0x4820:
1640 sendMessage(_parentScene, 0x2000, 0);
1641 GotoState(&Klaymen::stContinueClimbLadderUp);
1642 break;
1643 case 0x4821:
1644 sendMessage(_parentScene, 0x2000, 0);
1645 _destY = param.asInteger();
1646 GotoState(&Klaymen::stStartClimbLadderDown);
1647 break;
1648 case 0x4822:
1649 sendMessage(_parentScene, 0x2000, 0);
1650 _destY = param.asInteger();
1651 GotoState(&Klaymen::stStartClimbLadderUp);
1652 break;
1653 case 0x4823:
1654 sendMessage(_parentScene, 0x2001, 0);
1655 GotoState(&Klaymen::stClimbLadderHalf);
1656 break;
1657 case 0x4824:
1658 sendMessage(_parentScene, 0x2000, 0);
1659 _destY = _dataResource.getPoint(param.asInteger()).y;
1660 GotoState(&Klaymen::stStartClimbLadderDown);
1661 break;
1662 case 0x4825:
1663 sendMessage(_parentScene, 0x2000, 0);
1664 _destY = _dataResource.getPoint(param.asInteger()).y;
1665 GotoState(&Klaymen::stStartClimbLadderUp);
1666 break;
1667 case 0x4828:
1668 GotoState(&Klaymen::stTurnToBackToUse);
1669 break;
1670 case 0x483F:
1671 startSpecialWalkRight(param.asInteger());
1672 break;
1673 case 0x4840:
1674 startSpecialWalkLeft(param.asInteger());
1675 break;
1676 default:
1677 break;
1678 }
1679 return 0;
1680 }
1681
hmReadNote(int messageNum,const MessageParam & param,Entity * sender)1682 uint32 KmScene1004::hmReadNote(int messageNum, const MessageParam ¶m, Entity *sender) {
1683 uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
1684 switch (messageNum) {
1685 case NM_ANIMATION_START:
1686 if (param.asInteger() == 0x04684052) {
1687 _acceptInput = true;
1688 sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
1689 }
1690 break;
1691 default:
1692 break;
1693 }
1694 return messageResult;
1695 }
1696
stReadNote()1697 void KmScene1004::stReadNote() {
1698 _busyStatus = 2;
1699 _acceptInput = false;
1700 startAnimation(0x123E9C9F, 0, -1);
1701 SetUpdateHandler(&Klaymen::update);
1702 SetMessageHandler(&KmScene1004::hmReadNote);
1703 SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
1704 }
1705
1706 } // End of namespace Neverhood
1707