scummvm/engines/neverhood/modules/module1300_sprites.cpp
2014-02-18 02:39:36 +01:00

936 lines
24 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "neverhood/modules/module1300_sprites.h"
namespace Neverhood {
AsScene1302Bridge::AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene)
: AnimatedSprite(vm, 1100), _parentScene(parentScene) {
_x = 320;
_y = 240;
createSurface1(0x88148150, 500);
if (!getGlobalVar(V_FLYTRAP_RING_BRIDGE)) {
startAnimation(0x88148150, 0, -1);
_newStickFrameIndex = 0;
} else {
startAnimation(0x88148150, -1, -1);
_newStickFrameIndex = STICK_LAST_FRAME;
}
loadSound(0, 0x68895082);
loadSound(1, 0x689BD0C1);
SetUpdateHandler(&AnimatedSprite::update);
SetMessageHandler(&AsScene1302Bridge::handleMessage);
}
uint32 AsScene1302Bridge::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case NM_ANIMATION_STOP:
gotoNextState();
break;
case NM_KLAYMEN_OPEN_DOOR:
stLowerBridge();
break;
case NM_KLAYMEN_CLOSE_DOOR:
stRaiseBridge();
break;
}
return messageResult;
}
void AsScene1302Bridge::stLowerBridge() {
startAnimation(0x88148150, 0, -1);
playSound(1);
NextState(&AsScene1302Bridge::cbLowerBridgeEvent);
}
void AsScene1302Bridge::stRaiseBridge() {
startAnimation(0x88148150, 7, -1);
_playBackwards = true;
_newStickFrameIndex = 0;
playSound(0);
}
void AsScene1302Bridge::cbLowerBridgeEvent() {
sendMessage(_parentScene, 0x2032, 0);
startAnimation(0x88148150, -1, -1);
_newStickFrameIndex = STICK_LAST_FRAME;
}
SsScene1302Fence::SsScene1302Fence(NeverhoodEngine *vm)
: StaticSprite(vm, 0x11122122, 200) {
_firstY = _y;
if (getGlobalVar(V_FLYTRAP_RING_FENCE))
_y += 152;
loadSound(0, 0x7A00400C);
loadSound(1, 0x78184098);
SetUpdateHandler(&SsScene1302Fence::update);
SetMessageHandler(&SsScene1302Fence::handleMessage);
SetSpriteUpdate(NULL);
}
void SsScene1302Fence::update() {
handleSpriteUpdate();
updatePosition();
}
uint32 SsScene1302Fence::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case NM_KLAYMEN_OPEN_DOOR:
playSound(0);
SetMessageHandler(NULL);
SetSpriteUpdate(&SsScene1302Fence::suMoveDown);
break;
case NM_KLAYMEN_CLOSE_DOOR:
playSound(1);
SetMessageHandler(NULL);
SetSpriteUpdate(&SsScene1302Fence::suMoveUp);
break;
}
return messageResult;
}
void SsScene1302Fence::suMoveDown() {
if (_y < _firstY + 152)
_y += 8;
else {
SetMessageHandler(&SsScene1302Fence::handleMessage);
SetSpriteUpdate(NULL);
}
}
void SsScene1302Fence::suMoveUp() {
if (_y > _firstY)
_y -= 8;
else {
SetMessageHandler(&SsScene1302Fence::handleMessage);
SetSpriteUpdate(NULL);
}
}
AsScene1303Balloon::AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene)
: AnimatedSprite(vm, 1100), _parentScene(parentScene) {
createSurface(200, 128, 315);
_x = 289;
_y = 390;
startAnimation(0x800278D2, 0, -1);
SetUpdateHandler(&AnimatedSprite::update);
SetMessageHandler(&AsScene1303Balloon::handleMessage);
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
}
uint32 AsScene1303Balloon::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case 0x1011:
sendMessage(_parentScene, 0x4826, 0);
messageResult = 1;
break;
case NM_ANIMATION_UPDATE:
stPopBalloon();
break;
}
return messageResult;
}
uint32 AsScene1303Balloon::hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case NM_ANIMATION_START:
if (param.asInteger() == 0x020B0003)
playSound(0, 0x742B0055);
break;
case NM_ANIMATION_STOP:
playSound(0, 0x470007EE);
stopAnimation();
setVisible(false);
SetMessageHandler(NULL);
break;
}
return messageResult;
}
void AsScene1303Balloon::stPopBalloon() {
startAnimation(0xAC004CD0, 0, -1);
SetMessageHandler(&AsScene1303Balloon::hmBalloonPopped);
}
AsScene1304Needle::AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y)
: AnimatedSprite(vm, 0x548E9411, surfacePriority, x, y), _parentScene(parentScene) {
// NOTE: Skipped check if Klaymen already has the needle since that's done in the scene itself
SetMessageHandler(&AsScene1304Needle::handleMessage);
}
uint32 AsScene1304Needle::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case 0x1011:
sendMessage(_parentScene, 0x4826, 0);
messageResult = 1;
break;
case NM_KLAYMEN_USE_OBJECT:
setGlobalVar(V_HAS_NEEDLE, 1);
setVisible(false);
SetMessageHandler(NULL);
break;
}
return messageResult;
}
AsScene1306Elevator::AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor)
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _asElevatorDoor(asElevatorDoor), _isUp(false), _isDown(true),
_countdown(0) {
_x = 320;
_y = 240;
createSurface1(0x043B0270, 100);
startAnimation(0x043B0270, 0, -1);
_newStickFrameIndex = 0;
loadSound(0, 0x1C100E83);
loadSound(1, 0x1C08CEC5);
loadSound(2, 0x5D011E87);
SetMessageHandler(&AsScene1306Elevator::handleMessage);
}
void AsScene1306Elevator::update() {
if (_isUp && _countdown != 0 && (--_countdown == 0))
stGoingDown();
AnimatedSprite::update();
if (_currFrameIndex == 7 && _asElevatorDoor->getVisible()) {
playSound(1);
_asElevatorDoor->setVisible(false);
}
}
void AsScene1306Elevator::upGoingDown() {
AnimatedSprite::update();
if (_currFrameIndex == 5)
_asElevatorDoor->setVisible(true);
}
uint32 AsScene1306Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case 0x2001:
if (_isUp)
_countdown = 144;
messageResult = _isUp ? 1 : 0;
break;
case NM_ANIMATION_STOP:
gotoNextState();
break;
case NM_KLAYMEN_OPEN_DOOR:
if (_isDown)
stGoingUp();
break;
}
return messageResult;
}
void AsScene1306Elevator::stGoingUp() {
setVisible(true);
_isDown = false;
startAnimation(0x043B0270, 0, -1);
playSound(0);
SetUpdateHandler(&AsScene1306Elevator::update);
NextState(&AsScene1306Elevator::cbGoingUpEvent);
}
void AsScene1306Elevator::cbGoingUpEvent() {
sendMessage(_parentScene, NM_KLAYMEN_OPEN_DOOR, 0);
_isUp = true;
_countdown = 144;
stopAnimation();
setVisible(false);
SetUpdateHandler(&AsScene1306Elevator::update);
}
void AsScene1306Elevator::stGoingDown() {
_isUp = false;
setVisible(true);
startAnimation(0x043B0270, -1, -1);
_playBackwards = true;
playSound(1);
SetUpdateHandler(&AsScene1306Elevator::upGoingDown);
NextState(&AsScene1306Elevator::cbGoingDownEvent);
}
void AsScene1306Elevator::cbGoingDownEvent() {
_isDown = true;
sendMessage(_parentScene, NM_KLAYMEN_CLOSE_DOOR, 0);
stopAnimation();
SetUpdateHandler(&AsScene1306Elevator::update);
}
static const uint32 kAsScene1307KeyResourceList1[] = {
0x0438069C, 0x45B0023C, 0x05700217
};
static const uint32 kAsScene1307KeyResourceList2[] = {
0x04441334, 0x061433F0, 0x06019390
};
static const uint32 kAsScene1307KeyResourceList3[] = {
0x11A80030, 0x178812B1, 0x1488121C
};
static const uint32 *kAsScene1307KeyResourceLists[] = {
kAsScene1307KeyResourceList1,
kAsScene1307KeyResourceList2,
kAsScene1307KeyResourceList3
};
static const int kAsScene1307KeySurfacePriorities[] = {
700, 500, 300, 100
};
const uint kAsScene1307KeyPointsCount = 12;
static const NPoint kAsScene1307KeyPoints[] = {
{-2, 0}, {-5, 0}, { 5, 0},
{12, 0}, {17, 0}, {25, 0},
{16, -2}, {10, -6}, { 0, -7},
{-7, -3}, {-3, 4}, { 2, 2}
};
const uint kAsScene1307KeyFrameIndicesCount = 20;
static const int16 kAsScene1307KeyFrameIndices[] = {
1, 4, 8, 11, 15, 16, 17, 17, 17, 16,
15, 14, 12, 10, 9, 7, 5, 3, 2, 1
};
const int kAsScene1307KeyDivValue = 200;
const int16 kAsScene1307KeyXDelta = 70;
const int16 kAsScene1307KeyYDelta = -12;
AsScene1307Key::AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects)
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _keyIndex(keyIndex), _clipRects(clipRects),
_isClickable(true) {
NPoint pt;
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
_dataResource.load(0x22102142);
_pointList = _dataResource.getPointArray(0xAC849240);
pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
_x = pt.x;
_y = pt.y;
createSurface(kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4], 190, 148);
startAnimation(fileHashes[0], 0, -1);
loadSound(0, 0xDC4A1280);
loadSound(1, 0xCC021233);
loadSound(2, 0xC4C23844);
loadSound(3, 0xC4523208);
SetUpdateHandler(&AnimatedSprite::update);
SetMessageHandler(&AsScene1307Key::handleMessage);
}
uint32 AsScene1307Key::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case 0x1011:
if (_isClickable) {
sendMessage(_parentScene, 0x4826, 0);
stRemoveKey();
messageResult = 1;
}
break;
case NM_ANIMATION_UPDATE:
_isClickable = param.asInteger() != 0;
break;
case 0x2001:
setSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex, param.asInteger());
stMoveKey();
break;
case 0x2003:
playSound(3);
stUnlock();
break;
case 0x2004:
playSound(2);
stInsert();
break;
}
return messageResult;
}
void AsScene1307Key::suRemoveKey() {
if (_pointIndex < kAsScene1307KeyPointsCount) {
_x += kAsScene1307KeyPoints[_pointIndex].x;
_y += kAsScene1307KeyPoints[_pointIndex].y;
updateBounds();
_pointIndex++;
} else {
SetSpriteUpdate(NULL);
}
}
void AsScene1307Key::suInsertKey() {
if (_pointIndex < kAsScene1307KeyPointsCount) {
_x -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].x;
_y -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].y;
updateBounds();
_pointIndex++;
if (_pointIndex == 7)
playSound(0);
} else {
SetSpriteUpdate(NULL);
sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
}
}
void AsScene1307Key::suMoveKey() {
if (_pointIndex < kAsScene1307KeyFrameIndicesCount) {
_frameIndex += kAsScene1307KeyFrameIndices[_pointIndex];
_x = _prevX + (_deltaX * _frameIndex) / kAsScene1307KeyDivValue;
_y = _prevY + (_deltaY * _frameIndex) / kAsScene1307KeyDivValue;
updateBounds();
_pointIndex++;
} else {
NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
_x = pt.x + kAsScene1307KeyXDelta;
_y = pt.y + kAsScene1307KeyYDelta;
stInsertKey();
}
}
void AsScene1307Key::stRemoveKey() {
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
_pointIndex = 0;
startAnimation(fileHashes[0], 0, -1);
playSound(1);
SetSpriteUpdate(&AsScene1307Key::suRemoveKey);
}
void AsScene1307Key::stInsertKey() {
_pointIndex = 0;
sendMessage(_parentScene, NM_PRIORITY_CHANGE, kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
setClipRect(_clipRects[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
_newStickFrameIndex = STICK_LAST_FRAME;
SetSpriteUpdate(&AsScene1307Key::suInsertKey);
}
void AsScene1307Key::stMoveKey() {
NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
int16 newX = pt.x + kAsScene1307KeyXDelta;
int16 newY = pt.y + kAsScene1307KeyYDelta;
sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1000);
setClipRect(0, 0, 640, 480);
_prevX = _x;
_prevY = _y;
if (newX == _x && newY == _y) {
stInsertKey();
} else {
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
_pointIndex = 0;
_frameIndex = 0;
_deltaX = newX - _x;
_deltaY = newY - _y;
startAnimation(fileHashes[0], 0, -1);
SetSpriteUpdate(&AsScene1307Key::suMoveKey);
}
}
void AsScene1307Key::stUnlock() {
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
startAnimation(fileHashes[1], 0, -1);
_newStickFrameIndex = STICK_LAST_FRAME;
}
void AsScene1307Key::stInsert() {
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
startAnimation(fileHashes[2], 0, -1);
_newStickFrameIndex = STICK_LAST_FRAME;
}
AsScene1308JaggyDoor::AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene)
: AnimatedSprite(vm, 0xBA0AE050, 1100, 320, 240), _parentScene(parentScene) {
setVisible(false);
stopAnimation();
SetMessageHandler(&AsScene1308JaggyDoor::handleMessage);
}
uint32 AsScene1308JaggyDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case NM_ANIMATION_STOP:
gotoNextState();
break;
case NM_KLAYMEN_OPEN_DOOR:
stOpenDoor();
break;
case NM_KLAYMEN_CLOSE_DOOR:
stCloseDoor();
break;
}
return messageResult;
}
void AsScene1308JaggyDoor::stOpenDoor() {
startAnimation(0xBA0AE050, 0, -1);
setVisible(true);
playSound(0, calcHash("fxDoorOpen38"));
NextState(&AsScene1308JaggyDoor::stOpenDoorDone);
}
void AsScene1308JaggyDoor::stOpenDoorDone() {
sendMessage(_parentScene, 0x2000, 0);
stopAnimation();
setVisible(false);
}
void AsScene1308JaggyDoor::stCloseDoor() {
startAnimation(0xBA0AE050, -1, -1);
_playBackwards = true;
setVisible(true);
playSound(0, calcHash("fxDoorClose38"));
NextState(&AsScene1308JaggyDoor::stCloseDoorDone);
}
void AsScene1308JaggyDoor::stCloseDoorDone() {
sendMessage(_parentScene, 0x2001, 0);
stopAnimation();
}
AsScene1308KeyboardDoor::AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene)
: AnimatedSprite(vm, 0xA08A0851, 1100, 320, 240), _parentScene(parentScene) {
playSound(0, 0x51456049);
SetMessageHandler(&AsScene1308KeyboardDoor::handleMessage);
NextState(&AsScene1308KeyboardDoor::stFallingKeys);
}
uint32 AsScene1308KeyboardDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case NM_ANIMATION_STOP:
gotoNextState();
break;
}
return messageResult;
}
void AsScene1308KeyboardDoor::stFallingKeys() {
startAnimation(0x6238B191, 0, -1);
_x = 580;
_y = 383;
NextState(&AsScene1308KeyboardDoor::stFallingKeysDone);
}
void AsScene1308KeyboardDoor::stFallingKeysDone() {
sendMessage(_parentScene, 0x2004, 0);
stopAnimation();
setVisible(false);
}
AsScene1308LightWallSymbols::AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene)
: AnimatedSprite(vm, 0x80180A10, 100, 320, 240), _parentScene(parentScene) {
setVisible(false);
stopAnimation();
Entity::_priority = 1200;
SetMessageHandler(&AsScene1308LightWallSymbols::handleMessage);
}
uint32 AsScene1308LightWallSymbols::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case NM_POSITION_CHANGE:
stFadeIn();
break;
case 0x2003:
stFadeOut();
break;
case NM_ANIMATION_STOP:
gotoNextState();
break;
}
return messageResult;
}
void AsScene1308LightWallSymbols::stFadeIn() {
startAnimation(0x80180A10, 0, -1);
setVisible(true);
_newStickFrameIndex = STICK_LAST_FRAME;
}
void AsScene1308LightWallSymbols::stFadeOut() {
startAnimation(0x80180A10, -1, -1);
_playBackwards = true;
NextState(&AsScene1308LightWallSymbols::stFadeOutDone);
}
void AsScene1308LightWallSymbols::stFadeOutDone() {
sendMessage(_parentScene, 0x2003, 0);
stopAnimation();
setVisible(false);
}
SsScene1308Number::SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index)
: StaticSprite(vm, fileHash, 100) {
setVisible(false);
_x = _spriteResource.getPosition().x + index * 20;
updatePosition();
}
AsScene1308Mouse::AsScene1308Mouse(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1100) {
_x = 286;
_y = 429;
createSurface1(0xA282C472, 100);
startAnimation(0xA282C472, 0, -1);
SetUpdateHandler(&AnimatedSprite::update);
SetMessageHandler(&AsScene1308Mouse::handleMessage);
}
uint32 AsScene1308Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case NM_ANIMATION_START:
if (param.asInteger() == 0x66382026)
playSound(0, 0x0CD84468);
else if (param.asInteger() == 0x6E28061C)
playSound(0, 0x78C8402C);
else if (param.asInteger() == 0x462F0410)
playSound(0, 0x60984E28);
break;
}
return messageResult;
}
KmScene1303::KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
// Empty
}
uint32 KmScene1303::xHandleMessage(int messageNum, const MessageParam &param) {
switch (messageNum) {
case 0x4804:
GotoState(&Klaymen::stPeekWall1);
break;
case 0x483B:
GotoState(&Klaymen::stPeekWallReturn);
break;
case 0x483C:
GotoState(&Klaymen::stPeekWall2);
break;
}
return 0;
}
KmScene1304::KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
// Empty
}
uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam &param) {
switch (messageNum) {
case 0x4001:
case 0x4800:
startWalkToX(param.asPoint().x, false);
break;
case NM_KLAYMEN_STAND_IDLE:
GotoState(&Klaymen::stTryStandIdle);
break;
case NM_KLAYMEN_PICKUP:
if (param.asInteger() == 2)
GotoState(&Klaymen::stPickUpNeedle);
else if (param.asInteger() == 1)
GotoState(&Klaymen::stPickUpTube);
else
GotoState(&Klaymen::stPickUpGeneric);
break;
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
break;
case 0x481B:
if (param.asPoint().y != 0)
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
else
startWalkToAttachedSpriteXDistance(param.asPoint().x);
break;
case 0x481F:
if (param.asInteger() == 1)
GotoState(&Klaymen::stTurnAwayFromUse);
else if (param.asInteger() == 0)
GotoState(&Klaymen::stTurnToUseHalf);
else
GotoState(&Klaymen::stWonderAbout);
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
}
return 0;
}
KmScene1305::KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
// Empty
}
uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam &param) {
switch (messageNum) {
case 0x4001:
case 0x4800:
startWalkToX(param.asPoint().x, false);
break;
case NM_KLAYMEN_STAND_IDLE:
GotoState(&Klaymen::stTryStandIdle);
break;
case 0x4804:
GotoState(&KmScene1305::stCrashDown);
break;
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
break;
}
return 0;
}
void KmScene1305::stCrashDown() {
playSound(0, 0x41648271);
_busyStatus = 1;
_acceptInput = false;
startAnimationByHash(0x000BAB02, 0x88003000, 0);
SetUpdateHandler(&Klaymen::update);
SetSpriteUpdate(NULL);
SetMessageHandler(&Klaymen::hmLowLevelAnimation);
NextState(&KmScene1305::stCrashDownFinished);
}
void KmScene1305::stCrashDownFinished() {
setDoDeltaX(2);
stTryStandIdle();
}
KmScene1306::KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
// Empty
}
uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam &param) {
uint32 messageResult = 0;
switch (messageNum) {
case NM_ANIMATION_UPDATE:
_isSittingInTeleporter = param.asInteger() != 0;
messageResult = 1;
break;
case 0x4001:
case 0x4800:
startWalkToX(param.asPoint().x, false);
break;
case NM_KLAYMEN_STAND_IDLE:
if (_isSittingInTeleporter)
GotoState(&Klaymen::stSitIdleTeleporter);
else
GotoState(&Klaymen::stTryStandIdle);
break;
case NM_KLAYMEN_PICKUP:
if (param.asInteger() == 2)
GotoState(&Klaymen::stPickUpNeedle);
else if (param.asInteger() == 1)
GotoState(&Klaymen::stPickUpTube);
else
GotoState(&Klaymen::stPickUpGeneric);
break;
case NM_KLAYMEN_PRESS_BUTTON:
if (param.asInteger() == 1)
GotoState(&Klaymen::stPressButton);
else if (param.asInteger() == 2)
GotoState(&Klaymen::stPressFloorButton);
else
GotoState(&Klaymen::stPressButtonSide);
break;
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
break;
case NM_KLAYMEN_INSERT_DISK:
GotoState(&Klaymen::stInsertDisk);
break;
case 0x481B:
if (param.asPoint().y != 0)
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
else
startWalkToAttachedSpriteXDistance(param.asPoint().x);
break;
case NM_KLAYMEN_TURN_TO_USE:
if (_isSittingInTeleporter)
GotoState(&Klaymen::stTurnToUseInTeleporter);
else
GotoState(&Klaymen::stTurnToUse);
break;
case NM_KLAYMEN_RETURN_FROM_USE:
if (_isSittingInTeleporter)
GotoState(&Klaymen::stReturnFromUseInTeleporter);
else
GotoState(&Klaymen::stReturnFromUse);
break;
case 0x481F:
if (param.asInteger() == 1)
GotoState(&Klaymen::stWonderAboutAfter);
else if (param.asInteger() == 0)
GotoState(&Klaymen::stWonderAboutHalf);
else if (param.asInteger() == 4)
GotoState(&Klaymen::stTurnAwayFromUse);
else if (param.asInteger() == 3)
GotoState(&Klaymen::stTurnToUseHalf);
else
GotoState(&Klaymen::stWonderAbout);
break;
case 0x482D:
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
gotoNextStateExt();
break;
case 0x482E:
if (param.asInteger() == 1)
GotoState(&Klaymen::stWalkToFrontNoStep);
else
GotoState(&Klaymen::stWalkToFront);
break;
case 0x482F:
if (param.asInteger() == 1)
GotoState(&Klaymen::stTurnToFront);
else
GotoState(&Klaymen::stTurnToBack);
break;
case 0x4834:
GotoState(&Klaymen::stStepOver);
break;
case 0x4835:
sendMessage(_parentScene, 0x2000, 1);
_isSittingInTeleporter = true;
GotoState(&Klaymen::stSitInTeleporter);
break;
case 0x4836:
sendMessage(_parentScene, 0x2000, 0);
_isSittingInTeleporter = false;
GotoState(&Klaymen::stGetUpFromTeleporter);
break;
case 0x483D:
teleporterAppear(0xEE084A04);
break;
case 0x483E:
teleporterDisappear(0xB86A4274);
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
}
return messageResult;
}
KmScene1308::KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
// Empty
}
uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam &param) {
switch (messageNum) {
case 0x4001:
case 0x4800:
startWalkToX(param.asPoint().x, false);
break;
case NM_KLAYMEN_STAND_IDLE:
GotoState(&Klaymen::stTryStandIdle);
break;
case NM_KLAYMEN_MOVE_OBJECT:
if (param.asInteger() == 1)
GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
else
GotoState(&Klaymen::stMoveObjectFaceObject);
break;
case 0x480D:
GotoState(&Klaymen::stUseLever);
break;
case NM_KLAYMEN_PICKUP:
if (param.asInteger() == 2)
GotoState(&Klaymen::stPickUpNeedle);
else if (param.asInteger() == 1)
GotoState(&Klaymen::stPickUpTube);
else
GotoState(&Klaymen::stPickUpGeneric);
break;
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
break;
case NM_KLAYMEN_INSERT_DISK:
if (param.asInteger() == 1)
GotoState(&Klaymen::stInsertKey);
else
GotoState(&Klaymen::stInsertDisk);
break;
case 0x481B:
if (param.asPoint().y != 0)
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
else
startWalkToAttachedSpriteXDistance(param.asPoint().x);
break;
case NM_KLAYMEN_TURN_TO_USE:
GotoState(&Klaymen::stTurnToUse);
break;
case NM_KLAYMEN_RETURN_FROM_USE:
GotoState(&Klaymen::stReturnFromUse);
break;
case NM_KLAYMEN_RELEASE_LEVER:
GotoState(&Klaymen::stReleaseLever);
break;
case 0x4834:
GotoState(&Klaymen::stStepOver);
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
}
return 0;
}
} // End of namespace Neverhood