~ubuntu-branches/debian/jessie/scummvm/jessie

« back to all changes in this revision

Viewing changes to engines/neverhood/modules/module1200_sprites.cpp

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2014-08-10 00:50:36 UTC
  • mfrom: (1.2.22)
  • Revision ID: package-import@ubuntu.com-20140810005036-wls6i0dsxqfxu70g
Tags: 1.7.0+dfsg-1
* New upstream release [July 2014].
  - remove old/obsolete patches.
  + added new "drop1test.patch" to disable problematic test.
  + build with "--disable-eventrecorder" to avoid FTBFS in tests.
  + added "libjpeg-dev" and "libfaad-dev" to Build-Depends.
* Install all arch-independent files (themes, game data, etc.).
* Build-time re-compression of "classic" theme.
* Added "debian/gbp.conf".
* Standards-Version to 3.9.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/module1200_sprites.h"
 
24
 
 
25
namespace Neverhood {
 
26
 
 
27
static const uint32 kScene1201TntFileHashList1[] = {
 
28
        0x2098212D, 0x1600437E, 0x1600437E,
 
29
        0x00A840E3, 0x1A1830F6, 0x1A1830F6,
 
30
        0x00212062, 0x384010B6, 0x384010B6,
 
31
        0x07A01080, 0xD80C2837, 0xD80C2837,
 
32
        0x03A22092, 0xD8802CB6, 0xD8802CB6,
 
33
        0x03A93831, 0xDA460476, 0xDA460476
 
34
};
 
35
 
 
36
static const uint32 kScene1201TntFileHashList2[] = {
 
37
        0x3040C676, 0x10914448, 0x10914448,
 
38
        0x3448A066, 0x1288C049, 0x1288C049,
 
39
        0x78C0E026, 0x3098D05A, 0x3098D05A,
 
40
        0x304890E6, 0x1284E048, 0x1284E048,
 
41
        0xB140A1E6, 0x5088A068, 0x5088A068,
 
42
        0x74C4C866, 0x3192C059, 0x3192C059
 
43
};
 
44
 
 
45
SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2)
 
46
        : StaticSprite(vm, 900) {
 
47
 
 
48
        int16 x = kScene1201PointArray[pointIndex].x;
 
49
        int16 y = kScene1201PointArray[pointIndex].y;
 
50
        if (x < 300)
 
51
                loadSprite(kScene1201TntFileHashList1[elemIndex], kSLFDefDrawOffset | kSLFDefPosition, 50);
 
52
        else
 
53
                loadSprite(kScene1201TntFileHashList2[elemIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 50, x, y - 20);
 
54
        setClipRect(0, 0, 640, clipY2);
 
55
}
 
56
 
 
57
AsScene1201Tape::AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash)
 
58
        : AnimatedSprite(vm, fileHash, surfacePriority, x, y), _parentScene(parentScene), _nameHash(nameHash) {
 
59
 
 
60
        if (!getSubVar(VA_HAS_TAPE, _nameHash) && !getSubVar(VA_IS_TAPE_INSERTED, _nameHash)) {
 
61
                SetMessageHandler(&AsScene1201Tape::handleMessage);
 
62
        } else {
 
63
                setVisible(false);
 
64
                SetMessageHandler(NULL);
 
65
        }
 
66
}
 
67
 
 
68
uint32 AsScene1201Tape::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
 
69
        uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
 
70
        switch (messageNum) {
 
71
        case 0x1011:
 
72
                sendMessage(_parentScene, 0x4826, 0);
 
73
                messageResult = 1;
 
74
                break;
 
75
        case NM_KLAYMEN_USE_OBJECT:
 
76
                setSubVar(VA_HAS_TAPE, _nameHash, 1);
 
77
                setVisible(false);
 
78
                SetMessageHandler(NULL);
 
79
                break;
 
80
        }
 
81
        return messageResult;
 
82
}
 
83
 
 
84
AsScene1201TntManRope::AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging)
 
85
        : AnimatedSprite(vm, 1200) {
 
86
 
 
87
        SetUpdateHandler(&AnimatedSprite::update);
 
88
        SetMessageHandler(&AsScene1201TntManRope::handleMessage);
 
89
        createSurface(10, 34, 149);
 
90
        _x = 202;
 
91
        _y = -32;
 
92
        if (isDummyHanging) {
 
93
                startAnimation(0x928F0C10, 15, -1);
 
94
                _newStickFrameIndex = STICK_LAST_FRAME;
 
95
        } else {
 
96
                startAnimation(0x928F0C10, 0, -1);
 
97
                _newStickFrameIndex = 0;
 
98
        }
 
99
}
 
100
 
 
101
uint32 AsScene1201TntManRope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
 
102
        uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
 
103
        switch (messageNum) {
 
104
        case NM_ANIMATION_START:
 
105
                if (param.asInteger() == 0x02060018)
 
106
                        playSound(0, 0x47900E06);
 
107
                break;
 
108
        case NM_KLAYMEN_STOP_CLIMBING:
 
109
                startAnimation(0x928F0C10, 1, -1);
 
110
                _newStickFrameIndex = STICK_LAST_FRAME;
 
111
                break;
 
112
        }
 
113
        return messageResult;
 
114
}
 
115
 
 
116
AsScene1201RightDoor::AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
 
117
        : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0) {
 
118
 
 
119
        createSurface1(0xD088AC30, 100);
 
120
        _x = 320;
 
121
        _y = 240;
 
122
        SetUpdateHandler(&AsScene1201RightDoor::update);
 
123
        SetMessageHandler(&AsScene1201RightDoor::handleMessage);
 
124
        _newStickFrameIndex = STICK_LAST_FRAME;
 
125
        if (isOpen) {
 
126
                startAnimation(0xD088AC30, -1, -1);
 
127
                _newStickFrameIndex = STICK_LAST_FRAME;
 
128
                _countdown = 25;
 
129
        } else {
 
130
                stopAnimation();
 
131
                setVisible(false);
 
132
        }
 
133
}
 
134
 
 
135
void AsScene1201RightDoor::update() {
 
136
        if (_countdown != 0 && (--_countdown == 0))
 
137
                stCloseDoor();
 
138
        AnimatedSprite::update();
 
139
}
 
140
 
 
141
uint32 AsScene1201RightDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
 
142
        uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
 
143
        switch (messageNum) {
 
144
        case NM_ANIMATION_STOP:
 
145
                gotoNextState();
 
146
                break;
 
147
        case 0x4829:
 
148
                stOpenDoor();
 
149
                break;
 
150
        }
 
151
        return messageResult;
 
152
}
 
153
 
 
154
void AsScene1201RightDoor::stOpenDoor() {
 
155
        startAnimation(0xD088AC30, 0, -1);
 
156
        _newStickFrameIndex = STICK_LAST_FRAME;
 
157
        setVisible(true);
 
158
        playSound(0, calcHash("fxDoorOpen20"));
 
159
}
 
160
 
 
161
void AsScene1201RightDoor::stCloseDoor() {
 
162
        startAnimation(0xD088AC30, -1, -1);
 
163
        _playBackwards = true;
 
164
        setVisible(true);
 
165
        playSound(0, calcHash("fxDoorClose20"));
 
166
        NextState(&AsScene1201RightDoor::stCloseDoorDone);
 
167
}
 
168
 
 
169
void AsScene1201RightDoor::stCloseDoorDone() {
 
170
        stopAnimation();
 
171
        setVisible(false);
 
172
}
 
173
 
 
174
AsScene1201KlaymenHead::AsScene1201KlaymenHead(NeverhoodEngine *vm)
 
175
        : AnimatedSprite(vm, 1200) {
 
176
 
 
177
        createSurface(1200, 69, 98);
 
178
        SetUpdateHandler(&AnimatedSprite::update);
 
179
        SetMessageHandler(&AsScene1201KlaymenHead::handleMessage);
 
180
        SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
 
181
        setVisible(false);
 
182
}
 
183
 
 
184
uint32 AsScene1201KlaymenHead::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
 
185
        uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
 
186
        switch (messageNum) {
 
187
        case NM_KLAYMEN_STOP_CLIMBING:
 
188
                _x = 436;
 
189
                _y = 339;
 
190
                startAnimation(0xA060C599, 0, -1);
 
191
                setVisible(true);
 
192
                break;
 
193
        case NM_ANIMATION_STOP:
 
194
                stopAnimation();
 
195
                setVisible(false);
 
196
                gotoNextState();
 
197
                break;
 
198
        }
 
199
        return messageResult;
 
200
}
 
201
 
 
202
AsScene1201TntMan::AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isComingDown)
 
203
        : AnimatedSprite(vm, 1100), _parentScene(parentScene), _asTntManRope(asTntManRope),
 
204
        _isMoving(false) {
 
205
 
 
206
        SetUpdateHandler(&AnimatedSprite::update);
 
207
        SetMessageHandler(&AsScene1201TntMan::handleMessage);
 
208
        createSurface(990, 106, 181);
 
209
        _x = 201;
 
210
        if (isComingDown) {
 
211
                _y = 297;
 
212
                stComingDown();
 
213
        } else {
 
214
                _y = 334;
 
215
                stStanding();
 
216
        }
 
217
}
 
218
 
 
219
AsScene1201TntMan::~AsScene1201TntMan() {
 
220
        _vm->_soundMan->deleteSoundGroup(0x01D00560);
 
221
}
 
222
 
 
223
uint32 AsScene1201TntMan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
 
224
        uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
 
225
        switch (messageNum) {
 
226
        case NM_ANIMATION_START:
 
227
                if (param.asInteger() == 0x092870C0)
 
228
                        sendMessage(_asTntManRope, NM_KLAYMEN_STOP_CLIMBING, 0);
 
229
                else if (param.asInteger() == 0x11CA0144)
 
230
                        playSound(0, 0x51800A04);
 
231
                break;
 
232
        case 0x1011:
 
233
                sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
 
234
                messageResult = 1;
 
235
                break;
 
236
        case 0x480B:
 
237
                if (!_isMoving) {
 
238
                        _sprite = (Sprite*)sender;
 
239
                        stMoving();
 
240
                }
 
241
                break;
 
242
        }
 
243
        return messageResult;
 
244
 
 
245
}
 
246
 
 
247
uint32 AsScene1201TntMan::hmComingDown(int messageNum, const MessageParam &param, Entity *sender) {
 
248
        uint32 messageResult = AsScene1201TntMan::handleMessage(messageNum, param, sender);
 
249
        switch (messageNum) {
 
250
        case NM_ANIMATION_STOP:
 
251
                gotoNextState();
 
252
                break;
 
253
        }
 
254
        return messageResult;
 
255
}
 
256
 
 
257
void AsScene1201TntMan::suMoving() {
 
258
        _x = _sprite->getX() + 100;
 
259
}
 
260
 
 
261
void AsScene1201TntMan::stStanding() {
 
262
        startAnimation(0x654913D0, 0, -1);
 
263
        SetMessageHandler(&AsScene1201TntMan::handleMessage);
 
264
        SetSpriteUpdate(NULL);
 
265
}
 
266
 
 
267
void AsScene1201TntMan::stComingDown() {
 
268
        startAnimation(0x356803D0, 0, -1);
 
269
        SetMessageHandler(&AsScene1201TntMan::hmComingDown);
 
270
        SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
 
271
        NextState(&AsScene1201TntMan::stStanding);
 
272
}
 
273
 
 
274
void AsScene1201TntMan::stMoving() {
 
275
        _vm->_soundMan->addSound(0x01D00560, 0x4B044624);
 
276
        _vm->_soundMan->playSoundLooping(0x4B044624);
 
277
        _isMoving = true;
 
278
        startAnimation(0x85084190, 0, -1);
 
279
        SetMessageHandler(&AsScene1201TntMan::handleMessage);
 
280
        SetSpriteUpdate(&AsScene1201TntMan::suMoving);
 
281
        _newStickFrameIndex = STICK_LAST_FRAME;
 
282
}
 
283
 
 
284
AsScene1201TntManFlame::AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan)
 
285
        : AnimatedSprite(vm, 1200), _asTntMan(asTntMan) {
 
286
 
 
287
        createSurface1(0x828C0411, 995);
 
288
        SetUpdateHandler(&AsScene1201TntManFlame::update);
 
289
        SetMessageHandler(&Sprite::handleMessage);
 
290
        SetSpriteUpdate(&AsScene1201TntManFlame::suUpdate);
 
291
        startAnimation(0x828C0411, 0, -1);
 
292
        setVisible(false);
 
293
}
 
294
 
 
295
AsScene1201TntManFlame::~AsScene1201TntManFlame() {
 
296
        _vm->_soundMan->deleteSoundGroup(0x041080A4);
 
297
}
 
298
 
 
299
void AsScene1201TntManFlame::update() {
 
300
        AnimatedSprite::update();
 
301
        if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
 
302
                setVisible(true);
 
303
                SetUpdateHandler(&AnimatedSprite::update);
 
304
                _vm->_soundMan->addSound(0x041080A4, 0x460A1050);
 
305
                _vm->_soundMan->playSoundLooping(0x460A1050);
 
306
        }
 
307
}
 
308
 
 
309
void AsScene1201TntManFlame::suUpdate() {
 
310
        _x = _asTntMan->getX() - 18;
 
311
        _y = _asTntMan->getY() - 158;
 
312
}
 
313
 
 
314
AsScene1201Match::AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene)
 
315
        : AnimatedSprite(vm, 1100), _parentScene(parentScene), _countdown(0) {
 
316
 
 
317
        createSurface(1100, 57, 60);
 
318
        SetUpdateHandler(&AsScene1201Match::update);
 
319
        SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
 
320
        SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
 
321
        switch (getGlobalVar(V_MATCH_STATUS)) {
 
322
        case 0:
 
323
                _x = 521;
 
324
                _y = 112;
 
325
                _status = 0;
 
326
                stIdleOnDoorFrame();
 
327
                break;
 
328
        case 1:
 
329
                _x = 521;
 
330
                _y = 112;
 
331
                _status = 2;
 
332
                stOnDoorFrameAboutToMove();
 
333
                loadSound(0, 0xD00230CD);
 
334
                break;
 
335
        case 2:
 
336
                setDoDeltaX(1);
 
337
                _x = 403;
 
338
                _y = 337;
 
339
                _status = 0;
 
340
                stIdleOnFloor();
 
341
                break;
 
342
        }
 
343
}
 
344
 
 
345
void AsScene1201Match::update() {
 
346
        if (_countdown != 0 && (--_countdown == 0))
 
347
                gotoNextState();
 
348
        updateAnim();
 
349
        handleSpriteUpdate();
 
350
        updatePosition();
 
351
}
 
352
 
 
353
uint32 AsScene1201Match::hmOnDoorFrameAboutToMove(int messageNum, const MessageParam &param, Entity *sender) {
 
354
        uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
 
355
        switch (messageNum) {
 
356
        case NM_ANIMATION_START:
 
357
                if (param.asInteger() == 0x86668011)
 
358
                        playSound(0);
 
359
                break;
 
360
        }
 
361
        return messageResult;
 
362
}
 
363
 
 
364
uint32 AsScene1201Match::hmOnDoorFrameMoving(int messageNum, const MessageParam &param, Entity *sender) {
 
365
        uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
 
366
        switch (messageNum) {
 
367
        case NM_ANIMATION_STOP:
 
368
                gotoNextState();
 
369
                break;
 
370
        }
 
371
        return messageResult;
 
372
}
 
373
 
 
374
uint32 AsScene1201Match::hmIdle(int messageNum, const MessageParam &param, Entity *sender) {
 
375
        uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
 
376
        switch (messageNum) {
 
377
        case 0x1011:
 
378
                sendMessage(_parentScene, 0x2001, 0);
 
379
                messageResult = 1;
 
380
                break;
 
381
        case NM_KLAYMEN_USE_OBJECT:
 
382
                setVisible(false);
 
383
                setGlobalVar(V_MATCH_STATUS, 3);
 
384
                break;
 
385
        }
 
386
        return messageResult;
 
387
}
 
388
 
 
389
void AsScene1201Match::stOnDoorFrameMoving() {
 
390
        startAnimation(0x00842374, 0, -1);
 
391
        SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
 
392
        if (_status == 0) {
 
393
                NextState(&AsScene1201Match::stFallingFromDoorFrame);
 
394
        } else {
 
395
                NextState(&AsScene1201Match::stOnDoorFrameAboutToMove);
 
396
        }
 
397
}
 
398
 
 
399
void AsScene1201Match::stFallingFromDoorFrame() {
 
400
        setGlobalVar(V_MATCH_STATUS, 2);
 
401
        _x -= 199;
 
402
        _y += 119;
 
403
        startAnimation(0x018D0240, 0, -1);
 
404
        SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
 
405
        NextState(&AsScene1201Match::stIdleOnFloor);
 
406
}
 
407
 
 
408
void AsScene1201Match::stOnDoorFrameAboutToMove() {
 
409
        startAnimation(0x00842374, 0, -1);
 
410
        SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
 
411
        _newStickFrameIndex = 0;
 
412
        if (_status != 0) {
 
413
                _countdown = 36;
 
414
                _status--;
 
415
                NextState(&AsScene1201Match::stOnDoorFrameMoving);
 
416
        }
 
417
}
 
418
 
 
419
void AsScene1201Match::stIdleOnDoorFrame() {
 
420
        startAnimation(0x00842374, 0, -1);
 
421
        SetMessageHandler(&AsScene1201Match::hmIdle);
 
422
        _newStickFrameIndex = 0;
 
423
}
 
424
 
 
425
void AsScene1201Match::stIdleOnFloor() {
 
426
        setDoDeltaX(1);
 
427
        _x = 403;
 
428
        _y = 337;
 
429
        startAnimation(0x00842374, 0, -1);
 
430
        SetMessageHandler(&AsScene1201Match::hmIdle);
 
431
        _newStickFrameIndex = 0;
 
432
}
 
433
 
 
434
AsScene1201Creature::AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen)
 
435
        : AnimatedSprite(vm, 900), _parentScene(parentScene), _klaymen(klaymen), _klaymenTooClose(false) {
 
436
 
 
437
        // NOTE: _countdown2 and _countdown3 were unused/without effect and thus removed
 
438
 
 
439
        createSurface(1100, 203, 199);
 
440
        SetUpdateHandler(&AsScene1201Creature::update);
 
441
        SetMessageHandler(&AsScene1201Creature::hmWaiting);
 
442
        _x = 540;
 
443
        _y = 320;
 
444
        stWaiting();
 
445
}
 
446
 
 
447
void AsScene1201Creature::update() {
 
448
        bool oldKlaymenTooClose = _klaymenTooClose;
 
449
        _klaymenTooClose = _klaymen->getX() >= 385;
 
450
        if (_klaymenTooClose != oldKlaymenTooClose)
 
451
                stWaiting();
 
452
        if (_countdown != 0 && (--_countdown == 0))
 
453
                gotoNextState();
 
454
        updateAnim();
 
455
        handleSpriteUpdate();
 
456
        updatePosition();
 
457
}
 
458
 
 
459
uint32 AsScene1201Creature::hmWaiting(int messageNum, const MessageParam &param, Entity *sender) {
 
460
        uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
 
461
        switch (messageNum) {
 
462
        case NM_ANIMATION_START:
 
463
                if (param.asInteger() == 0x02060018)
 
464
                        playSound(0, 0xCD298116);
 
465
                break;
 
466
        case 0x2004:
 
467
                GotoState(&AsScene1201Creature::stStartReachForTntDummy);
 
468
                break;
 
469
        case NM_KLAYMEN_STOP_CLIMBING:
 
470
                GotoState(&AsScene1201Creature::stPincerSnapKlaymen);
 
471
                break;
 
472
        }
 
473
        return messageResult;
 
474
}
 
475
 
 
476
uint32 AsScene1201Creature::hmPincerSnap(int messageNum, const MessageParam &param, Entity *sender) {
 
477
        uint32 messageResult = hmWaiting(messageNum, param, sender);
 
478
        switch (messageNum) {
 
479
        case NM_ANIMATION_STOP:
 
480
                gotoNextState();
 
481
                break;
 
482
        }
 
483
        return messageResult;
 
484
}
 
485
 
 
486
uint32 AsScene1201Creature::hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender) {
 
487
        uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
 
488
        switch (messageNum) {
 
489
        case NM_ANIMATION_START:
 
490
                if (param.asInteger() == 0x02060018) {
 
491
                        playSound(0, 0xCD298116);
 
492
                        sendMessage(_parentScene, 0x4814, 0);
 
493
                        sendMessage(_klaymen, 0x4814, 0);
 
494
                }
 
495
                break;
 
496
        case NM_ANIMATION_STOP:
 
497
                gotoNextState();
 
498
                break;
 
499
        }
 
500
        return messageResult;
 
501
}
 
502
 
 
503
void AsScene1201Creature::stWaiting() {
 
504
        startAnimation(0x08081513, 0, -1);
 
505
        SetMessageHandler(&AsScene1201Creature::hmWaiting);
 
506
        NextState(&AsScene1201Creature::stPincerSnap);
 
507
        _countdown = 36;
 
508
}
 
509
 
 
510
void AsScene1201Creature::stPincerSnap() {
 
511
        if (!_klaymenTooClose) {
 
512
                startAnimation(0xCA287133, 0, -1);
 
513
                SetMessageHandler(&AsScene1201Creature::hmPincerSnap);
 
514
                NextState(&AsScene1201Creature::stWaiting);
 
515
        }
 
516
}
 
517
 
 
518
void AsScene1201Creature::stStartReachForTntDummy() {
 
519
        startAnimation(0x08081513, 0, -1);
 
520
        SetMessageHandler(&AsScene1201Creature::hmWaiting);
 
521
        NextState(&AsScene1201Creature::stReachForTntDummy);
 
522
        _countdown = 48;
 
523
}
 
524
 
 
525
void AsScene1201Creature::stReachForTntDummy() {
 
526
        startAnimation(0x5A201453, 0, -1);
 
527
        SetMessageHandler(&AsScene1201Creature::hmWaiting);
 
528
        _countdown = 0;
 
529
}
 
530
 
 
531
void AsScene1201Creature::stPincerSnapKlaymen() {
 
532
        startAnimation(0xCA287133, 0, -1);
 
533
        SetMessageHandler(&AsScene1201Creature::hmPincerSnapKlaymen);
 
534
        NextState(&AsScene1201Creature::stWaiting);
 
535
        _countdown = 0;
 
536
}
 
537
 
 
538
AsScene1201LeftDoor::AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen)
 
539
        : AnimatedSprite(vm, 1100), _klaymen(klaymen) {
 
540
 
 
541
        _x = 320;
 
542
        _y = 240;
 
543
        createSurface(800, 55, 199);
 
544
        if (_klaymen->getX() < 100) {
 
545
                startAnimation(0x508A111B, 0, -1);
 
546
                _newStickFrameIndex = STICK_LAST_FRAME;
 
547
                playSound(0, calcHash("fxDoorOpen03"));
 
548
        } else {
 
549
                startAnimation(0x508A111B, -1, -1);
 
550
                _newStickFrameIndex = STICK_LAST_FRAME;
 
551
        }
 
552
        SetUpdateHandler(&AnimatedSprite::update);
 
553
        SetMessageHandler(&AsScene1201LeftDoor::handleMessage);
 
554
}
 
555
 
 
556
uint32 AsScene1201LeftDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
 
557
        uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
 
558
        switch (messageNum) {
 
559
        case NM_KLAYMEN_CLOSE_DOOR:
 
560
                stCloseDoor();
 
561
                break;
 
562
        }
 
563
        return messageResult;
 
564
}
 
565
 
 
566
void AsScene1201LeftDoor::stCloseDoor() {
 
567
        startAnimation(0x508A111B, -1, -1);
 
568
        _playBackwards = true;
 
569
        _newStickFrameIndex = 0;
 
570
}
 
571
 
 
572
static const NPoint kScene1202Points[] = {
 
573
        {203, 140}, {316, 212}, {277, 264},
 
574
        {176, 196}, {275, 159}, {366, 212},
 
575
        {230, 195}, {412, 212}, {368, 263},
 
576
        {204, 192}, {365, 164}, {316, 262},
 
577
        {191, 255}, {280, 213}, {406, 266},
 
578
        {214, 254}, {316, 158}, {402, 161}
 
579
};
 
580
 
 
581
static const uint32 kScene1202FileHashes[] = {
 
582
        0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
 
583
        0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
 
584
        0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
 
585
        0x1AC90B8, 0x1AC18B8, 0x1AC18B8,
 
586
        0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
 
587
        0x1AC50B8, 0x1AC14B8, 0x1AC14B8
 
588
};
 
589
 
 
590
AsScene1202TntItem::AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int itemIndex)
 
591
        : AnimatedSprite(vm, 900), _parentScene(parentScene), _itemIndex(itemIndex) {
 
592
 
 
593
        int positionIndex;
 
594
 
 
595
        SetUpdateHandler(&AnimatedSprite::update);
 
596
        SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
 
597
        positionIndex = getSubVar(VA_TNT_POSITIONS, _itemIndex);
 
598
        createSurface(900, 37, 67);
 
599
        _x = kScene1202Points[positionIndex].x;
 
600
        _y = kScene1202Points[positionIndex].y;
 
601
        stShowIdle();
 
602
}
 
603
 
 
604
uint32 AsScene1202TntItem::hmShowIdle(int messageNum, const MessageParam &param, Entity *sender) {
 
605
        uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
 
606
        switch (messageNum) {
 
607
        case 0x1011:
 
608
                sendMessage(_parentScene, 0x2000, _itemIndex);
 
609
                messageResult = 1;
 
610
                break;
 
611
        case 0x2001:
 
612
                _newPosition = (int)param.asInteger();
 
613
                stChangePositionFadeOut();
 
614
                break;
 
615
        }
 
616
        return messageResult;
 
617
}
 
618
 
 
619
uint32 AsScene1202TntItem::hmChangePosition(int messageNum, const MessageParam &param, Entity *sender) {
 
620
        uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
 
621
        switch (messageNum) {
 
622
        case NM_ANIMATION_STOP:
 
623
                gotoNextState();
 
624
                break;
 
625
        }
 
626
        return messageResult;
 
627
}
 
628
 
 
629
void AsScene1202TntItem::stShowIdle() {
 
630
        startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
 
631
        SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
 
632
        _newStickFrameIndex = 0;
 
633
}
 
634
 
 
635
void AsScene1202TntItem::stChangePositionFadeOut() {
 
636
        startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
 
637
        SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
 
638
        NextState(&AsScene1202TntItem::stChangePositionFadeIn);
 
639
}
 
640
 
 
641
void AsScene1202TntItem::stChangePositionFadeIn() {
 
642
        _x = kScene1202Points[_newPosition].x;
 
643
        _y = kScene1202Points[_newPosition].y;
 
644
        startAnimation(kScene1202FileHashes[_itemIndex], 6, -1);
 
645
        _playBackwards = true;
 
646
        SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
 
647
        NextState(&AsScene1202TntItem::stChangePositionDone);
 
648
}
 
649
 
 
650
void AsScene1202TntItem::stChangePositionDone() {
 
651
        sendMessage(_parentScene, NM_POSITION_CHANGE, _itemIndex);
 
652
        stShowIdle();
 
653
}
 
654
 
 
655
static const KlaymenIdleTableItem klaymenIdleTable1201[] = {
 
656
        {1, kIdleSpinHead},
 
657
        {1, kIdleChest},
 
658
        {1, kIdleHeadOff},
 
659
};
 
660
 
 
661
KmScene1201::KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
 
662
        : Klaymen(vm, parentScene, x, y) {
 
663
 
 
664
        setKlaymenIdleTable(klaymenIdleTable1201, ARRAYSIZE(klaymenIdleTable1201));
 
665
        _doYHitIncr = true;
 
666
}
 
667
 
 
668
uint32 KmScene1201::xHandleMessage(int messageNum, const MessageParam &param) {
 
669
        switch (messageNum) {
 
670
        case 0x4001:
 
671
        case 0x4800:
 
672
                startWalkToX(param.asPoint().x, false);
 
673
                break;
 
674
        case NM_KLAYMEN_STAND_IDLE:
 
675
                GotoState(&Klaymen::stTryStandIdle);
 
676
                break;
 
677
        case NM_KLAYMEN_MOVE_OBJECT:
 
678
                GotoState(&Klaymen::stMoveObject);
 
679
                break;
 
680
        case NM_KLAYMEN_PICKUP:
 
681
                GotoState(&Klaymen::stPickUpGeneric);
 
682
                break;
 
683
        case 0x4813:
 
684
                GotoState(&KmScene1201::stFetchMatch);
 
685
                break;
 
686
        case 0x4814:
 
687
                GotoState(&KmScene1201::stTumbleHeadless);
 
688
                break;
 
689
        case 0x4815:
 
690
                GotoState(&KmScene1201::stCloseEyes);
 
691
                break;
 
692
        case NM_KLAYMEN_PRESS_BUTTON:
 
693
                if (param.asInteger() == 0)
 
694
                        GotoState(&Klaymen::stPressButtonSide);
 
695
                break;
 
696
        case 0x4817:
 
697
                setDoDeltaX(param.asInteger());
 
698
                gotoNextStateExt();
 
699
                break;
 
700
        case 0x481B:
 
701
                if (param.asPoint().y != 0)
 
702
                        startWalkToXDistance(param.asPoint().y, param.asPoint().x);
 
703
                else
 
704
                        startWalkToAttachedSpriteXDistance(param.asPoint().x);
 
705
                break;
 
706
        case NM_KLAYMEN_TURN_TO_USE:
 
707
                GotoState(&Klaymen::stTurnToUse);
 
708
                break;
 
709
        case NM_KLAYMEN_RETURN_FROM_USE:
 
710
                GotoState(&Klaymen::stReturnFromUse);
 
711
                break;
 
712
        case 0x481F:
 
713
                GotoState(&Klaymen::stWonderAbout);
 
714
                break;
 
715
        case 0x482D:
 
716
                setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
 
717
                gotoNextStateExt();
 
718
                break;
 
719
        case 0x483F:
 
720
                startSpecialWalkRight(param.asInteger());
 
721
                break;
 
722
        case 0x4840:
 
723
                startSpecialWalkLeft(param.asInteger());
 
724
                break;
 
725
        }
 
726
        return 0;
 
727
}
 
728
 
 
729
void KmScene1201::stTumbleHeadless() {
 
730
        if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::stTumbleHeadless))) {
 
731
                _busyStatus = 1;
 
732
                _acceptInput = false;
 
733
                setDoDeltaX(0);
 
734
                startAnimation(0x2821C590, 0, -1);
 
735
                SetUpdateHandler(&Klaymen::update);
 
736
                SetMessageHandler(&KmScene1201::hmTumbleHeadless);
 
737
                SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
 
738
                NextState(&Klaymen::stTryStandIdle);
 
739
                sendMessage(_parentScene, 0x8000, 0);
 
740
                playSound(0, 0x62E0A356);
 
741
        }
 
742
}
 
743
 
 
744
void KmScene1201::stCloseEyes() {
 
745
        if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::stCloseEyes))) {
 
746
                _busyStatus = 1;
 
747
                _acceptInput = false;
 
748
                startAnimation(0x5420E254, 0, -1);
 
749
                SetUpdateHandler(&Klaymen::update);
 
750
                SetMessageHandler(&Klaymen::hmLowLevel);
 
751
                SetSpriteUpdate(NULL);
 
752
        }
 
753
}
 
754
 
 
755
uint32 KmScene1201::hmMatch(int messageNum, const MessageParam &param, Entity *sender) {
 
756
        uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
 
757
        switch (messageNum) {
 
758
        case NM_ANIMATION_START:
 
759
                if (param.asInteger() == 0x51281850) {
 
760
                        setGlobalVar(V_TNT_DUMMY_FUSE_LIT, 1);
 
761
                } else if (param.asInteger() == 0x43000538) {
 
762
                        playSound(0, 0x21043059);
 
763
                } else if (param.asInteger() == 0x02B20220) {
 
764
                        playSound(0, 0xC5408620);
 
765
                } else if (param.asInteger() == 0x0A720138) {
 
766
                        playSound(0, 0xD4C08010);
 
767
                } else if (param.asInteger() == 0xB613A180) {
 
768
                        playSound(0, 0x44051000);
 
769
                }
 
770
                break;
 
771
        }
 
772
        return messageResult;
 
773
}
 
774
 
 
775
void KmScene1201::stFetchMatch() {
 
776
        if (!stStartAction(AnimationCallback(&KmScene1201::stFetchMatch))) {
 
777
                _busyStatus = 0;
 
778
                _acceptInput = false;
 
779
                setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
 
780
                startAnimation(0x9CAA0218, 0, -1);
 
781
                SetUpdateHandler(&Klaymen::update);
 
782
                SetMessageHandler(&KmScene1201::hmMatch);
 
783
                SetSpriteUpdate(NULL);
 
784
                NextState(&KmScene1201::stLightMatch);
 
785
        }
 
786
}
 
787
 
 
788
void KmScene1201::stLightMatch() {
 
789
        _busyStatus = 1;
 
790
        _acceptInput = false;
 
791
        setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
 
792
        startAnimation(0x1222A513, 0, -1);
 
793
        SetUpdateHandler(&Klaymen::update);
 
794
        SetMessageHandler(&KmScene1201::hmMatch);
 
795
        SetSpriteUpdate(NULL);
 
796
}
 
797
 
 
798
uint32 KmScene1201::hmTumbleHeadless(int messageNum, const MessageParam &param, Entity *sender) {
 
799
        uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
 
800
        switch (messageNum) {
 
801
        case NM_ANIMATION_START:
 
802
                if (param.asInteger() == 0x000F0082) {
 
803
                        playSound(0, 0x74E2810F);
 
804
                }
 
805
                break;
 
806
        }
 
807
        return messageResult;
 
808
}
 
809
 
 
810
} // End of namespace Neverhood