aboutsummaryrefslogtreecommitdiff
path: root/engines/neverhood/modules/module2200_sprites.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/neverhood/modules/module2200_sprites.cpp')
-rw-r--r--engines/neverhood/modules/module2200_sprites.cpp1429
1 files changed, 1429 insertions, 0 deletions
diff --git a/engines/neverhood/modules/module2200_sprites.cpp b/engines/neverhood/modules/module2200_sprites.cpp
new file mode 100644
index 0000000000..30f0404cf1
--- /dev/null
+++ b/engines/neverhood/modules/module2200_sprites.cpp
@@ -0,0 +1,1429 @@
+/* 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/module2200_sprites.h"
+
+namespace Neverhood {
+
+AsScene2201CeilingFan::AsScene2201CeilingFan(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ _x = 403;
+ _y = 259;
+ createSurface(100, 233, 96);
+ startAnimation(0x8600866, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+}
+
+AsScene2201Door::AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen), _ssDoorLight(ssDoorLight), _countdown(0), _isOpen(isOpen) {
+
+ _x = 408;
+ _y = 290;
+ createSurface(900, 63, 266);
+ SetUpdateHandler(&AsScene2201Door::update);
+ SetMessageHandler(&AsScene2201Door::handleMessage);
+ if (_isOpen) {
+ startAnimation(0xE2CB0412, -1, -1);
+ _countdown = 48;
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(0xE2CB0412, 0, -1);
+ _newStickFrameIndex = 0;
+ _ssDoorLight->setVisible(false);
+ }
+}
+
+void AsScene2201Door::update() {
+ if (_countdown != 0 && _isOpen && (--_countdown == 0))
+ stCloseDoor();
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2201Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x11001090) {
+ if (_isOpen)
+ _ssDoorLight->setVisible(true);
+ } else if (param.asInteger() == 0x11283090) {
+ if (!_isOpen)
+ _ssDoorLight->setVisible(false);
+ }
+ break;
+ case 0x2000:
+ if (_isOpen)
+ _countdown = 144;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ _countdown = 144;
+ if (!_isOpen)
+ stOpenDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2201Door::stOpenDoor() {
+ _isOpen = true;
+ startAnimation(0xE2CB0412, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ playSound(0, calcHash("fxDoorOpen33"));
+}
+
+void AsScene2201Door::stCloseDoor() {
+ _isOpen = false;
+ startAnimation(0xE2CB0412, -1, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+ playSound(0, calcHash("fxDoorClose33"));
+}
+
+SsScene2201PuzzleCube::SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex)
+ : StaticSprite(vm, 900) {
+
+ createSurface(100, 16, 16);
+ loadSprite(kSsScene2201PuzzleCubeFileHashes[cubeIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 0,
+ kSsScene2201PuzzleCubePoints[positionIndex].x, kSsScene2201PuzzleCubePoints[positionIndex].y);
+}
+
+static const NPoint kSsScene2202PuzzleCubePoints[] = {
+ {196, 105}, {323, 102}, {445, 106},
+ {192, 216}, {319, 220}, {446, 216},
+ {188, 320}, {319, 319}, {443, 322}
+};
+
+static const uint32 kSsScene2202PuzzleCubeFileHashes1[] = {
+ 0xA500800C, 0x2182910C, 0x2323980C,
+ 0x23049084, 0x21008080, 0x2303900C,
+ 0x6120980C, 0x2504D808
+};
+
+static const uint32 kSsScene2202PuzzleCubeFileHashes2[] = {
+ 0x0AAD8080, 0x0A290291, 0x0A2BA398,
+ 0x822B8490, 0x86298080, 0x0A2B8390,
+ 0x0A69A098, 0x0E2D84D8
+};
+
+SsScene2202PuzzleCube::SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _cubeSymbol(cubeSymbol), _cubePosition(cubePosition), _isMoving(false) {
+
+ int surfacePriority;
+
+ SetUpdateHandler(&SsScene2202PuzzleCube::update);
+ SetMessageHandler(&SsScene2202PuzzleCube::handleMessage);
+ if (_cubePosition >= 0 && _cubePosition <= 2)
+ surfacePriority = 100;
+ else if (_cubePosition >= 3 && _cubePosition <= 5)
+ surfacePriority = 300;
+ else
+ surfacePriority = 500;
+ debug(1, "TODO: Unused SurfacePriority: %d", surfacePriority);
+ loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset | kSLFSetPosition | kSLFDefCollisionBoundsOffset, 0,
+ kSsScene2202PuzzleCubePoints[_cubePosition].x, kSsScene2202PuzzleCubePoints[_cubePosition].y);
+ loadSound(0, 0x40958621);
+ loadSound(1, 0x51108241);
+}
+
+void SsScene2202PuzzleCube::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 SsScene2202PuzzleCube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_isMoving && !getGlobalVar(V_TILE_PUZZLE_SOLVED))
+ sendMessage(_parentScene, 0x2000, _cubePosition);
+ messageResult = 1;
+ break;
+ case 0x2001:
+ _isMoving = true;
+ moveCube(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene2202PuzzleCube::suMoveCubeX() {
+
+ bool done = false;
+
+ if (_counterDirection) {
+ if (_counter > 2)
+ _counter -= 2;
+ } else {
+ if (_counter < 20)
+ _counter += 2;
+ }
+
+ for (int16 i = 0; i < _counter; i++) {
+ _x += _xIncr;
+ _errValue += _yDelta;
+ if (_errValue >= _xDelta) {
+ _errValue -= _xDelta;
+ _y += _yIncr;
+ }
+ if (_x == _newX && _y == _newY) {
+ done = true;
+ break;
+ }
+ if (_x == _xFlagPos)
+ _counterDirection = true;
+ }
+
+ if (done)
+ stopMoving();
+
+ updateBounds();
+
+}
+
+void SsScene2202PuzzleCube::suMoveCubeY() {
+
+ bool done = false;
+
+ if (_counterDirection) {
+ if (_counter > 2)
+ _counter -= 2;
+ } else {
+ if (_counter < 20)
+ _counter += 2;
+ }
+
+ for (int16 i = 0; i < _counter; i++) {
+ _y += _yIncr;
+ _errValue += _xDelta;
+ if (_errValue >= _yDelta) {
+ _errValue -= _yDelta;
+ _x += _xIncr;
+ }
+ if (_x == _newX && _y == _newY) {
+ done = true;
+ break;
+ }
+ if (_x == _xFlagPos)
+ _counterDirection = true;
+ }
+
+ if (done)
+ stopMoving();
+
+ updateBounds();
+
+}
+
+void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) {
+
+ loadSprite(kSsScene2202PuzzleCubeFileHashes1[_cubeSymbol], kSLFCenteredDrawOffset);
+
+ setSubVar(VA_CUBE_POSITIONS, _cubePosition, (uint32)-1);
+ setSubVar(VA_CUBE_POSITIONS, newCubePosition, (uint32)_cubeSymbol);
+
+ _cubePosition = newCubePosition;
+ _errValue = 0;
+ _counterDirection = false;
+ _counter = 0;
+ _newX = kSsScene2202PuzzleCubePoints[newCubePosition].x;
+ _newY = kSsScene2202PuzzleCubePoints[newCubePosition].y;
+
+ if (_x == _newX && _y == _newY)
+ return;
+
+ if (_x <= _newX) {
+ if (_y <= _newY) {
+ _xDelta = _newX - _x;
+ _yDelta = _newY - _y;
+ _xIncr = 1;
+ _yIncr = 1;
+ } else {
+ _xDelta = _newX - _x;
+ _yDelta = _y - _newY;
+ _xIncr = 1;
+ _yIncr = -1;
+ }
+ } else {
+ if (_y <= _newY) {
+ _xDelta = _x - _newX;
+ _yDelta = _newY - _y;
+ _xIncr = -1;
+ _yIncr = 1;
+ } else {
+ _xDelta = _x - _newX;
+ _yDelta = _y - _newY;
+ _xIncr = -1;
+ _yIncr = -1;
+ }
+ }
+
+ if (_xDelta > _yDelta) {
+ SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeX);
+ if (_xIncr > 0) {
+ if (_newX - _x >= 180)
+ _xFlagPos = _newX - 90;
+ else
+ _xFlagPos = _x + _newX / 2;
+ } else {
+ if (_x - _newX >= 180)
+ _xFlagPos = _x + 90;
+ else
+ _xFlagPos = _x / 2 + _newX;
+ }
+ playSound(0);
+ } else {
+ SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeY);
+ if (_yIncr > 0) {
+ if (_newY - _y >= 180)
+ _xFlagPos = _newY - 90;
+ else
+ _xFlagPos = _y + _newY / 2;
+ } else {
+ if (_y - _newY >= 180)
+ _xFlagPos = _y + 90;
+ else
+ _xFlagPos = _y / 2 + _newY;
+ }
+ playSound(1);
+ }
+
+}
+
+void SsScene2202PuzzleCube::stopMoving() {
+ loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset);
+ SetSpriteUpdate(NULL);
+ _isMoving = false;
+ sendMessage(_parentScene, 0x2002, _cubePosition);
+}
+
+static const uint32 kAsCommonKeyFileHashes[] = {
+ 0x2450D850, 0x0C9CE8D0, 0x2C58A152
+};
+
+AsCommonKey::AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y)
+ : AnimatedSprite(vm, kAsCommonKeyFileHashes[keyIndex], surfacePriority, x, y), _parentScene(parentScene), _keyIndex(keyIndex) {
+
+ if (!getSubVar(VA_HAS_KEY, _keyIndex) && !getSubVar(VA_IS_KEY_INSERTED, _keyIndex)) {
+ SetMessageHandler(&AsCommonKey::handleMessage);
+ } else {
+ // If Klaymen already has the key or it's already inserted then don't show it
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+}
+
+uint32 AsCommonKey::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 0x4806:
+ setSubVar(VA_HAS_KEY, _keyIndex, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+ return messageResult;
+}
+
+static const uint32 kAsScene2203DoorFileHashes[] = {
+ 0x7868AE10, 0x1A488110
+};
+
+AsScene2203Door::AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _doorIndex(doorIndex) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2203Door::handleMessage);
+ _x = 320;
+ _y = 240;
+ createSurface1(kAsScene2203DoorFileHashes[_doorIndex], 900);
+ if (getGlobalVar(V_LARGE_DOOR_NUMBER) == _doorIndex) {
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 0, -1);
+ _newStickFrameIndex = 0;
+ }
+}
+
+uint32 AsScene2203Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
+ sendMessage(_parentScene, 0x2002, 0);
+ else
+ sendMessage(_parentScene, 0x2001, 0);
+ messageResult = 1;
+ break;
+ case 0x2000:
+ _otherDoor = (Sprite*)param.asEntity();
+ break;
+ case 0x3002:
+ if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
+ sendMessage(_parentScene, 0x4808, 0);
+ stopAnimation();
+ break;
+ case 0x4808:
+ setGlobalVar(V_LARGE_DOOR_NUMBER, _doorIndex);
+ sendMessage(_otherDoor, 0x4809, 0);
+ openDoor();
+ break;
+ case 0x4809:
+ closeDoor();
+ sendMessage(_parentScene, 0x2003, 0);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2203Door::openDoor() {
+ playSound(0, 0x341014C4);
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 1, -1);
+}
+
+void AsScene2203Door::closeDoor() {
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+}
+
+SsScene2205DoorFrame::SsScene2205DoorFrame(NeverhoodEngine *vm)
+ : StaticSprite(vm, 900) {
+
+ SetMessageHandler(&SsScene2205DoorFrame::handleMessage);
+ createSurface(1100, 45, 206);
+ loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
+}
+
+uint32 SsScene2205DoorFrame::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
+ break;
+ }
+ return messageResult;
+}
+
+static const int16 kAsScene2206DoorSpikesXDeltasOpen[] = {
+ -24, -28, -18, 6, 9, -8
+};
+
+static const int16 kAsScene2206DoorSpikesXDeltasClose[] = {
+ -8, 7, 11, 26, 13, 14
+};
+
+AsScene2206DoorSpikes::AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash)
+ : StaticSprite(vm, fileHash, 200) {
+
+ if (getGlobalVar(V_SPIKES_RETRACTED))
+ _x -= 63;
+ SetUpdateHandler(&AsScene2206DoorSpikes::update);
+ SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene2206DoorSpikes::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene2206DoorSpikes::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4808:
+ _deltaIndex = 0;
+ playSound(0, 0x032746E0);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&AsScene2206DoorSpikes::suOpen);
+ break;
+ case 0x4809:
+ _deltaIndex = 0;
+ playSound(0, 0x002642C0);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&AsScene2206DoorSpikes::suClose);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2206DoorSpikes::suOpen() {
+ if (_deltaIndex < 6) {
+ _x += kAsScene2206DoorSpikesXDeltasOpen[_deltaIndex];
+ _deltaIndex++;
+ } else {
+ SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene2206DoorSpikes::suClose() {
+ if (_deltaIndex < 6) {
+ _x += kAsScene2206DoorSpikesXDeltasClose[_deltaIndex];
+ _deltaIndex++;
+ } else {
+ SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+AsScene2206Platform::AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash)
+ : StaticSprite(vm, fileHash, 50) {
+
+ SetUpdateHandler(&AsScene2206Platform::update);
+ SetMessageHandler(&AsScene2206Platform::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene2206Platform::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene2206Platform::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4803:
+ _yDelta = 0;
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&AsScene2206Platform::suMoveDown);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2206Platform::suMoveDown() {
+ _yDelta++;
+ _y += _yDelta;
+}
+
+SsScene2206TestTube::SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash)
+ : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene) {
+
+ if (getGlobalVar(V_HAS_TEST_TUBE)) {
+ setVisible(false);
+ SetMessageHandler(NULL);
+ } else
+ SetMessageHandler(&SsScene2206TestTube::handleMessage);
+ _collisionBoundsOffset = _drawOffset;
+ updateBounds();
+}
+
+uint32 SsScene2206TestTube::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 0x4806:
+ setGlobalVar(V_HAS_TEST_TUBE, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2207Elevator::AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 900), _parentScene(parentScene), _pointIndex(0), _destPointIndex(0), _destPointIndexDelta(0) {
+
+ NPoint pt;
+
+ _dataResource.load(0x00524846);
+ _pointArray = _dataResource.getPointArray(0x005B02B7);
+ pt = _dataResource.getPoint(0x403A82B1);
+ _x = pt.x;
+ _y = pt.y;
+ createSurface(1100, 129, 103);
+ startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, 0, 0);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AsScene2207Elevator::update);
+ SetMessageHandler(&AsScene2207Elevator::handleMessage);
+ SetSpriteUpdate(&AsScene2207Elevator::suSetPosition);
+}
+
+AsScene2207Elevator::~AsScene2207Elevator() {
+ _vm->_soundMan->deleteSoundGroup(0x02700413);
+}
+
+void AsScene2207Elevator::update() {
+
+ if (_destPointIndex + _destPointIndexDelta > _pointIndex) {
+ _pointIndex++;
+ startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
+ _newStickFrameIndex = _pointIndex;
+ if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
+ if (_destPointIndexDelta != 0)
+ _destPointIndexDelta = 0;
+ else {
+ _vm->_soundMan->deleteSound(0xD3B02847);
+ playSound(0, 0x53B8284A);
+ }
+ }
+ }
+
+ if (_destPointIndex + _destPointIndexDelta < _pointIndex) {
+ _pointIndex--;
+ if (_pointIndex == 0)
+ sendMessage(_parentScene, 0x2003, 0);
+ startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
+ _newStickFrameIndex = _pointIndex;
+ if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
+ if (_destPointIndexDelta != 0)
+ _destPointIndexDelta = 0;
+ else {
+ _vm->_soundMan->deleteSound(0xD3B02847);
+ playSound(0, 0x53B8284A);
+ }
+ }
+ }
+
+ if (_pointIndex > 20 && _surface->getPriority() != 900)
+ sendMessage(_parentScene, 0x2002, 900);
+ else if (_pointIndex < 20 && _surface->getPriority() != 1100)
+ sendMessage(_parentScene, 0x2002, 1100);
+
+ AnimatedSprite::update();
+
+ if (_destPointIndex + _destPointIndexDelta == _pointIndex && _isMoving) {
+ sendMessage(_parentScene, 0x2004, 0);
+ _isMoving = false;
+ }
+
+}
+
+void AsScene2207Elevator::suSetPosition() {
+ _x = (*_pointArray)[_pointIndex].x;
+ _y = (*_pointArray)[_pointIndex].y - 60;
+ updateBounds();
+}
+
+uint32 AsScene2207Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ moveToY(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207Elevator::moveToY(int16 y) {
+ int16 minDistance = 480;
+
+ if (!_pointArray || _pointArray->size() == 0)
+ return;
+
+ for (uint i = 0; i < _pointArray->size(); i++) {
+ int16 distance = ABS(y - (*_pointArray)[i].y);
+ if (distance < minDistance) {
+ minDistance = distance;
+ _destPointIndex = i;
+ }
+ }
+
+ if (_destPointIndex != _pointIndex) {
+ if (_destPointIndex == 0 || _destPointIndex == (int)_pointArray->size() - 1)
+ _destPointIndexDelta = 0;
+ else if (_destPointIndex < _pointIndex)
+ _destPointIndexDelta = -2;
+ else
+ _destPointIndexDelta = 2;
+ _vm->_soundMan->addSound(0x02700413, 0xD3B02847);
+ _vm->_soundMan->playSoundLooping(0xD3B02847);
+ }
+
+ _isMoving = true;
+
+}
+
+AsScene2207Lever::AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ _x = x;
+ _y = y;
+ createSurface(1010, 71, 73);
+ setDoDeltaX(doDeltaX);
+ startAnimation(0x80880090, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2207Lever::handleMessage);
+}
+
+uint32 AsScene2207Lever::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 0x3002:
+ gotoNextState();
+ stopAnimation();
+ break;
+ case 0x4807:
+ stLeverUp();
+ break;
+ case 0x480F:
+ stLeverDown();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207Lever::stLeverDown() {
+ startAnimation(0x80880090, 1, -1);
+ playSound(0, 0x40581882);
+ FinalizeState(&AsScene2207Lever::stLeverDownEvent);
+}
+
+void AsScene2207Lever::stLeverDownEvent() {
+ sendMessage(_parentScene, 0x480F, 0);
+}
+
+void AsScene2207Lever::stLeverUp() {
+ startAnimation(0x80880090, 6, -1);
+ _playBackwards = true;
+ playSound(0, 0x40581882);
+ FinalizeState(&AsScene2207Lever::stLeverUpEvent);
+}
+
+void AsScene2207Lever::stLeverUpEvent() {
+ sendMessage(_parentScene, 0x4807, 0);
+}
+
+AsScene2207WallRobotAnimation::AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1200), _idle(true) {
+
+ _x = 309;
+ _y = 320;
+ createSurface1(0xCCFD6090, 100);
+ startAnimation(0xCCFD6090, 0, -1);
+ _newStickFrameIndex = 0;
+ loadSound(1, 0x40330872);
+ loadSound(2, 0x72A2914A);
+ loadSound(3, 0xD4226080);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2207WallRobotAnimation::handleMessage);
+}
+
+AsScene2207WallRobotAnimation::~AsScene2207WallRobotAnimation() {
+ _vm->_soundMan->deleteSoundGroup(0x80D00820);
+}
+
+uint32 AsScene2207WallRobotAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (!_idle) {
+ if (param.asInteger() == 0x3423093) {
+ _vm->_soundMan->addSound(0x80D00820, 0x12121943);
+ _vm->_soundMan->playSoundLooping(0x12121943);
+ } else if (param.asInteger() == 0x834AB011) {
+ stopSound(0);
+ stopSound(1);
+ stopSound(2);
+ stopSound(3);
+ _vm->_soundMan->deleteSound(0x12121943);
+ } else if (param.asInteger() == 0x3A980501)
+ playSound(1);
+ else if (param.asInteger() == 0x2A2AD498)
+ playSound(2);
+ else if (param.asInteger() == 0xC4980008)
+ playSound(3);
+ else if (param.asInteger() == 0x06B84228)
+ playSound(0, 0xE0702146);
+ }
+ break;
+ case 0x2006:
+ stStartAnimation();
+ break;
+ case 0x2007:
+ stStopAnimation();
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207WallRobotAnimation::stStartAnimation() {
+ if (!_idle) {
+ NextState(NULL);
+ } else {
+ startAnimation(0xCCFD6090, 0, -1);
+ _idle = false;
+ setVisible(true);
+ }
+}
+
+void AsScene2207WallRobotAnimation::stStopAnimation() {
+ NextState(&AsScene2207WallRobotAnimation::cbStopAnimation);
+}
+
+void AsScene2207WallRobotAnimation::cbStopAnimation() {
+ stopAnimation();
+ stopSound(0);
+ stopSound(1);
+ stopSound(2);
+ stopSound(3);
+ _vm->_soundMan->deleteSound(0x12121943);
+ _idle = true;
+ setVisible(false);
+}
+
+AsScene2207WallCannonAnimation::AsScene2207WallCannonAnimation(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200), _idle(true) {
+
+ _x = 309;
+ _y = 320;
+ createSurface1(0x8CAA0099, 100);
+ startAnimation(0x8CAA0099, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2207WallCannonAnimation::handleMessage);
+}
+
+uint32 AsScene2207WallCannonAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2006:
+ stStartAnimation();
+ break;
+ case 0x2007:
+ stStopAnimation();
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207WallCannonAnimation::stStartAnimation() {
+ if (!_idle) {
+ NextState(NULL);
+ } else {
+ setVisible(true);
+ startAnimation(0x8CAA0099, 0, -1);
+ _idle = false;
+ }
+}
+
+void AsScene2207WallCannonAnimation::stStopAnimation() {
+ NextState(&AsScene2207WallCannonAnimation::cbStopAnimation);
+}
+
+void AsScene2207WallCannonAnimation::cbStopAnimation() {
+ stopAnimation();
+ setVisible(false);
+ _idle = true;
+}
+
+SsScene2207Symbol::SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index)
+ : StaticSprite(vm, fileHash, 100) {
+
+ _x = 330;
+ _y = 246 + index * 50;
+ updatePosition();
+}
+
+KmScene2201::KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _surface->setClipRects(clipRects, clipRectsCount);
+ _dataResource.load(0x04104242);
+}
+
+uint32 KmScene2201::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ 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 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene2203::KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ 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 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x4819:
+ GotoState(&KmScene2203::stClayDoorOpen);
+ break;
+ case 0x481A:
+ 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 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene2203::stClayDoorOpen() {
+ if (!stStartAction(AnimationCallback(&KmScene2203::stClayDoorOpen))) {
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x5CCCB330, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2203::hmClayDoorOpen);
+ SetSpriteUpdate(&Klaymen::suUpdateDestX);
+ }
+}
+
+uint32 KmScene2203::hmClayDoorOpen(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x040D4186) {
+ sendMessage(_attachedSprite, 0x4808, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2205::KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+void KmScene2205::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2205::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene2206::KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _walkResumeFrameIncr = 1;
+ _vm->_soundMan->addSound(0x80101800, 0xD3B02847);
+}
+
+KmScene2206::~KmScene2206() {
+ _vm->_soundMan->deleteSoundGroup(0x80101800);
+}
+
+void KmScene2206::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ GotoState(&KmScene2206::stRidePlatformDown);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ 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 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ 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 0x4837:
+ stopWalking();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene2206::suRidePlatformDown() {
+ _platformDeltaY++;
+ _y += _platformDeltaY;
+ if (_y > 600)
+ sendMessage(this, 0x1019, 0);
+}
+
+void KmScene2206::stRidePlatformDown() {
+ if (!stStartActionFromIdle(AnimationCallback(&KmScene2206::stRidePlatformDown))) {
+ _busyStatus = 1;
+ sendMessage(_parentScene, 0x4803, 0);
+ _acceptInput = false;
+ _platformDeltaY = 0;
+ startAnimation(0x5420E254, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevel);
+ SetSpriteUpdate(&KmScene2206::suRidePlatformDown);
+ _vm->_soundMan->playSoundLooping(0xD3B02847);
+ }
+}
+
+KmScene2207::KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x2001:
+ GotoState(&Klaymen::stRidePlatform);
+ break;
+ case 0x2005:
+ suRidePlatform();
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stInteractLever);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ 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 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x4827:
+ GotoState(&Klaymen::stReleaseLever);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene2242::KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+void KmScene2242::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2242::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4812:
+ 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() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmHallOfRecords::KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+ // Empty
+}
+
+void KmHallOfRecords::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmHallOfRecords::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmScene2247::KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+void KmScene2247::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood