/* 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/klayman.h" #include "neverhood/collisionman.h" #include "neverhood/resourceman.h" #include "neverhood/staticdata.h" namespace Neverhood { static const KlaymanIdleTableItem klaymanTable1[] = { {1, &Klayman::stDoIdlePickEar}, {1, &Klayman::sub41FDA0}, {1, &Klayman::sub41FDF0}, {1, &Klayman::stDoIdleChest}, {1, &Klayman::sub41FEB0} }; static const KlaymanIdleTableItem klaymanTable2[] = { {1, &Klayman::stDoIdlePickEar}, {1, &Klayman::sub41FDA0}, {1, &Klayman::stDoIdleChest}, {1, &Klayman::sub41FEB0} }; #if 0 static const KlaymanIdleTableItem klaymanTable3[] = { {1, &Klayman::sub421430}, {1, &Klayman::sub421480} }; #endif static const KlaymanIdleTableItem klaymanTable4[] = { {1, &Klayman::sub41FDA0}, {1, &Klayman::stDoIdleChest}, {1, &Klayman::sub41FEB0}, }; // Klayman Klayman::Klayman(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, int surfacePriority, int objectPriority, NRectArray *clipRects) : AnimatedSprite(vm, objectPriority), _soundResource1(vm), _soundResource2(vm), _counterMax(0), _counter(0), _isMoveObjectRequested(false), _counter3Max(0), _isWalkingOpenDoorNotified(false), _counter1(0), _counter2(0), /*_field118(0), */_status2(0), _acceptInput(true), _attachedSprite(NULL), _isWalking(false), _status3(1), _parentScene(parentScene), _isSneaking(false), _isLargeStep(false), _flagF6(false), _isLeverDown(false), _flagFA(false), _ladderStatus(0), _pathPoints(NULL), _resourceHandle(-1), _soundFlag(false) { // TODO DirtySurface createSurface(surfacePriority, 320, 200); _x = x; _y = y; _destX = x; _destY = y; _flags = 2; setKlaymanIdleTable1(); stTryStandIdle(); SetUpdateHandler(&Klayman::update); } void Klayman::xUpdate() { // Empty } uint32 Klayman::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4818: startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; } return 0; } void Klayman::update() { AnimatedSprite::update(); xUpdate(); } void Klayman::setKlaymanIdleTable(const KlaymanIdleTableItem *table, int tableCount) { _idleTable = table; _idleTableCount = tableCount; _idleTableMaxValue = 0; for (int i = 0; i < tableCount; i++) { _idleTableMaxValue += table[i].value; } } void Klayman::setKlaymanIdleTable1() { setKlaymanIdleTable(klaymanTable1, ARRAYSIZE(klaymanTable1)); } void Klayman::setKlaymanIdleTable2() { setKlaymanIdleTable(klaymanTable2, ARRAYSIZE(klaymanTable2)); } void Klayman::setKlaymanIdleTable3() { // TODO setKlaymanIdleTable(klaymanTable3, ARRAYSIZE(klaymanTable3)); } void Klayman::stDoIdlePickEar() { startIdleAnimation(0x5B20C814, AnimationCallback(&Klayman::stIdlePickEar)); } void Klayman::stIdlePickEar() { _status2 = 1; _acceptInput = true; startAnimation(0x5B20C814, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmIdlePickEar); SetSpriteUpdate(NULL); NextState(&Klayman::stStandAround); FinalizeState(&Klayman::evIdlePickEarDone); } uint32 Klayman::hmIdlePickEar(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x04DBC02C) { _soundResource1.play(0x44528AA1); } break; } return messageResult; } void Klayman::evIdlePickEarDone() { _soundResource1.stop(); } void Klayman::sub41FDA0() { startIdleAnimation(0xD122C137, AnimationCallback(&Klayman::sub41FDB0)); } void Klayman::sub41FDB0() { _status2 = 1; _acceptInput = true; startAnimation(0xD122C137, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41E980); SetSpriteUpdate(NULL); NextState(&Klayman::stStandAround); } uint32 Klayman::handleMessage41E980(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x808A0008) { _soundResource1.play(0xD948A340); } break; } return messageResult; } void Klayman::sub41FDF0() { startIdleAnimation(0x543CD054, AnimationCallback(&Klayman::sub41FE00)); } void Klayman::sub41FE00() { _status2 = 1; _acceptInput = true; startAnimation(0x543CD054, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41E9E0); SetSpriteUpdate(NULL); NextState(&Klayman::stStandAround); FinalizeState(&Klayman::sub41FE50); } void Klayman::sub41FE50() { _soundResource1.stop(); } uint32 Klayman::handleMessage41E9E0(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x5A0F0104) { _soundResource1.play(0x7970A100); } else if (param.asInteger() == 0x9A9A0109) { _soundResource1.play(0xD170CF04); } else if (param.asInteger() == 0x989A2169) { _soundResource1.play(0xD073CF14); } break; } return messageResult; } void Klayman::stDoIdleChest() { startIdleAnimation(0x40A0C034, AnimationCallback(&Klayman::stIdleChest)); } void Klayman::stIdleChest() { _status2 = 1; _acceptInput = true; startAnimation(0x40A0C034, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmIdleChest); SetSpriteUpdate(NULL); NextState(&Klayman::stStandAround); } uint32 Klayman::hmIdleChest(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x0D2A0288) { _soundResource1.play(0xD192A368); } break; } return messageResult; } void Klayman::sub41FEB0() { startIdleAnimation(0x5120E137, AnimationCallback(&Klayman::sub41FEC0)); } void Klayman::sub41FEC0() { _status2 = 1; _acceptInput = true; startAnimation(0x5120E137, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EFE0); SetSpriteUpdate(NULL); NextState(&Klayman::stStandAround); } uint32 Klayman::handleMessage41EFE0(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0xC006000C) { _soundResource1.play(0x9D406340); } else if (param.asInteger() == 0x2E4A2940) { _soundResource1.play(0x53A4A1D4); } else if (param.asInteger() == 0xAA0A0860) { _soundResource1.play(0x5BE0A3C6); } else if (param.asInteger() == 0xC0180260) { _soundResource1.play(0x5D418366); } break; } return messageResult; } void Klayman::sub421350() { _status2 = 0; _acceptInput = true; startAnimation(0x582EC138, 0, -1); _counter = 0; SetSpriteUpdate(NULL); SetUpdateHandler(&Klayman::update41D1C0); SetMessageHandler(&Klayman::handleMessage41D360); _counter3 = 0; _counterMax = 8; _counter3Max = _vm->_rnd->getRandomNumber(64 - 1) + 24; } void Klayman::update41D1C0() { update(); _counter++; if (_counter >= _counterMax) { _counter = 0; if (_idleTable) { int randomValue = _vm->_rnd->getRandomNumber(_idleTableMaxValue); for (int i = 0; i < _idleTableCount; i++) { if (randomValue < _idleTable[_idleTableCount].value) { (this->*(_idleTable[_idleTableCount].callback))(); _counterMax = _vm->_rnd->getRandomNumber(128) + 24; break; } randomValue -= _idleTable[_idleTableCount].value; } } } else { _counter3++; if (_counter3 >= _counter3Max) { _counter3 = 0; _counter3Max = _vm->_rnd->getRandomNumber(64) + 24; stIdleSitBlink(); } } } void Klayman::stIdleSitBlink() { _status2 = 0; _acceptInput = true; startAnimation(0x5C24C018, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(NULL); NextState(&Klayman::stIdleSitBlinkSecond); } void Klayman::stIdleSitBlinkSecond() { _status2 = 0; _acceptInput = true; startAnimation(0x5C24C018, 0, -1); SetUpdateHandler(&Klayman::update41D1C0); SetMessageHandler(&Klayman::handleMessage41D360); SetSpriteUpdate(NULL); } void Klayman::stPickUpNeedle() { setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0); if (!stStartAction(AnimationCallback(&Klayman::stPickUpNeedle))) { _status2 = 1; _acceptInput = false; startAnimation(0x1449C169, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmPickUpGeneric); SetSpriteUpdate(NULL); } } void Klayman::sub41FFF0() { setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0); if (!stStartAction(AnimationCallback(&Klayman::sub41FFF0))) { _status2 = 1; _acceptInput = false; startAnimation(0x0018C032, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D640); SetSpriteUpdate(NULL); } } uint32 Klayman::handleMessage41D640(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0xC1380080) { if (_attachedSprite) { sendMessage(_attachedSprite, 0x4806, 0); _soundResource1.play(0xC8004340); } } else if (param.asInteger() == 0x02B20220) { _soundResource1.play(0xC5408620); } else if (param.asInteger() == 0x03020231) { _soundResource1.play(0xD4C08010); } else if (param.asInteger() == 0x67221A03) { _soundResource1.play(0x44051000); } else if (param.asInteger() == 0x925A0C1E) { _soundResource1.play(0x40E5884D); } break; } return messageResult; } void Klayman::stTurnToUseInTeleporter() { _status2 = 0; _acceptInput = false; startAnimation(0xD229823D, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(NULL); } void Klayman::stReturnFromUseInTeleporter() { _status2 = 0; _acceptInput = false; startAnimation(0x9A2801E0, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(NULL); } void Klayman::stStepOver() { if (!stStartAction(AnimationCallback(&Klayman::stStepOver))) { _status2 = 2; _acceptInput = false; startAnimation(0x004AA310, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmStartWalking); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } } void Klayman::stSitInTeleporter() { if (!stStartAction(AnimationCallback(&Klayman::stSitInTeleporter))) { _status2 = 0; _acceptInput = false; startAnimation(0x392A0330, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmSitInTeleporter); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } } uint32 Klayman::hmSitInTeleporter(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x001A2832) { _soundResource1.play(0xC0E4884C); } break; } return messageResult; } void Klayman::stGetUpFromTeleporter() { _status2 = 0; _acceptInput = false; startAnimation(0x913AB120, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } ///////////////////////////////////////////////////////////////// void Klayman::sub41CE70() { _destX = _x; if (!_isWalking && !_isSneaking && !_isLargeStep) { gotoState(NULL); gotoNextStateExt(); } } void Klayman::startIdleAnimation(uint32 fileHash, AnimationCb callback) { _resourceHandle = _vm->_res->useResource(fileHash); if (_resourceHandle != -1) { // TODO _vm->_res->moveToFront(_resourceHandle); NextState(callback); SetUpdateHandler(&Klayman::upIdleAnimation); } } void Klayman::upIdleAnimation() { // TODO Check if this odd stuff is needed or just some cache optimization if (_vm->_res->isResourceDataValid(_resourceHandle)) { gotoNextStateExt(); // TODO _vm->_res->moveToBack(_resourceHandle); _vm->_res->unuseResource(_resourceHandle); _resourceHandle = -1; } else { // TODO _vm->_res->moveToFront(_resourceHandle); } update(); } bool Klayman::stStartActionFromIdle(AnimationCb callback) { if (_status2 == 2) { _status2 = 1; _acceptInput = false; startAnimation(0x9A7020B8, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmStartAction); SetSpriteUpdate(NULL); NextState(callback); return true; } return false; } void Klayman::gotoNextStateExt() { if (_finalizeStateCb) { AnimationCb cb = _finalizeStateCb; _finalizeStateCb = NULL; (this->*cb)(); } if (_nextStateCb) { AnimationCb cb = _nextStateCb; _nextStateCb = NULL; (this->*cb)(); #if 0 // TODO } else if (_callbackList) { removeCallbackList(); #endif } else { sendMessage(_parentScene, 0x1006, 0); } } void Klayman::sub41C770() { _flagFA = false; _status3 = 1; } void Klayman::sub41C790() { if (_flagFA) _status3 = 0; } void Klayman::stTryStandIdle() { if (!stStartActionFromIdle(AnimationCallback(&Klayman::stTryStandIdle))) { _status2 = 1; _acceptInput = true; startAnimation(0x5420E254, 0, -1); _counter = 0; _counter3 = 0; _counter3Max = _vm->_rnd->getRandomNumber(64) + 24; SetUpdateHandler(&Klayman::update41D0F0); SetMessageHandler(&Klayman::handleMessage41D360); SetSpriteUpdate(NULL); } } void Klayman::update41D0F0() { update(); if (++_counter >= 720) { _counter = 0; if (_idleTable) { int randomValue = _vm->_rnd->getRandomNumber(_idleTableMaxValue); for (int i = 0; i < _idleTableCount; i++) { if (randomValue < _idleTable[_idleTableCount].value) { (this->*(_idleTable[_idleTableCount].callback))(); break; } randomValue -= _idleTable[_idleTableCount].value; } } } else if (++_counter3 >= _counter3Max) { _counter3 = 0; _counter3Max = _vm->_rnd->getRandomNumber(64) + 24; stStand(); } } uint32 Klayman::handleMessage41D360(int messageNum, const MessageParam ¶m, Entity *sender) { Sprite::handleMessage(messageNum, param, sender); uint32 messageResult = xHandleMessage(messageNum, param); switch (messageNum) { case 0x1008: messageResult = _acceptInput; break; case 0x1014: _attachedSprite = (Sprite*)(param.asEntity()); break; case 0x1019: gotoNextStateExt(); break; case 0x101C: sub41C770(); break; case 0x1021: sub41C790(); break; case 0x481C: _status3 = param.asInteger(); _flagFA = true; messageResult = 1; break; case 0x482C: if (param.asInteger() != 0) { _pathPoints = _dataResource.getPointArray(param.asInteger()); } else { _pathPoints = NULL; } break; } return messageResult; } void Klayman::stStand() { _status2 = 1; _acceptInput = true; startAnimation(0x5900C41E, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(NULL); NextState(&Klayman::stStandAround); } uint32 Klayman::handleMessage41D480(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D360(messageNum, param, sender); switch (messageNum) { case 0x3002: gotoNextStateExt(); break; } return messageResult; } void Klayman::stStandAround() { _status2 = 1; _acceptInput = true; startAnimation(0x5420E254, 0, -1); SetUpdateHandler(&Klayman::update41D0F0); SetMessageHandler(&Klayman::handleMessage41D360); SetSpriteUpdate(NULL); } uint32 Klayman::hmStartAction(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x271AA210) { _soundResource1.play(0x4924AAC4); } else if (param.asInteger() == 0x2B22AA81) { _soundResource1.play(0x0A2AA8E0); } break; } return messageResult; } void Klayman::startWalkToX(int16 x, bool flag) { int16 xdiff = ABS(x - _x); if (x == _x) { _destX = x; if (!_isWalking && !_isSneaking && !_isLargeStep) { gotoState(NULL); gotoNextStateExt(); } } else if (xdiff <= 36 && !_isWalking && !_isSneaking && !_isLargeStep) { _destX = x; gotoState(NULL); gotoNextStateExt(); } else if (xdiff <= 42 && _status3 != 3) { if (_isSneaking && ((!_doDeltaX && x - _x > 0) || (_doDeltaX && x - _x < 0)) && ABS(_destX - _x) > xdiff) { _destX = x; } else { _destX = x; GotoState(&Klayman::stSneak); } } else if (_isWalking && ((!_doDeltaX && x - _x > 0) || (_doDeltaX && x - _x < 0))) { _destX = x; } else if (flag) { _destX = x; GotoState(&Klayman::sub421550); } else { _destX = x; GotoState(&Klayman::stStartWalking); } } void Klayman::stWakeUp() { _status2 = 1; _acceptInput = false; startAnimation(0x527AC970, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(NULL); } void Klayman::stSleeping() { _status2 = 0; _acceptInput = true; startAnimation(0x5A38C110, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmSleeping); SetSpriteUpdate(NULL); } uint32 Klayman::hmSleeping(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D360(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x03060012) { _soundResource1.play(0xC0238244); } break; } return messageResult; } bool Klayman::stStartAction(AnimationCb callback3) { if (_status2 == 1) { _status2 = 2; _acceptInput = false; startAnimation(0x5C7080D4, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmStartAction); SetSpriteUpdate(&Klayman::spriteUpdate41F250); NextState(callback3); return true; } else { _x = _destX; return false; } } void Klayman::spriteUpdate41F250() { int16 xdiff = _destX - _x; if (_doDeltaX) { _x -= _deltaX; } else { _x += _deltaX; } _deltaX = 0; if (_doDeltaY) { _y -= _deltaY; } else { _y += _deltaY; } _deltaY = 0; if (_frameChanged) { if (xdiff > 6) _x += 6; else if (xdiff < -6) _x -= 6; else _x = _destX; } processDelta(); } void Klayman::suWalking() { int16 xdiff = _destX - _x; if (_currFrameIndex == 9) { if (xdiff > 26) _deltaX += xdiff - 26; else if (xdiff < -26) _deltaX -= xdiff + 26; } if (xdiff > _deltaX) xdiff = _deltaX; else if (xdiff < -_deltaX) xdiff = -_deltaX; _deltaX = 0; if (_destX != _x) { HitRect *hitRectPrev = _vm->_collisionMan->findHitRectAtPos(_x, _y); _x += xdiff; if (_pathPoints) { walkAlongPathPoints(); } else { HitRect *hitRectNext = _vm->_collisionMan->findHitRectAtPos(_x, _y); if (hitRectNext->type == 0x5002) { _y = MAX(hitRectNext->rect.y1, hitRectNext->rect.y2 - (hitRectNext->rect.x2 - _x) / 2); } else if (hitRectNext->type == 0x5003) { _y = MAX(hitRectNext->rect.y1, hitRectNext->rect.y2 - (_x - hitRectNext->rect.x1) / 2); } else if (hitRectPrev->type == 0x5002) { if (xdiff > 0) { _y = hitRectPrev->rect.y2; } else { _y = hitRectPrev->rect.y1; } } else if (hitRectPrev->type == 0x5003) { if (xdiff < 0) { _y = hitRectPrev->rect.y2; } else { _y = hitRectPrev->rect.y1; } } } processDelta(); } } void Klayman::stSneak() { _status2 = 1; _isSneaking = true; _acceptInput = true; setDoDeltaX(_destX < _x ? 1 : 0); startAnimation(0x5C48C506, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmWalking); SetSpriteUpdate(&Klayman::suWalking); FinalizeState(&Klayman::stWalkingDone); } void Klayman::stWalkingDone() { _isSneaking = false; } uint32 Klayman::hmWalking(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D360(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x32180101) { _soundResource1.play(0x4924AAC4); } else if (param.asInteger() == 0x0A2A9098) { _soundResource1.play(0x0A2AA8E0); } else if (param.asInteger() == 0x32188010) { _soundResource1.play(_soundFlag ? 0x48498E46 : 0x405002D8); } else if (param.asInteger() == 0x02A2909C) { _soundResource1.play(_soundFlag ? 0x50399F64 : 0x0460E2FA); } break; case 0x3002: _x = _destX; gotoNextStateExt(); break; } return messageResult; } void Klayman::stStartWalking() { if (!stStartActionFromIdle(AnimationCallback(&Klayman::stStartWalking))) { _status2 = 0; _isWalking = true; _acceptInput = true; setDoDeltaX(_destX < _x ? 1 : 0); startAnimation(0x242C0198, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmStartWalking); SetSpriteUpdate(&Klayman::suWalkingTestExit); FinalizeState(&Klayman::stStartWalkingDone); NextState(&Klayman::stWalking); } } void Klayman::stStartWalkingDone() { _isWalking = false; } uint32 Klayman::hmStartWalking(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x32180101) { _soundResource1.play(_soundFlag ? 0x48498E46 : 0x405002D8); } else if (param.asInteger() == 0x0A2A9098) { _soundResource1.play(_soundFlag ? 0x50399F64 : 0x0460E2FA); } break; } return messageResult; } void Klayman::stWalking() { _status2 = 0; _isWalking = true; _acceptInput = true; startAnimation(0x1A249001, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EB70); SetSpriteUpdate(&Klayman::spriteUpdate41F300); FinalizeState(&Klayman::stStartWalkingDone); NextState(&Klayman::stUpdateWalking); } void Klayman::spriteUpdate41F300() { SetSpriteUpdate(&Klayman::suWalkingTestExit); _deltaX = 0; } uint32 Klayman::handleMessage41EB70(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D360(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x32180101) { _soundResource1.play(_soundFlag ? 0x48498E46 : 0x405002D8); } else if (param.asInteger() == 0x0A2A9098) { _soundResource1.play(_soundFlag ? 0x50399F64 : 0x0460E2FA); } break; } return messageResult; } void Klayman::stUpdateWalking() { if (_status3 == 2) { gotoNextStateExt(); } else if (_status3 == 3) { stWalkingOpenDoor(); } else { _isSneaking = true; _acceptInput = true; if (ABS(_destX - _x) <= 42 && _currFrameIndex >= 5 && _currFrameIndex <= 11) { if (_status3 == 0) { _status2 = 1; startAnimation(0xF234EE31, 0, -1); } else { _status2 = 2; startAnimation(0xF135CC21, 0, -1); } } else if (ABS(_destX - _x) <= 10 && (_currFrameIndex >= 12 || _currFrameIndex <= 4)) { if (_status3 == 0) { _status2 = 1; startAnimation(0x8604A152, 0, -1); } else { _status2 = 2; startAnimation(0xA246A132, 0, -1); } } SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmWalking); SetSpriteUpdate(&Klayman::suWalking); FinalizeState(&Klayman::stWalkingDone); } } void Klayman::suWalkingTestExit() { int16 xdiff = ABS(_destX - _x); int16 xdelta = _destX - _x; if (xdelta > _deltaX) xdelta = _deltaX; else if (xdelta < -_deltaX) xdelta = -_deltaX; _deltaX = 0; if (xdiff == 0 || (_status3 != 2 && _status3 != 3 && xdiff <= 42 && _currFrameIndex >= 5 && _currFrameIndex <= 11) || (_status3 != 2 && _status3 != 3 && xdiff <= 10 && (_currFrameIndex >= 12 || _currFrameIndex <= 4)) || (_status3 == 3 && xdiff < 30) || (_status3 == 3 && xdiff < 150 && _currFrameIndex >= 6)) { sendMessage(this, 0x1019, 0); } else { HitRect *hitRectPrev = _vm->_collisionMan->findHitRectAtPos(_x, _y); _x += xdelta; if (_pathPoints) { walkAlongPathPoints(); } else { HitRect *hitRectNext = _vm->_collisionMan->findHitRectAtPos(_x, _y); if (hitRectNext->type == 0x5002) { _y = MAX(hitRectNext->rect.y1, hitRectNext->rect.y2 - (hitRectNext->rect.x2 - _x) / 2); } else if (hitRectNext->type == 0x5003) { _y = MAX(hitRectNext->rect.y1, hitRectNext->rect.y2 - (_x - hitRectNext->rect.x1) / 2); } else if (hitRectPrev->type == 0x5002) { _y = xdelta > 0 ? hitRectPrev->rect.y2 : hitRectPrev->rect.y1; } else if (hitRectPrev->type == 0x5003) { _y = xdelta < 0 ? hitRectPrev->rect.y2 : hitRectPrev->rect.y1; } else if (_flagF6 && xdelta != 0) { if (hitRectNext->type == 0x5000) { _y++; } else if (hitRectNext->type == 0x5001 && _y > hitRectNext->rect.y1) { _y--; } } } processDelta(); } } uint32 Klayman::handleMessage41E210(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x4AB28209) { sendMessage(_attachedSprite, 0x482A, 0); } else if (param.asInteger() == 0x88001184) { sendMessage(_attachedSprite, 0x482B, 0); } break; } return messageResult; } void Klayman::stPickUpGeneric() { setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0); if (!stStartAction(AnimationCallback(&Klayman::stPickUpGeneric))) { _status2 = 1; _acceptInput = false; startAnimation(0x1C28C178, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmPickUpGeneric); SetSpriteUpdate(NULL); } } uint32 Klayman::hmPickUpGeneric(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0xC1380080) { if (_attachedSprite) { sendMessage(_attachedSprite, 0x4806, 0); } _soundResource1.play(0x40208200); } else if (param.asInteger() == 0x02B20220) { _soundResource1.play(0xC5408620); } else if (param.asInteger() == 0x03020231) { _soundResource1.play(0xD4C08010); } else if (param.asInteger() == 0x67221A03) { _soundResource1.play(0x44051000); } else if (param.asInteger() == 0x2EAE0303) { _soundResource1.play(0x03630300); } else if (param.asInteger() == 0x61CE4467) { _soundResource1.play(0x03630300); } break; } return messageResult; } void Klayman::stTurnPressButton() { if (!stStartAction(AnimationCallback(&Klayman::stTurnPressButton))) { _status2 = 2; _acceptInput = true; startAnimation(0x1C02B03D, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmPressButton); SetSpriteUpdate(NULL); } } uint32 Klayman::hmPressButton(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x0D01B294) { if (_attachedSprite) { sendMessage(_attachedSprite, 0x480B, 0); } } else if (param.asInteger() == 0x32180101) { _soundResource1.play(0x4924AAC4); } else if (param.asInteger() == 0x0A2A9098) { _soundResource1.play(0x0A2AA8E0); } break; } return messageResult; } void Klayman::stStampFloorButton() { if (!stStartAction(AnimationCallback(&Klayman::stStampFloorButton))) { _status2 = 2; _acceptInput = true; startAnimation(0x1C16B033, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmPressButton); SetSpriteUpdate(NULL); } } void Klayman::stPressButtonSide() { if (!stStartActionFromIdle(AnimationCallback(&Klayman::stPressButtonSide))) { _status2 = 1; _acceptInput = true; startAnimation(0x1CD89029, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmPressButton); SetSpriteUpdate(&Klayman::spriteUpdate41F250); } } void Klayman::startSpecialWalkRight(int16 x) { if (_x == x) { _destX = x; gotoState(NULL); gotoNextStateExt(); } else if (_x < x) { startWalkToX(x, false); } else if (_x - x <= 105) { sub41CAC0(x); } else { startWalkToX(x, false); } } void Klayman::startSpecialWalkLeft(int16 x) { if (x == _x) { _destX = x; gotoState(NULL); gotoNextStateExt(); } else if (x < _x) { startWalkToX(x, false); } else if (x - _x <= 105) { sub41CAC0(x); } else { startWalkToX(x, false); } } void Klayman::sub41CDE0(int16 x) { _status3 = 2; if (_x == x) { _destX = x; if (_isWalking) { GotoState(NULL); gotoNextStateExt(); } } else if (_isWalking && ((!_doDeltaX && x - _x > 0) || (_doDeltaX && x - _x < 0))) { _destX = x; } else { _destX = x; GotoState(&Klayman::sub421680); } } void Klayman::sub421680() { _isWalking = true; _acceptInput = true; _status3 = 2; setDoDeltaX(_destX < _x ? 1 : 0); startAnimation(0x3A4CD934, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41ED70); SetSpriteUpdate(&Klayman::suWalkingTestExit); FinalizeState(&Klayman::stStartWalkingDone); } uint32 Klayman::handleMessage41ED70(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D360(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x32180101) _soundResource1.play(0x4924AAC4); else if (param.asInteger() == 0x0A2A9098) _soundResource1.play(0x0A2AA8E0); } return messageResult; } void Klayman::sub421640() { _status2 = 0; _acceptInput = true; startAnimation(0x90D0D1D0, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D360); SetSpriteUpdate(NULL); } void Klayman::sub421740() { _status2 = 0; _acceptInput = true; startAnimation(0x11C8D156, 30, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(NULL); } void Klayman::sub421780() { _status2 = 0; _acceptInput = true; startAnimation(0x11C8D156, 0, 10); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(NULL); } void Klayman::sub421700() { _status2 = 0; _acceptInput = true; startAnimation(0x11C8D156, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(NULL); } void Klayman::sub421840() { _status2 = 0; _acceptInput = false; startAnimationByHash(0x3F9CC394, 0x14884392, 0); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EE00); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } uint32 Klayman::handleMessage41EE00(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x80C110B5) sendMessage(_parentScene, 0x482A, 0); else if (param.asInteger() == 0x110010D1) sendMessage(_parentScene, 0x482B, 0); else if (param.asInteger() == 0x32180101) _soundResource1.play(0x4924AAC4); else if (param.asInteger() == 0x0A2A9098) _soundResource1.play(0x0A2AA8E0); break; } return messageResult; } void Klayman::sub421800() { _status2 = 0; _acceptInput = false; startAnimation(0x2F1C4694, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EE00); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } void Klayman::sub4217C0() { _status2 = 0; _acceptInput = false; startAnimation(0x3F9CC394, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EE00); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } void Klayman::sub421900() { _status2 = 0; _acceptInput = false; startAnimationByHash(0x37ECD436, 0, 0x8520108C); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EE00); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } void Klayman::sub4218C0() { _status2 = 0; _acceptInput = false; startAnimation(0x16EDDE36, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EE00); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } void Klayman::sub421880() { _status2 = 0; _acceptInput = false; startAnimation(0x37ECD436, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EE00); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } void Klayman::sub420F60() { if (!stStartAction(AnimationCallback(&Klayman::sub420F60))) { _status2 = 2; _acceptInput = false; startAnimation(0x3F28E094, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41E6C0); SetSpriteUpdate(NULL); NextState(&Klayman::sub420FB0); } } void Klayman::sub420FB0() { _acceptInput = false; startAnimation(0x3A28C094, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41E6C0); SetSpriteUpdate(NULL); } uint32 Klayman::handleMessage41E6C0(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x4AB28209) { sendMessage(_attachedSprite, 0x482A, 0); sendMessage(_attachedSprite, 0x480F, 0); } else if (param.asInteger() == 0x88001184) { sendMessage(_attachedSprite, 0x482B, 0); } break; } return messageResult; } void Klayman::sub421110() { if (!stStartAction(AnimationCallback(&Klayman::sub421110))) { _status2 = 1; _acceptInput = false; startAnimation(0x1A38A814, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41E750); SetSpriteUpdate(NULL); } } uint32 Klayman::handleMessage41E750(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x02B20220) _soundResource1.play(0xC5408620); else if (param.asInteger() == 0x0A720138) _soundResource1.play(0xD4C08010); else if (param.asInteger() == 0x03020231) _soundResource1.play(0xD4C08010); else if (param.asInteger() == 0xB613A180) _soundResource1.play(0x44051000); else if (param.asInteger() == 0x67221A03) _soundResource1.play(0x44051000); else if (param.asInteger() == 0x038A010B) _soundResource1.play(0x00018040); else if (param.asInteger() == 0x422B0280) _soundResource1.play(0x166FC6E0); else if (param.asInteger() == 0x925A0C1E) _soundResource1.play(0x40E5884D); break; } return messageResult; } void Klayman::sub4215E0() { _status2 = 0; _isWalking = true; _acceptInput = true; SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EB70); SetSpriteUpdate(&Klayman::spriteUpdate41F300); NextState(&Klayman::stUpdateWalking); FinalizeState(&Klayman::stStartWalkingDone); startAnimation(0x5A2CBC00, 0, -1); } void Klayman::sub421550() { if (!stStartActionFromIdle(AnimationCallback(&Klayman::sub421550))) { _status2 = 0; _isWalking = true; _acceptInput = true; setDoDeltaX(_destX < _x ? 1 : 0); startAnimation(0x272C1199, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmStartWalking); SetSpriteUpdate(&Klayman::suWalkingTestExit); FinalizeState(&Klayman::stStartWalkingDone); NextState(&Klayman::sub4215E0); } } void Klayman::sub41CC40(int16 x1, int16 x2) { if (_x > x1) { if (_x == x1 + x2) { _destX = x1 + x2; gotoState(NULL); gotoNextStateExt(); } else if (_x < x1 + x2) { sub41CAC0(x1 + x2); } else { startWalkToX(x1 + x2, false); } } else { if (_x == x1 - x2) { _destX = x1 - x2; gotoState(NULL); gotoNextStateExt(); } else if (_x > x1 - x2) { sub41CAC0(x1 - x2); } else { startWalkToX(x1 - x2, false); } } } void Klayman::sub41CAC0(int16 x) { int16 xdiff = ABS(x - _x); if (x == _x) { _destX = x; if (!_isWalking && !_isSneaking && !_isLargeStep) { gotoState(NULL); gotoNextStateExt(); } } else if (xdiff <= 36 && !_isWalking && !_isSneaking && !_isLargeStep) { _destX = x; gotoState(NULL); gotoNextStateExt(); } else if (xdiff <= 42 && _status3 != 3) { if (_isSneaking && ((!_doDeltaX && x - _x > 0) || (_doDeltaX && x - _x < 0)) && ABS(_destX - _x) > xdiff) { _destX = x; } else { _destX = x; GotoState(&Klayman::stSneak); } } else if (_isLargeStep && ((!_doDeltaX && x - _x > 0) || (_doDeltaX && x - _x < 0))) { _destX = x; } else { _destX = x; GotoState(&Klayman::stLargeStep); } } void Klayman::stLargeStep() { _status2 = 2; _isLargeStep = true; _acceptInput = true; setDoDeltaX(_destX >= _x ? 1 : 0); startAnimation(0x08B28116, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmLargeStep); SetSpriteUpdate(&Klayman::suLargeStep); FinalizeState(&Klayman::stLargeStepDone); } void Klayman::stLargeStepDone() { _isLargeStep = false; } void Klayman::suLargeStep() { int16 xdiff = _destX - _x; if (_doDeltaX) { _deltaX = -_deltaX; } if (_currFrameIndex == 7) { _deltaX = xdiff; } if ((xdiff > 0 && xdiff > _deltaX) || (xdiff < 0 && xdiff < _deltaX)) xdiff = _deltaX; _deltaX = 0; if (_x != _destX) { HitRect *hitRectPrev = _vm->_collisionMan->findHitRectAtPos(_x, _y); _x += xdiff; if (_pathPoints) { walkAlongPathPoints(); } else { HitRect *hitRectNext = _vm->_collisionMan->findHitRectAtPos(_x, _y); if (hitRectNext->type == 0x5002) { _y = MAX(hitRectNext->rect.y1, hitRectNext->rect.y2 - (hitRectNext->rect.x2 - _x) / 2); } else if (hitRectNext->type == 0x5003) { _y = MAX(hitRectNext->rect.y1, hitRectNext->rect.y2 - (_x - hitRectNext->rect.x1) / 2); } else if (hitRectPrev->type == 0x5002) { _y = xdiff > 0 ? hitRectPrev->rect.y2 : hitRectPrev->rect.y1; } else if (hitRectPrev->type == 0x5003) { _y = xdiff < 0 ? hitRectPrev->rect.y2 : hitRectPrev->rect.y1; } } processDelta(); } } uint32 Klayman::hmLargeStep(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D360(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x32180101) { _soundResource1.play(0x4924AAC4); } else if (param.asInteger() == 0x0A2A9098) { _soundResource1.play(0x0A2AA8E0); } break; case 0x3002: _x = _destX; gotoNextStateExt(); break; } return messageResult; } void Klayman::stWonderAboutHalf() { _status2 = 0; _acceptInput = true; startAnimation(0xD820A114, 0, 10); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(NULL); } void Klayman::stWonderAboutAfter() { _status2 = 1; _acceptInput = true; startAnimation(0xD820A114, 30, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(NULL); } void Klayman::stTurnToUseHalf() { _status2 = 0; _acceptInput = true; startAnimation(0x9B250AD2, 0, 7); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmTurnToUse); SetSpriteUpdate(NULL); } uint32 Klayman::hmTurnToUse(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x32180101) { _soundResource1.play(0x4924AAC4); } else if (param.asInteger() == 0x0A2A9098) { _soundResource1.play(0x0A2AA8E0); } break; } return messageResult; } void Klayman::stTurnAwayFromUse() { _status2 = 1; _acceptInput = true; startAnimation(0x98F88391, 4, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmTurnToUse); SetSpriteUpdate(NULL); } void Klayman::stWonderAbout() { _status2 = 1; _acceptInput = true; startAnimation(0xD820A114, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(NULL); } void Klayman::stPeekWall() { _status2 = 1; _acceptInput = true; startAnimation(0xAC20C012, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmPeekWall); SetSpriteUpdate(NULL); } uint32 Klayman::hmPeekWall(int messageNum, const MessageParam ¶m, Entity *sender) { int16 speedUpFrameIndex; switch (messageNum) { case 0x1008: speedUpFrameIndex = getFrameIndex(kKlaymanSpeedUpHash); if (_currFrameIndex < speedUpFrameIndex) startAnimation(0xAC20C012, speedUpFrameIndex, -1); return 0; case 0x100D: if (param.asInteger() == 0x32180101) { _soundResource1.play(0x405002D8); } else if (param.asInteger() == 0x0A2A9098) { _soundResource1.play(0x0460E2FA); } break; } return handleMessage41D480(messageNum, param, sender); } void Klayman::stJumpToRing1() { if (!stStartAction(AnimationCallback(&Klayman::stJumpToRing1))) { _status2 = 0; startAnimation(0xD82890BA, 0, -1); setupJumpToRing(); } } void Klayman::setupJumpToRing() { _acceptInput = false; SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmJumpToRing); SetSpriteUpdate(&Klayman::spriteUpdate41F230); NextState(&Klayman::sub420340); sendMessage(_attachedSprite, 0x482B, 0); } uint32 Klayman::hmJumpToRing(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x168050A0) { if (_attachedSprite) { sendMessage(_attachedSprite, 0x4806, 0); } _acceptInput = true; } else if (param.asInteger() == 0x320AC306) { _soundResource1.play(0x5860C640); } else if (param.asInteger() == 0x4AB28209) { sendMessage(_attachedSprite, 0x482A, 0); } else if (param.asInteger() == 0x88001184) { sendMessage(_attachedSprite, 0x482B, 0); } break; } return messageResult; } void Klayman::spriteUpdate41F230() { AnimatedSprite::updateDeltaXY(); _destX = _x; } void Klayman::sub420340() { _status2 = 0; _acceptInput = true; startAnimation(0x4829E0B8, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D360); SetSpriteUpdate(NULL); } void Klayman::stJumpToRing2() { if (!stStartAction(AnimationCallback(&Klayman::stJumpToRing2))) { _status2 = 0; startAnimation(0x900980B2, 0, -1); setupJumpToRing(); } } void Klayman::stJumpToRing3() { if (!stStartAction(AnimationCallback(&Klayman::stJumpToRing3))) { _status2 = 0; _acceptInput = false; startAnimation(0xBA1910B2, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F230); SetMessageHandler(&Klayman::hmJumpToRing3); NextState(&Klayman::stHoldRing); sendMessage(_attachedSprite, 0x482B, 0); } } uint32 Klayman::hmJumpToRing3(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x168050A0) { if (_attachedSprite) { sendMessage(_attachedSprite, 0x4806, 0); } } else if (param.asInteger() == 0x320AC306) { _soundResource1.play(0x5860C640); } else if (param.asInteger() == 0x4AB28209) { sendMessage(_attachedSprite, 0x482A, 0); } else if (param.asInteger() == 0x88001184) { sendMessage(_attachedSprite, 0x482B, 0); } break; } return messageResult; } void Klayman::stHoldRing() { _status2 = 0; _acceptInput = true; startAnimation(0x4A293FB0, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmHoldRing); SetSpriteUpdate(NULL); } uint32 Klayman::hmHoldRing(int messageNum, const MessageParam ¶m, Entity *sender) { if (messageNum == 0x1008) { stReleaseRing(); return 0; } return handleMessage41D360(messageNum, param, sender); } void Klayman::stReleaseRing() { _status2 = 1; _acceptInput = false; if (_attachedSprite) { sendMessage(_attachedSprite, 0x4807, 0); _attachedSprite = NULL; } startAnimation(0xB869A4B9, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(NULL); } void Klayman::stJumpToRing4() { if (!stStartAction(AnimationCallback(&Klayman::stJumpToRing4))) { _status2 = 0; startAnimation(0xB8699832, 0, -1); setupJumpToRing(); } } void Klayman::sub41CCE0(int16 x) { sub41CC40(_attachedSprite->getX(), x); } void Klayman::stContinueClimbLadderUp() { _status2 = 0; _acceptInput = true; _ladderStatus = 3; startAnimationByHash(0x3A292504, 0x01084280, 0); _newStickFrameHash = 0x01084280; SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D360); SetSpriteUpdate(NULL); gotoNextStateExt(); } void Klayman::stStartClimbLadderDown() { if (!stStartAction(AnimationCallback(&Klayman::stStartClimbLadderDown))) { _status2 = 0; if (_destY < _y) { if (_ladderStatus == 1) { _ladderStatus = 2; stClimbLadderHalf(); } else { gotoNextStateExt(); } } else if (_ladderStatus == 0) { _ladderStatus = 2; _acceptInput = false; startAnimation(0x122D1505, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmClimbLadderUpDown); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } else if (_ladderStatus == 3) { _ladderStatus = 2; _acceptInput = true; startAnimationByHash(0x122D1505, 0x01084280, 0); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmClimbLadderUpDown); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } else if (_ladderStatus == 1) { _ladderStatus = 2; _acceptInput = true; startAnimation(0x122D1505, 29 - _currFrameIndex, -1); } } } void Klayman::stClimbLadderHalf() { _status2 = 2; if (_ladderStatus == 1) { _ladderStatus = 0; _acceptInput = false; startAnimationByHash(0x3A292504, 0x02421405, 0); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41DFD0); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } else if (_ladderStatus == 2) { _ladderStatus = 0; _acceptInput = false; startAnimationByHash(0x122D1505, 0x02421405, 0); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41DFD0); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } else { gotoNextStateExt(); } } uint32 Klayman::handleMessage41DFD0(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x489B025C) { _soundResource1.play(0x52C4C2D7); } else if (param.asInteger() == 0x400A0E64) { _soundResource1.play(0x50E081D9); } else if (param.asInteger() == 0x32180101) { _soundResource1.play(0x405002D8); } else if (param.asInteger() == 0x0A2A9098) { _soundResource1.play(0x0460E2FA); } break; } return messageResult; } uint32 Klayman::hmClimbLadderUpDown(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D360(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x01084280) { _acceptInput = true; } else if (param.asInteger() == 0x489B025C) { _soundResource1.play(0x52C4C2D7); } else if (param.asInteger() == 0x400A0E64) { _soundResource1.play(0x50E081D9); } else if (param.asInteger() == 0x02421405) { if (_ladderStatus == 1) { startAnimationByHash(0x3A292504, 0x01084280, 0); if (_destY >= _y - 30) sendMessage(this, 0x1019, 0); } else { startAnimationByHash(0x122D1505, 0x01084280, 0); if (_destY <= _y) sendMessage(this, 0x1019, 0); } } break; } return messageResult; } void Klayman::stStartClimbLadderUp() { if (!stStartAction(AnimationCallback(&Klayman::stStartClimbLadderUp))) { _status2 = 0; if (_destY >= _y - 30) { gotoNextStateExt(); } else if (_ladderStatus == 0) { _ladderStatus = 1; _acceptInput = false; startAnimation(0x3A292504, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmClimbLadderUpDown); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } else if (_ladderStatus == 3) { _ladderStatus = 1; _acceptInput = true; startAnimationByHash(0x3A292504, 0x01084280, 0); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmClimbLadderUpDown); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } else if (_ladderStatus == 2) { _ladderStatus = 1; _acceptInput = true; startAnimation(0x3A292504, 29 - _currFrameIndex, -1); } } } void Klayman::stWalkToFrontNoStep() { _status2 = 2; _acceptInput = false; startAnimationByHash(0xF229C003, 0x14884392, 0); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmWalkToFront); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } uint32 Klayman::hmWalkToFront(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x80C110B5) { sendMessage(_parentScene, 0x482A, 0); } else if (param.asInteger() == 0x110010D1) { sendMessage(_parentScene, 0x482B, 0); } else if (param.asInteger() == 0x32180101) { _soundResource1.play(_soundFlag ? 0x48498E46 : 0x405002D8); } else if (param.asInteger() == 0x0A2A9098) { _soundResource1.play(_soundFlag ? 0x50399F64 : 0x0460E2FA); } break; } return messageResult; } void Klayman::stWalkToFront() { if (!stStartAction(AnimationCallback(&Klayman::stWalkToFront))) { _status2 = 2; _acceptInput = false; startAnimation(0xF229C003, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmWalkToFront); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } } void Klayman::stTurnToFront() { if (!stStartAction(AnimationCallback(&Klayman::stTurnToFront))) { _status2 = 0; _acceptInput = false; startAnimationByHash(0xCA221107, 0x8520108C, 0); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmWalkToFront); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } } void Klayman::stTurnToBack() { if (!stStartAction(AnimationCallback(&Klayman::stTurnToBack))) { _status2 = 2; _acceptInput = false; startAnimation(0xCA221107, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmWalkToFront); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } } void Klayman::stLandOnFeet() { _status2 = 1; _acceptInput = true; startAnimation(0x18118554, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmLandOnFeet); SetSpriteUpdate(NULL); } uint32 Klayman::hmLandOnFeet(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x320AC306) { _soundResource1.play(0x5860C640); } break; } return messageResult; } void Klayman::stTurnToBackToUse() { if (!stStartAction(AnimationCallback(&Klayman::stTurnToBackToUse))) { _status2 = 2; _acceptInput = false; startAnimation(0x91540140, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmTurnToBackToUse); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } } uint32 Klayman::hmTurnToBackToUse(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0xC61A0119) { _soundResource1.play(0x402338C2); } else if (param.asInteger() == 0x32180101) { _soundResource1.play(0x4924AAC4); } else if (param.asInteger() == 0x0A2A9098) { _soundResource1.play(0x0A2AA8E0); } break; } return messageResult; } void Klayman::stClayDoorOpen() { if (!stStartAction(AnimationCallback(&Klayman::stClayDoorOpen))) { _status2 = 2; _acceptInput = false; startAnimation(0x5CCCB330, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F230); SetMessageHandler(&Klayman::hmClayDoorOpen); } } uint32 Klayman::hmClayDoorOpen(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x040D4186) { if (_attachedSprite) { sendMessage(_attachedSprite, 0x4808, 0); } } break; } return messageResult; } void Klayman::stTurnToUse() { if (!stStartAction(AnimationCallback(&Klayman::stTurnToUse))) { _status2 = 2; _acceptInput = false; startAnimation(0x9B250AD2, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F230); SetMessageHandler(&Klayman::hmTurnToUse); } } void Klayman::stReturnFromUse() { _status2 = 2; _acceptInput = false; startAnimation(0x98F88391, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F230); SetMessageHandler(&Klayman::hmTurnToUse); } void Klayman::stWalkingOpenDoor() { _isWalkingOpenDoorNotified = false; _acceptInput = false; startAnimation(0x11A8E012, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::suWalkingOpenDoor); SetMessageHandler(&Klayman::hmStartWalking); } void Klayman::suWalkingOpenDoor() { if (!_isWalkingOpenDoorNotified && ABS(_destX - _x) < 80) { sendMessage(_parentScene, 0x4829, 0); _isWalkingOpenDoorNotified = true; } AnimatedSprite::updateDeltaXY(); } void Klayman::stMoveObjectSkipTurnFaceObject() { setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0); _isMoveObjectRequested = false; _acceptInput = true; startAnimationByHash(0x0C1CA072, 0x01084280, 0); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F230); SetMessageHandler(&Klayman::hmMoveObjectTurn); } void Klayman::sub420660() { sendMessage(_attachedSprite, 0x4807, 0); } uint32 Klayman::hmMoveObjectTurn(int messageNum, const MessageParam ¶m, Entity *sender) { switch (messageNum) { case 0x100D: if (param.asInteger() == 0x01084280) { if (_attachedSprite) sendMessage(_attachedSprite, 0x480B, _doDeltaX ? 1 : 0); } else if (param.asInteger() == 0x02421405) { if (_isMoveObjectRequested && sendMessage(_attachedSprite, 0x480C, _doDeltaX ? 1 : 0) != 0) { stMoveObjectSkipTurn(); } else { FinalizeState(&Klayman::sub420660); SetMessageHandler(&Klayman::handleMessage41D480); } } else if (param.asInteger() == 0x32180101) { _soundResource1.play(0x405002D8); } else if (param.asInteger() == 0x0A2A9098) { _soundResource1.play(0x0460E2FA); } break; case 0x480A: _isMoveObjectRequested = true; return 0; } return handleMessage41D480(messageNum, param, sender); } void Klayman::stMoveObjectSkipTurn() { _isMoveObjectRequested = false; _acceptInput = true; startAnimationByHash(0x0C1CA072, 0x01084280, 0); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F230); SetMessageHandler(&Klayman::hmMoveObjectTurn); } void Klayman::stMoveObjectFaceObject() { setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0); if (!stStartAction(AnimationCallback(&Klayman::stMoveObjectFaceObject))) { _status2 = 2; _isMoveObjectRequested = false; _acceptInput = true; startAnimation(0x0C1CA072, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F230); SetMessageHandler(&Klayman::hmMoveObjectTurn); } } void Klayman::stUseLever() { if (!stStartAction(AnimationCallback(&Klayman::stUseLever))) { _status2 = 0; if (_isLeverDown) { stUseLeverRelease(); } else { sendMessage(_attachedSprite, 0x482B, 0); startAnimation(0x0C303040, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F230); SetMessageHandler(&Klayman::handleMessage41E210); NextState(&Klayman::stPullLeverDown); _acceptInput = false; } } } // Exactly the same code as sub420DA0 which was removed void Klayman::stPullLeverDown() { startAnimation(0x0D318140, 0, -1); sendMessage(_attachedSprite, 0x480F, 0); NextState(&Klayman::stHoldLeverDown); } void Klayman::stHoldLeverDown() { startAnimation(0x4464A440, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F230); SetMessageHandler(&Klayman::handleMessage41D360); _isLeverDown = true; _acceptInput = true; } void Klayman::stUseLeverRelease() { startAnimation(0x09018068, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F230); SetMessageHandler(&Klayman::handleMessage41E210); sendMessage(_attachedSprite, 0x4807, 0); NextState(&Klayman::stPullLeverDown); _acceptInput = false; } void Klayman::stReleaseLever() { if (_isLeverDown) { _status2 = 2; startAnimation(0x09018068, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F230); SetMessageHandler(&Klayman::handleMessage41E210); sendMessage(_attachedSprite, 0x4807, 0); NextState(&Klayman::stLetGoOfLever); _acceptInput = false; _isLeverDown = false; } else { gotoNextStateExt(); } } void Klayman::stLetGoOfLever() { startAnimation(0x0928C048, 0, -1); FinalizeState(&Klayman::cbLeverReleasedEvent); } void Klayman::cbLeverReleasedEvent() { sendMessage(_attachedSprite, 0x482A, 0); } void Klayman::stInsertDisk() { if (!stStartActionFromIdle(AnimationCallback(&Klayman::stInsertDisk))) { _status2 = 2; _counter2 = 0; for (uint32 i = 0; i < 20; i++) { if (getSubVar(0x02038314, i)) { setSubVar(0x02720344, i, 1); setSubVar(0x02038314, i, 0); _counter2++; } } if (_counter2 == 0) { gotoState(NULL); gotoNextStateExt(); } else { startAnimation(0xD8C8D100, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F250); SetMessageHandler(&Klayman::hmInsertDisk); _acceptInput = false; _counter2--; } } } uint32 Klayman::hmInsertDisk(int messageNum, const MessageParam ¶m, Entity *sender) { switch (messageNum) { case 0x100D: if (param.asInteger() == 0x06040580) { if (_counter2 == 0) { // TODO: Calc calcHash value somewhere else nextAnimationByHash(0xD8C8D100, calcHash("GoToStartLoop/Finish"), 0); } } else if (_counter2 != 0 && param.asInteger() == calcHash("GoToStartLoop/Finish")) { _counter2--; startAnimationByHash(0xD8C8D100, 0x01084280, 0); } else if (param.asInteger() == 0x062A1510) { _soundResource1.play(0x41688704); } else if (param.asInteger() == 0x02B20220) { _soundResource1.play(0xC5408620); } else if (param.asInteger() == 0x0A720138) { _soundResource1.play(0xD4C08010); } else if (param.asInteger() == 0xB613A180) { _soundResource1.play(0x44051000); } else if (param.asInteger() == 0x0E040501) { _soundResource1.play(0xC6A129C1); } } return handleMessage41D480(messageNum, param, sender); } void Klayman::walkAlongPathPoints() { if (_x <= (*_pathPoints)[0].x) _y = (*_pathPoints)[0].y; else if (_x >= (*_pathPoints)[_pathPoints->size() - 1].x) _y = (*_pathPoints)[_pathPoints->size() - 1].y; else { int16 deltaX = _x - (*_pathPoints)[0].x, deltaXIncr = 0; uint index = 0; while (deltaX > 0) { NPoint pt2 = (*_pathPoints)[index]; NPoint pt1 = index + 1 >= _pathPoints->size() ? (*_pathPoints)[0] : (*_pathPoints)[index + 1]; int16 xd = ABS(pt1.x - pt2.x); int16 yd = ABS(pt1.y - pt2.y); if (deltaX + deltaXIncr >= xd) { deltaX -= xd; deltaX += deltaXIncr; ++index; if (index >= _pathPoints->size()) index = 0; _y = (*_pathPoints)[index].y; } else { deltaXIncr += deltaX; if (pt1.y >= pt2.y) { _y = pt2.y + (yd * deltaXIncr) / xd; } else { _y = pt2.y - (yd * deltaXIncr) / xd; } deltaX = 0; } } } } void Klayman::sub4204C0() { _status2 = 0; _acceptInput = false; startAnimationByHash(0x00AB8C10, 0x01084280, 0); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F920); SetMessageHandler(&Klayman::handleMessage41E5F0); } void Klayman::spriteUpdate41F920() { updateDeltaXY(); if (_y >= _destY) { _y = _destY; processDelta(); gotoNextStateExt(); } } uint32 Klayman::handleMessage41E5F0(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D360(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x168050A0) sendMessage(_attachedSprite, 0x4806, 0); else if (param.asInteger() == 0x320AC306) startAnimationByHash(0x00AB8C10, 0x01084280, 0); else if (param.asInteger() == 0x4AB28209) sendMessage(_attachedSprite, 0x482A, 0); else if (param.asInteger() == 0x88001184) sendMessage(_attachedSprite, 0x482B, 0); break; } return messageResult; } void Klayman::sub421230() { _status2 = 2; _acceptInput = false; startAnimationByHash(0x38445000, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&Klayman::handleMessage41F1D0); } uint32 Klayman::handleMessage41F1D0(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x040C4C01) _soundResource1.play(0x01E11140); break; } return messageResult; } void Klayman::sub421270() { if (!stStartAction(AnimationCallback(&Klayman::sub421270))) { _status2 = 2; _acceptInput = false; startAnimation(0x1B3D8216, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::hmTurnToUse); SetSpriteUpdate(&Klayman::spriteUpdate41F230); } } void Klayman::sub420460() { if (!stStartAction(AnimationCallback(&Klayman::sub420460))) { _status2 = 0; _acceptInput = false; startAnimation(0x00AB8C10, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41E5F0); SetSpriteUpdate(&Klayman::spriteUpdate41F920); sendMessage(_attachedSprite, 0x482B, 0); } } void Klayman::sub420500() { _status2 = 1; _acceptInput = false; startAnimationByHash(0x00AB8C10, 0x320AC306, 0); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&Klayman::handleMessage41F0E0); NextState(&Klayman::stReleaseRing); } uint32 Klayman::handleMessage41F0E0(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x320AC306) _soundResource1.play(0x5860C640); break; } return messageResult; } //############################################################################## // KmScene1001 KmScene1001::KmScene1001(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { } uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4804: if (param.asInteger() == 2) GotoState(&Klayman::stSleeping); break; case 0x480D: GotoState(&KmScene1001::sub44FA50); break; case NM_KLAYMAN_PICKUP: GotoState(&Klayman::stPickUpGeneric); break; case NM_KLAYMAN_PRESS_BUTTON: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnPressButton); } else if (param.asInteger() == 2) { GotoState(&Klayman::stStampFloorButton); } else { GotoState(&Klayman::stPressButtonSide); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: // TODO: It's not really a point but an x1/x2 pair if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481F: if (param.asInteger() == 0) { GotoState(&Klayman::stWonderAboutHalf); } else if (param.asInteger() == 1) { GotoState(&Klayman::stWonderAboutAfter); } else if (param.asInteger() == 3) { GotoState(&Klayman::stTurnToUseHalf); } else if (param.asInteger() == 4) { GotoState(&Klayman::stTurnAwayFromUse); } else { GotoState(&Klayman::stWonderAbout); } break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; case 0x4836: if (param.asInteger() == 1) { sendMessage(_parentScene, 0x2002, 0); GotoState(&Klayman::stWakeUp); } break; case 0x483F: startSpecialWalkRight(param.asInteger()); break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return 0; } void KmScene1001::sub44FA50() { if (!stStartAction(AnimationCallback(&KmScene1001::sub44FA50))) { _status2 = 2; _acceptInput = false; startAnimation(0x00648953, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene1001::handleMessage44FA00); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); } } uint32 KmScene1001::handleMessage44FA00(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Klayman::handleMessage41E210(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x4AB28209) { sendMessage(_attachedSprite, 0x480F, 0); } break; } return messageResult; } // KmScene1002 KmScene1002::KmScene1002(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, Sprite *class599, Sprite *ssLadderArch) : Klayman(vm, parentScene, x, y, 1000, 1000), _otherSprite(NULL), _class599(class599), _ssLadderArch(ssLadderArch), _status(0) { setKlaymanIdleTable1(); } void KmScene1002::xUpdate() { if (_x >= 250 && _x <= 435 && _y >= 420) { if (_status == 0) { // TODO setKlaymanIdleTable(stru_4B44C8); _status = 1; } } else if (_status == 1) { setKlaymanIdleTable1(); _status = 0; } } uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x2001: GotoState(&KmScene1002::sub449E90); break; case 0x2007: _otherSprite = (Sprite*)param.asEntity(); break; case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4803: if (param.asInteger() == 1) { GotoState(&KmScene1002::stJumpAndFall); } else if (param.asInteger() == 2) { GotoState(&KmScene1002::stDropFromRing); } break; case 0x4804: GotoState(&Klayman::stPeekWall); break; case 0x4805: switch (param.asInteger()) { case 1: GotoState(&Klayman::stJumpToRing1); break; case 2: GotoState(&Klayman::stJumpToRing2); break; case 3: GotoState(&Klayman::stJumpToRing3); break; case 4: GotoState(&Klayman::stJumpToRing4); break; } break; case 0x480A: GotoState(&KmScene1002::stMoveVenusFlyTrap); break; case 0x480D: GotoState(&KmScene1002::sub449E20); break; case NM_KLAYMAN_PRESS_BUTTON: if (param.asInteger() == 0) { GotoState(&KmScene1002::stPressDoorButton); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: sub41CCE0(param.asInteger()); break; case 0x4820: sendMessage(_parentScene, 0x2005, 0); GotoState(&Klayman::stContinueClimbLadderUp); break; case 0x4821: sendMessage(_parentScene, 0x2005, 0); _destY = param.asInteger(); GotoState(&Klayman::stStartClimbLadderDown); break; case 0x4822: sendMessage(_parentScene, 0x2005, 0); _destY = param.asInteger(); GotoState(&Klayman::stStartClimbLadderUp); break; case 0x4823: sendMessage(_parentScene, 0x2006, 0); GotoState(&Klayman::stClimbLadderHalf); break; case 0x482E: if (param.asInteger() == 1) { GotoState(&Klayman::stWalkToFrontNoStep); } else { GotoState(&Klayman::stWalkToFront); } break; case 0x482F: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnToFront); } else { GotoState(&Klayman::stTurnToBack); } break; case 0x483F: startSpecialWalkRight(param.asInteger()); break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return 0; } void KmScene1002::update4497D0() { Klayman::update(); if (_counter1 != 0 && (--_counter1 == 0)) { _surface->setVisible(true); SetUpdateHandler(&Klayman::update); } } uint32 KmScene1002::handleMessage449800(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x168050A0) { if (_attachedSprite) { sendMessage(_attachedSprite, 0x480F, 0); } } else if (param.asInteger() == 0x586B0300) { if (_otherSprite) { sendMessage(_otherSprite, 0x480E, 1); } } else if (param.asInteger() == 0x4AB28209) { if (_attachedSprite) { sendMessage(_attachedSprite, 0x482A, 0); } } else if (param.asInteger() == 0x88001184) { if (_attachedSprite) { sendMessage(_attachedSprite, 0x482B, 0); } } break; } return messageResult; } uint32 KmScene1002::handleMessage4498E0(int messageNum, const MessageParam ¶m, Entity *sender) { switch (messageNum) { case 0x4811: _soundResource1.play(0x5252A0E4); setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0); if (_doDeltaX) { _x = ((Sprite*)sender)->getX() - 75; } else { _x = ((Sprite*)sender)->getX() + 75; } _y = ((Sprite*)sender)->getY() - 200; if (param.asInteger() == 0) { sub449EF0(); } else if (param.asInteger() == 1) { sub44A0D0(); } else if (param.asInteger() == 2) { stSpitOutFall(); } break; } return 0; } uint32 KmScene1002::hmPressDoorButton(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x942D2081) { _acceptInput = false; sendMessage(_attachedSprite, 0x2003, 0); } else if (param.asInteger() == 0xDA600012) { stHitByBoxingGlove(); } else if (param.asInteger() == 0x0D01B294) { _acceptInput = false; sendMessage(_attachedSprite, 0x480B, 0); } break; } return messageResult; } uint32 KmScene1002::hmMoveVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender) { switch (messageNum) { case 0x100D: if (param.asInteger() == 0x01084280) { sendMessage(_attachedSprite, 0x480B, (uint32)_doDeltaX); } else if (param.asInteger() == 0x02421405) { if (_isMoveObjectRequested) { if (sendMessage(_attachedSprite, 0x480C, (uint32)_doDeltaX) != 0) stContinueMovingVenusFlyTrap(); } else { SetMessageHandler(&KmScene1002::hmFirstMoveVenusFlyTrap); } } else if (param.asInteger() == 0x4AB28209) { sendMessage(_attachedSprite, 0x482A, 0); } else if (param.asInteger() == 0x88001184) { sendMessage(_attachedSprite, 0x482B, 0); } else if (param.asInteger() == 0x32180101) { _soundResource1.play(0x405002D8); } else if (param.asInteger() == 0x0A2A9098) { _soundResource1.play(0x0460E2FA); } break; case 0x480A: _isMoveObjectRequested = true; return 0; } return handleMessage41D480(messageNum, param, sender); } uint32 KmScene1002::hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x4AB28209) { sendMessage(_attachedSprite, 0x482A, 0); } else if (param.asInteger() == 0x88001184) { sendMessage(_attachedSprite, 0x482B, 0); } else if (param.asInteger() == 0x32180101) { _soundResource1.play(0x405002D8); } else if (param.asInteger() == 0x0A2A9098) { _soundResource1.play(0x0460E2FA); } break; } return messageResult; } uint32 KmScene1002::handleMessage449C90(int messageNum, const MessageParam ¶m, Entity *sender) { int16 speedUpFrameIndex; uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x1008: speedUpFrameIndex = getFrameIndex(kKlaymanSpeedUpHash); if (_currFrameIndex < speedUpFrameIndex) { startAnimation(0x35AA8059, speedUpFrameIndex, -1); _y = 435; } messageResult = 0; break; case 0x100D: if (param.asInteger() == 0x1A1A0785) { _soundResource1.play(0x40F0A342); } else if (param.asInteger() == 0x60428026) { _soundResource1.play(0x40608A59); } break; } return messageResult; } uint32 KmScene1002::handleMessage449D60(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D360(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x1307050A) { _soundResource1.play(0x40428A09); } break; } return messageResult; } void KmScene1002::suFallDown() { AnimatedSprite::updateDeltaXY(); HitRect *hitRect = _vm->_collisionMan->findHitRectAtPos(_x, _y + 10); if (hitRect->type == 0x5001) { _y = hitRect->rect.y1; processDelta(); sendMessage(this, 0x1019, 0); } _vm->_collisionMan->checkCollision(this, 0xFFFF, 0x4810, 0); } void KmScene1002::sub449E20() { if (!stStartAction(AnimationCallback(&KmScene1002::sub449E20))) { _status2 = 2; _acceptInput = false; startAnimation(0x584984B4, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); SetMessageHandler(&KmScene1002::handleMessage449800); NextState(&Klayman::stLandOnFeet); sendMessage(_attachedSprite, 0x482B, 0); } } void KmScene1002::sub449E90() { _soundResource1.play(0x56548280); _status2 = 0; _acceptInput = false; _surface->setVisible(false); startAnimation(0x5420E254, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene1002::handleMessage4498E0); } void KmScene1002::sub449EF0() { _counter1 = 1; _status2 = 0; _acceptInput = false; startAnimation(0x000BAB02, 0, -1); SetUpdateHandler(&KmScene1002::update4497D0); // Weird stuff happening SetMessageHandler(&Klayman::handleMessage41D360); //SetMessageHandler(&Klayman::handleMessage41D480); SetSpriteUpdate(&KmScene1002::suFallDown); NextState(&KmScene1002::sub449F70); sendMessage(_class599, 0x482A, 0); sendMessage(_ssLadderArch, 0x482A, 0); } void KmScene1002::sub449F70() { sendMessage(_parentScene, 0x1024, 1); _soundResource1.play(0x41648271); _status2 = 1; _acceptInput = false; _isWalking = false; startAnimationByHash(0x000BAB02, 0x88003000, 0); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene1002::handleMessage41D480); NextState(&KmScene1002::sub44A230); sendMessage(_parentScene, 0x2002, 0); // TODO _callbackList = NULL; _attachedSprite = NULL; sendMessage(_class599, 0x482B, 0); sendMessage(_ssLadderArch, 0x482B, 0); } void KmScene1002::stSpitOutFall() { _counter1 = 1; _status2 = 0; _acceptInput = false; startAnimation(0x9308C132, 0, -1); SetUpdateHandler(&KmScene1002::update4497D0); SetSpriteUpdate(&KmScene1002::suFallDown); SetMessageHandler(&Klayman::handleMessage41D480); NextState(&KmScene1002::sub449F70); sendMessage(_class599, 0x482A, 0); sendMessage(_ssLadderArch, 0x482A, 0); } void KmScene1002::sub44A0D0() { _counter1 = 1; _status2 = 0; _acceptInput = false; startAnimation(0x0013A206, 0, -1); SetUpdateHandler(&KmScene1002::update4497D0); SetMessageHandler(&Klayman::handleMessage41D360); SetSpriteUpdate(&KmScene1002::suFallDown); NextState(&KmScene1002::sub44A150); sendMessage(_class599, 0x482A, 0); sendMessage(_ssLadderArch, 0x482A, 0); } void KmScene1002::sub44A150() { sendMessage(_parentScene, 0x1024, 1); _soundResource1.play(0x41648271); _status2 = 1; _acceptInput = false; _isWalking = false; startAnimationByHash(0x0013A206, 0x88003000, 0); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene1002::handleMessage41D480); SetSpriteUpdate(NULL); NextState(&KmScene1002::sub44A230); sendMessage(_parentScene, 0x2002, 0); // TODO _callbackList = NULL; _attachedSprite = NULL; sendMessage(_class599, 0x482B, 0); sendMessage(_ssLadderArch, 0x482B, 0); } void KmScene1002::sub44A230() { setDoDeltaX(2); stTryStandIdle(); } void KmScene1002::stJumpAndFall() { if (!stStartAction(AnimationCallback(&KmScene1002::stJumpAndFall))) { sendMessage(_parentScene, 0x1024, 3); _status2 = 2; _acceptInput = false; startAnimation(0xB93AB151, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene1002::handleMessage449D60); SetSpriteUpdate(&KmScene1002::suFallDown); NextState(&Klayman::stLandOnFeet); } } void KmScene1002::stDropFromRing() { if (_attachedSprite) { _x = _attachedSprite->getX(); sendMessage(_attachedSprite, 0x4807, 0); _attachedSprite = NULL; } _status2 = 2; _acceptInput = false; startAnimation(0x586984B1, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene1002::handleMessage41D360); SetSpriteUpdate(&KmScene1002::suFallDown); NextState(&Klayman::stLandOnFeet); } void KmScene1002::stPressDoorButton() { _status2 = 2; _acceptInput = true; setDoDeltaX(0); startAnimation(0x1CD89029, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene1002::hmPressDoorButton); SetSpriteUpdate(&Klayman::spriteUpdate41F250); } void KmScene1002::stHitByBoxingGlove() { _status2 = 1; _acceptInput = false; startAnimation(0x35AA8059, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene1002::handleMessage449C90); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); FinalizeState(&KmScene1002::stHitByBoxingGloveDone); } void KmScene1002::stHitByBoxingGloveDone() { sendMessage(_parentScene, 0x1024, 1); } void KmScene1002::stMoveVenusFlyTrap() { if (!stStartAction(AnimationCallback(&KmScene1002::stMoveVenusFlyTrap))) { _status2 = 2; _isMoveObjectRequested = false; _acceptInput = true; setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0); startAnimation(0x5C01A870, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene1002::hmMoveVenusFlyTrap); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); FinalizeState(&KmScene1002::stMoveVenusFlyTrapDone); } } void KmScene1002::stContinueMovingVenusFlyTrap() { _isMoveObjectRequested = false; _acceptInput = true; startAnimationByHash(0x5C01A870, 0x01084280, 0); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene1002::hmMoveVenusFlyTrap); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); FinalizeState(&KmScene1002::stMoveVenusFlyTrapDone); } void KmScene1002::stMoveVenusFlyTrapDone() { sendMessage(_attachedSprite, 0x482A, 0); } // KmScene1004 KmScene1004::KmScene1004(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { _dataResource.load(0x01900A04); } uint32 KmScene1004::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x4818: startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; case 0x481E: GotoState(&KmScene1004::stReadNote); break; case 0x4820: sendMessage(_parentScene, 0x2000, 0); GotoState(&Klayman::stContinueClimbLadderUp); break; case 0x4821: sendMessage(_parentScene, 0x2000, 0); _destY = param.asInteger(); GotoState(&Klayman::stStartClimbLadderDown); break; case 0x4822: sendMessage(_parentScene, 0x2000, 0); _destY = param.asInteger(); GotoState(&Klayman::stStartClimbLadderUp); break; case 0x4823: sendMessage(_parentScene, 0x2001, 0); GotoState(&Klayman::stClimbLadderHalf); break; case 0x4824: sendMessage(_parentScene, 0x2000, 0); _destY = _dataResource.getPoint(param.asInteger()).y; GotoState(&Klayman::stStartClimbLadderDown); break; case 0x4825: sendMessage(_parentScene, 0x2000, 0); _destY = _dataResource.getPoint(param.asInteger()).y; GotoState(&Klayman::stStartClimbLadderUp); break; case 0x4828: GotoState(&Klayman::stTurnToBackToUse); break; case 0x483F: startSpecialWalkRight(param.asInteger()); break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return 0; } uint32 KmScene1004::hmReadNote(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x04684052) { _acceptInput = true; sendMessage(_parentScene, 0x2002, 0); } break; } return messageResult; } void KmScene1004::stReadNote() { _status2 = 2; _acceptInput = false; startAnimation(0x123E9C9F, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene1004::hmReadNote); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); } KmScene1109::KmScene1109(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000), _isSittingInTeleporter(false) { // Empty } uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x2000: _isSittingInTeleporter = param.asInteger() != 0; break; case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: if (_isSittingInTeleporter) GotoState(&Klayman::sub421350); else GotoState(&Klayman::stTryStandIdle); break; case 0x4804: if (param.asInteger() != 0) { _destX = param.asInteger(); GotoState(&Klayman::stWalking); } else { GotoState(&Klayman::stPeekWall); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481D: if (_isSittingInTeleporter) GotoState(&Klayman::stTurnToUseInTeleporter); break; case 0x481E: if (_isSittingInTeleporter)//CHECKME GotoState(&Klayman::stReturnFromUseInTeleporter); break; case 0x4834: GotoState(&Klayman::stStepOver); break; case 0x4835: sendMessage(_parentScene, 0x2000, 1); _isSittingInTeleporter = true; GotoState(&Klayman::stSitInTeleporter); break; case 0x4836: sendMessage(_parentScene, 0x2000, 0); _isSittingInTeleporter = false; GotoState(&Klayman::stGetUpFromTeleporter); break; case 0x483D: sub461F30(); break; case 0x483E: sub461F70(); break; } return 0; } uint32 KmScene1109::handleMessage461EA0(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Klayman::handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x4E0A2C24) { _soundResource1.play(0x85B10BB8); } else if (param.asInteger() == 0x4E6A0CA0) { _soundResource1.play(0xC5B709B0); } break; } return messageResult; } void KmScene1109::sub461F30() { _status2 = 0; _acceptInput = false; SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene1109::handleMessage461EA0); startAnimation(0x2C2A4A1C, 0, -1); } void KmScene1109::sub461F70() { _status2 = 0; _acceptInput = false; SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene1109::handleMessage461EA0); startAnimation(0x3C2E4245, 0, -1); } // KmScene1201 KmScene1201::KmScene1201(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, Entity *class464) : Klayman(vm, parentScene, x, y, 1000, 1000), _class464(class464), _countdown(0) { // TODO setKlaymanIdleTable(dword_4AEF10, 3); _flagF6 = true; } uint32 KmScene1201::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x480A: GotoState(&KmScene1201::stMoveObject); break; case NM_KLAYMAN_PICKUP: GotoState(&Klayman::stPickUpGeneric); break; case 0x4813: GotoState(&KmScene1201::stFetchMatch); break; case 0x4814: GotoState(&KmScene1201::stTumbleHeadless); break; case 0x4815: GotoState(&KmScene1201::sub40E040); break; case NM_KLAYMAN_PRESS_BUTTON: if (param.asInteger() == 0) { GotoState(&Klayman::stPressButtonSide); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481D: GotoState(&Klayman::stTurnToUse); break; case 0x481E: GotoState(&Klayman::stReturnFromUse); break; case 0x481F: GotoState(&Klayman::stWonderAbout); 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 KmScene1201::update40DBE0() { if (_x >= 380) gotoNextStateExt(); Klayman::update(); } uint32 KmScene1201::hmMatch(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Klayman::handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x51281850) { setGlobalVar(0x20A0C516, 1); } else if (param.asInteger() == 0x43000538) { _soundResource1.play(0x21043059); } else if (param.asInteger() == 0x02B20220) { _soundResource1.play(0xC5408620); } else if (param.asInteger() == 0x0A720138) { _soundResource1.play(0xD4C08010); } else if (param.asInteger() == 0xB613A180) { _soundResource1.play(0x44051000); } break; } return messageResult; } void KmScene1201::stFetchMatch() { if (!stStartAction(AnimationCallback(&KmScene1201::stFetchMatch))) { _status2 = 0; _acceptInput = false; setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0); startAnimation(0x9CAA0218, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene1201::hmMatch); NextState(&KmScene1201::stLightMatch); } } void KmScene1201::stLightMatch() { _status2 = 1; _acceptInput = false; setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0); startAnimation(0x1222A513, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene1201::hmMatch); } uint32 KmScene1201::hmMoveObject(int messageNum, const MessageParam ¶m, Entity *sender) { switch (messageNum) { case 0x100D: if (param.asInteger() == 0x01084280) { _soundResource1.play(0x405002D8); if (_attachedSprite) { sendMessage(_attachedSprite, 0x480B, 0); } } else if (param.asInteger() == 0x02421405) { if (_countdown != 0) { _countdown--; stMoveObjectSkipTurn(); } else { SetMessageHandler(&Klayman::handleMessage41D480); } } break; } return Klayman::handleMessage41D480(messageNum, param, sender); } uint32 KmScene1201::hmTumbleHeadless(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Klayman::handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x000F0082) { _soundResource1.play(0x74E2810F); } break; } return messageResult; } void KmScene1201::stMoveObject() { if (!stStartAction(AnimationCallback(&KmScene1201::stMoveObject))) { _status2 = 2; _acceptInput = false; _countdown = 8; setDoDeltaX(0); startAnimation(0x0C1CA072, 0, -1); SetUpdateHandler(&KmScene1201::update40DBE0); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); SetMessageHandler(&KmScene1201::hmMoveObject); } } void KmScene1201::stMoveObjectSkipTurn() { _acceptInput = false; startAnimationByHash(0x0C1CA072, 0x01084280, 0); SetUpdateHandler(&KmScene1201::update40DBE0); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); SetMessageHandler(&KmScene1201::hmMoveObject); } void KmScene1201::stTumbleHeadless() { if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::stTumbleHeadless))) { _status2 = 1; _acceptInput = false; setDoDeltaX(0); startAnimation(0x2821C590, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); SetMessageHandler(&KmScene1201::hmTumbleHeadless); NextState(&Klayman::stTryStandIdle); sendMessage(_class464, 0x2006, 0); _soundResource1.play(0x62E0A356); } } void KmScene1201::sub40E040() { if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::sub40E040))) { _status2 = 1; _acceptInput = false; startAnimation(0x5420E254, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&Klayman::handleMessage41D360); } } KmScene1303::KmScene1303(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } uint32 KmScene1303::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4804: GotoState(&KmScene1303::stPeekWall1); break; case 0x483B: GotoState(&KmScene1303::stPeekWallReturn); break; case 0x483C: GotoState(&KmScene1303::stPeekWall2); break; } return 0; } uint32 KmScene1303::hmPeekWallReturn(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == calcHash("PopBalloon")) { sendMessage(_parentScene, 0x2000, 0); } else if (param.asInteger() == 0x02B20220) { _soundResource1.play(0xC5408620); } else if (param.asInteger() == 0x0A720138) { _soundResource1.play(0xD4C08010); } else if (param.asInteger() == 0xB613A180) { _soundResource1.play(0x44051000); } break; } return messageResult; } void KmScene1303::update4161A0() { Klayman::update(); _counter3++; if (_counter3 >= _counter3Max) stPeekWall3(); } void KmScene1303::stPeekWall1() { _status2 = 0; _acceptInput = true; startAnimation(0xAC20C012, 8, 37); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&Klayman::handleMessage41D480); NextState(&KmScene1303::stPeekWall3); } void KmScene1303::stPeekWall2() { _status2 = 1; _acceptInput = false; startAnimation(0xAC20C012, 43, 49); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&Klayman::handleMessage41D480); } void KmScene1303::stPeekWall3() { _counter3 = 0; _status2 = 0; _acceptInput = true; _counter3Max = _vm->_rnd->getRandomNumber(64) + 24; startAnimation(0xAC20C012, 38, 42); SetUpdateHandler(&KmScene1303::update4161A0); SetSpriteUpdate(NULL); SetMessageHandler(&Klayman::handleMessage41D360); _newStickFrameIndex = 42; } void KmScene1303::stPeekWallReturn() { _status2 = 0; _acceptInput = false; startAnimation(0x2426932E, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene1303::hmPeekWallReturn); } KmScene1304::KmScene1304(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case NM_KLAYMAN_PICKUP: if (param.asInteger() == 2) { GotoState(&Klayman::stPickUpNeedle); } else if (param.asInteger() == 1) { GotoState(&Klayman::sub41FFF0); } else { GotoState(&Klayman::stPickUpGeneric); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481F: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnAwayFromUse); } else if (param.asInteger() == 0) { GotoState(&Klayman::stTurnToUseHalf); } else { GotoState(&Klayman::stWonderAbout); } break; case 0x483F: startSpecialWalkRight(param.asInteger()); break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return 0; } KmScene1305::KmScene1305(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4804: GotoState(&KmScene1305::stCrashDown); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; } return 0; } void KmScene1305::stCrashDown() { _soundResource1.play(0x41648271); _status2 = 1; _acceptInput = false; startAnimationByHash(0x000BAB02, 0x88003000, 0); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&Klayman::handleMessage41D480); NextState(&KmScene1305::cbCrashDownEvent); } void KmScene1305::cbCrashDownEvent() { setDoDeltaX(2); stTryStandIdle(); } KmScene1306::KmScene1306(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { _isSittingInTeleporter = false; } uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam ¶m) { uint32 messageResult = 0; switch (messageNum) { case 0x2000: _isSittingInTeleporter = param.asInteger() != 0; break; case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: if (_isSittingInTeleporter) GotoState(&Klayman::sub421350); else GotoState(&Klayman::stTryStandIdle); break; case NM_KLAYMAN_PICKUP: if (param.asInteger() == 2) { GotoState(&Klayman::stPickUpNeedle); } else if (param.asInteger() == 1) { GotoState(&Klayman::sub41FFF0); } else { GotoState(&Klayman::stPickUpGeneric); } break; case NM_KLAYMAN_PRESS_BUTTON: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnPressButton); } else if (param.asInteger() == 2) { GotoState(&Klayman::stStampFloorButton); } else { GotoState(&Klayman::stPressButtonSide); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case NM_KLAYMAN_INSERT_DISK: GotoState(&Klayman::stInsertDisk); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481D: if (_isSittingInTeleporter) GotoState(&Klayman::stTurnToUseInTeleporter); else GotoState(&Klayman::stTurnToUse); break; case 0x481E: if (_isSittingInTeleporter) GotoState(&Klayman::stReturnFromUseInTeleporter); else GotoState(&Klayman::stReturnFromUse); break; case 0x481F: if (param.asInteger() == 1) { GotoState(&Klayman::stWonderAboutAfter); } else if (param.asInteger() == 0) { GotoState(&Klayman::stWonderAboutHalf); } else if (param.asInteger() == 4) { GotoState(&Klayman::stTurnAwayFromUse); } else if (param.asInteger() == 3) { GotoState(&Klayman::stTurnToUseHalf); } else { GotoState(&Klayman::stWonderAbout); } break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; case 0x482E: if (param.asInteger() == 1) { GotoState(&Klayman::stWalkToFrontNoStep); } else { GotoState(&Klayman::stWalkToFront); } break; case 0x482F: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnToFront); } else { GotoState(&Klayman::stTurnToBack); } break; case 0x4834: GotoState(&Klayman::stStepOver); break; case 0x4835: sendMessage(_parentScene, 0x2000, 1); _isSittingInTeleporter = true; GotoState(&Klayman::stSitInTeleporter); break; case 0x4836: sendMessage(_parentScene, 0x2000, 0); _isSittingInTeleporter = false; GotoState(&Klayman::stGetUpFromTeleporter); break; case 0x483D: sub417D40(); break; case 0x483E: sub417D80(); break; case 0x483F: startSpecialWalkRight(param.asInteger()); break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return messageResult; } void KmScene1306::sub417D40() { _status2 = 0; _acceptInput = false; startAnimation(0xEE084A04, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene1306::handleMessage417CB0); } void KmScene1306::sub417D80() { _status2 = 0; _acceptInput = false; startAnimation(0xB86A4274, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene1306::handleMessage417CB0); } uint32 KmScene1306::handleMessage417CB0(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x4E0A2C24) { _soundResource1.play(0x85B10BB8); } else if (param.asInteger() == 0x4E6A0CA0) { _soundResource1.play(0xC5B709B0); } } return messageResult; } KmScene1308::KmScene1308(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000), _flag1(false) { // Empty } uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x480A: if (param.asInteger() == 1) { GotoState(&Klayman::stMoveObjectSkipTurnFaceObject); } else { GotoState(&Klayman::stMoveObjectFaceObject); } break; case 0x480D: GotoState(&KmScene1001::stUseLever); break; case NM_KLAYMAN_PICKUP: if (param.asInteger() == 2) { GotoState(&Klayman::stPickUpNeedle); } else if (param.asInteger() == 1) { GotoState(&Klayman::sub41FFF0); } else { GotoState(&Klayman::stPickUpGeneric); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case NM_KLAYMAN_INSERT_DISK: if (param.asInteger() == 1) { GotoState(&KmScene1308::sub456150); } else { GotoState(&Klayman::stInsertDisk); } break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481D: GotoState(&Klayman::stTurnToUse); break; case 0x481E: GotoState(&Klayman::stReturnFromUse); break; case NM_KLAYMAN_RELEASE_LEVER: GotoState(&Klayman::stReleaseLever); break; case 0x4834: GotoState(&Klayman::stStepOver); break; case 0x483F: startSpecialWalkRight(param.asInteger()); break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return 0; } uint32 KmScene1308::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Klayman::handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (!_flag1 && param.asInteger() == 0x06040580) { nextAnimationByHash(0xDC409440, 0x46431401, 0); } else if (_flag1 && param.asInteger() == 0x46431401) { _flag1 = false; startAnimationByHash(0xDC409440, 0x01084280, 0); } else if (param.asInteger() == 0x062A1510) { _soundResource1.play(0x41688704); } else if (param.asInteger() == 0x02B20220) { _soundResource1.play(0xC5408620); } else if (param.asInteger() == 0x0A720138) { _soundResource1.play(0xD4C08010); } else if (param.asInteger() == 0xB613A180) { _soundResource1.play(0x44051000); } else if (param.asInteger() == 0x0E4C8141) { _soundResource1.play(0xDC4A1280); } break; } return messageResult; } void KmScene1308::sub456150() { if (!stStartActionFromIdle(AnimationCallback(&KmScene1308::sub456150))) { _status2 = 2; _flag1 = false; for (uint i = 0; i < 3; i++) { if (getSubVar(0x0090EA95, i)) { bool more; setSubVar(0x08D0AB11, i, 1); setSubVar(0x0090EA95, i, 0); do { more = false; setSubVar(0xA010B810, i, _vm->_rnd->getRandomNumber(16 - 1)); for (uint j = 0; j < i && !more; j++) { if (getSubVar(0x08D0AB11, j) && getSubVar(0xA010B810, j) == getSubVar(0xA010B810, i)) more = true; } if (getSubVar(0xA010B810, i) == getSubVar(0x0C10A000, i)) more = true; } while (more); _flag1 = true; } } if (!_flag1) { gotoState(NULL); gotoNextStateExt(); } else { _acceptInput = false; startAnimation(0xDC409440, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F250); SetMessageHandler(&KmScene1308::handleMessage); _flag1 = false; } } } // KmScene1401 KmScene1401::KmScene1401(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x480A: if (param.asInteger() == 1) { GotoState(&Klayman::stMoveObjectSkipTurnFaceObject); } else { GotoState(&Klayman::stMoveObjectFaceObject); } break; case NM_KLAYMAN_PRESS_BUTTON: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnPressButton); } else if (param.asInteger() == 2) { GotoState(&Klayman::stStampFloorButton); } else { GotoState(&Klayman::stPressButtonSide); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481F: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnAwayFromUse); } else if (param.asInteger() == 0) { GotoState(&Klayman::stTurnToUseHalf); } else { GotoState(&Klayman::stWonderAbout); } break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; case 0x482E: if (param.asInteger() == 1) { GotoState(&Klayman::stWalkToFrontNoStep); } else { GotoState(&Klayman::stWalkToFront); } break; case 0x482F: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnToFront); } else { GotoState(&Klayman::stTurnToBack); } break; } return 0; } // KmScene1402 KmScene1402::KmScene1402(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { SetFilterY(&Sprite::defFilterY); } uint32 KmScene1402::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x480A: if (param.asInteger() == 1) { GotoState(&Klayman::stMoveObjectSkipTurnFaceObject); } else { GotoState(&Klayman::stMoveObjectFaceObject); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481D: GotoState(&Klayman::stTurnToUse); break; case 0x481E: GotoState(&Klayman::stReturnFromUse); break; } return 0; } // KmScene1403 KmScene1403::KmScene1403(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { setKlaymanIdleTable(klaymanTable4, ARRAYSIZE(klaymanTable4)); } uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x480A: if (param.asInteger() == 1) { GotoState(&Klayman::stMoveObjectSkipTurnFaceObject); } else { GotoState(&Klayman::stMoveObjectFaceObject); } break; case 0x480D: GotoState(&KmScene1001::stUseLever); break; case NM_KLAYMAN_PICKUP: if (param.asInteger() == 2) { GotoState(&Klayman::stPickUpNeedle); } else if (param.asInteger() == 1) { GotoState(&Klayman::sub41FFF0); } else { GotoState(&Klayman::stPickUpGeneric); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case NM_KLAYMAN_RELEASE_LEVER: GotoState(&Klayman::stReleaseLever); break; case 0x483F: startSpecialWalkRight(param.asInteger()); break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return 0; } // KmScene1404 KmScene1404::KmScene1404(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x480A: if (param.asInteger() == 1) { GotoState(&Klayman::stMoveObjectSkipTurnFaceObject); } else { GotoState(&Klayman::stMoveObjectFaceObject); } break; case NM_KLAYMAN_PICKUP: if (param.asInteger() == 2) { GotoState(&Klayman::stPickUpNeedle); } else if (param.asInteger() == 1) { GotoState(&Klayman::sub41FFF0); } else { GotoState(&Klayman::stPickUpGeneric); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case NM_KLAYMAN_INSERT_DISK: GotoState(&Klayman::stInsertDisk); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481D: GotoState(&Klayman::stTurnToUse); break; case 0x481E: GotoState(&Klayman::stReturnFromUse); break; case 0x481F: if (param.asInteger() == 1) { GotoState(&Klayman::stWonderAboutAfter); } else if (param.asInteger() == 0) { GotoState(&Klayman::stWonderAboutHalf); } else if (param.asInteger() == 4) { GotoState(&Klayman::stTurnAwayFromUse); } else if (param.asInteger() == 3) { GotoState(&Klayman::stTurnToUseHalf); } else { GotoState(&Klayman::stWonderAbout); } 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; } KmScene1608::KmScene1608(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000), _isSittingInTeleporter(false) { } uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x2032: _isSittingInTeleporter = param.asInteger() != 0; break; case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: if (_isSittingInTeleporter) GotoState(&Klayman::sub421350); else GotoState(&Klayman::stTryStandIdle); break; case NM_KLAYMAN_PICKUP: if (param.asInteger() == 2) { GotoState(&Klayman::stPickUpNeedle); } else if (param.asInteger() == 1) { GotoState(&Klayman::sub41FFF0); } else { GotoState(&Klayman::stPickUpGeneric); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481D: if (_isSittingInTeleporter) GotoState(&Klayman::stTurnToUseInTeleporter); break; case 0x481E: if (_isSittingInTeleporter)//CHECKME GotoState(&Klayman::stReturnFromUseInTeleporter); break; case 0x481F: if (param.asInteger() == 1) { GotoState(&Klayman::stWonderAboutAfter); } else if (param.asInteger() == 0) { GotoState(&Klayman::stWonderAboutHalf); } else if (param.asInteger() == 4) { GotoState(&Klayman::stTurnAwayFromUse); } else if (param.asInteger() == 3) { GotoState(&Klayman::stTurnToUseHalf); } else { GotoState(&Klayman::stWonderAbout); } break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; case 0x4834: GotoState(&Klayman::stStepOver); break; case 0x4835: sendMessage(_parentScene, 0x2032, 1); _isSittingInTeleporter = true; GotoState(&Klayman::stSitInTeleporter); break; case 0x4836: sendMessage(_parentScene, 0x2032, 0); _isSittingInTeleporter = false; GotoState(&Klayman::stGetUpFromTeleporter); break; case 0x483F: startSpecialWalkRight(param.asInteger()); break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return 0; } // KmScene1705 KmScene1705::KmScene1705(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000), _isSittingInTeleporter(false) { // Empty } uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam ¶m) { uint32 messageResult = 0; switch (messageNum) { case 0x2000: _isSittingInTeleporter = param.asInteger() != 0; messageResult = 1; break; case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: if (_isSittingInTeleporter) { GotoState(&Klayman::sub421350); } else { GotoState(&Klayman::stTryStandIdle); } break; case 0x4803: GotoState(&KmScene1705::stFallSkipJump); break; case NM_KLAYMAN_PICKUP: if (param.asInteger() == 2) { GotoState(&Klayman::stPickUpNeedle); } else if (param.asInteger() == 1) { GotoState(&Klayman::sub41FFF0); } else { GotoState(&Klayman::stPickUpGeneric); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481D: if (_isSittingInTeleporter) { GotoState(&Klayman::stTurnToUseInTeleporter); } break; case 0x481E: if (_isSittingInTeleporter) { GotoState(&Klayman::stReturnFromUseInTeleporter); } break; case 0x481F: if (param.asInteger() == 1) { GotoState(&Klayman::stWonderAboutAfter); } else if (param.asInteger() == 0) { GotoState(&Klayman::stWonderAboutHalf); } else if (param.asInteger() == 4) { GotoState(&Klayman::stTurnAwayFromUse); } else if (param.asInteger() == 3) { GotoState(&Klayman::stTurnToUseHalf); } else { GotoState(&Klayman::stWonderAbout); } break; case 0x4834: GotoState(&Klayman::stStepOver); break; case 0x4835: sendMessage(_parentScene, 0x2000, 1); _isSittingInTeleporter = true; GotoState(&Klayman::stSitInTeleporter); break; case 0x4836: sendMessage(_parentScene, 0x2000, 0); _isSittingInTeleporter = false; GotoState(&Klayman::stGetUpFromTeleporter); break; case 0x483D: sub468AD0(); break; case 0x483E: sub468B10(); break; } return messageResult; } uint32 KmScene1705::handleMessage4689A0(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x4E0A2C24) { _soundResource1.play(0x85B10BB8); } else if (param.asInteger() == 0x4E6A0CA0) { _soundResource1.play(0xC5B709B0); } break; } return messageResult; } void KmScene1705::spriteUpdate468A30() { updateDeltaXY(); HitRect *hitRect = _vm->_collisionMan->findHitRectAtPos(_x, _y + 10); if (hitRect->type == 0x5001) { _y = hitRect->rect.y1; processDelta(); sendMessage(this, 0x1019, 0); } } void KmScene1705::stFallSkipJump() { _status2 = 2; _acceptInput = false; startAnimationByHash(0xB93AB151, 0x40A100F8, 0); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&KmScene1705::spriteUpdate468A30); SetMessageHandler(&Klayman::handleMessage41D360); NextState(&Klayman::stLandOnFeet); } void KmScene1705::sub468AD0() { _status2 = 0; _acceptInput = false; startAnimation(0x5E0A4905, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene1705::handleMessage4689A0); } void KmScene1705::sub468B10() { _status2 = 0; _acceptInput = false; startAnimation(0xD86E4477, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene1705::handleMessage4689A0); } KmScene1901::KmScene1901(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481D: GotoState(&Klayman::stTurnToUse); break; case 0x481E: GotoState(&Klayman::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; } KmScene2001::KmScene2001(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000), _isSittingInTeleporter(false) { // Empty } uint32 KmScene2001::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x2000: _isSittingInTeleporter = param.asInteger() != 0; break; case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: if (_isSittingInTeleporter) { GotoState(&Klayman::sub421350); } else GotoState(&Klayman::stTryStandIdle); break; case 0x4804: if (param.asInteger() != 0) { _destX = param.asInteger(); GotoState(&Klayman::stWalking); } else GotoState(&Klayman::stPeekWall); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481D: if (_isSittingInTeleporter) GotoState(&Klayman::stTurnToUseInTeleporter); break; case 0x481E: if (_isSittingInTeleporter) { GotoState(&Klayman::stReturnFromUseInTeleporter); } break; case 0x4834: GotoState(&Klayman::stStepOver); break; case 0x4835: sendMessage(_parentScene, 0x2000, 1); _isSittingInTeleporter = true; GotoState(&Klayman::stSitInTeleporter); break; case 0x4836: sendMessage(_parentScene, 0x2000, 0); _isSittingInTeleporter = false; GotoState(&Klayman::stGetUpFromTeleporter); break; case 0x483D: sub440230(); break; case 0x483E: stDoTeleport(); break; } return 0; } uint32 KmScene2001::handleMessage4401A0(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x4E0A2C24) { _soundResource1.play(0x85B10BB8); } if (param.asInteger() == 0x4E6A0CA0) { _soundResource1.play(0xC5B709B0); } break; } return messageResult; } void KmScene2001::sub440230() { _status2 = 0; _acceptInput = false; startAnimation(0xBE68CC54, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene2001::handleMessage4401A0); } void KmScene2001::stDoTeleport() { _status2 = 0; _acceptInput = false; startAnimation(0x18AB4ED4, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene2001::handleMessage4401A0); } KmScene2101::KmScene2101(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000), _isSittingInTeleporter(false) { // Empty } uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam ¶m) { uint32 messageResult = 0; switch (messageNum) { case 0x2000: _isSittingInTeleporter = param.asInteger() != 0; messageResult = 1; break; case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: if (_isSittingInTeleporter) GotoState(&Klayman::sub421350); else GotoState(&Klayman::stTryStandIdle); break; case 0x4811: GotoState(&KmScene2101::sub4862C0); break; case NM_KLAYMAN_PICKUP: if (param.asInteger() == 2) { GotoState(&Klayman::stPickUpNeedle); } else if (param.asInteger() == 1) { GotoState(&Klayman::sub41FFF0); } else { GotoState(&Klayman::stPickUpGeneric); } break; case NM_KLAYMAN_PRESS_BUTTON: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnPressButton); } else if (param.asInteger() == 2) { GotoState(&Klayman::stStampFloorButton); } else { GotoState(&Klayman::stPressButtonSide); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481D: if (_isSittingInTeleporter) GotoState(&Klayman::stTurnToUseInTeleporter); break; case 0x481E: if (_isSittingInTeleporter)//CHECKME GotoState(&Klayman::stReturnFromUseInTeleporter); break; case 0x4834: GotoState(&Klayman::stStepOver); break; case 0x4835: sendMessage(_parentScene, 0x2000, 1); _isSittingInTeleporter = true; GotoState(&Klayman::stSitInTeleporter); break; case 0x4836: sendMessage(_parentScene, 0x2000, 0); _isSittingInTeleporter = false; GotoState(&Klayman::stGetUpFromTeleporter); break; case 0x483D: sub486320(); break; case 0x483E: sub486360(); break; } return messageResult; } uint32 KmScene2101::handleMessage486160(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); int16 speedUpFrameIndex; switch (messageNum) { case 0x1008: speedUpFrameIndex = getFrameIndex(kKlaymanSpeedUpHash); if (_currFrameIndex < speedUpFrameIndex) { startAnimation(0x35AA8059, speedUpFrameIndex, -1); _y = 438; } messageResult = 0; break; case 0x100D: if (param.asInteger() == 0x1A1A0785) { _soundResource1.play(0x40F0A342); } else if (param.asInteger() == 0x60428026) { _soundResource1.play(0x40608A59); } break; } return messageResult; } uint32 KmScene2101::handleMessage486230(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x4E0A2C24) { _soundResource1.play(0x85B10BB8); } else if (param.asInteger() == 0x4E6A0CA0) { _soundResource1.play(0xC5B709B0); } break; } return messageResult; } void KmScene2101::sub4862C0() { _status2 = 1; _acceptInput = false; startAnimation(0x35AA8059, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); SetMessageHandler(&KmScene2101::handleMessage486160); _soundResource1.play(0x402E82D4); } void KmScene2101::sub486320() { _status2 = 0; _acceptInput = false; startAnimation(0xFF290E30, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene2101::handleMessage486230); } void KmScene2101::sub486360() { _status2 = 0; _acceptInput = false; startAnimation(0x9A28CA1C, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene2101::handleMessage486230); } KmScene2201::KmScene2201(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount) // TODO: NRect *rect1, int16 unk in Klayman ctor : Klayman(vm, parentScene, x, y, 1000, 1000) { _dataResource.load(0x04104242); _flagF6 = false; } uint32 KmScene2201::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case NM_KLAYMAN_PICKUP: GotoState(&Klayman::stPickUpGeneric); break; case NM_KLAYMAN_PRESS_BUTTON: if (param.asInteger() == 0) { GotoState(&Klayman::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) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481D: GotoState(&Klayman::stTurnToUse); break; case 0x481E: GotoState(&Klayman::stReturnFromUse); break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; case 0x482E: if (param.asInteger() == 1) { GotoState(&Klayman::stWalkToFrontNoStep); } else { GotoState(&Klayman::stWalkToFront); } break; case 0x482F: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnToFront); } else { GotoState(&Klayman::stTurnToBack); } break; case 0x483F: startSpecialWalkRight(param.asInteger()); break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return 0; } KmScene2203::KmScene2203(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case NM_KLAYMAN_PICKUP: if (param.asInteger() == 2) { GotoState(&Klayman::stPickUpNeedle); } else if (param.asInteger() == 1) { GotoState(&Klayman::sub41FFF0); } else { GotoState(&Klayman::stPickUpGeneric); } break; case NM_KLAYMAN_PRESS_BUTTON: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnPressButton); } else if (param.asInteger() == 2) { GotoState(&Klayman::stStampFloorButton); } else { GotoState(&Klayman::stPressButtonSide); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x4818: startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; case 0x4819: GotoState(&Klayman::stClayDoorOpen); break; case NM_KLAYMAN_INSERT_DISK: GotoState(&Klayman::stInsertDisk); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481D: GotoState(&Klayman::stTurnToUse); break; case 0x481E: GotoState(&Klayman::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; } KmScene2205::KmScene2205(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } void KmScene2205::xUpdate() { setGlobalVar(0x18288913, _currFrameIndex); } uint32 KmScene2205::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4804: if (param.asInteger() != 0) { _destX = param.asInteger(); GotoState(&KmScene2205::sub423980); } else { GotoState(&Klayman::stPeekWall); } break; case NM_KLAYMAN_PRESS_BUTTON: if (param.asInteger() == 0) { GotoState(&Klayman::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; } void KmScene2205::sub423980() { int16 frameIndex = getGlobalVar(0x18288913); if (frameIndex < 0 || frameIndex > 13) frameIndex = 0; _status2 = 0; _isWalking = true; _acceptInput = true; startAnimation(0x1A249001, frameIndex, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EB70); SetSpriteUpdate(&Klayman::spriteUpdate41F300); NextState(&Klayman::stUpdateWalking); FinalizeState(&Klayman::stStartWalkingDone); } KmScene2206::KmScene2206(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // TODO Sound1ChList_addSoundResource(0x80101800, 0xD3B02847); } KmScene2206::~KmScene2206() { // TODO Sound1ChList_sub_407AF0(0x80101800); } void KmScene2206::xUpdate() { setGlobalVar(0x18288913, _currFrameIndex); } uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4803: GotoState(&KmScene2206::sub482490); break; case 0x4804: if (param.asInteger() != 0) { _destX = param.asInteger(); GotoState(&KmScene2206::sub482530); } else { GotoState(&Klayman::stPeekWall); } break; case NM_KLAYMAN_PICKUP: if (param.asInteger() == 1) { GotoState(&Klayman::sub41FFF0); } else { GotoState(&Klayman::stPickUpGeneric); } break; case NM_KLAYMAN_PRESS_BUTTON: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnPressButton); } else if (param.asInteger() == 2) { GotoState(&Klayman::stStampFloorButton); } else { GotoState(&Klayman::stPressButtonSide); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481F: if (param.asInteger() == 0) { GotoState(&Klayman::stWonderAboutHalf); } else if (param.asInteger() == 1) { GotoState(&Klayman::stWonderAboutAfter); } else if (param.asInteger() == 3) { GotoState(&Klayman::stTurnToUseHalf); } else if (param.asInteger() == 4) { GotoState(&Klayman::stTurnAwayFromUse); } else { GotoState(&Klayman::stWonderAbout); } break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; case 0x482E: if (param.asInteger() == 1) { GotoState(&Klayman::stWalkToFrontNoStep); } else { GotoState(&Klayman::stWalkToFront); } break; case 0x482F: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnToFront); } else { GotoState(&Klayman::stTurnToBack); } break; case 0x4837: sub41CE70(); break; case 0x483F: startSpecialWalkRight(param.asInteger()); break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return 0; } void KmScene2206::spriteUpdate482450() { _yDelta++; _y += _yDelta; if (_y > 600) sendMessage(this, 0x1019, 0); } void KmScene2206::sub482490() { if (!stStartActionFromIdle(AnimationCallback(&KmScene2206::sub482490))) { _status2 = 1; sendMessage(_parentScene, 0x4803, 0); _acceptInput = false; _yDelta = 0; startAnimation(0x5420E254, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41D360); SetSpriteUpdate(&KmScene2206::spriteUpdate482450); // TODO Sound1ChList_playLooping(0xD3B02847); } } void KmScene2206::sub482530() { int16 frameIndex = getGlobalVar(0x18288913) + 1; if (frameIndex < 0 || frameIndex > 13) frameIndex = 0; _status2 = 0; _isWalking = true; _acceptInput = true; startAnimation(0x1A249001, frameIndex, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EB70); SetSpriteUpdate(&Klayman::spriteUpdate41F300); NextState(&Klayman::stUpdateWalking); FinalizeState(&Klayman::stStartWalkingDone); } KmScene2207::KmScene2207(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x2001: GotoState(&KmScene2207::sub442460); break; case 0x2005: spriteUpdate442430(); GotoState(&KmScene2207::stTryStandIdle); break; case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x480D: GotoState(&KmScene2207::sub4424B0); break; case NM_KLAYMAN_PICKUP: GotoState(&Klayman::stPickUpGeneric); break; case NM_KLAYMAN_PRESS_BUTTON: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnPressButton); } else if (param.asInteger() == 2) { GotoState(&Klayman::stStampFloorButton); } else { GotoState(&Klayman::stPressButtonSide); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case NM_KLAYMAN_RELEASE_LEVER: GotoState(&Klayman::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; } void KmScene2207::spriteUpdate442430() { _x = _attachedSprite->getX() - 20; _y = _attachedSprite->getY() + 46; processDelta(); } void KmScene2207::sub442460() { if (!stStartActionFromIdle(AnimationCallback(&KmScene2207::sub442460))) { _status2 = 1; _acceptInput = true; startAnimation(0x5420E254, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&KmScene2207::spriteUpdate442430); SetMessageHandler(&Klayman::handleMessage41D360); } } void KmScene2207::sub4424B0() { if (!stStartAction(AnimationCallback(&KmScene2207::sub4424B0))) { _status2 = 0; if (_isLeverDown) { stUseLeverRelease(); } else { _acceptInput = false; startAnimation(0x0C303040, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&KmScene2207::spriteUpdate41F230); SetMessageHandler(&Klayman::handleMessage41E210); NextState(&KmScene2207::sub442520); } } } void KmScene2207::sub442520() { startAnimation(0x0D318140, 0, -1); sendMessage(_attachedSprite, 0x480F, 0); NextState(&KmScene2207::sub442560); } void KmScene2207::sub442560() { startAnimation(0x1564A2C0, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F230); NextState(&KmScene2207::sub4425A0); _acceptInput = true; _isLeverDown = true; } void KmScene2207::sub4425A0() { startAnimation(0x4464A440, 0, -1); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&Klayman::spriteUpdate41F230); SetMessageHandler(&Klayman::handleMessage41D360); _acceptInput = true; _isLeverDown = true; } KmScene2242::KmScene2242(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } void KmScene2242::xUpdate() { setGlobalVar(0x18288913, _currFrameIndex); } uint32 KmScene2242::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4804: if (param.asInteger() != 0) { _destX = param.asInteger(); GotoState(&KmScene2242::sub444D20); } else { GotoState(&Klayman::stPeekWall); } break; case NM_KLAYMAN_PICKUP: if (param.asInteger() == 2) { GotoState(&Klayman::stPickUpNeedle); } else if (param.asInteger() == 1) { GotoState(&Klayman::sub41FFF0); } else { GotoState(&Klayman::stPickUpGeneric); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481F: if (param.asInteger() == 0) { GotoState(&Klayman::stWonderAboutHalf); } else if (param.asInteger() == 1) { GotoState(&Klayman::stWonderAboutAfter); } else if (param.asInteger() == 3) { GotoState(&Klayman::stTurnToUseHalf); } else if (param.asInteger() == 4) { GotoState(&Klayman::stTurnAwayFromUse); } else { GotoState(&Klayman::stWonderAbout); } break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; case 0x4837: sub41CE70(); break; } return 0; } void KmScene2242::sub444D20() { int16 frameIndex = (int16)getGlobalVar(0x18288913); if (frameIndex < 0 || frameIndex > 13) frameIndex = 0; _status2 = 0; _isWalking = true; _acceptInput = true; startAnimation(0x1A249001, frameIndex, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EB70); SetSpriteUpdate(&Klayman::spriteUpdate41F300); NextState(&Klayman::stUpdateWalking); FinalizeState(&Klayman::stStartWalkingDone); } KmHallOfRecords::KmHallOfRecords(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } void KmHallOfRecords::xUpdate() { setGlobalVar(0x18288913, _currFrameIndex); } uint32 KmHallOfRecords::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4804: if (param.asInteger() != 0) { _destX = param.asInteger(); GotoState(&KmHallOfRecords::sub43B130); } else { GotoState(&Klayman::stPeekWall); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481F: if (param.asInteger() == 0) { GotoState(&Klayman::stWonderAboutHalf); } else if (param.asInteger() == 1) { GotoState(&Klayman::stWonderAboutAfter); } else if (param.asInteger() == 3) { GotoState(&Klayman::stTurnToUseHalf); } else if (param.asInteger() == 4) { GotoState(&Klayman::stTurnAwayFromUse); } else { GotoState(&Klayman::stWonderAbout); } break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; case 0x4837: sub41CE70(); break; } return 0; } void KmHallOfRecords::sub43B130() { int16 frameIndex = (int16)getGlobalVar(0x18288913); if (frameIndex < 0 || frameIndex > 13) frameIndex = 0; _status2 = 0; _isWalking = true; _acceptInput = true; startAnimation(0x1A249001, frameIndex, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EB70); SetSpriteUpdate(&Klayman::spriteUpdate41F300); NextState(&Klayman::stUpdateWalking); FinalizeState(&Klayman::stStartWalkingDone); } KmScene2247::KmScene2247(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } void KmScene2247::xUpdate() { setGlobalVar(0x18288913, _currFrameIndex); } uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4804: if (param.asInteger() != 0) { _destX = param.asInteger(); GotoState(&KmScene2247::sub453520); } else { GotoState(&Klayman::stPeekWall); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481F: if (param.asInteger() == 0) { GotoState(&Klayman::stWonderAboutHalf); } else if (param.asInteger() == 1) { GotoState(&Klayman::stWonderAboutAfter); } else if (param.asInteger() == 3) { GotoState(&Klayman::stTurnToUseHalf); } else if (param.asInteger() == 4) { GotoState(&Klayman::stTurnAwayFromUse); } else { GotoState(&Klayman::stWonderAbout); } break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; case 0x4837: sub41CE70(); break; } return 0; } void KmScene2247::sub453520() { int16 frameIndex = (int16)getGlobalVar(0x18288913); if (frameIndex < 0 || frameIndex > 13) frameIndex = 0; _status2 = 0; _isWalking = true; _acceptInput = true; startAnimation(0x1A249001, frameIndex, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&Klayman::handleMessage41EB70); SetSpriteUpdate(&Klayman::spriteUpdate41F300); NextState(&Klayman::stUpdateWalking); FinalizeState(&Klayman::stStartWalkingDone); } KmScene2401::KmScene2401(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000), _readyToSpit(false) { // Empty } uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam ¶m) { uint32 messageResult = 0; switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4816: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnPressButton); } else if (param.asInteger() == 2) { GotoState(&Klayman::stStampFloorButton); } else { GotoState(&Klayman::stPressButtonSide); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481F: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnAwayFromUse); } else if (param.asInteger() == 0) { GotoState(&Klayman::stTurnToUseHalf); } else { GotoState(&Klayman::stWonderAbout); } break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; case 0x482E: if (param.asInteger() == 1) { GotoState(&Klayman::stWalkToFrontNoStep); } else { GotoState(&Klayman::stWalkToFront); } break; case 0x482F: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnToFront); } else { GotoState(&Klayman::stTurnToBack); } break; case 0x4832: GotoState(&Klayman::sub421110); break; case 0x4833: if (param.asInteger() == 1) GotoState(&Klayman::stWonderAboutHalf); else { _spitPipeIndex = sendMessage(_parentScene, 0x2000, 0); GotoState(&KmScene2401::stTrySpitIntoPipe); } break; case 0x483F: startSpecialWalkRight(param.asInteger()); break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return messageResult; } uint32 KmScene2401::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = Klayman::handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x16401CA6) { _canSpit = true; if (_contSpit) spitIntoPipe(); } else if (param.asInteger() == 0xC11C0008) { _canSpit = false; _acceptInput = false; _readyToSpit = false; } else if (param.asInteger() == 0x018A0001) { sendMessage(_parentScene, 0x2001, _spitDestPipeIndex); } break; } return messageResult; } void KmScene2401::stTrySpitIntoPipe() { if (_readyToSpit) { _contSpit = true; _spitContDestPipeIndex = _spitPipeIndex; if (_canSpit) spitIntoPipe(); } else if (!stStartAction(AnimationCallback(&KmScene2401::stTrySpitIntoPipe))) { _status2 = 2; _acceptInput = true; _spitDestPipeIndex = _spitPipeIndex; _readyToSpit = true; _canSpit = false; _contSpit = false; startAnimation(0x1808B150, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene2401::handleMessage); SetSpriteUpdate(NULL); } } void KmScene2401::spitIntoPipe() { _contSpit = false; _spitDestPipeIndex = _spitContDestPipeIndex; _canSpit = false; _acceptInput = false; startAnimation(0x1B08B553, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene2401::handleMessage); SetSpriteUpdate(NULL); NextState(&KmScene2401::stContSpitIntoPipe); } void KmScene2401::stContSpitIntoPipe() { _canSpit = true; _acceptInput = true; startAnimationByHash(0x1808B150, 0x16401CA6, 0); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene2401::handleMessage); SetSpriteUpdate(NULL); } KmScene2501::KmScene2501(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000), _isSittingInTeleporter(false) { // Empty } uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam ¶m) { uint32 messageResult = 0; switch (messageNum) { case 0x2000: _isSittingInTeleporter = param.asInteger() != 0; messageResult = 1; break; case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: if (_isSittingInTeleporter) GotoState(&Klayman::sub421350); else GotoState(&Klayman::stTryStandIdle); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481D: if (_isSittingInTeleporter) GotoState(&Klayman::stTurnToUseInTeleporter); break; case 0x481E: if (_isSittingInTeleporter) GotoState(&Klayman::stReturnFromUseInTeleporter); break; case 0x4834: GotoState(&Klayman::stStepOver); break; case 0x4835: sendMessage(_parentScene, 0x2000, 1); _isSittingInTeleporter = true; GotoState(&Klayman::stSitInTeleporter); break; case 0x4836: sendMessage(_parentScene, 0x2000, 0); _isSittingInTeleporter = false; GotoState(&Klayman::stGetUpFromTeleporter); break; } return messageResult; } KmScene2801::KmScene2801(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } uint32 KmScene2801::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case NM_KLAYMAN_PICKUP: GotoState(&Klayman::stPickUpGeneric); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481D: GotoState(&Klayman::stTurnToUse); break; case 0x481E: GotoState(&Klayman::stReturnFromUse); break; case 0x481F: if (param.asInteger() == 1) { GotoState(&Klayman::stWonderAboutAfter); } else if (param.asInteger() == 0) { GotoState(&Klayman::stWonderAboutHalf); } else if (param.asInteger() == 4) { GotoState(&Klayman::stTurnAwayFromUse); } else if (param.asInteger() == 3) { GotoState(&Klayman::stTurnToUseHalf); } else { GotoState(&Klayman::stWonderAbout); } break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; case 0x482E: if (param.asInteger() == 1) { GotoState(&Klayman::stWalkToFrontNoStep); } else { GotoState(&Klayman::stWalkToFront); } break; case 0x482F: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnToFront); } else { GotoState(&Klayman::stTurnToBack); } break; case 0x4837: sub41CE70(); break; } return 0; } KmScene2803::KmScene2803(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount) : Klayman(vm, parentScene, x, y, 1000, 1000) { // TODO ClipRects stuff _dataResource.load(0x00900849); } uint32 KmScene2803::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4803: _destY = param.asInteger(); GotoState(&Klayman::sub4204C0); break; case 0x4804: if (param.asInteger() == 3) GotoState(&Klayman::sub421230); break; case 0x480D: GotoState(&Klayman::sub420F60); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x4818: startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; case 0x481D: GotoState(&Klayman::stTurnToUse); break; case 0x481E: GotoState(&Klayman::stReturnFromUse); break; case 0x481F: if (param.asInteger() == 1) { GotoState(&Klayman::stWonderAboutAfter); } else { GotoState(&Klayman::stWonderAboutHalf); } break; case 0x482E: GotoState(&Klayman::stWalkToFront); break; case 0x482F: GotoState(&Klayman::stTurnToBack); break; case 0x4834: GotoState(&Klayman::stStepOver); break; case 0x4838: GotoState(&Klayman::sub420500); break; } return 0; } KmScene2803b::KmScene2803b(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000), _soundResource(vm) { _dataResource.load(0x81120132); _soundResource.load(0x10688664); } uint32 KmScene2803b::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: sub41CDE0(param.asPoint().x); break; case 0x4004: GotoState(&Klayman::sub421640); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x4818: sub41CDE0(_dataResource.getPoint(param.asInteger()).x); break; case 0x481F: if (param.asInteger() == 1) GotoState(&Klayman::sub421740); else if (param.asInteger() == 0) GotoState(&Klayman::sub421780); else GotoState(&Klayman::sub421700); break; case 0x482E: if (param.asInteger() == 1) GotoState(&Klayman::sub421840); else if (param.asInteger() == 2) GotoState(&Klayman::sub421800); else GotoState(&Klayman::sub4217C0); break; case 0x482F: if (param.asInteger() == 1) GotoState(&Klayman::sub421900); else if (param.asInteger() == 2) GotoState(&Klayman::sub4218C0); else GotoState(&Klayman::sub421880); break; case 0x4830: GotoState(&KmScene2803b::sub460670); break; } return 0; } uint32 KmScene2803b::handleMessage460600(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x80C110B5) sendMessage(_parentScene, 0x482A, 0); else if (param.asInteger() == 0x33288344) _soundResource.play(); break; } return messageResult; } void KmScene2803b::sub460670() { _status2 = 0; _acceptInput = false; startAnimation(0x1AE88904, 0, -1); _soundResource1.play(0x4C69EA53); SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); SetMessageHandler(&KmScene2803b::handleMessage460600); } KmScene2805::KmScene2805(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000), _isSittingInTeleporter(false) { // Empty } uint32 KmScene2805::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x2000: _isSittingInTeleporter = param.asInteger() != 0; break; case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: if (_isSittingInTeleporter) GotoState(&Klayman::sub421350); else GotoState(&Klayman::stTryStandIdle); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481D: if (_isSittingInTeleporter) GotoState(&Klayman::stTurnToUseInTeleporter); break; case 0x481E: if (_isSittingInTeleporter) GotoState(&Klayman::stReturnFromUseInTeleporter); break; case 0x4834: GotoState(&Klayman::stStepOver); break; case 0x4835: sendMessage(_parentScene, 0x2000, 1); _isSittingInTeleporter = true; GotoState(&Klayman::stSitInTeleporter); break; case 0x4836: sendMessage(_parentScene, 0x2000, 0); _isSittingInTeleporter = false; GotoState(&Klayman::stGetUpFromTeleporter); break; case 0x483D: sub404890(); break; case 0x483E: sub4048D0(); break; } return 0; } uint32 KmScene2805::handleMessage404800(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x4E0A2C24) _soundResource1.play(0x85B10BB8); else if (param.asInteger() == 0x4E6A0CA0) _soundResource1.play(0xC5B709B0); break; } return messageResult; } void KmScene2805::sub404890() { _status2 = 0; _acceptInput = false; SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene2805::handleMessage404800); startAnimation(0xDE284B74, 0, -1); } void KmScene2805::sub4048D0() { _status2 = 0; _acceptInput = false; SetUpdateHandler(&Klayman::update); SetSpriteUpdate(NULL); SetMessageHandler(&KmScene2805::handleMessage404800); startAnimation(0xD82A4094, 0, -1); } KmScene2806::KmScene2806(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, bool flag, NRect *clipRects, uint clipRectsCount) : Klayman(vm, parentScene, x, y, 1000, 1000), _soundRes1(vm), _soundRes2(vm), _soundRes3(vm), _soundRes4(vm), _soundRes5(vm) { // Empty if (flag) { // TODO Maybe? Don't know. Set Klayman clip rects _soundRes1.load(0x58E0C341); _soundRes2.load(0x40A00342); _soundRes3.load(0xD0A1C348); _soundRes4.load(0x166FC6E0); _soundRes5.load(0x00018040); } _dataResource.load(0x98182003); } uint32 KmScene2806::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4804: startWalkToX(440, true); break; case 0x480D: GotoState(&Klayman::sub420F60); break; case 0x4816: if (param.asInteger() == 0) { GotoState(&Klayman::stPressButtonSide); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x4818: startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; case 0x4831: GotoState(&KmScene2806::sub40F780); break; case 0x4832: if (param.asInteger() == 1) { GotoState(&KmScene2806::sub40F7C0); } else { GotoState(&Klayman::sub421110); } break; } return 0; } uint32 KmScene2806::handleMessage40F1F0(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x1008: if (_flag1) { startAnimationByHash(0x1C388C04, 0x004A2148, 0); messageResult = 0; } else _flag2 = true; break; case 0x100D: if (param.asInteger() == 0x0002418E) sendMessage(_parentScene, 0x2000, 0); else if (param.asInteger() == 0x924090C2) { _flag1 = true; if (_flag2) { startAnimationByHash(0x1C388C04, 0x004A2148, 0); messageResult = 0; } } else if (param.asInteger() == 0x004A2148) _flag1 = false; else if (param.asInteger() == 0x02B20220) _soundResource1.play(0xC5408620); else if (param.asInteger() == 0x0A720138) _soundResource1.play(0xD4C08010); else if (param.asInteger() == 0x03020231) _soundResource1.play(0xD4C08010); else if (param.asInteger() == 0xB613A180) _soundResource1.play(0x44051000); else if (param.asInteger() == 0x67221A03) _soundResource1.play(0x44051000); else if (param.asInteger() == 0x038A010B) _soundResource1.play(0x00018040); else if (param.asInteger() == 0x422B0280) _soundResource1.play(0x166FC6E0); else if (param.asInteger() == 0x925A0C1E) _soundResource1.play(0x40E5884D); else if (param.asInteger() == 0x00020814) _soundResource1.play(0x786CC6D0); else if (param.asInteger() == 0x06020500) _soundResource1.play(0x1069C0E1); else if (param.asInteger() == 0x02128C00) _soundResource1.play(0x5068C4C3); else if (param.asInteger() == 0x82022030) _soundResource1.play(0x5C48C0E8); break; } return messageResult; } uint32 KmScene2806::handleMessage40F570(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x32180101) _soundResource1.play(0x405002D8); else if (param.asInteger() == 0x0A2A9098) _soundResource1.play(0x0460E2FA); else if (param.asInteger() == 0xD00A0C0C) _soundRes1.play(); else if (param.asInteger() == 0x04121920) _soundRes2.play(); else if (param.asInteger() == 0x030B4480) _soundRes3.play(); else if (param.asInteger() == 0x422B0280) _soundRes4.play(); else if (param.asInteger() == 0x038A010B) _soundRes5.play(); else if (param.asInteger() == 0x67221A03) _soundResource1.play(0x44051000); else if (param.asInteger() == 0x02B20220) _soundResource1.play(0xC5408620); else if (param.asInteger() == 0x925A0C1E) _soundResource1.play(0x40E5884D); else if (param.asInteger() == 0x03020231) _soundResource1.play(0xD4C08010); else if (param.asInteger() == 0x08040840) setDoDeltaX(2); break; } return messageResult; } void KmScene2806::sub40F780() { _status2 = 0; _acceptInput = false; SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); SetMessageHandler(&KmScene2806::handleMessage40F570); startAnimation(0x2838C010, 0, -1); } void KmScene2806::sub40F7C0() { _status2 = 1; _acceptInput = false; _flag1 = false; _flag2 = false; SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); SetMessageHandler(&KmScene2806::handleMessage40F1F0); startAnimation(0x1C388C04, 0, -1); } KmScene2809::KmScene2809(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, bool flag, NRect *clipRects, uint clipRectsCount) : Klayman(vm, parentScene, x, y, 1000, 1000), _soundRes1(vm), _soundRes2(vm), _soundRes3(vm), _soundRes4(vm), _soundRes5(vm) { if (flag) { // TODO Maybe? Don't know. Set Klayman clip rects _soundRes1.load(0x58E0C341); _soundRes2.load(0x40A00342); _soundRes3.load(0xD0A1C348); _soundRes4.load(0x166FC6E0); _soundRes5.load(0x00018040); } _dataResource.load(0x1830009A); } uint32 KmScene2809::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4804: startWalkToX(226, true); break; case 0x480D: GotoState(&Klayman::sub420F60); break; case 0x4816: if (param.asInteger() == 0) { GotoState(&Klayman::stPressButtonSide); } break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x4818: startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; case 0x4831: GotoState(&KmScene2809::sub458550); break; case 0x4832: if (param.asInteger() == 1) { GotoState(&KmScene2809::sub458590); } else { GotoState(&Klayman::sub421110); } break; } return 0; } uint32 KmScene2809::handleMessage457FC0(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x1008: if (_flag1) { startAnimationByHash(0x1C388C04, 0x004A2148, 0); messageResult = 0; } else _flag2 = true; break; case 0x100D: if (param.asInteger() == 0x0002418E) sendMessage(_parentScene, 0x2000, 0); else if (param.asInteger() == 0x924090C2) { _flag1 = true; if (_flag2) { startAnimationByHash(0x1C388C04, 0x004A2148, 0); messageResult = 0; } } else if (param.asInteger() == 0x004A2148) _flag1 = false; else if (param.asInteger() == 0x02B20220) _soundResource1.play(0xC5408620); else if (param.asInteger() == 0x0A720138) _soundResource1.play(0xD4C08010); else if (param.asInteger() == 0x03020231) _soundResource1.play(0xD4C08010); else if (param.asInteger() == 0xB613A180) _soundResource1.play(0x44051000); else if (param.asInteger() == 0x67221A03) _soundResource1.play(0x44051000); else if (param.asInteger() == 0x038A010B) _soundResource1.play(0x00018040); else if (param.asInteger() == 0x422B0280) _soundResource1.play(0x166FC6E0); else if (param.asInteger() == 0x925A0C1E) _soundResource1.play(0x40E5884D); else if (param.asInteger() == 0x000F0082) _soundResource1.play(0x546CDCC1); else if (param.asInteger() == 0x00020814) _soundResource1.play(0x786CC6D0); else if (param.asInteger() == 0x06020500) _soundResource1.play(0x1069C0E1); else if (param.asInteger() == 0x02128C00) _soundResource1.play(0x5068C4C3); else if (param.asInteger() == 0x82022030) _soundResource1.play(0x5C48C0E8); break; } return messageResult; } uint32 KmScene2809::handleMessage458340(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: if (param.asInteger() == 0x32180101) _soundResource1.play(0x405002D8); else if (param.asInteger() == 0x0A2A9098) _soundResource1.play(0x0460E2FA); else if (param.asInteger() == 0xD00A0C0C) _soundRes1.play(); else if (param.asInteger() == 0x04121920) _soundRes2.play(); else if (param.asInteger() == 0x030B4480) _soundRes3.play(); else if (param.asInteger() == 0x422B0280) _soundRes4.play(); else if (param.asInteger() == 0x038A010B) _soundRes5.play(); else if (param.asInteger() == 0x67221A03) _soundResource1.play(0x44051000); else if (param.asInteger() == 0x02B20220) _soundResource1.play(0xC5408620); else if (param.asInteger() == 0x925A0C1E) _soundResource1.play(0x40E5884D); else if (param.asInteger() == 0x03020231) _soundResource1.play(0xD4C08010); else if (param.asInteger() == 0x08040840) setDoDeltaX(2); break; } return messageResult; } void KmScene2809::sub458550() { _status2 = 0; _acceptInput = false; startAnimation(0x2838C010, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene2809::handleMessage458340); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); } void KmScene2809::sub458590() { _status2 = 1; _acceptInput = false; _flag1 = false; _flag2 = false; startAnimation(0x1C388C04, 0, -1); SetUpdateHandler(&Klayman::update); SetMessageHandler(&KmScene2809::handleMessage457FC0); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); } KmScene2810Small::KmScene2810Small(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } uint32 KmScene2810Small::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: sub41CDE0(param.asPoint().x); break; case 0x4004: GotoState(&Klayman::sub421640); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x4818: sub41CDE0(_dataResource.getPoint(param.asInteger()).x); break; case 0x481F: if (param.asInteger() == 1) GotoState(&Klayman::sub421740); else if (param.asInteger() == 0) GotoState(&Klayman::sub421780); else GotoState(&Klayman::sub421700); break; case 0x482E: if (param.asInteger() == 1) { GotoState(&Klayman::sub421840); } else { GotoState(&Klayman::sub4217C0); } break; case 0x482F: if (param.asInteger() == 1) { GotoState(&Klayman::sub421900); } else { GotoState(&Klayman::sub421880); } break; case 0x4837: sub41CE70(); break; } return 0; } KmScene2810::KmScene2810(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, NRect *clipRects, uint clipRectsCount) : Klayman(vm, parentScene, x, y, 1000, 1000) { // TODO ClipRects stuff } uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4803: _destY = param.asInteger(); GotoState(&Klayman::sub4204C0); break; case 0x4804: if (param.asInteger() == 3) GotoState(&Klayman::sub421230); break; case 0x4812: GotoState(&Klayman::stPickUpGeneric); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x4818: startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; case 0x481B: if (param.asPoint().y != 0) { sub41CC40(param.asPoint().y, param.asPoint().x); } else { sub41CCE0(param.asPoint().x); } break; case 0x481F: if (param.asInteger() == 0) { GotoState(&Klayman::stWonderAboutHalf); } else if (param.asInteger() == 1) { GotoState(&Klayman::stWonderAboutAfter); } else if (param.asInteger() == 3) { GotoState(&Klayman::stTurnToUseHalf); } else if (param.asInteger() == 4) { GotoState(&Klayman::stTurnAwayFromUse); } else if (param.asInteger() == 5) { GotoState(&Klayman::sub421270); } else { GotoState(&Klayman::stWonderAbout); } break; case 0x4820: sendMessage(_parentScene, 0x2000, 0); GotoState(&Klayman::stContinueClimbLadderUp); break; case 0x4821: sendMessage(_parentScene, 0x2000, 0); _destY = param.asInteger(); GotoState(&Klayman::stStartClimbLadderDown); break; case 0x4822: sendMessage(_parentScene, 0x2000, 0); _destY = param.asInteger(); GotoState(&Klayman::stStartClimbLadderUp); break; case 0x4823: sendMessage(_parentScene, 0x2001, 0); GotoState(&Klayman::stClimbLadderHalf); break; case 0x4824: sendMessage(_parentScene, 0x2000, 0); _destY = _dataResource.getPoint(param.asInteger()).y; GotoState(&Klayman::stStartClimbLadderDown); break; case 0x4825: sendMessage(_parentScene, 0x2000, 0); _destY = _dataResource.getPoint(param.asInteger()).y; GotoState(&Klayman::stStartClimbLadderUp); break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; case 0x4837: sub41CE70(); break; } return 0; } KmScene2812::KmScene2812(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) : Klayman(vm, parentScene, x, y, 1000, 1000) { // Empty } uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam ¶m) { switch (messageNum) { case 0x4001: case 0x4800: startWalkToX(param.asPoint().x, false); break; case 0x4004: GotoState(&Klayman::stTryStandIdle); break; case 0x4805: _destY = param.asInteger(); debug("_destY = %d", _destY); GotoState(&Klayman::sub420460); break; case 0x4812: if (param.asInteger() == 2) GotoState(&Klayman::stPickUpNeedle); else if (param.asInteger() == 1) GotoState(&Klayman::sub41FFF0); else GotoState(&Klayman::stPickUpGeneric); break; case 0x4817: setDoDeltaX(param.asInteger()); gotoNextStateExt(); break; case 0x481A: GotoState(&Klayman::stInsertDisk); break; case 0x481B: if (param.asPoint().y != 0) sub41CC40(param.asPoint().y, param.asPoint().x); else sub41CCE0(param.asPoint().x); break; case 0x481D: GotoState(&Klayman::stTurnToUse); break; case 0x481E: GotoState(&Klayman::stReturnFromUse); break; case 0x4820: sendMessage(_parentScene, 0x2001, 0); GotoState(&Klayman::stContinueClimbLadderUp); break; case 0x4821: sendMessage(_parentScene, 0x2001, 0); _destY = param.asInteger(); GotoState(&Klayman::stStartClimbLadderDown); break; case 0x4822: sendMessage(_parentScene, 0x2001, 0); _destY = param.asInteger(); GotoState(&Klayman::stStartClimbLadderUp); break; case 0x4823: sendMessage(_parentScene, 0x2002, 0); GotoState(&Klayman::stClimbLadderHalf); break; case 0x482D: setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); gotoNextStateExt(); break; case 0x482E: if (param.asInteger() == 1) { GotoState(&Klayman::stWalkToFrontNoStep); } else { GotoState(&Klayman::stWalkToFront); } break; case 0x482F: if (param.asInteger() == 1) { GotoState(&Klayman::stTurnToFront); } else { GotoState(&Klayman::stTurnToBack); } break; case 0x483F: startSpecialWalkRight(param.asInteger()); break; case 0x4840: startSpecialWalkLeft(param.asInteger()); break; } return 0; } } // End of namespace Neverhood