Initial commit
This commit is contained in:
794
engines/neverhood/modules/module1000.cpp
Normal file
794
engines/neverhood/modules/module1000.cpp
Normal file
@@ -0,0 +1,794 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1000.h"
|
||||
#include "neverhood/modules/module1000_sprites.h"
|
||||
|
||||
#include "common/config-manager.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module1000::Module1000(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
_musicFileHash = getGlobalVar(V_ENTRANCE_OPEN) ? 0x81106480 : 0x00103144;
|
||||
|
||||
_vm->_soundMan->addMusic(0x03294419, 0x061880C6);
|
||||
_vm->_soundMan->addMusic(0x03294419, _musicFileHash);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 0)
|
||||
createScene(0, 0);
|
||||
else if (which == 1)
|
||||
createScene(1, 1);
|
||||
|
||||
}
|
||||
|
||||
Module1000::~Module1000() {
|
||||
_vm->_soundMan->deleteMusicGroup(0x03294419);
|
||||
}
|
||||
|
||||
void Module1000::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1000::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_vm->_soundMan->startMusic(0x061880C6, 0, 0);
|
||||
_childObject = new Scene1001(_vm, this, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_vm->_soundMan->startMusic(0x061880C6, 0, 0);
|
||||
_childObject = new Scene1002(_vm, this, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
_vm->_soundMan->startMusic(0x061880C6, 0, 0);
|
||||
createStaticScene(0xC084110C, 0x41108C00);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
_vm->_soundMan->stopMusic(0x061880C6, 0, 2);
|
||||
_childObject = new Scene1004(_vm, this, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_vm->_soundMan->stopMusic(0x061880C6, 0, 0);
|
||||
_vm->_soundMan->startMusic(_musicFileHash, 0, 0);
|
||||
_childObject = new Scene1005(_vm, this, which);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1000::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1000::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 2)
|
||||
createScene(2, 0);
|
||||
else
|
||||
createScene(1, 0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 1)
|
||||
leaveModule(0);
|
||||
else if (_moduleResult == 2) {
|
||||
if (_vm->isDemo() && !_vm->isBigDemo())
|
||||
// Demo version returns to the same scene
|
||||
createScene(1, 2);
|
||||
else
|
||||
createScene(3, 0);
|
||||
} else
|
||||
createScene(0, 1);
|
||||
break;
|
||||
case 2:
|
||||
createScene(0, 2);
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 1)
|
||||
createScene(4, 0);
|
||||
else
|
||||
createScene(1, 2);
|
||||
break;
|
||||
case 4:
|
||||
_vm->_soundMan->stopMusic(_musicFileHash, 0, 1);
|
||||
createScene(3, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _asDoor(nullptr), _asWindow(nullptr) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetMessageHandler(&Scene1001::handleMessage);
|
||||
|
||||
setHitRects(0x004B4860);
|
||||
setBackground(0x4086520E);
|
||||
setPalette(0x4086520E);
|
||||
insertScreenMouse(0x6520A400);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
setRectList(0x004B49F0);
|
||||
insertKlaymen<KmScene1001>(200, 433);
|
||||
setMessageList(0x004B4888);
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the right
|
||||
setRectList(0x004B49F0);
|
||||
insertKlaymen<KmScene1001>(640, 433);
|
||||
setMessageList(0x004B4898);
|
||||
} else if (which == 2) {
|
||||
// Klaymen returning from looking through the window
|
||||
setRectList(0x004B49F0);
|
||||
if (getGlobalVar(V_KLAYMEN_IS_DELTA_X)) {
|
||||
insertKlaymen<KmScene1001>(390, 433);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
} else {
|
||||
insertKlaymen<KmScene1001>(300, 433);
|
||||
}
|
||||
setMessageList(0x004B4970);
|
||||
} else {
|
||||
// Klaymen sleeping
|
||||
setRectList(0x004B4A00);
|
||||
insertKlaymen<KmScene1001>(200, 433);
|
||||
setMessageList(0x004B4890);
|
||||
}
|
||||
|
||||
tempSprite = insertStaticSprite(0x2080A3A8, 1300);
|
||||
|
||||
_klaymen->setClipRect(0, 0, tempSprite->getDrawRect().x2(), 480);
|
||||
|
||||
if (!getGlobalVar(V_DOOR_BUSTED)) {
|
||||
_asDoor = insertSprite<AsScene1001Door>();
|
||||
_asDoor->setClipRect(0, 0, tempSprite->getDrawRect().x2(), 480);
|
||||
}
|
||||
|
||||
_asLever = insertSprite<AsScene1001Lever>(this, 150, 433, 1);
|
||||
|
||||
insertStaticSprite(0x809861A6, 950);
|
||||
insertStaticSprite(0x89C03848, 1100);
|
||||
|
||||
_ssButton = insertSprite<SsCommonButtonSprite>(this, 0x15288120, 100, 0);
|
||||
|
||||
if (!getGlobalVar(V_WINDOW_OPEN)) {
|
||||
tempSprite = insertStaticSprite(0x8C066150, 200);
|
||||
_asWindow = insertSprite<AsScene1001Window>();
|
||||
_asWindow->setClipRect(tempSprite->getDrawRect());
|
||||
}
|
||||
|
||||
_asHammer = insertSprite<AsScene1001Hammer>(_asDoor);
|
||||
|
||||
}
|
||||
|
||||
Scene1001::~Scene1001() {
|
||||
setGlobalVar(V_KLAYMEN_IS_DELTA_X, _klaymen->isDoDeltaX());
|
||||
}
|
||||
|
||||
uint32 Scene1001::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x00342624) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asLever);
|
||||
setMessageList2(0x004B4910);
|
||||
messageResult = 1;
|
||||
} else if (param.asInteger() == 0x21E64A00) {
|
||||
if (getGlobalVar(V_DOOR_BUSTED)) {
|
||||
setMessageList(0x004B48A8);
|
||||
} else {
|
||||
setMessageList(0x004B48C8);
|
||||
}
|
||||
messageResult = 1;
|
||||
} else if (param.asInteger() == 0x040424D0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssButton);
|
||||
} else if (param.asInteger() == 0x80006358) {
|
||||
if (getGlobalVar(V_WINDOW_OPEN)) {
|
||||
setMessageList(0x004B4938);
|
||||
} else {
|
||||
setMessageList(0x004B4960);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
setRectList(0x004B49F0);
|
||||
break;
|
||||
case 0x480B:
|
||||
sendMessage(_asWindow, 0x2001, 0);
|
||||
break;
|
||||
case NM_KLAYMEN_LOWER_LEVER:
|
||||
sendMessage(_asHammer, 0x2000, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
Scene1002::Scene1002(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _isKlaymenFloor(false), _isClimbingLadder(false), _asKlaymenPeekHand(nullptr) {
|
||||
|
||||
NRect tempClipRect;
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetUpdateHandler(&Scene1002::update);
|
||||
SetMessageHandler(&Scene1002::handleMessage);
|
||||
|
||||
setHitRects(0x004B4138);
|
||||
setBackground(0x12C23307);
|
||||
setPalette(0x12C23307);
|
||||
|
||||
insertStaticSprite(0x06149428, 1100);
|
||||
insertStaticSprite(0x312C8774, 1100);
|
||||
|
||||
_ssLadderArch = insertStaticSprite(0x152C1313, 1015);
|
||||
_ssLadderArchPart1 = insertStaticSprite(0x060000A0, 1200);
|
||||
_ssLadderArchPart2 = insertStaticSprite(0xB2A423B0, 1100);
|
||||
_ssLadderArchPart3 = insertStaticSprite(0x316E0772, 1100);
|
||||
|
||||
_ssCeiling = insertStaticSprite(0x316C4BB4, 1015);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
if (_vm->_gameState.which == 0) {
|
||||
// Klaymen on top
|
||||
insertKlaymen<KmScene1002>(90, 226);
|
||||
_asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
setMessageList(0x004B4270);
|
||||
_klaymen->setClipRect(31, 0, _ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart3->getDrawRect().y2());
|
||||
_asKlaymenLadderHands->getSurface()->getClipRect() = _klaymen->getSurface()->getClipRect();
|
||||
_klaymen->setRepl(64, 0);
|
||||
} else {
|
||||
// Klaymen on the floor
|
||||
insertKlaymen<KmScene1002>(379, 435);
|
||||
_asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
setMessageList(0x004B4270);
|
||||
_klaymen->setClipRect(_ssLadderArch->getDrawRect().x, 0, _ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart1->getDrawRect().y2());
|
||||
_asKlaymenLadderHands->setClipRect(_klaymen->getClipRect());
|
||||
}
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the right
|
||||
insertKlaymen<KmScene1002>(650, 435);
|
||||
_asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
setMessageList(0x004B4478);
|
||||
_klaymen->setClipRect(_ssLadderArch->getDrawRect().x, 0, _ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart1->getDrawRect().y2());
|
||||
_asKlaymenLadderHands->setClipRect(_klaymen->getClipRect());
|
||||
_vm->_gameState.which = 1;
|
||||
} else if (which == 2) {
|
||||
// Klaymen coming up the ladder
|
||||
insertKlaymen<KmScene1002>(68, 645);
|
||||
_asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
setMessageList(0x004B4298);
|
||||
_klaymen->setClipRect(_ssLadderArch->getDrawRect().x, 0, _ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart1->getDrawRect().y2());
|
||||
_asKlaymenLadderHands->setClipRect(_klaymen->getClipRect());
|
||||
_vm->_gameState.which = 1;
|
||||
sendMessage(_klaymen, 0x4820, 0);
|
||||
} else {
|
||||
// Klaymen entering from the left, peeking
|
||||
insertKlaymen<KmScene1002>(90, 226);
|
||||
_asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
setMessageList(0x004B4470);
|
||||
_klaymen->setClipRect(31, 0, _ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart3->getDrawRect().y2());
|
||||
_asKlaymenLadderHands->setClipRect(_klaymen->getClipRect());
|
||||
_asKlaymenPeekHand = insertSprite<AsScene1002KlaymenPeekHand>(this, _klaymen);
|
||||
_asKlaymenPeekHand->setClipRect(_klaymen->getClipRect());
|
||||
_klaymen->setRepl(64, 0);
|
||||
_vm->_gameState.which = 0;
|
||||
}
|
||||
|
||||
insertScreenMouse(0x23303124);
|
||||
|
||||
tempSprite = insertStaticSprite(0xB3242310, 825);
|
||||
tempClipRect.set(tempSprite->getDrawRect().x, tempSprite->getDrawRect().y,
|
||||
_ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart2->getDrawRect().y2());
|
||||
|
||||
_asRing1 = insertSprite<AsScene1002Ring>(this, false, 258, 191, _ssCeiling->getDrawRect().y, false);
|
||||
_asRing2 = insertSprite<AsScene1002Ring>(this, false, 297, 189, _ssCeiling->getDrawRect().y, false);
|
||||
_asRing3 = insertSprite<AsScene1002Ring>(this, true, 370, 201, _ssCeiling->getDrawRect().y, getGlobalVar(V_FLYTRAP_RING_DOOR));
|
||||
_asRing4 = insertSprite<AsScene1002Ring>(this, false, 334, 191, _ssCeiling->getDrawRect().y, false);
|
||||
_asRing5 = insertSprite<AsScene1002Ring>(this, false, 425, 184, _ssCeiling->getDrawRect().y, false);
|
||||
|
||||
_asDoor = insertSprite<AsScene1002Door>(tempClipRect);
|
||||
tempSprite = insertSprite<AsScene1002BoxingGloveHitEffect>();
|
||||
_asDoorSpy = insertSprite<AsScene1002DoorSpy>(tempClipRect, this, _asDoor, tempSprite);
|
||||
_ssPressButton = insertSprite<SsCommonPressButton>(this, 0x00412692, 0x140B60BE, 800, 0);
|
||||
_asVenusFlyTrap = insertSprite<AsScene1002VenusFlyTrap>(this, _klaymen, false);
|
||||
addCollisionSprite(_asVenusFlyTrap);
|
||||
|
||||
sendEntityMessage(_klaymen, NM_CAR_MOVE_TO_PREV_POINT, _asVenusFlyTrap);
|
||||
|
||||
_asOutsideDoorBackground = insertSprite<AsScene1002OutsideDoorBackground>();
|
||||
|
||||
setRectList(0x004B43A0);
|
||||
|
||||
loadSound(1, 0x60755842);
|
||||
loadSound(2, 0x616D5821);
|
||||
|
||||
}
|
||||
|
||||
Scene1002::~Scene1002() {
|
||||
}
|
||||
|
||||
void Scene1002::update() {
|
||||
Scene::update();
|
||||
if (!_isKlaymenFloor && _klaymen->getY() > 230) {
|
||||
_klaymen->setClipRect(_ssLadderArch->getDrawRect().x, 0, _ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart1->getDrawRect().y2());
|
||||
_asKlaymenLadderHands->setClipRect(_klaymen->getClipRect());
|
||||
deleteSprite(&_ssLadderArchPart3);
|
||||
_klaymen->clearRepl();
|
||||
_isKlaymenFloor = true;
|
||||
_vm->_gameState.which = 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene1002::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0xE6EE60E1) {
|
||||
if (getGlobalVar(V_FLYTRAP_RING_DOOR))
|
||||
setMessageList(0x004B4428);
|
||||
else
|
||||
setMessageList(0x004B4448);
|
||||
messageResult = 1;
|
||||
} else if (param.asInteger() == 0x4A845A00)
|
||||
sendEntityMessage(_klaymen, 0x1014, _asRing1);
|
||||
else if (param.asInteger() == 0x43807801)
|
||||
sendEntityMessage(_klaymen, 0x1014, _asRing2);
|
||||
else if (param.asInteger() == 0x46C26A01) {
|
||||
if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
|
||||
setMessageList(0x004B44B8);
|
||||
} else {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asRing3);
|
||||
if (_asVenusFlyTrap->getX() - 10 < 366 && _asVenusFlyTrap->getX() + 10 > 366) {
|
||||
setGlobalVar(V_FLYTRAP_RING_EATEN, 1);
|
||||
setMessageList(0x004B44A8);
|
||||
} else {
|
||||
setMessageList(0x004B44A0);
|
||||
}
|
||||
}
|
||||
messageResult = 1;
|
||||
} else if (param.asInteger() == 0x468C7B11)
|
||||
sendEntityMessage(_klaymen, 0x1014, _asRing4);
|
||||
else if (param.asInteger() == 0x42845B19)
|
||||
sendEntityMessage(_klaymen, 0x1014, _asRing5);
|
||||
else if (param.asInteger() == 0xC0A07458)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssPressButton);
|
||||
break;
|
||||
case 0x1024:
|
||||
sendMessage(_parentModule, 0x1024, param.asInteger());
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (_isClimbingLadder) {
|
||||
setMessageList2(0x004B43D0);
|
||||
} else {
|
||||
if (_klaymen->getY() > 420) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asVenusFlyTrap);
|
||||
setMessageList2(0x004B4480);
|
||||
} else if (_klaymen->getY() > 227) {
|
||||
setMessageList2(0x004B41E0);
|
||||
} else {
|
||||
setMessageList2(0x004B4148);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
_messageList = nullptr;
|
||||
break;
|
||||
case NM_KLAYMEN_CLIMB_LADDER:
|
||||
_isClimbingLadder = true;
|
||||
setRectList(0x004B4418);
|
||||
break;
|
||||
case NM_KLAYMEN_STOP_CLIMBING:
|
||||
_isClimbingLadder = false;
|
||||
setRectList(0x004B43A0);
|
||||
break;
|
||||
case NM_KLAYMEN_USE_OBJECT:
|
||||
if (sender == _asRing1) {
|
||||
setGlobalVar(V_RADIO_ENABLED, 0);
|
||||
playSound(0, 0x665198C0);
|
||||
} else if (sender == _asRing2) {
|
||||
setGlobalVar(V_RADIO_ENABLED, 0);
|
||||
playSound(0, 0xE2D389C0);
|
||||
} else if (sender == _asRing3) {
|
||||
setGlobalVar(V_RADIO_ENABLED, 0);
|
||||
playSound(1);
|
||||
sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
sendMessage(_asOutsideDoorBackground, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
} else if (sender == _asRing4) {
|
||||
setGlobalVar(V_RADIO_ENABLED, 0);
|
||||
playSound(0, 0xE0558848);
|
||||
} else if (sender == _asRing5) {
|
||||
setGlobalVar(V_RADIO_ENABLED, 1);
|
||||
playSound(0, 0x44014282);
|
||||
}
|
||||
break;
|
||||
case NM_KLAYMEN_RAISE_LEVER:
|
||||
if (sender == _asRing3) {
|
||||
playSound(2);
|
||||
sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
|
||||
sendMessage(_asOutsideDoorBackground, NM_KLAYMEN_CLOSE_DOOR, 0);
|
||||
} else if (sender == _asVenusFlyTrap) {
|
||||
if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
|
||||
sendMessage(_asRing3, NM_KLAYMEN_RAISE_LEVER, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x480B:
|
||||
sendEntityMessage(_klaymen, 0x1014, _asDoorSpy);
|
||||
break;
|
||||
case NM_KLAYMEN_LOWER_LEVER:
|
||||
setGlobalVar(V_RADIO_ENABLED, 0);
|
||||
playSound(1);
|
||||
sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
sendMessage(_asOutsideDoorBackground, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
break;
|
||||
case 0x8000:
|
||||
setSpriteSurfacePriority(_ssCeiling, 995);
|
||||
setSpriteSurfacePriority(_ssLadderArch, 995);
|
||||
break;
|
||||
case 0x8001:
|
||||
setSpriteSurfacePriority(_ssCeiling, 1015);
|
||||
setSpriteSurfacePriority(_ssLadderArch, 1015);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
Scene1004::Scene1004(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _paletteAreaStatus(-1) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetUpdateHandler(&Scene1004::update);
|
||||
SetMessageHandler(&Scene1004::handleMessage);
|
||||
|
||||
setBackground(0x50C03005);
|
||||
|
||||
if (getGlobalVar(V_ENTRANCE_OPEN)) {
|
||||
setPalette(0xA30BA329);
|
||||
_palette->addBasePalette(0xA30BA329, 0, 256, 0);
|
||||
} else {
|
||||
setPalette(0x50C03005);
|
||||
_palette->addBasePalette(0x50C03005, 0, 256, 0);
|
||||
}
|
||||
addEntity(_palette);
|
||||
|
||||
insertScreenMouse(0x03001504);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
setRectList(0x004B7C70);
|
||||
insertKlaymen<KmScene1004>(330, 327);
|
||||
setMessageList(0x004B7C18);
|
||||
} else if (which == 1) {
|
||||
// Klaymen returning from reading a note
|
||||
setRectList(0x004B7C70);
|
||||
insertKlaymen<KmScene1004>(330, 327);
|
||||
setMessageList(0x004B7C08);
|
||||
} else {
|
||||
// Klaymen coming down the ladder
|
||||
loadDataResource(0x01900A04);
|
||||
insertKlaymen<KmScene1004>(_dataResource.getPoint(0x80052A29).x, 27);
|
||||
setMessageList(0x004B7BF0);
|
||||
}
|
||||
|
||||
updatePaletteArea();
|
||||
|
||||
_asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
|
||||
insertStaticSprite(0x800034A0, 1100);
|
||||
insertStaticSprite(0x64402020, 1100);
|
||||
insertStaticSprite(0x3060222E, 1300);
|
||||
tempSprite = insertStaticSprite(0x0E002004, 1300);
|
||||
|
||||
_klaymen->setClipRect(0, tempSprite->getDrawRect().y, 640, 480);
|
||||
_asKlaymenLadderHands->setClipRect(_klaymen->getClipRect());
|
||||
|
||||
_asTrashCan = insertSprite<AsScene1004TrashCan>();
|
||||
|
||||
}
|
||||
|
||||
void Scene1004::update() {
|
||||
Scene::update();
|
||||
updatePaletteArea();
|
||||
}
|
||||
|
||||
uint32 Scene1004::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x926500A1) {
|
||||
setMessageList(0x004B7C20);
|
||||
messageResult = 1;
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
loadDataResource(0x01900A04);
|
||||
break;
|
||||
case 0x2001:
|
||||
setRectList(0x004B7C70);
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
sendMessage(_asTrashCan, NM_POSITION_CHANGE, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void Scene1004::updatePaletteArea() {
|
||||
if (_klaymen->getY() < 150) {
|
||||
if (_paletteAreaStatus != 0) {
|
||||
_paletteAreaStatus = 0;
|
||||
_palette->addBasePalette(0x406B0D10, 0, 64, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
}
|
||||
} else {
|
||||
if (_paletteAreaStatus != 1) {
|
||||
_paletteAreaStatus = 1;
|
||||
_palette->addBasePalette(0x24332243, 0, 64, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene1005::Scene1005(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
SetMessageHandler(&Scene1005::handleMessage);
|
||||
|
||||
if (getGlobalVar(V_ENTRANCE_OPEN)) {
|
||||
setBackground(0x2800E011);
|
||||
setPalette(0x2800E011);
|
||||
insertStaticSprite(0x492D5AD7, 100);
|
||||
insertPuzzleMouse(0x0E015288, 20, 620);
|
||||
} else {
|
||||
setBackground(0x8870A546);
|
||||
setPalette(0x8870A546);
|
||||
insertStaticSprite(0x40D1E0A9, 100);
|
||||
insertStaticSprite(0x149C00A6, 100);
|
||||
insertPuzzleMouse(0x0A54288F, 20, 620);
|
||||
}
|
||||
|
||||
drawTextToBackground();
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene1005::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
|
||||
leaveScene(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Scene1005::drawTextToBackground() {
|
||||
uint32 textIndex = getTextIndex();
|
||||
if (_vm->getLanguage() == Common::Language::JA_JPN) {
|
||||
static const struct {
|
||||
uint32 image_id;
|
||||
int x, y;
|
||||
} jp_images[] = {
|
||||
/* 1 */ { 0xB1048044, 205, 39 },
|
||||
/* 2 */ { 0x31048045, 201, 54 },
|
||||
/* 3 */ { 0x31048046, 193, 37 },
|
||||
/* 4 */ { 0x31048040, 192, 57 },
|
||||
/* 5 */ { 0x3104804C, 195, 43 },
|
||||
/* 6 */ { 0x31048054, 188, 32 },
|
||||
/* 7 */ { 0x31048064, 201, 52 },
|
||||
/* 8 */ { 0x31048004, 191, 51 },
|
||||
/* 9 */ { 0x310480C4, 197, 58 },
|
||||
/* 10 */ { 0xB2048044, 196, 65 },
|
||||
/* 11 */ { 0x32048045, 188, 53 },
|
||||
/* 12 */ { 0x32048046, 190, 71 },
|
||||
/* 13 */ { 0x32048040, 210, 45 },
|
||||
/* 14 */ { 0x3204804C, 199, 67 },
|
||||
/* 15 */ { 0x32048054, 214, 58 },
|
||||
/* 16 */ { 0x32048064, 201, 52 },
|
||||
/* 17 */ { 0x32048004, 205, 57 },
|
||||
/* 18 */ { 0x320480C4, 215, 65 },
|
||||
/* 19 */ { 0x32048144, 223, 85 },
|
||||
/* 20 */ { 0x34048045, 208, 82 },
|
||||
/* 21 */ { 0x34048046, 200, 66 },
|
||||
/* 22 */ { 0x34048040, 209, 76 },
|
||||
/* 23 */ { 0x3404804C, 211, 80 },
|
||||
/* 24 */ { 0x34048054, 211, 50 },
|
||||
/* 25 */ { 0x34048064, 224, 76 },
|
||||
/* 26 */ { 0x34048004, 209, 85 },
|
||||
/* 27 */ { 0x340480C4, 202, 61 },
|
||||
/* 28 */ { 0x34048144, 206, 79 },
|
||||
/* 29 */ { 0x34048244, 219, 71 },
|
||||
/* 30 */ { 0x38048046, 200, 87 },
|
||||
/* 31 */ { 0x38048040, 215, 85 },
|
||||
/* 32 */ { 0x3804804C, 209, 87 },
|
||||
/* 33 */ { 0x38048054, 201, 62 },
|
||||
/* 34 */ { 0x38048064, 213, 95 },
|
||||
/* 35 */ { 0x38048004, 204, 90 },
|
||||
/* 36 */ { 0x380480C4, 214, 77 },
|
||||
/* 37 */ { 0x38048144, 211, 96 },
|
||||
/* 38 */ { 0x38048244, 207, 91 },
|
||||
/* 39 */ { 0x38048444, 207, 71 },
|
||||
/* 40 */ { 0x20048040, 206, 68 },
|
||||
/* 41 */ { 0x2004804C, 201, 140 },
|
||||
/* 42 */ { 0x20048054, 218, 122 },
|
||||
/* 43 */ { 0x20048064, 219, 107 },
|
||||
/* 44 */ { 0x20048004, 214, 115 },
|
||||
/* 45 */ { 0x200480C4, 193, 142 },
|
||||
/* 46 */ { 0x20048144, 210, 130 },
|
||||
/* 47 */ { 0x20048244, 208, 110 },
|
||||
/* 48 */ { 0x20048444, 213, 112 },
|
||||
/* 49 */ { 0x20048844, 221, 112 },
|
||||
/* 50 */ { 0x1004804C, 207, 133 },
|
||||
/* 51 */ { 0x10048054, 209, 111 },
|
||||
};
|
||||
if (textIndex >= ARRAYSIZE(jp_images))
|
||||
textIndex = 0;
|
||||
addSprite(new StaticSprite(_vm, jp_images[textIndex].image_id, kSLFSetPosition, jp_images[textIndex].x, jp_images[textIndex].y));
|
||||
} else {
|
||||
TextResource textResource(_vm);
|
||||
const char *textStart, *textEnd;
|
||||
int16 x = 188, y = 36;
|
||||
FontSurface *fontSurface = FontSurface::createFontSurface(_vm, getGlobalVar(V_ENTRANCE_OPEN) ? 0x283CE401 : 0xC6604282);
|
||||
textResource.load(0x80283101);
|
||||
textStart = textResource.getString(textIndex, textEnd);
|
||||
if (_vm->shouldOffsetFontNhc()) {
|
||||
x += 15;
|
||||
y += 18;
|
||||
}
|
||||
while (textStart < textEnd) {
|
||||
fontSurface->drawString(_background->getSurface(), x, y, (const byte*)textStart);
|
||||
y += 36;
|
||||
textStart += strlen(textStart) + 1;
|
||||
}
|
||||
delete fontSurface;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene1005::getTextIndex() {
|
||||
uint32 textIndex;
|
||||
textIndex = getTextIndex1();
|
||||
if (getGlobalVar(V_ENTRANCE_OPEN)) {
|
||||
textIndex = getKloggsTextIndex();
|
||||
}
|
||||
if (getGlobalVar(V_TEXT_FLAG1) && getGlobalVar(V_TEXT_INDEX) == textIndex) {
|
||||
textIndex = getTextIndex3(textIndex);
|
||||
} else {
|
||||
setGlobalVar(V_TEXT_FLAG1, 1);
|
||||
setGlobalVar(V_TEXT_INDEX, textIndex);
|
||||
}
|
||||
return textIndex;
|
||||
}
|
||||
|
||||
uint32 Scene1005::getTextIndex1() {
|
||||
uint32 textIndex;
|
||||
if (getGlobalVar(V_WORLDS_JOINED)) {
|
||||
if (!getGlobalVar(V_DOOR_PASSED))
|
||||
textIndex = 18;
|
||||
else if (!getGlobalVar(V_ROBOT_TARGET))
|
||||
textIndex = 19;
|
||||
else if (getGlobalVar(V_ROBOT_HIT)) {
|
||||
if (!getGlobalVar(V_ENTRANCE_OPEN))
|
||||
textIndex = 23;
|
||||
else if (!getSubVar(VA_HAS_KEY, 0) && !getSubVar(VA_IS_KEY_INSERTED, 0))
|
||||
textIndex = 24;
|
||||
else if (!getGlobalVar(V_HAS_FINAL_KEY))
|
||||
textIndex = 26;
|
||||
else if (!getSubVar(VA_HAS_KEY, 1) && !getSubVar(VA_IS_KEY_INSERTED, 1))
|
||||
textIndex = 27;
|
||||
else if (!getGlobalVar(V_HAS_FINAL_KEY))
|
||||
textIndex = 28;
|
||||
else
|
||||
textIndex = 29;
|
||||
} else if (!getGlobalVar(V_FELL_DOWN_HOLE))
|
||||
textIndex = 20;
|
||||
else if (!getGlobalVar(V_SEEN_SYMBOLS_NO_LIGHT))
|
||||
textIndex = 21;
|
||||
else
|
||||
textIndex = 22;
|
||||
} else if (getGlobalVar(V_BOLT_DOOR_UNLOCKED)) {
|
||||
if (!getGlobalVar(V_WALL_BROKEN))
|
||||
textIndex = 12;
|
||||
else if (!getGlobalVar(V_STAIRS_DOWN_ONCE))
|
||||
textIndex = 13;
|
||||
else if (!getGlobalVar(V_RADIO_ENABLED))
|
||||
textIndex = 50;
|
||||
else if (!getGlobalVar(V_UNUSED))
|
||||
textIndex = 14;
|
||||
else if (!getGlobalVar(V_BEEN_SHRINKING_ROOM))
|
||||
textIndex = 15;
|
||||
else if (!getGlobalVar(V_BEEN_STATUE_ROOM))
|
||||
textIndex = 16;
|
||||
else
|
||||
textIndex = 17;
|
||||
} else if (!getGlobalVar(V_FLYTRAP_RING_EATEN)) {
|
||||
textIndex = 0;
|
||||
} else if (getGlobalVar(V_CREATURE_EXPLODED)) {
|
||||
if (!getGlobalVar(V_TILE_PUZZLE_SOLVED))
|
||||
textIndex = 4;
|
||||
else if (!getGlobalVar(V_HAS_TEST_TUBE))
|
||||
textIndex = 5;
|
||||
else if (!getSubVar(VA_LOCKS_DISABLED, 0x40119852))
|
||||
textIndex = 6;
|
||||
else if (!getGlobalVar(V_WATER_RUNNING))
|
||||
textIndex = 7;
|
||||
else if (!getGlobalVar(V_NOTES_PUZZLE_SOLVED))
|
||||
textIndex = 8;
|
||||
else if (!getSubVar(VA_LOCKS_DISABLED, 0x304008D2))
|
||||
textIndex = 9;
|
||||
else if (!getSubVar(VA_LOCKS_DISABLED, 0x01180951))
|
||||
textIndex = 10;
|
||||
else
|
||||
textIndex = 11;
|
||||
} else if (!getGlobalVar(V_CREATURE_ANGRY)) {
|
||||
textIndex = 1;
|
||||
} else if (getGlobalVar(V_TNT_DUMMY_BUILT)) {
|
||||
textIndex = 3;
|
||||
} else {
|
||||
textIndex = 2;
|
||||
}
|
||||
return textIndex;
|
||||
}
|
||||
|
||||
uint32 Scene1005::getKloggsTextIndex() {
|
||||
uint32 textIndex = getGlobalVar(V_TEXT_COUNTING_INDEX1);
|
||||
if (textIndex + 1 > 10) {
|
||||
textIndex = 0;
|
||||
}
|
||||
setGlobalVar(V_TEXT_COUNTING_INDEX1, textIndex + 1);
|
||||
return textIndex + 40;
|
||||
}
|
||||
|
||||
uint32 Scene1005::getTextIndex3(uint32 usefulHint) {
|
||||
uint32 textIndex = getGlobalVar(V_TEXT_COUNTING_INDEX2);
|
||||
if (textIndex + 1 > 10 && ConfMan.getBool("repeatwilliehint")) {
|
||||
setGlobalVar(V_TEXT_COUNTING_INDEX2, 0);
|
||||
return usefulHint;
|
||||
}
|
||||
if (textIndex + 1 > 10) {
|
||||
textIndex = 0;
|
||||
}
|
||||
setGlobalVar(V_TEXT_COUNTING_INDEX2, textIndex + 1);
|
||||
return textIndex + 30;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
109
engines/neverhood/modules/module1000.h
Normal file
109
engines/neverhood/modules/module1000.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1000_H
|
||||
#define NEVERHOOD_MODULES_MODULE1000_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1000 : public Module {
|
||||
public:
|
||||
Module1000(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1000() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
uint32 _musicFileHash;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene1001 : public Scene {
|
||||
public:
|
||||
Scene1001(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene1001() override;
|
||||
protected:
|
||||
Sprite *_asHammer;
|
||||
Sprite *_asDoor;
|
||||
Sprite *_asWindow;
|
||||
Sprite *_asLever;
|
||||
Sprite *_ssButton;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1002 : public Scene {
|
||||
public:
|
||||
Scene1002(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene1002() override;
|
||||
protected:
|
||||
Sprite *_asRing1;
|
||||
Sprite *_asRing2;
|
||||
Sprite *_asRing3;
|
||||
Sprite *_asRing4;
|
||||
Sprite *_asRing5;
|
||||
Sprite *_asDoor;
|
||||
Sprite *_asDoorSpy;
|
||||
Sprite *_asVenusFlyTrap;
|
||||
Sprite *_ssLadderArch;
|
||||
Sprite *_ssLadderArchPart1;
|
||||
Sprite *_ssLadderArchPart2;
|
||||
Sprite *_ssLadderArchPart3;
|
||||
Sprite *_ssCeiling;
|
||||
Sprite *_asKlaymenLadderHands;
|
||||
Sprite *_asKlaymenPeekHand;
|
||||
Sprite *_asOutsideDoorBackground;
|
||||
Sprite *_ssPressButton;
|
||||
bool _isKlaymenFloor;
|
||||
bool _isClimbingLadder;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1004 : public Scene {
|
||||
public:
|
||||
Scene1004(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_asKlaymenLadderHands;
|
||||
Sprite *_asTrashCan;
|
||||
int _paletteAreaStatus;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void updatePaletteArea();
|
||||
};
|
||||
|
||||
class Scene1005 : public Scene {
|
||||
public:
|
||||
Scene1005(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void drawTextToBackground();
|
||||
uint32 getTextIndex();
|
||||
uint32 getTextIndex1();
|
||||
uint32 getKloggsTextIndex();
|
||||
uint32 getTextIndex3(uint32 usefulHint);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1000_H */
|
||||
1705
engines/neverhood/modules/module1000_sprites.cpp
Normal file
1705
engines/neverhood/modules/module1000_sprites.cpp
Normal file
File diff suppressed because it is too large
Load Diff
261
engines/neverhood/modules/module1000_sprites.h
Normal file
261
engines/neverhood/modules/module1000_sprites.h
Normal file
@@ -0,0 +1,261 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1000_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1000_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class AsScene1001Door : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1001Door(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void hammerHitsDoor();
|
||||
void stShowIdleDoor();
|
||||
void stBustedDoorMove();
|
||||
void stBustedDoorGone();
|
||||
};
|
||||
|
||||
class AsScene1001Hammer : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor);
|
||||
protected:
|
||||
Sprite *_asDoor;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1001Window : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1001Window(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1001Lever : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsCommonButtonSprite : public StaticSprite {
|
||||
public:
|
||||
SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 _soundFileHash;
|
||||
int16 _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1002Ring : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
bool _isSpecial;
|
||||
void update();
|
||||
uint32 hmRingIdle(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmRingPulled1(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmRingPulled2(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmRingHangingLow(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmRingReleased(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1002Door : public StaticSprite {
|
||||
public:
|
||||
AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect);
|
||||
protected:
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suOpenDoor();
|
||||
void suCloseDoor();
|
||||
};
|
||||
|
||||
class AsScene1002BoxingGloveHitEffect : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1002DoorSpy : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Sprite *_asDoor;
|
||||
Sprite *_asBoxingGloveHitEffect;
|
||||
NRect _clipRect;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmDoorSpyAnimation(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suDoorSpy();
|
||||
void stDoorSpyIdle();
|
||||
void stDoorSpyBoxingGlove();
|
||||
};
|
||||
|
||||
class SsCommonPressButton : public StaticSprite {
|
||||
public:
|
||||
SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
|
||||
void setFileHashes(uint32 fileHash1, uint32 fileHash2);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 _soundFileHash;
|
||||
uint32 _fileHashes[2];
|
||||
int _status;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1002VenusFlyTrap : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Sprite *_klaymen;
|
||||
int _countdown;
|
||||
bool _isSecond;
|
||||
void update();
|
||||
void upIdle();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmAnimationSimple(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmAnimationExt(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stWalkBack();
|
||||
void stWalk();
|
||||
void stRelease();
|
||||
void stGrabRing();
|
||||
void stRingGrabbed();
|
||||
void stKlaymenInside();
|
||||
void stIdle();
|
||||
void stKlaymenInsideMoving();
|
||||
void stSpitOutKlaymen();
|
||||
void swallowKlaymen();
|
||||
};
|
||||
|
||||
class AsScene1002OutsideDoorBackground : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002OutsideDoorBackground(NeverhoodEngine *vm);
|
||||
protected:
|
||||
int _countdown;
|
||||
bool _isDoorClosed;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOpenDoor();
|
||||
void stCloseDoor();
|
||||
void stDoorClosed();
|
||||
};
|
||||
|
||||
class AsScene1002KlaymenLadderHands : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen);
|
||||
protected:
|
||||
Klaymen *_klaymen;
|
||||
void update();
|
||||
};
|
||||
|
||||
class AsScene1002KlaymenPeekHand : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Klaymen *_klaymen;
|
||||
bool _isClipRectSaved;
|
||||
NRect _savedClipRect;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1004TrashCan : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1004TrashCan(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene1001 : public Klaymen {
|
||||
public:
|
||||
KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void stWakeUp();
|
||||
void stSleeping();
|
||||
void stPullHammerLever();
|
||||
uint32 hmSleeping(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmPullHammerLever(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1002 : public Klaymen {
|
||||
public:
|
||||
KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void stJumpToRing1();
|
||||
void stJumpToRing2();
|
||||
void stJumpToRing3();
|
||||
void stJumpToRing4();
|
||||
void setupJumpToRing();
|
||||
void stHangOnRing();
|
||||
void stHoldRing3();
|
||||
void stDropFromRing();
|
||||
void stJumpToRingVenusFlyTrap();
|
||||
void stJumpAndFall();
|
||||
void stMoveVenusFlyTrap();
|
||||
void stContinueMovingVenusFlyTrap();
|
||||
void evMoveVenusFlyTrapDone();
|
||||
void stPressDoorButton();
|
||||
void stHitByBoxingGlove();
|
||||
void evHitByBoxingGloveDone();
|
||||
|
||||
uint32 hmJumpToRing(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmJumpToRing3(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmHoldRing3(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmJumpAndFall(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmMoveVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmPressDoorButton(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmHitByBoxingGlove(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void xUpdate() override;
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1004 : public Klaymen {
|
||||
public:
|
||||
KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void stReadNote();
|
||||
uint32 hmReadNote(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1000_SPRITES_H */
|
||||
543
engines/neverhood/modules/module1100.cpp
Normal file
543
engines/neverhood/modules/module1100.cpp
Normal file
@@ -0,0 +1,543 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/gamemodule.h"
|
||||
#include "neverhood/navigationscene.h"
|
||||
#include "neverhood/modules/module1100.h"
|
||||
#include "neverhood/modules/module1100_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule1100SoundList[] = {
|
||||
0x90805C50,
|
||||
0xB288D450,
|
||||
0x98C05840,
|
||||
0x98A01500,
|
||||
0xB4005E50,
|
||||
0x92025040,
|
||||
0x90035066,
|
||||
0x74E01054,
|
||||
0
|
||||
};
|
||||
|
||||
Module1100::Module1100(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
if (which < 0) {
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
} else if (which == 1) {
|
||||
createScene(8, 1);
|
||||
} else {
|
||||
createScene(8, 3);
|
||||
}
|
||||
|
||||
_vm->_soundMan->addSoundList(0x0002C818, kModule1100SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule1100SoundList, true, 50, 600, 20, 250);
|
||||
_vm->_soundMan->setSoundParams(0x74E01054, false, 100, 200, 10, 20);
|
||||
_vm->_soundMan->setSoundVolume(0x74E01054, 60);
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);
|
||||
|
||||
}
|
||||
|
||||
Module1100::~Module1100() {
|
||||
_vm->_soundMan->deleteGroup(0x0002C818);
|
||||
}
|
||||
|
||||
void Module1100::createScene(int sceneNum, int which) {
|
||||
static const uint32 kSmackerFileHashList06[] = {0x10880805, 0x1088081D, 0};
|
||||
static const uint32 kSmackerFileHashList07[] = {0x00290321, 0x01881000, 0};
|
||||
static const byte kNavigationTypes02[] = {1, 0, 4, 1};
|
||||
debug(1, "Module1100::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_countdown = 65;
|
||||
createNavigationScene(0x004B8430, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_countdown = 50;
|
||||
createNavigationScene(0x004B8460, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
if (getGlobalVar(V_ROBOT_TARGET)) {
|
||||
createNavigationScene(0x004B84F0, which, kNavigationTypes02);
|
||||
} else {
|
||||
createNavigationScene(0x004B8490, which, kNavigationTypes02);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
if (getGlobalVar(V_ROBOT_TARGET)) {
|
||||
createNavigationScene(0x004B8580, which);
|
||||
} else {
|
||||
createNavigationScene(0x004B8550, which);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_childObject = new Scene1105(_vm, this);
|
||||
break;
|
||||
case 5:
|
||||
_vm->gameState().sceneNum = 5;
|
||||
if (getGlobalVar(V_ROBOT_TARGET))
|
||||
createSmackerScene(0x04180001, true, false, false);
|
||||
else
|
||||
createSmackerScene(0x04180007, true, false, false);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
_vm->_soundMan->deleteSoundGroup(0x0002C818);
|
||||
createSmackerScene(kSmackerFileHashList06, true, true, false);
|
||||
break;
|
||||
case 7:
|
||||
_vm->gameState().sceneNum = 7;
|
||||
_vm->_soundMan->setSoundParams(0x74E01054, false, 0, 0, 0, 0);
|
||||
createSmackerScene(kSmackerFileHashList07, true, true, false);
|
||||
break;
|
||||
case 8:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
_childObject = new Scene1109(_vm, this, which);
|
||||
break;
|
||||
case 1002:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
_countdown = 40;
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(true);
|
||||
createSmackerScene(0x00012211, true, true, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1100::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1100::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_countdown = 0;
|
||||
_vm->_soundMan->setSoundVolume(0x48498E46, 65);
|
||||
_vm->_soundMan->setSoundVolume(0x50399F64, 65);
|
||||
if (_moduleResult == 0) {
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0);
|
||||
createScene(1, 0);
|
||||
} else if (_moduleResult == 1) {
|
||||
/* NOTE This fixes a bug in the original where the "tunnel" footstep
|
||||
sounds are played instead of the correct footsteps. */
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);
|
||||
createScene(8, 0);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
_countdown = 0;
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);
|
||||
if (getGlobalVar(V_ROBOT_HIT)) {
|
||||
if (_moduleResult == 0)
|
||||
createScene(6, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(0, 1);
|
||||
} else {
|
||||
if (_moduleResult == 0)
|
||||
createScene(2, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(0, 1);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
_vm->_soundMan->setSoundParams(0x74E01054, false, 0, 0, 0, 0);
|
||||
if (_navigationAreaType == 3)
|
||||
createScene(7, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(3, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(1002, -1);
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 0)
|
||||
createScene(4, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(2, 3);
|
||||
break;
|
||||
case 4:
|
||||
if (_moduleResult == 0)
|
||||
createScene(3, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(5, -1);
|
||||
break;
|
||||
case 5:
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(false);
|
||||
if (getGlobalVar(V_ROBOT_TARGET))
|
||||
createScene(3, 0);
|
||||
else
|
||||
createScene(4, 0);
|
||||
break;
|
||||
case 6:
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(false);
|
||||
leaveModule(1);
|
||||
break;
|
||||
case 7:
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(false);
|
||||
createScene(2, 2);
|
||||
break;
|
||||
case 8:
|
||||
if (_moduleResult == 0)
|
||||
createScene(0, 0);
|
||||
else if (_moduleResult == 1)
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1002:
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(false);
|
||||
_countdown = 0;
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0);
|
||||
createScene(1, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (navigationScene()->isWalkingForward() && _countdown != 0 && (--_countdown == 0)) {
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0);
|
||||
_vm->_soundMan->setSoundVolume(0x48498E46, 65);
|
||||
_vm->_soundMan->setSoundVolume(0x50399F64, 65);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (navigationScene()->isWalkingForward() && _countdown != 0 && (--_countdown == 0))
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);
|
||||
break;
|
||||
case 2:
|
||||
_vm->_soundMan->setSoundParams(0x74E01054, !navigationScene()->isWalkingForward(), 0, 0, 0, 0);
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 1002:
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0);
|
||||
_vm->_soundMan->setSoundVolume(0x48498E46, 65);
|
||||
_vm->_soundMan->setSoundVolume(0x50399F64, 65);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const uint32 kScene1105BackgroundFileHashes[] = {
|
||||
0x20018662,
|
||||
0x20014202,
|
||||
0x20012202,
|
||||
0x20010002 // CHECKME: This used ??
|
||||
};
|
||||
|
||||
static const uint32 kScene1105FileHashes[] = {
|
||||
0x00028006,
|
||||
0x0100A425,
|
||||
0x63090415,
|
||||
0x082100C4,
|
||||
0x0068C607,
|
||||
0x00018344,
|
||||
0x442090E4,
|
||||
0x0400E004,
|
||||
0x5020A054,
|
||||
0xB14A891E
|
||||
};
|
||||
|
||||
Scene1105::Scene1105(NeverhoodEngine *vm, Module *parentModule)
|
||||
: Scene(vm, parentModule), _countdown(0), _isPanelOpen(false), _isActionButtonClicked(false), _doMoveTeddy(false),
|
||||
_isClosePanelDone(false), _leaveResult(0), _backgroundIndex(0) {
|
||||
|
||||
Sprite *ssOpenButton;
|
||||
|
||||
_vm->gameModule()->initMemoryPuzzle();
|
||||
|
||||
SetUpdateHandler(&Scene1105::update);
|
||||
SetMessageHandler(&Scene1105::handleMessage);
|
||||
|
||||
setBackground(0x20010002);
|
||||
setPalette(0x20010002);
|
||||
|
||||
_asTeddyBear = insertSprite<AsScene1105TeddyBear>(this);
|
||||
ssOpenButton = insertSprite<SsScene1105OpenButton>(this);
|
||||
addCollisionSprite(ssOpenButton);
|
||||
insertPuzzleMouse(0x10006208, 20, 620);
|
||||
|
||||
loadSound(0, 0x48442057);
|
||||
loadSound(1, 0xC025014F);
|
||||
loadSound(2, 0x68E25540);
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene1105::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
|
||||
if (!_isActionButtonClicked && _backgroundIndex == 0) {
|
||||
if (_isPanelOpen) {
|
||||
_isPanelOpen = false;
|
||||
_backgroundIndex = 15;
|
||||
SetUpdateHandler(&Scene1105::upClosePanel);
|
||||
} else
|
||||
_isClosePanelDone = true;
|
||||
_leaveResult = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x2001:
|
||||
showMouse(false);
|
||||
_backgroundIndex = 24;
|
||||
SetUpdateHandler(&Scene1105::upOpenPanel);
|
||||
break;
|
||||
case 0x2003:
|
||||
_backgroundIndex = 24;
|
||||
_leaveResult = 1;
|
||||
SetUpdateHandler(&Scene1105::upClosePanel);
|
||||
break;
|
||||
case NM_KLAYMEN_RAISE_LEVER:
|
||||
if (sender == _ssActionButton) {
|
||||
if (getSubVar(VA_GOOD_DICE_NUMBERS, 0) == getSubVar(VA_CURR_DICE_NUMBERS, 0) &&
|
||||
getSubVar(VA_GOOD_DICE_NUMBERS, 1) == getSubVar(VA_CURR_DICE_NUMBERS, 1) &&
|
||||
getSubVar(VA_GOOD_DICE_NUMBERS, 2) == getSubVar(VA_CURR_DICE_NUMBERS, 2)) {
|
||||
setGlobalVar(V_ROBOT_TARGET, 1);
|
||||
playSound(2);
|
||||
_doMoveTeddy = true;
|
||||
} else {
|
||||
sendMessage(_asTeddyBear, NM_POSITION_CHANGE, 0);
|
||||
}
|
||||
showMouse(false);
|
||||
_isActionButtonClicked = true;
|
||||
}
|
||||
break;
|
||||
case 0x4826:
|
||||
if (_isPanelOpen) {
|
||||
if (sender == _ssActionButton) {
|
||||
sendMessage(_ssActionButton, 0x480B, 0);
|
||||
_isPanelOpen = false;
|
||||
} else if (!getGlobalVar(V_ROBOT_TARGET)) {
|
||||
if (sender == _ssSymbol1UpButton) {
|
||||
if (getSubVar(VA_CURR_DICE_NUMBERS, 0) < 9) {
|
||||
incSubVar(VA_CURR_DICE_NUMBERS, 0, +1);
|
||||
sendMessage(_ssSymbol1UpButton, 0x480B, 0);
|
||||
sendMessage(_ssSymbolDice[0], 0x2000, 0);
|
||||
}
|
||||
} else if (sender == _ssSymbol1DownButton) {
|
||||
if (getSubVar(VA_CURR_DICE_NUMBERS, 0) > 1) {
|
||||
incSubVar(VA_CURR_DICE_NUMBERS, 0, -1);
|
||||
sendMessage(_ssSymbol1DownButton, 0x480B, 0);
|
||||
sendMessage(_ssSymbolDice[0], 0x2000, 0);
|
||||
}
|
||||
} else if (sender == _ssSymbol2UpButton) {
|
||||
if (getSubVar(VA_CURR_DICE_NUMBERS, 1) < 9) {
|
||||
incSubVar(VA_CURR_DICE_NUMBERS, 1, +1);
|
||||
sendMessage(_ssSymbol2UpButton, 0x480B, 0);
|
||||
sendMessage(_ssSymbolDice[1], 0x2000, 0);
|
||||
}
|
||||
} else if (sender == _ssSymbol2DownButton) {
|
||||
if (getSubVar(VA_CURR_DICE_NUMBERS, 1) > 1) {
|
||||
incSubVar(VA_CURR_DICE_NUMBERS, 1, -1);
|
||||
sendMessage(_ssSymbol2DownButton, 0x480B, 0);
|
||||
sendMessage(_ssSymbolDice[1], 0x2000, 0);
|
||||
}
|
||||
} else if (sender == _ssSymbol3UpButton) {
|
||||
if (getSubVar(VA_CURR_DICE_NUMBERS, 2) < 9) {
|
||||
incSubVar(VA_CURR_DICE_NUMBERS, 2, +1);
|
||||
sendMessage(_ssSymbol3UpButton, 0x480B, 0);
|
||||
sendMessage(_ssSymbolDice[2], 0x2000, 0);
|
||||
}
|
||||
} else if (sender == _ssSymbol3DownButton) {
|
||||
if (getSubVar(VA_CURR_DICE_NUMBERS, 2) > 1) {
|
||||
incSubVar(VA_CURR_DICE_NUMBERS, 2, -1);
|
||||
sendMessage(_ssSymbol3DownButton, 0x480B, 0);
|
||||
sendMessage(_ssSymbolDice[2], 0x2000, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void Scene1105::createObjects() {
|
||||
_ssSymbols[0] = insertSprite<SsScene1105Symbol>(kScene1105FileHashes[getSubVar(VA_DICE_MEMORY_SYMBOLS, 0)], 161, 304);
|
||||
_ssSymbols[1] = insertSprite<SsScene1105Symbol>(kScene1105FileHashes[getSubVar(VA_DICE_MEMORY_SYMBOLS, 1)], 294, 304);
|
||||
_ssSymbols[2] = insertSprite<SsScene1105Symbol>(kScene1105FileHashes[getSubVar(VA_DICE_MEMORY_SYMBOLS, 2)], 440, 304);
|
||||
|
||||
_ssSymbolDice[0] = insertSprite<SsScene1105SymbolDie>(0, 206, 304);
|
||||
_ssSymbolDice[1] = insertSprite<SsScene1105SymbolDie>(1, 339, 304);
|
||||
_ssSymbolDice[2] = insertSprite<SsScene1105SymbolDie>(2, 485, 304);
|
||||
|
||||
_ssSymbol1UpButton = insertSprite<SsScene1105Button>(this, 0x08002860, NRect::make(146, 362, 192, 403));
|
||||
addCollisionSprite(_ssSymbol1UpButton);
|
||||
_ssSymbol1DownButton = insertSprite<SsScene1105Button>(this, 0x42012460, NRect::make(147, 404, 191, 442));
|
||||
addCollisionSprite(_ssSymbol1DownButton);
|
||||
_ssSymbol2UpButton = insertSprite<SsScene1105Button>(this, 0x100030A0, NRect::make(308, 361, 355, 402));
|
||||
addCollisionSprite(_ssSymbol2UpButton);
|
||||
_ssSymbol2DownButton = insertSprite<SsScene1105Button>(this, 0x840228A0, NRect::make(306, 406, 352, 445));
|
||||
addCollisionSprite(_ssSymbol2DownButton);
|
||||
_ssSymbol3UpButton = insertSprite<SsScene1105Button>(this, 0x20000120, NRect::make(476, 358, 509, 394));
|
||||
addCollisionSprite(_ssSymbol3UpButton);
|
||||
_ssSymbol3DownButton = insertSprite<SsScene1105Button>(this, 0x08043121, NRect::make(463, 401, 508, 438));
|
||||
addCollisionSprite(_ssSymbol3DownButton);
|
||||
_ssActionButton = insertSprite<SsScene1105Button>(this, 0x8248AD35, NRect::make(280, 170, 354, 245));
|
||||
addCollisionSprite(_ssActionButton);
|
||||
|
||||
_isPanelOpen = true;
|
||||
|
||||
_asTeddyBear->show();
|
||||
|
||||
insertPuzzleMouse(0x18666208, 20, 620);
|
||||
|
||||
}
|
||||
|
||||
void Scene1105::upOpenPanel() {
|
||||
Scene::update();
|
||||
if (_backgroundIndex != 0) {
|
||||
_backgroundIndex--;
|
||||
if (_backgroundIndex < 6 && _backgroundIndex % 2 == 0) {
|
||||
uint32 backgroundFileHash = kScene1105BackgroundFileHashes[_backgroundIndex / 2];
|
||||
changeBackground(backgroundFileHash);
|
||||
_palette->addPalette(backgroundFileHash, 0, 256, 0);
|
||||
}
|
||||
if (_backgroundIndex == 10)
|
||||
playSound(0);
|
||||
if (_backgroundIndex == 0) {
|
||||
SetUpdateHandler(&Scene1105::update);
|
||||
_countdown = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scene1105::upClosePanel() {
|
||||
Scene::update();
|
||||
if (_backgroundIndex != 0) {
|
||||
_backgroundIndex--;
|
||||
if (_backgroundIndex == 14) {
|
||||
showMouse(false);
|
||||
_ssSymbols[0]->hide();
|
||||
_ssSymbols[1]->hide();
|
||||
_ssSymbols[2]->hide();
|
||||
_ssSymbolDice[0]->hide();
|
||||
_ssSymbolDice[1]->hide();
|
||||
_ssSymbolDice[2]->hide();
|
||||
}
|
||||
if (_backgroundIndex < 6 && _backgroundIndex % 2 == 0) {
|
||||
uint32 backgroundFileHash = kScene1105BackgroundFileHashes[3 - _backgroundIndex / 2]; // CHECKME
|
||||
if (_backgroundIndex == 4) {
|
||||
playSound(1);
|
||||
_asTeddyBear->hide();
|
||||
}
|
||||
changeBackground(backgroundFileHash);
|
||||
_palette->addPalette(backgroundFileHash, 0, 256, 0);
|
||||
}
|
||||
if (_backgroundIndex == 0) {
|
||||
SetUpdateHandler(&Scene1105::update);
|
||||
_isClosePanelDone = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scene1105::update() {
|
||||
Scene::update();
|
||||
if (_countdown != 0 && (--_countdown == 0))
|
||||
createObjects();
|
||||
if (_isClosePanelDone && !isSoundPlaying(1))
|
||||
leaveScene(_leaveResult);
|
||||
if (_doMoveTeddy && !isSoundPlaying(2)) {
|
||||
sendMessage(_asTeddyBear, NM_POSITION_CHANGE, 0);
|
||||
_doMoveTeddy = false;
|
||||
}
|
||||
}
|
||||
|
||||
Scene1109::Scene1109(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
SetMessageHandler(&Scene1109::handleMessage);
|
||||
|
||||
setBackground(0x8449E02F);
|
||||
setPalette(0x8449E02F);
|
||||
insertScreenMouse(0x9E02B84C);
|
||||
|
||||
_sprite1 = insertStaticSprite(0x600CEF01, 1100);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1109>(140, 436);
|
||||
setMessageList(0x004B6260);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
} else if (which == 1) {
|
||||
// Klaymen teleporting in
|
||||
insertKlaymen<KmScene1109>(450, 436);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B6268, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
} else if (which == 2) {
|
||||
// Klaymen teleporting out
|
||||
insertKlaymen<KmScene1109>(450, 436);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B6318, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
} else if (which == 3) {
|
||||
// Klaymen returning from teleporter console
|
||||
insertKlaymen<KmScene1109>(450, 436);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B6278, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene1109>(0, 436);
|
||||
setMessageList(0x004B6258);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
}
|
||||
|
||||
_klaymen->setClipRect(0, 0, _sprite1->getDrawRect().x2(), 480);
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene1109::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (param.asInteger()) {
|
||||
setRectList(0x004B63A8);
|
||||
_klaymen->setKlaymenIdleTable3();
|
||||
} else {
|
||||
setRectList(0x004B6398);
|
||||
_klaymen->setKlaymenIdleTable1();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
84
engines/neverhood/modules/module1100.h
Normal file
84
engines/neverhood/modules/module1100.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1100_H
|
||||
#define NEVERHOOD_MODULES_MODULE1100_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1100 : public Module {
|
||||
public:
|
||||
Module1100(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1100() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
int _countdown;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class AsScene1105TeddyBear;
|
||||
class SsScene1105Symbol;
|
||||
class SsScene1105SymbolDie;
|
||||
|
||||
class Scene1105 : public Scene {
|
||||
public:
|
||||
Scene1105(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
int _countdown;
|
||||
int _backgroundIndex;
|
||||
bool _isPanelOpen;
|
||||
bool _isActionButtonClicked;
|
||||
bool _doMoveTeddy;
|
||||
bool _isClosePanelDone;
|
||||
int _leaveResult;
|
||||
AsScene1105TeddyBear *_asTeddyBear;
|
||||
SsScene1105Symbol *_ssSymbols[3];
|
||||
SsScene1105SymbolDie *_ssSymbolDice[3];
|
||||
Sprite *_ssSymbol1UpButton;
|
||||
Sprite *_ssSymbol1DownButton;
|
||||
Sprite *_ssSymbol2UpButton;
|
||||
Sprite *_ssSymbol2DownButton;
|
||||
Sprite *_ssSymbol3UpButton;
|
||||
Sprite *_ssSymbol3DownButton;
|
||||
Sprite *_ssActionButton;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createObjects();
|
||||
void upOpenPanel();
|
||||
void upClosePanel();
|
||||
void update();
|
||||
};
|
||||
|
||||
class Scene1109 : public Scene {
|
||||
public:
|
||||
Scene1109(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1100_H */
|
||||
274
engines/neverhood/modules/module1100_sprites.cpp
Normal file
274
engines/neverhood/modules/module1100_sprites.cpp
Normal file
@@ -0,0 +1,274 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1100_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kSsScene1105SymbolDieFileHashes[] = {
|
||||
0,
|
||||
0x90898414,
|
||||
0x91098414,
|
||||
0x92098414,
|
||||
0x94098414,
|
||||
0x98098414,
|
||||
0x80098414,
|
||||
0xB0098414,
|
||||
0xD0098414,
|
||||
0x10098414
|
||||
};
|
||||
|
||||
SsScene1105Button::SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds)
|
||||
: StaticSprite(vm, fileHash, 200), _parentScene(parentScene), _countdown(0) {
|
||||
|
||||
_collisionBounds = collisionBounds;
|
||||
SetMessageHandler(&SsScene1105Button::handleMessage);
|
||||
SetUpdateHandler(&SsScene1105Button::update);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
void SsScene1105Button::update() {
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 0);
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene1105Button::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_countdown == 0) {
|
||||
sendMessage(_parentScene, 0x4826, 0);
|
||||
messageResult = 1;
|
||||
}
|
||||
break;
|
||||
case 0x480B:
|
||||
_countdown = 8;
|
||||
setVisible(true);
|
||||
playSound(0, 0x44141000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
SsScene1105Symbol::SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y)
|
||||
: StaticSprite(vm, 0) {
|
||||
|
||||
loadSprite(fileHash, kSLFCenteredDrawOffset | kSLFSetPosition, 200, x, y);
|
||||
}
|
||||
|
||||
void SsScene1105Symbol::hide() {
|
||||
setVisible(false);
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
SsScene1105SymbolDie::SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y)
|
||||
: StaticSprite(vm, 1100), _dieIndex(dieIndex) {
|
||||
|
||||
_x = x;
|
||||
_y = y;
|
||||
createSurface(200, 50, 50);
|
||||
loadSymbolSprite();
|
||||
SetMessageHandler(&SsScene1105SymbolDie::handleMessage);
|
||||
}
|
||||
|
||||
uint32 SsScene1105SymbolDie::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
loadSymbolSprite();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void SsScene1105SymbolDie::loadSymbolSprite() {
|
||||
loadSprite(kSsScene1105SymbolDieFileHashes[getSubVar(VA_CURR_DICE_NUMBERS, _dieIndex)], kSLFCenteredDrawOffset);
|
||||
}
|
||||
|
||||
void SsScene1105SymbolDie::hide() {
|
||||
setVisible(false);
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
AsScene1105TeddyBear::AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene) {
|
||||
|
||||
createSurface(100, 556, 328);
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1105TeddyBear::handleMessage);
|
||||
startAnimation(0x65084002, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
setVisible(false);
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
loadSound(0, 0xCE840261);
|
||||
loadSound(1, 0xCCA41A62);
|
||||
}
|
||||
|
||||
uint32 AsScene1105TeddyBear::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_POSITION_CHANGE:
|
||||
if (getGlobalVar(V_ROBOT_TARGET)) {
|
||||
startAnimation(0x6B0C0432, 0, -1);
|
||||
playSound(0);
|
||||
} else {
|
||||
startAnimation(0x65084002, 0, -1);
|
||||
playSound(1);
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
sendMessage(_parentScene, 0x2003, 0);
|
||||
stopAnimation();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1105TeddyBear::show() {
|
||||
setVisible(true);
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
void AsScene1105TeddyBear::hide() {
|
||||
setVisible(false);
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
SsScene1105OpenButton::SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _isClicked(false) {
|
||||
|
||||
loadSprite(0x8228A46C, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
|
||||
setVisible(false);
|
||||
loadSound(0, 0x44045140);
|
||||
SetUpdateHandler(&SsScene1105OpenButton::update);
|
||||
SetMessageHandler(&SsScene1105OpenButton::handleMessage);
|
||||
}
|
||||
|
||||
void SsScene1105OpenButton::update() {
|
||||
updatePosition();
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
setVisible(false);
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene1105OpenButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_countdown == 0 && !_isClicked) {
|
||||
playSound(0);
|
||||
setVisible(true);
|
||||
_isClicked = true;
|
||||
_countdown = 4;
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene1109::KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4804:
|
||||
if (param.asInteger() != 0) {
|
||||
_destX = param.asInteger();
|
||||
GotoState(&Klaymen::stWalkingFirst);
|
||||
} else
|
||||
GotoState(&Klaymen::stPeekWall);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2000, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
case 0x483D:
|
||||
teleporterAppear(0x2C2A4A1C);
|
||||
break;
|
||||
case 0x483E:
|
||||
teleporterDisappear(0x3C2E4245);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
87
engines/neverhood/modules/module1100_sprites.h
Normal file
87
engines/neverhood/modules/module1100_sprites.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1100_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1100_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class SsScene1105Button : public StaticSprite {
|
||||
public:
|
||||
SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsScene1105Symbol : public StaticSprite {
|
||||
public:
|
||||
SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y);
|
||||
void hide();
|
||||
};
|
||||
|
||||
class SsScene1105SymbolDie : public StaticSprite {
|
||||
public:
|
||||
SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y);
|
||||
void hide();
|
||||
protected:
|
||||
uint _dieIndex;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void loadSymbolSprite();
|
||||
};
|
||||
|
||||
class AsScene1105TeddyBear : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene);
|
||||
void show();
|
||||
void hide();
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsScene1105OpenButton : public StaticSprite {
|
||||
public:
|
||||
SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _countdown;
|
||||
bool _isClicked;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene1109 : public Klaymen {
|
||||
public:
|
||||
KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1100_SPRITES_H */
|
||||
471
engines/neverhood/modules/module1200.cpp
Normal file
471
engines/neverhood/modules/module1200.cpp
Normal file
@@ -0,0 +1,471 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1200.h"
|
||||
#include "neverhood/modules/module1200_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module1200::Module1200(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
SetMessageHandler(&Module1200::handleMessage);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 1)
|
||||
createScene(0, 2);
|
||||
else
|
||||
createScene(0, 0);
|
||||
|
||||
_vm->_soundMan->addMusic(0x00478311, 0x62222CAE);
|
||||
_vm->_soundMan->startMusic(0x62222CAE, 0, 0);
|
||||
}
|
||||
|
||||
Module1200::~Module1200() {
|
||||
_vm->_soundMan->deleteMusicGroup(0x00478311);
|
||||
}
|
||||
|
||||
void Module1200::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1200::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene1201(_vm, this, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_childObject = new Scene1202(_vm, this);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
_vm->_soundMan->stopMusic(0x62222CAE, 0, 0);
|
||||
createSmackerScene(0x31890001, true, true, false);
|
||||
setGlobalVar(V_SEEN_CREATURE_EXPLODE_VID, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1200::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1200::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(1, 0);
|
||||
else if (_moduleResult == 2) {
|
||||
if (getGlobalVar(V_CREATURE_EXPLODED) && !getGlobalVar(V_SEEN_CREATURE_EXPLODE_VID))
|
||||
createScene(2, -1);
|
||||
else
|
||||
leaveModule(1);
|
||||
} else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1:
|
||||
createScene(0, 1);
|
||||
break;
|
||||
case 2:
|
||||
_vm->_soundMan->startMusic(0x62222CAE, 0, 0);
|
||||
createScene(0, 3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const uint32 kScene1201InitArray[] = {
|
||||
1, 0, 2, 4, 5, 3, 6, 7, 8, 10, 9, 11, 13, 14, 12, 16, 17, 15
|
||||
};
|
||||
|
||||
Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _creatureExploded(false), _asMatch(nullptr), _asTntMan(nullptr),
|
||||
_asCreature(nullptr), _asTntManRope(nullptr), _asLeftDoor(nullptr), _asRightDoor(nullptr), _asTape(nullptr) {
|
||||
|
||||
int16 topY1, topY2, topY3, topY4;
|
||||
int16 x1, x2;
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetUpdateHandler(&Scene1201::update);
|
||||
SetMessageHandler(&Scene1201::handleMessage);
|
||||
|
||||
setHitRects(0x004AEBD0);
|
||||
|
||||
if (!getSubVar(VA_IS_PUZZLE_INIT, 0xE8058B52)) {
|
||||
setSubVar(VA_IS_PUZZLE_INIT, 0xE8058B52, 1);
|
||||
for (uint32 index = 0; index < 18; index++)
|
||||
setSubVar(VA_TNT_POSITIONS, index, kScene1201InitArray[index]);
|
||||
}
|
||||
|
||||
insertScreenMouse(0x9A2C0409);
|
||||
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 3, 1100, 243, 340, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
|
||||
tempSprite = insertStaticSprite(0x03C82530, 100);
|
||||
topY1 = tempSprite->getY() + tempSprite->getDrawRect().height;
|
||||
|
||||
tempSprite = insertStaticSprite(0x88182069, 200);
|
||||
topY2 = tempSprite->getY() + tempSprite->getDrawRect().height;
|
||||
|
||||
tempSprite = insertStaticSprite(0x476014E0, 300);
|
||||
topY3 = tempSprite->getY() + tempSprite->getDrawRect().height;
|
||||
|
||||
tempSprite = insertStaticSprite(0x04063110, 500);
|
||||
topY4 = tempSprite->getY() + 1;
|
||||
|
||||
_asTntManRope = insertSprite<AsScene1201TntManRope>(getGlobalVar(V_TNT_DUMMY_BUILT) && which != 1);
|
||||
_asTntManRope->setClipRect(0, topY4, 640, 480);
|
||||
|
||||
insertStaticSprite(0x400B04B0, 1200);
|
||||
|
||||
tempSprite = insertStaticSprite(0x40295462, 1200);
|
||||
x1 = tempSprite->getX();
|
||||
|
||||
tempSprite = insertStaticSprite(0xA29223FA, 1200);
|
||||
x2 = tempSprite->getX() + tempSprite->getDrawRect().width;
|
||||
|
||||
_asKlaymenHead = insertSprite<AsScene1201KlaymenHead>();
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1201>(364, 333);
|
||||
setMessageList(0x004AEC08);
|
||||
} else if (which == 3) {
|
||||
// Klaymen standing after the weasel exploded
|
||||
insertKlaymen<KmScene1201>(400, 329);
|
||||
setMessageList(0x004AEC08);
|
||||
} else if (which == 2) {
|
||||
// Klaymen entering from the right
|
||||
if (getGlobalVar(V_CREATURE_ANGRY) && !getGlobalVar(V_CREATURE_EXPLODED)) {
|
||||
insertKlaymen<KmScene1201>(374, 333);
|
||||
setMessageList(0x004AEC08);
|
||||
} else {
|
||||
insertKlaymen<KmScene1201>(640, 329);
|
||||
setMessageList(0x004AEC20);
|
||||
}
|
||||
} else if (which == 1) {
|
||||
// Klaymen returning from the TNT console
|
||||
if (getGlobalVar(V_KLAYMEN_IS_DELTA_X)) {
|
||||
insertKlaymen<KmScene1201>(364, 333);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
} else {
|
||||
insertKlaymen<KmScene1201>(246, 333);
|
||||
}
|
||||
setMessageList(0x004AEC30);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene1201>(0, 336);
|
||||
setMessageList(0x004AEC10);
|
||||
}
|
||||
|
||||
_klaymen->setClipRect(x1, 0, x2, 480);
|
||||
_klaymen->setRepl(64, 0);
|
||||
|
||||
if (getGlobalVar(V_CREATURE_ANGRY) && !getGlobalVar(V_CREATURE_EXPLODED)) {
|
||||
setBackground(0x4019A2C4);
|
||||
setPalette(0x4019A2C4);
|
||||
_asRightDoor = nullptr;
|
||||
} else {
|
||||
setBackground(0x40206EC5);
|
||||
setPalette(0x40206EC5);
|
||||
_asRightDoor = insertSprite<AsScene1201RightDoor>(_klaymen, which == 2);
|
||||
}
|
||||
|
||||
if (getGlobalVar(V_TNT_DUMMY_BUILT)) {
|
||||
insertStaticSprite(0x10002ED8, 500);
|
||||
if (!getGlobalVar(V_CREATURE_EXPLODED)) {
|
||||
_asTntMan = insertSprite<AsScene1201TntMan>(this, _asTntManRope, which == 1);
|
||||
_asTntMan->setClipRect(x1, 0, x2, 480);
|
||||
_asTntMan->setRepl(64, 0);
|
||||
addCollisionSprite(_asTntMan);
|
||||
tempSprite = insertSprite<AsScene1201TntManFlame>(_asTntMan);
|
||||
tempSprite->setClipRect(x1, 0, x2, 480);
|
||||
}
|
||||
|
||||
uint32 tntIndex = 1;
|
||||
while (tntIndex < 18) {
|
||||
uint32 elemIndex = getSubVar(VA_TNT_POSITIONS, tntIndex);
|
||||
int16 clipY2;
|
||||
if (kScene1201PointArray[elemIndex].y < 175)
|
||||
clipY2 = topY1;
|
||||
else if (kScene1201PointArray[elemIndex].y < 230)
|
||||
clipY2 = topY2;
|
||||
else
|
||||
clipY2 = topY3;
|
||||
insertSprite<SsScene1201Tnt>(tntIndex, getSubVar(VA_TNT_POSITIONS, tntIndex), clipY2);
|
||||
elemIndex = getSubVar(VA_TNT_POSITIONS, tntIndex + 1);
|
||||
if (kScene1201PointArray[elemIndex].y < 175)
|
||||
clipY2 = topY1;
|
||||
else if (kScene1201PointArray[elemIndex].y < 230)
|
||||
clipY2 = topY2;
|
||||
else
|
||||
clipY2 = topY3;
|
||||
insertSprite<SsScene1201Tnt>(tntIndex + 1, getSubVar(VA_TNT_POSITIONS, tntIndex + 1), clipY2);
|
||||
tntIndex += 3;
|
||||
}
|
||||
|
||||
if (getGlobalVar(V_CREATURE_ANGRY) && !getGlobalVar(V_CREATURE_EXPLODED)) {
|
||||
setRectList(0x004AEE58);
|
||||
} else {
|
||||
setRectList(0x004AEDC8);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
insertStaticSprite(0x8E8A1981, 900);
|
||||
|
||||
uint32 tntIndex = 0;
|
||||
while (tntIndex < 18) {
|
||||
uint32 elemIndex = getSubVar(VA_TNT_POSITIONS, tntIndex);
|
||||
int16 clipY2;
|
||||
if (kScene1201PointArray[elemIndex].x < 300) {
|
||||
clipY2 = 480;
|
||||
} else {
|
||||
if (kScene1201PointArray[elemIndex].y < 175)
|
||||
clipY2 = topY1;
|
||||
else if (kScene1201PointArray[elemIndex].y < 230)
|
||||
clipY2 = topY2;
|
||||
else
|
||||
clipY2 = topY3;
|
||||
}
|
||||
insertSprite<SsScene1201Tnt>(tntIndex, getSubVar(VA_TNT_POSITIONS, tntIndex), clipY2);
|
||||
tntIndex++;
|
||||
}
|
||||
|
||||
if (getGlobalVar(V_CREATURE_ANGRY) && !getGlobalVar(V_CREATURE_EXPLODED))
|
||||
setRectList(0x004AEE18);
|
||||
else
|
||||
setRectList(0x004AED88);
|
||||
|
||||
}
|
||||
|
||||
tempSprite = insertStaticSprite(0x63D400BC, 900);
|
||||
|
||||
_asLeftDoor = insertSprite<AsScene1201LeftDoor>(_klaymen);
|
||||
_asLeftDoor->setClipRect(x1, tempSprite->getDrawRect().y, tempSprite->getDrawRect().x2(), 480);
|
||||
|
||||
if (getGlobalVar(V_CREATURE_ANGRY) && getGlobalVar(V_MATCH_STATUS) == 0)
|
||||
setGlobalVar(V_MATCH_STATUS, 1);
|
||||
|
||||
_asMatch = nullptr;
|
||||
|
||||
if (getGlobalVar(V_MATCH_STATUS) < 3) {
|
||||
_asMatch = insertSprite<AsScene1201Match>(this);
|
||||
addCollisionSprite(_asMatch);
|
||||
}
|
||||
|
||||
if (getGlobalVar(V_CREATURE_ANGRY) && getGlobalVar(V_CREATURE_EXPLODED) == 0) {
|
||||
_asCreature = insertSprite<AsScene1201Creature>(this, _klaymen);
|
||||
_asCreature->setClipRect(x1, 0, x2, 480);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Scene1201::~Scene1201() {
|
||||
if (_creatureExploded)
|
||||
setGlobalVar(V_CREATURE_EXPLODED, 1);
|
||||
setGlobalVar(V_KLAYMEN_IS_DELTA_X, _klaymen->isDoDeltaX() ? 1 : 0);
|
||||
}
|
||||
|
||||
void Scene1201::update() {
|
||||
Scene::update();
|
||||
if (_asMatch && getGlobalVar(V_MATCH_STATUS) == 3)
|
||||
deleteSprite(&_asMatch);
|
||||
}
|
||||
|
||||
uint32 Scene1201::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x07053000) {
|
||||
_creatureExploded = true;
|
||||
sendMessage(_asCreature, 0x2004, 0);
|
||||
} else if (param.asInteger() == 0x140E5744)
|
||||
sendMessage(_asCreature, NM_KLAYMEN_CLIMB_LADDER, 0);
|
||||
else if (param.asInteger() == 0x40253C40) {
|
||||
_canAcceptInput = false;
|
||||
sendMessage(_asCreature, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
} else if (param.asInteger() == 0x090EB048) {
|
||||
if (_klaymen->getX() < 572)
|
||||
setMessageList2(0x004AEC90);
|
||||
else
|
||||
setMessageList2(0x004AEC20);
|
||||
}
|
||||
break;
|
||||
case 0x2001:
|
||||
if (getGlobalVar(V_MATCH_STATUS) == 0)
|
||||
setMessageList2(0x004AECB0);
|
||||
else {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asMatch);
|
||||
setMessageList2(0x004AECC0);
|
||||
}
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
|
||||
// Move the TNT dummy if the fuse is burning
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTntMan);
|
||||
setMessageList2(0x004AECF0, false);
|
||||
} else if (getGlobalVar(V_MATCH_STATUS) == 3) {
|
||||
// Light the TNT dummy if we have the match
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTntMan);
|
||||
if (_klaymen->getX() > _asTntMan->getX())
|
||||
setMessageList(0x004AECD0);
|
||||
else
|
||||
setMessageList(0x004AECE0);
|
||||
}
|
||||
break;
|
||||
case 0x4814:
|
||||
cancelMessageList();
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asTape) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTape);
|
||||
setMessageList(0x004AED38);
|
||||
}
|
||||
break;
|
||||
case 0x4829:
|
||||
sendMessage(_asRightDoor, 0x4829, 0);
|
||||
break;
|
||||
case 0x8000:
|
||||
sendMessage(_asKlaymenHead, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
static const uint32 kScene1202Table[] = {
|
||||
1, 2, 0, 4, 5, 3, 7, 8, 6, 10, 11, 9, 13, 14, 12, 16, 17, 15
|
||||
};
|
||||
|
||||
Scene1202::Scene1202(NeverhoodEngine *vm, Module *parentModule)
|
||||
: Scene(vm, parentModule), _paletteResource(vm),
|
||||
_soundToggle(true), _isPuzzleSolved(false), _counter(0), _clickedIndex(-1) {
|
||||
|
||||
SetMessageHandler(&Scene1202::handleMessage);
|
||||
SetUpdateHandler(&Scene1202::update);
|
||||
|
||||
setBackground(0x60210ED5);
|
||||
setPalette(0x60210ED5);
|
||||
addEntity(_palette);
|
||||
|
||||
_paletteResource.load(0x60250EB5);
|
||||
_paletteResource.copyPalette(_paletteData);
|
||||
|
||||
insertPuzzleMouse(0x10ED160A, 20, 620);
|
||||
|
||||
for (int tntIndex = 0; tntIndex < 18; tntIndex++) {
|
||||
_asTntItems[tntIndex] = insertSprite<AsScene1202TntItem>(this, tntIndex);
|
||||
addCollisionSprite(_asTntItems[tntIndex]);
|
||||
}
|
||||
|
||||
insertStaticSprite(0x8E8419C1, 1100);
|
||||
|
||||
if (getGlobalVar(V_TNT_DUMMY_BUILT))
|
||||
SetMessageHandler(&Scene1202::hmSolved);
|
||||
|
||||
playSound(0, 0x40106542);
|
||||
loadSound(1, 0x40005446);
|
||||
loadSound(2, 0x40005446); // Same sound as slot 1
|
||||
loadSound(3, 0x68E25540);
|
||||
|
||||
}
|
||||
|
||||
Scene1202::~Scene1202() {
|
||||
if (isSolved())
|
||||
setGlobalVar(V_TNT_DUMMY_BUILT, 1);
|
||||
}
|
||||
|
||||
void Scene1202::update() {
|
||||
Scene::update();
|
||||
if (_isPuzzleSolved) {
|
||||
if (!isSoundPlaying(3))
|
||||
leaveScene(0);
|
||||
} else if (_counter == 0 && isSolved()) {
|
||||
_clickedIndex = 0;
|
||||
SetMessageHandler(&Scene1202::hmSolved);
|
||||
setGlobalVar(V_TNT_DUMMY_BUILT, 1);
|
||||
_palette->copyToBasePalette(_paletteData);
|
||||
_palette->startFadeToPalette(24);
|
||||
playSound(3);
|
||||
_isPuzzleSolved = true;
|
||||
} else if (_clickedIndex >= 0 && _counter == 0) {
|
||||
// Swap TNT positions
|
||||
int destIndex = kScene1202Table[_clickedIndex];
|
||||
sendMessage(_asTntItems[_clickedIndex], 0x2001, getSubVar(VA_TNT_POSITIONS, destIndex));
|
||||
sendMessage(_asTntItems[destIndex], 0x2001, getSubVar(VA_TNT_POSITIONS, _clickedIndex));
|
||||
int temp = getSubVar(VA_TNT_POSITIONS, destIndex);
|
||||
setSubVar(VA_TNT_POSITIONS, destIndex, getSubVar(VA_TNT_POSITIONS, _clickedIndex));
|
||||
setSubVar(VA_TNT_POSITIONS, _clickedIndex, temp);
|
||||
_counter = 2;
|
||||
_clickedIndex = -1;
|
||||
playSound(_soundToggle ? 1 : 2);
|
||||
_soundToggle = !_soundToggle;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene1202::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !_isPuzzleSolved)
|
||||
leaveScene(0);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_clickedIndex = (int)param.asInteger();
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
_counter--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 Scene1202::hmSolved(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
|
||||
leaveScene(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Scene1202::isSolved() {
|
||||
return
|
||||
getSubVar(VA_TNT_POSITIONS, 0) == 0 && getSubVar(VA_TNT_POSITIONS, 3) == 3 &&
|
||||
getSubVar(VA_TNT_POSITIONS, 6) == 6 && getSubVar(VA_TNT_POSITIONS, 9) == 9 &&
|
||||
getSubVar(VA_TNT_POSITIONS, 12) == 12 && getSubVar(VA_TNT_POSITIONS, 15) == 15;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
81
engines/neverhood/modules/module1200.h
Normal file
81
engines/neverhood/modules/module1200.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1200_H
|
||||
#define NEVERHOOD_MODULES_MODULE1200_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1200 : public Module {
|
||||
public:
|
||||
Module1200(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1200() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class AsScene1201TntMan;
|
||||
|
||||
class Scene1201 : public Scene {
|
||||
public:
|
||||
Scene1201(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene1201() override;
|
||||
protected:
|
||||
Sprite *_asMatch;
|
||||
AsScene1201TntMan *_asTntMan;
|
||||
Sprite *_asCreature;
|
||||
Sprite *_asTntManRope;
|
||||
Sprite *_asLeftDoor;
|
||||
Sprite *_asRightDoor;
|
||||
Sprite *_asTape;
|
||||
Sprite *_asKlaymenHead;
|
||||
bool _creatureExploded;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1202 : public Scene {
|
||||
public:
|
||||
Scene1202(NeverhoodEngine *vm, Module *parentModule);
|
||||
~Scene1202() override;
|
||||
protected:
|
||||
PaletteResource _paletteResource;
|
||||
Sprite *_asTntItems[18];
|
||||
int _counter;
|
||||
int _clickedIndex;
|
||||
byte _paletteData[1024];
|
||||
bool _isPuzzleSolved;
|
||||
bool _soundToggle;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmSolved(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
bool isSolved();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1200_H */
|
||||
847
engines/neverhood/modules/module1200_sprites.cpp
Normal file
847
engines/neverhood/modules/module1200_sprites.cpp
Normal file
@@ -0,0 +1,847 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1200_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kScene1201TntFileHashList1[] = {
|
||||
0x2098212D, 0x1600437E, 0x1600437E,
|
||||
0x00A840E3, 0x1A1830F6, 0x1A1830F6,
|
||||
0x00212062, 0x384010B6, 0x384010B6,
|
||||
0x07A01080, 0xD80C2837, 0xD80C2837,
|
||||
0x03A22092, 0xD8802CB6, 0xD8802CB6,
|
||||
0x03A93831, 0xDA460476, 0xDA460476
|
||||
};
|
||||
|
||||
static const uint32 kScene1201TntFileHashList2[] = {
|
||||
0x3040C676, 0x10914448, 0x10914448,
|
||||
0x3448A066, 0x1288C049, 0x1288C049,
|
||||
0x78C0E026, 0x3098D05A, 0x3098D05A,
|
||||
0x304890E6, 0x1284E048, 0x1284E048,
|
||||
0xB140A1E6, 0x5088A068, 0x5088A068,
|
||||
0x74C4C866, 0x3192C059, 0x3192C059
|
||||
};
|
||||
|
||||
SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2)
|
||||
: StaticSprite(vm, 900) {
|
||||
|
||||
int16 x = kScene1201PointArray[pointIndex].x;
|
||||
int16 y = kScene1201PointArray[pointIndex].y;
|
||||
if (x < 300)
|
||||
loadSprite(kScene1201TntFileHashList1[elemIndex], kSLFDefDrawOffset | kSLFDefPosition, 50);
|
||||
else
|
||||
loadSprite(kScene1201TntFileHashList2[elemIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 50, x, y - 20);
|
||||
setClipRect(0, 0, 640, clipY2);
|
||||
}
|
||||
|
||||
AsScene1201Tape::AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash)
|
||||
: AnimatedSprite(vm, fileHash, surfacePriority, x, y), _parentScene(parentScene), _nameHash(nameHash) {
|
||||
|
||||
if (!getSubVar(VA_HAS_TAPE, _nameHash) && !getSubVar(VA_IS_TAPE_INSERTED, _nameHash)) {
|
||||
SetMessageHandler(&AsScene1201Tape::handleMessage);
|
||||
} else {
|
||||
setVisible(false);
|
||||
SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 AsScene1201Tape::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, 0x4826, 0);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case NM_KLAYMEN_USE_OBJECT:
|
||||
setSubVar(VA_HAS_TAPE, _nameHash, 1);
|
||||
setVisible(false);
|
||||
SetMessageHandler(nullptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene1201TntManRope::AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging)
|
||||
: AnimatedSprite(vm, 1200) {
|
||||
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1201TntManRope::handleMessage);
|
||||
createSurface(10, 34, 149);
|
||||
_x = 202;
|
||||
_y = -32;
|
||||
if (isDummyHanging) {
|
||||
startAnimation(0x928F0C10, 15, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
} else {
|
||||
startAnimation(0x928F0C10, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 AsScene1201TntManRope::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x02060018)
|
||||
playSound(0, 0x47900E06);
|
||||
break;
|
||||
case NM_KLAYMEN_STOP_CLIMBING:
|
||||
startAnimation(0x928F0C10, 1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene1201RightDoor::AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
|
||||
: AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0) {
|
||||
|
||||
createSurface1(0xD088AC30, 100);
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
SetUpdateHandler(&AsScene1201RightDoor::update);
|
||||
SetMessageHandler(&AsScene1201RightDoor::handleMessage);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
if (isOpen) {
|
||||
startAnimation(0xD088AC30, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
_countdown = 25;
|
||||
} else {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1201RightDoor::update() {
|
||||
if (_countdown != 0 && (--_countdown == 0))
|
||||
stCloseDoor();
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
uint32 AsScene1201RightDoor::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case 0x4829:
|
||||
stOpenDoor();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1201RightDoor::stOpenDoor() {
|
||||
startAnimation(0xD088AC30, 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
setVisible(true);
|
||||
playSound(0, calcHash("fxDoorOpen20"));
|
||||
}
|
||||
|
||||
void AsScene1201RightDoor::stCloseDoor() {
|
||||
startAnimation(0xD088AC30, -1, -1);
|
||||
_playBackwards = true;
|
||||
setVisible(true);
|
||||
playSound(0, calcHash("fxDoorClose20"));
|
||||
NextState(&AsScene1201RightDoor::stCloseDoorDone);
|
||||
}
|
||||
|
||||
void AsScene1201RightDoor::stCloseDoorDone() {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
AsScene1201KlaymenHead::AsScene1201KlaymenHead(NeverhoodEngine *vm)
|
||||
: AnimatedSprite(vm, 1200) {
|
||||
|
||||
createSurface(1200, 69, 98);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1201KlaymenHead::handleMessage);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
uint32 AsScene1201KlaymenHead::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_KLAYMEN_STOP_CLIMBING:
|
||||
_x = 436;
|
||||
_y = 339;
|
||||
startAnimation(0xA060C599, 0, -1);
|
||||
setVisible(true);
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene1201TntMan::AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isComingDown)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _asTntManRope(asTntManRope),
|
||||
_isMoving(false) {
|
||||
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1201TntMan::handleMessage);
|
||||
createSurface(990, 106, 181);
|
||||
_x = 201;
|
||||
if (isComingDown) {
|
||||
_y = 297;
|
||||
stComingDown();
|
||||
} else {
|
||||
_y = 334;
|
||||
stStanding();
|
||||
}
|
||||
}
|
||||
|
||||
AsScene1201TntMan::~AsScene1201TntMan() {
|
||||
_vm->_soundMan->deleteSoundGroup(0x01D00560);
|
||||
}
|
||||
|
||||
uint32 AsScene1201TntMan::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x092870C0)
|
||||
sendMessage(_asTntManRope, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
else if (param.asInteger() == 0x11CA0144)
|
||||
playSound(0, 0x51800A04);
|
||||
break;
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x480B:
|
||||
if (!_isMoving) {
|
||||
_sprite = (Sprite*)sender;
|
||||
stMoving();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
|
||||
}
|
||||
|
||||
uint32 AsScene1201TntMan::hmComingDown(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = AsScene1201TntMan::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1201TntMan::suMoving() {
|
||||
_x = _sprite->getX() + 100;
|
||||
}
|
||||
|
||||
void AsScene1201TntMan::stStanding() {
|
||||
startAnimation(0x654913D0, 0, -1);
|
||||
SetMessageHandler(&AsScene1201TntMan::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
|
||||
void AsScene1201TntMan::stComingDown() {
|
||||
startAnimation(0x356803D0, 0, -1);
|
||||
SetMessageHandler(&AsScene1201TntMan::hmComingDown);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
NextState(&AsScene1201TntMan::stStanding);
|
||||
}
|
||||
|
||||
void AsScene1201TntMan::stMoving() {
|
||||
_vm->_soundMan->addSound(0x01D00560, 0x4B044624);
|
||||
_vm->_soundMan->playSoundLooping(0x4B044624);
|
||||
_isMoving = true;
|
||||
startAnimation(0x85084190, 0, -1);
|
||||
SetMessageHandler(&AsScene1201TntMan::handleMessage);
|
||||
SetSpriteUpdate(&AsScene1201TntMan::suMoving);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
|
||||
AsScene1201TntManFlame::AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan)
|
||||
: AnimatedSprite(vm, 1200), _asTntMan(asTntMan) {
|
||||
|
||||
createSurface1(0x828C0411, 995);
|
||||
SetUpdateHandler(&AsScene1201TntManFlame::update);
|
||||
SetMessageHandler(&Sprite::handleMessage);
|
||||
SetSpriteUpdate(&AsScene1201TntManFlame::suUpdate);
|
||||
startAnimation(0x828C0411, 0, -1);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
AsScene1201TntManFlame::~AsScene1201TntManFlame() {
|
||||
_vm->_soundMan->deleteSoundGroup(0x041080A4);
|
||||
}
|
||||
|
||||
void AsScene1201TntManFlame::update() {
|
||||
AnimatedSprite::update();
|
||||
if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
|
||||
setVisible(true);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
_vm->_soundMan->addSound(0x041080A4, 0x460A1050);
|
||||
_vm->_soundMan->playSoundLooping(0x460A1050);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1201TntManFlame::suUpdate() {
|
||||
_x = _asTntMan->getX() - 18;
|
||||
_y = _asTntMan->getY() - 158;
|
||||
}
|
||||
|
||||
AsScene1201Match::AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _countdown(0) {
|
||||
|
||||
createSurface(1100, 57, 60);
|
||||
SetUpdateHandler(&AsScene1201Match::update);
|
||||
SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
switch (getGlobalVar(V_MATCH_STATUS)) {
|
||||
case 0:
|
||||
_x = 521;
|
||||
_y = 112;
|
||||
_status = 0;
|
||||
stIdleOnDoorFrame();
|
||||
break;
|
||||
case 1:
|
||||
_x = 521;
|
||||
_y = 112;
|
||||
_status = 2;
|
||||
stOnDoorFrameAboutToMove();
|
||||
loadSound(0, 0xD00230CD);
|
||||
break;
|
||||
case 2:
|
||||
setDoDeltaX(1);
|
||||
_x = 403;
|
||||
_y = 337;
|
||||
_status = 0;
|
||||
stIdleOnFloor();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1201Match::update() {
|
||||
if (_countdown != 0 && (--_countdown == 0))
|
||||
gotoNextState();
|
||||
updateAnim();
|
||||
handleSpriteUpdate();
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
uint32 AsScene1201Match::hmOnDoorFrameAboutToMove(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x86668011)
|
||||
playSound(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1201Match::hmOnDoorFrameMoving(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1201Match::hmIdle(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case NM_KLAYMEN_USE_OBJECT:
|
||||
setVisible(false);
|
||||
setGlobalVar(V_MATCH_STATUS, 3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1201Match::stOnDoorFrameMoving() {
|
||||
startAnimation(0x00842374, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
|
||||
if (_status == 0) {
|
||||
NextState(&AsScene1201Match::stFallingFromDoorFrame);
|
||||
} else {
|
||||
NextState(&AsScene1201Match::stOnDoorFrameAboutToMove);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1201Match::stFallingFromDoorFrame() {
|
||||
setGlobalVar(V_MATCH_STATUS, 2);
|
||||
_x -= 199;
|
||||
_y += 119;
|
||||
startAnimation(0x018D0240, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
|
||||
NextState(&AsScene1201Match::stIdleOnFloor);
|
||||
}
|
||||
|
||||
void AsScene1201Match::stOnDoorFrameAboutToMove() {
|
||||
startAnimation(0x00842374, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
|
||||
_newStickFrameIndex = 0;
|
||||
if (_status != 0) {
|
||||
_countdown = 36;
|
||||
_status--;
|
||||
NextState(&AsScene1201Match::stOnDoorFrameMoving);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1201Match::stIdleOnDoorFrame() {
|
||||
startAnimation(0x00842374, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Match::hmIdle);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
|
||||
void AsScene1201Match::stIdleOnFloor() {
|
||||
setDoDeltaX(1);
|
||||
_x = 403;
|
||||
_y = 337;
|
||||
startAnimation(0x00842374, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Match::hmIdle);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
|
||||
AsScene1201Creature::AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen)
|
||||
: AnimatedSprite(vm, 900), _parentScene(parentScene), _klaymen(klaymen), _klaymenTooClose(false) {
|
||||
|
||||
// NOTE: _countdown2 and _countdown3 were unused/without effect and thus removed
|
||||
|
||||
createSurface(1100, 203, 199);
|
||||
SetUpdateHandler(&AsScene1201Creature::update);
|
||||
SetMessageHandler(&AsScene1201Creature::hmWaiting);
|
||||
_x = 540;
|
||||
_y = 320;
|
||||
stWaiting();
|
||||
}
|
||||
|
||||
void AsScene1201Creature::update() {
|
||||
bool oldKlaymenTooClose = _klaymenTooClose;
|
||||
_klaymenTooClose = _klaymen->getX() >= 385;
|
||||
if (_klaymenTooClose != oldKlaymenTooClose)
|
||||
stWaiting();
|
||||
if (_countdown != 0 && (--_countdown == 0))
|
||||
gotoNextState();
|
||||
updateAnim();
|
||||
handleSpriteUpdate();
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
uint32 AsScene1201Creature::hmWaiting(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x02060018)
|
||||
playSound(0, 0xCD298116);
|
||||
break;
|
||||
case 0x2004:
|
||||
GotoState(&AsScene1201Creature::stStartReachForTntDummy);
|
||||
break;
|
||||
case NM_KLAYMEN_STOP_CLIMBING:
|
||||
GotoState(&AsScene1201Creature::stPincerSnapKlaymen);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1201Creature::hmPincerSnap(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = hmWaiting(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1201Creature::hmPincerSnapKlaymen(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x02060018) {
|
||||
playSound(0, 0xCD298116);
|
||||
sendMessage(_parentScene, 0x4814, 0);
|
||||
sendMessage(_klaymen, 0x4814, 0);
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1201Creature::stWaiting() {
|
||||
startAnimation(0x08081513, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Creature::hmWaiting);
|
||||
NextState(&AsScene1201Creature::stPincerSnap);
|
||||
_countdown = 36;
|
||||
}
|
||||
|
||||
void AsScene1201Creature::stPincerSnap() {
|
||||
if (!_klaymenTooClose) {
|
||||
startAnimation(0xCA287133, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Creature::hmPincerSnap);
|
||||
NextState(&AsScene1201Creature::stWaiting);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1201Creature::stStartReachForTntDummy() {
|
||||
startAnimation(0x08081513, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Creature::hmWaiting);
|
||||
NextState(&AsScene1201Creature::stReachForTntDummy);
|
||||
_countdown = 48;
|
||||
}
|
||||
|
||||
void AsScene1201Creature::stReachForTntDummy() {
|
||||
startAnimation(0x5A201453, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Creature::hmWaiting);
|
||||
_countdown = 0;
|
||||
}
|
||||
|
||||
void AsScene1201Creature::stPincerSnapKlaymen() {
|
||||
startAnimation(0xCA287133, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Creature::hmPincerSnapKlaymen);
|
||||
NextState(&AsScene1201Creature::stWaiting);
|
||||
_countdown = 0;
|
||||
}
|
||||
|
||||
AsScene1201LeftDoor::AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen)
|
||||
: AnimatedSprite(vm, 1100), _klaymen(klaymen) {
|
||||
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
createSurface(800, 55, 199);
|
||||
if (_klaymen->getX() < 100) {
|
||||
startAnimation(0x508A111B, 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
playSound(0, calcHash("fxDoorOpen03"));
|
||||
} else {
|
||||
startAnimation(0x508A111B, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1201LeftDoor::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1201LeftDoor::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_KLAYMEN_CLOSE_DOOR:
|
||||
stCloseDoor();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1201LeftDoor::stCloseDoor() {
|
||||
startAnimation(0x508A111B, -1, -1);
|
||||
_playBackwards = true;
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
|
||||
static const NPoint kScene1202Points[] = {
|
||||
{203, 140}, {316, 212}, {277, 264},
|
||||
{176, 196}, {275, 159}, {366, 212},
|
||||
{230, 195}, {412, 212}, {368, 263},
|
||||
{204, 192}, {365, 164}, {316, 262},
|
||||
{191, 255}, {280, 213}, {406, 266},
|
||||
{214, 254}, {316, 158}, {402, 161}
|
||||
};
|
||||
|
||||
static const uint32 kScene1202FileHashes[] = {
|
||||
0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
|
||||
0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
|
||||
0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
|
||||
0x1AC90B8, 0x1AC18B8, 0x1AC18B8,
|
||||
0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
|
||||
0x1AC50B8, 0x1AC14B8, 0x1AC14B8
|
||||
};
|
||||
|
||||
AsScene1202TntItem::AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int itemIndex)
|
||||
: AnimatedSprite(vm, 900), _parentScene(parentScene), _itemIndex(itemIndex) {
|
||||
|
||||
int positionIndex;
|
||||
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
|
||||
positionIndex = getSubVar(VA_TNT_POSITIONS, _itemIndex);
|
||||
createSurface(900, 37, 67);
|
||||
_x = kScene1202Points[positionIndex].x;
|
||||
_y = kScene1202Points[positionIndex].y;
|
||||
stShowIdle();
|
||||
}
|
||||
|
||||
uint32 AsScene1202TntItem::hmShowIdle(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, 0x2000, _itemIndex);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x2001:
|
||||
_newPosition = (int)param.asInteger();
|
||||
stChangePositionFadeOut();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1202TntItem::hmChangePosition(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1202TntItem::stShowIdle() {
|
||||
startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
|
||||
SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
|
||||
void AsScene1202TntItem::stChangePositionFadeOut() {
|
||||
startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
|
||||
SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
|
||||
NextState(&AsScene1202TntItem::stChangePositionFadeIn);
|
||||
}
|
||||
|
||||
void AsScene1202TntItem::stChangePositionFadeIn() {
|
||||
_x = kScene1202Points[_newPosition].x;
|
||||
_y = kScene1202Points[_newPosition].y;
|
||||
startAnimation(kScene1202FileHashes[_itemIndex], 6, -1);
|
||||
_playBackwards = true;
|
||||
SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
|
||||
NextState(&AsScene1202TntItem::stChangePositionDone);
|
||||
}
|
||||
|
||||
void AsScene1202TntItem::stChangePositionDone() {
|
||||
sendMessage(_parentScene, NM_POSITION_CHANGE, _itemIndex);
|
||||
stShowIdle();
|
||||
}
|
||||
|
||||
static const KlaymenIdleTableItem klaymenIdleTable1201[] = {
|
||||
{1, kIdleSpinHead},
|
||||
{1, kIdleChest},
|
||||
{1, kIdleHeadOff},
|
||||
};
|
||||
|
||||
KmScene1201::KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
setKlaymenIdleTable(klaymenIdleTable1201, ARRAYSIZE(klaymenIdleTable1201));
|
||||
_doYHitIncr = true;
|
||||
}
|
||||
|
||||
uint32 KmScene1201::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case NM_KLAYMEN_MOVE_OBJECT:
|
||||
GotoState(&Klaymen::stMoveObject);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case 0x4813:
|
||||
GotoState(&KmScene1201::stFetchMatch);
|
||||
break;
|
||||
case 0x4814:
|
||||
GotoState(&KmScene1201::stTumbleHeadless);
|
||||
break;
|
||||
case 0x4815:
|
||||
GotoState(&KmScene1201::stCloseEyes);
|
||||
break;
|
||||
case NM_KLAYMEN_PRESS_BUTTON:
|
||||
if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stPressButtonSide);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
GotoState(&Klaymen::stTurnToUse);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
GotoState(&Klaymen::stReturnFromUse);
|
||||
break;
|
||||
case 0x481F:
|
||||
GotoState(&Klaymen::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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KmScene1201::stTumbleHeadless() {
|
||||
if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::stTumbleHeadless))) {
|
||||
_busyStatus = 1;
|
||||
_acceptInput = false;
|
||||
setDoDeltaX(0);
|
||||
startAnimation(0x2821C590, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene1201::hmTumbleHeadless);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
NextState(&Klaymen::stTryStandIdle);
|
||||
sendMessage(_parentScene, 0x8000, 0);
|
||||
playSound(0, 0x62E0A356);
|
||||
}
|
||||
}
|
||||
|
||||
void KmScene1201::stCloseEyes() {
|
||||
if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::stCloseEyes))) {
|
||||
_busyStatus = 1;
|
||||
_acceptInput = false;
|
||||
startAnimation(0x5420E254, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&Klaymen::hmLowLevel);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 KmScene1201::hmMatch(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x51281850) {
|
||||
setGlobalVar(V_TNT_DUMMY_FUSE_LIT, 1);
|
||||
} else if (param.asInteger() == 0x43000538) {
|
||||
playSound(0, 0x21043059);
|
||||
} else if (param.asInteger() == 0x02B20220) {
|
||||
playSound(0, 0xC5408620);
|
||||
} else if (param.asInteger() == 0x0A720138) {
|
||||
playSound(0, 0xD4C08010);
|
||||
} else if (param.asInteger() == 0xB613A180) {
|
||||
playSound(0, 0x44051000);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void KmScene1201::stFetchMatch() {
|
||||
if (!stStartAction(AnimationCallback(&KmScene1201::stFetchMatch))) {
|
||||
_busyStatus = 0;
|
||||
_acceptInput = false;
|
||||
setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
|
||||
startAnimation(0x9CAA0218, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene1201::hmMatch);
|
||||
SetSpriteUpdate(nullptr);
|
||||
NextState(&KmScene1201::stLightMatch);
|
||||
}
|
||||
}
|
||||
|
||||
void KmScene1201::stLightMatch() {
|
||||
_busyStatus = 1;
|
||||
_acceptInput = false;
|
||||
setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
|
||||
startAnimation(0x1222A513, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene1201::hmMatch);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
|
||||
uint32 KmScene1201::hmTumbleHeadless(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x000F0082) {
|
||||
playSound(0, 0x74E2810F);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
186
engines/neverhood/modules/module1200_sprites.h
Normal file
186
engines/neverhood/modules/module1200_sprites.h
Normal file
@@ -0,0 +1,186 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1200_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1200_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Used for both the scene sprites and the scene itself (for clipping)
|
||||
static const NPoint kScene1201PointArray[] = {
|
||||
{218, 193}, {410, 225}, {368, 277},
|
||||
{194, 227}, {366, 174}, {458, 224},
|
||||
{242, 228}, {512, 228}, {458, 277},
|
||||
{217, 233}, {458, 173}, {410, 276},
|
||||
{203, 280}, {371, 226}, {508, 279},
|
||||
{230, 273}, {410, 171}, {493, 174}
|
||||
};
|
||||
|
||||
class AsScene1201Tape : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 _nameHash;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1201TntManRope : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1201RightDoor : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
|
||||
protected:
|
||||
Sprite *_klaymen;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOpenDoor();
|
||||
void stCloseDoor();
|
||||
void stCloseDoorDone();
|
||||
};
|
||||
|
||||
class AsScene1201KlaymenHead : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201KlaymenHead(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1201TntMan : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isDown);
|
||||
~AsScene1201TntMan() override;
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Sprite *_asTntManRope;
|
||||
Sprite *_sprite;
|
||||
bool _isMoving;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmComingDown(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suMoving();
|
||||
void stStanding();
|
||||
void stComingDown();
|
||||
void stMoving();
|
||||
};
|
||||
|
||||
class AsScene1201TntManFlame : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan);
|
||||
~AsScene1201TntManFlame() override;
|
||||
protected:
|
||||
Sprite *_asTntMan;
|
||||
void update();
|
||||
void suUpdate();
|
||||
};
|
||||
|
||||
class AsScene1201Match : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _countdown;
|
||||
int _status;
|
||||
void update();
|
||||
uint32 hmOnDoorFrameAboutToMove(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmOnDoorFrameMoving(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmIdle(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOnDoorFrameMoving();
|
||||
void stFallingFromDoorFrame();
|
||||
void stOnDoorFrameAboutToMove();
|
||||
void stIdleOnDoorFrame();
|
||||
void stIdleOnFloor();
|
||||
};
|
||||
|
||||
class AsScene1201Creature : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Sprite *_klaymen;
|
||||
int _countdown;
|
||||
bool _klaymenTooClose;
|
||||
void update();
|
||||
uint32 hmWaiting(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmPincerSnap(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmPincerSnapKlaymen(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stWaiting();
|
||||
void stPincerSnap();
|
||||
void stStartReachForTntDummy();
|
||||
void stReachForTntDummy();
|
||||
void stPincerSnapKlaymen();
|
||||
};
|
||||
|
||||
class AsScene1201LeftDoor : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen);
|
||||
protected:
|
||||
Sprite *_klaymen;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stCloseDoor();
|
||||
};
|
||||
|
||||
class SsScene1201Tnt : public StaticSprite {
|
||||
public:
|
||||
SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2);
|
||||
};
|
||||
|
||||
class AsScene1202TntItem : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int index);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _itemIndex, _newPosition;
|
||||
uint32 hmShowIdle(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmChangePosition(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stShowIdle();
|
||||
void stChangePositionFadeOut();
|
||||
void stChangePositionFadeIn();
|
||||
void stChangePositionDone();
|
||||
};
|
||||
|
||||
class KmScene1201 : public Klaymen {
|
||||
public:
|
||||
KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void stCloseEyes();
|
||||
void stTumbleHeadless();
|
||||
void stFetchMatch();
|
||||
void stLightMatch();
|
||||
|
||||
uint32 hmTumbleHeadless(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmMatch(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1200_SPRITES_H */
|
||||
1258
engines/neverhood/modules/module1300.cpp
Normal file
1258
engines/neverhood/modules/module1300.cpp
Normal file
File diff suppressed because it is too large
Load Diff
166
engines/neverhood/modules/module1300.h
Normal file
166
engines/neverhood/modules/module1300.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1300_H
|
||||
#define NEVERHOOD_MODULES_MODULE1300_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class SmackerPlayer;
|
||||
|
||||
class Module1300 : public Module {
|
||||
public:
|
||||
Module1300(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1300() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
uint32 _musicFileHash;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene1302 : public Scene {
|
||||
public:
|
||||
Scene1302(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_asVenusFlyTrap;
|
||||
Sprite *_asBridge;
|
||||
Sprite *_ssFence;
|
||||
Sprite *_asRing1;
|
||||
Sprite *_asRing2;
|
||||
Sprite *_asRing3;
|
||||
Sprite *_asRing4;
|
||||
Sprite *_asRing5;
|
||||
Sprite *_class595;
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1303 : public Scene {
|
||||
public:
|
||||
Scene1303(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_asBalloon;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1304 : public Scene {
|
||||
public:
|
||||
Scene1304(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_asKey;
|
||||
Sprite *_asNeedle;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1305 : public Scene {
|
||||
public:
|
||||
Scene1305(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1306 : public Scene {
|
||||
public:
|
||||
Scene1306(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene1306() override;
|
||||
protected:
|
||||
Sprite *_ssButton;
|
||||
Sprite *_asTape;
|
||||
AnimatedSprite *_asElevatorDoor;
|
||||
Sprite *_asElevator;
|
||||
Sprite *_sprite1;
|
||||
Sprite *_asKey;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 handleMessage416EB0(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1307 : public Scene {
|
||||
public:
|
||||
Scene1307(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
NPointArray *_keyHolePoints;
|
||||
NRect _keyHoleRects[16];
|
||||
NRect _clipRects[4];
|
||||
Sprite *_asKeys[3];
|
||||
int _countdown;
|
||||
Sprite *_asCurrKey;
|
||||
bool _isInsertingKey;
|
||||
bool _doLeaveScene;
|
||||
bool _isPuzzleSolved;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1308 : public Scene {
|
||||
public:
|
||||
Scene1308(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_asTape;
|
||||
Sprite *_asJaggyDoor;
|
||||
Sprite *_asLightWallSymbols;
|
||||
Sprite *_ssNumber1;
|
||||
Sprite *_ssNumber2;
|
||||
Sprite *_ssNumber3;
|
||||
AnimatedSprite *_asProjector;
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
Sprite *_sprite4;
|
||||
Sprite *_sprite5;
|
||||
bool _isProjecting;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1317 : public Scene {
|
||||
public:
|
||||
Scene1317(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
SmackerPlayer *_smackerPlayer;
|
||||
bool _klaymenBlinks;
|
||||
int _klaymenBlinkCountdown;
|
||||
int _decisionCountdown;
|
||||
uint32 _smackerFileHash;
|
||||
bool _keepLastSmackerFrame;
|
||||
void update();
|
||||
void upChooseKing();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmChooseKing(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmHoborgAsKing(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmEndMovie(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stChooseKing();
|
||||
void stNoDecisionYet();
|
||||
void stHoborgAsKing();
|
||||
void stKlaymenAsKing();
|
||||
void stEndMovie();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1300_H */
|
||||
966
engines/neverhood/modules/module1300_sprites.cpp
Normal file
966
engines/neverhood/modules/module1300_sprites.cpp
Normal file
@@ -0,0 +1,966 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1300_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
AsScene1302Bridge::AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene) {
|
||||
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
createSurface1(0x88148150, 500);
|
||||
if (!getGlobalVar(V_FLYTRAP_RING_BRIDGE)) {
|
||||
startAnimation(0x88148150, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
} else {
|
||||
startAnimation(0x88148150, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
loadSound(0, 0x68895082);
|
||||
loadSound(1, 0x689BD0C1);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1302Bridge::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1302Bridge::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
stLowerBridge();
|
||||
break;
|
||||
case NM_KLAYMEN_CLOSE_DOOR:
|
||||
stRaiseBridge();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1302Bridge::stLowerBridge() {
|
||||
startAnimation(0x88148150, 0, -1);
|
||||
playSound(1);
|
||||
NextState(&AsScene1302Bridge::cbLowerBridgeEvent);
|
||||
}
|
||||
|
||||
void AsScene1302Bridge::stRaiseBridge() {
|
||||
startAnimation(0x88148150, 7, -1);
|
||||
_playBackwards = true;
|
||||
_newStickFrameIndex = 0;
|
||||
playSound(0);
|
||||
}
|
||||
|
||||
void AsScene1302Bridge::cbLowerBridgeEvent() {
|
||||
sendMessage(_parentScene, 0x2032, 0);
|
||||
startAnimation(0x88148150, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
|
||||
SsScene1302Fence::SsScene1302Fence(NeverhoodEngine *vm)
|
||||
: StaticSprite(vm, 0x11122122, 200) {
|
||||
|
||||
_firstY = _y;
|
||||
if (getGlobalVar(V_FLYTRAP_RING_FENCE))
|
||||
_y += 152;
|
||||
loadSound(0, 0x7A00400C);
|
||||
loadSound(1, 0x78184098);
|
||||
SetUpdateHandler(&SsScene1302Fence::update);
|
||||
SetMessageHandler(&SsScene1302Fence::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
|
||||
void SsScene1302Fence::update() {
|
||||
handleSpriteUpdate();
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
uint32 SsScene1302Fence::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
playSound(0);
|
||||
SetMessageHandler(nullptr);
|
||||
SetSpriteUpdate(&SsScene1302Fence::suMoveDown);
|
||||
break;
|
||||
case NM_KLAYMEN_CLOSE_DOOR:
|
||||
playSound(1);
|
||||
SetMessageHandler(nullptr);
|
||||
SetSpriteUpdate(&SsScene1302Fence::suMoveUp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void SsScene1302Fence::suMoveDown() {
|
||||
if (_y < _firstY + 152)
|
||||
_y += 8;
|
||||
else {
|
||||
SetMessageHandler(&SsScene1302Fence::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void SsScene1302Fence::suMoveUp() {
|
||||
if (_y > _firstY)
|
||||
_y -= 8;
|
||||
else {
|
||||
SetMessageHandler(&SsScene1302Fence::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
AsScene1303Balloon::AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene) {
|
||||
|
||||
createSurface(200, 128, 315);
|
||||
_x = 289;
|
||||
_y = 390;
|
||||
startAnimation(0x800278D2, 0, -1);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1303Balloon::handleMessage);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
}
|
||||
|
||||
uint32 AsScene1303Balloon::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, 0x4826, 0);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
stPopBalloon();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1303Balloon::hmBalloonPopped(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x020B0003)
|
||||
playSound(0, 0x742B0055);
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
playSound(0, 0x470007EE);
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
SetMessageHandler(nullptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1303Balloon::stPopBalloon() {
|
||||
startAnimation(0xAC004CD0, 0, -1);
|
||||
SetMessageHandler(&AsScene1303Balloon::hmBalloonPopped);
|
||||
}
|
||||
|
||||
AsScene1304Needle::AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y)
|
||||
: AnimatedSprite(vm, 0x548E9411, surfacePriority, x, y), _parentScene(parentScene) {
|
||||
|
||||
// NOTE: Skipped check if Klaymen already has the needle since that's done in the scene itself
|
||||
SetMessageHandler(&AsScene1304Needle::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1304Needle::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, 0x4826, 0);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case NM_KLAYMEN_USE_OBJECT:
|
||||
setGlobalVar(V_HAS_NEEDLE, 1);
|
||||
setVisible(false);
|
||||
SetMessageHandler(nullptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene1306Elevator::AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _asElevatorDoor(asElevatorDoor), _isUp(false), _isDown(true),
|
||||
_countdown(0) {
|
||||
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
createSurface1(0x043B0270, 100);
|
||||
startAnimation(0x043B0270, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
loadSound(0, 0x1C100E83);
|
||||
loadSound(1, 0x1C08CEC5);
|
||||
loadSound(2, 0x5D011E87);
|
||||
SetMessageHandler(&AsScene1306Elevator::handleMessage);
|
||||
}
|
||||
|
||||
void AsScene1306Elevator::update() {
|
||||
if (_isUp && _countdown != 0 && (--_countdown == 0))
|
||||
stGoingDown();
|
||||
AnimatedSprite::update();
|
||||
if (_currFrameIndex == 7 && _asElevatorDoor->getVisible()) {
|
||||
playSound(1);
|
||||
_asElevatorDoor->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1306Elevator::upGoingDown() {
|
||||
AnimatedSprite::update();
|
||||
if (_currFrameIndex == 5)
|
||||
_asElevatorDoor->setVisible(true);
|
||||
}
|
||||
|
||||
uint32 AsScene1306Elevator::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x2001:
|
||||
if (_isUp)
|
||||
_countdown = 144;
|
||||
messageResult = _isUp ? 1 : 0;
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
if (_isDown)
|
||||
stGoingUp();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1306Elevator::stGoingUp() {
|
||||
setVisible(true);
|
||||
_isDown = false;
|
||||
startAnimation(0x043B0270, 0, -1);
|
||||
playSound(0);
|
||||
SetUpdateHandler(&AsScene1306Elevator::update);
|
||||
NextState(&AsScene1306Elevator::cbGoingUpEvent);
|
||||
}
|
||||
|
||||
void AsScene1306Elevator::cbGoingUpEvent() {
|
||||
sendMessage(_parentScene, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
_isUp = true;
|
||||
_countdown = 144;
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
SetUpdateHandler(&AsScene1306Elevator::update);
|
||||
}
|
||||
|
||||
void AsScene1306Elevator::stGoingDown() {
|
||||
_isUp = false;
|
||||
setVisible(true);
|
||||
startAnimation(0x043B0270, -1, -1);
|
||||
_playBackwards = true;
|
||||
playSound(1);
|
||||
SetUpdateHandler(&AsScene1306Elevator::upGoingDown);
|
||||
NextState(&AsScene1306Elevator::cbGoingDownEvent);
|
||||
}
|
||||
|
||||
void AsScene1306Elevator::cbGoingDownEvent() {
|
||||
_isDown = true;
|
||||
sendMessage(_parentScene, NM_KLAYMEN_CLOSE_DOOR, 0);
|
||||
stopAnimation();
|
||||
SetUpdateHandler(&AsScene1306Elevator::update);
|
||||
}
|
||||
|
||||
static const uint32 kAsScene1307KeyResourceList1[] = {
|
||||
0x0438069C, 0x45B0023C, 0x05700217
|
||||
};
|
||||
|
||||
static const uint32 kAsScene1307KeyResourceList2[] = {
|
||||
0x04441334, 0x061433F0, 0x06019390
|
||||
};
|
||||
|
||||
static const uint32 kAsScene1307KeyResourceList3[] = {
|
||||
0x11A80030, 0x178812B1, 0x1488121C
|
||||
};
|
||||
|
||||
static const uint32 *kAsScene1307KeyResourceLists[] = {
|
||||
kAsScene1307KeyResourceList1,
|
||||
kAsScene1307KeyResourceList2,
|
||||
kAsScene1307KeyResourceList3
|
||||
};
|
||||
|
||||
static const int kAsScene1307KeySurfacePriorities[] = {
|
||||
700, 500, 300, 100
|
||||
};
|
||||
|
||||
const uint kAsScene1307KeyPointsCount = 12;
|
||||
|
||||
static const NPoint kAsScene1307KeyPoints[] = {
|
||||
{-2, 0}, {-5, 0}, { 5, 0},
|
||||
{12, 0}, {17, 0}, {25, 0},
|
||||
{16, -2}, {10, -6}, { 0, -7},
|
||||
{-7, -3}, {-3, 4}, { 2, 2}
|
||||
};
|
||||
|
||||
const uint kAsScene1307KeyFrameIndicesCount = 20;
|
||||
|
||||
static const int16 kAsScene1307KeyFrameIndices[] = {
|
||||
1, 4, 8, 11, 15, 16, 17, 17, 17, 16,
|
||||
15, 14, 12, 10, 9, 7, 5, 3, 2, 1
|
||||
};
|
||||
|
||||
const int kAsScene1307KeyDivValue = 200;
|
||||
const int16 kAsScene1307KeyXDelta = 70;
|
||||
const int16 kAsScene1307KeyYDelta = -12;
|
||||
|
||||
AsScene1307Key::AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _keyIndex(keyIndex), _clipRects(clipRects),
|
||||
_isClickable(true) {
|
||||
|
||||
NPoint pt;
|
||||
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
|
||||
|
||||
_dataResource.load(0x22102142);
|
||||
_pointList = _dataResource.getPointArray(0xAC849240);
|
||||
pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
|
||||
_x = pt.x;
|
||||
_y = pt.y;
|
||||
createSurface(kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4], 190, 148);
|
||||
startAnimation(fileHashes[0], 0, -1);
|
||||
loadSound(0, 0xDC4A1280);
|
||||
loadSound(1, 0xCC021233);
|
||||
loadSound(2, 0xC4C23844);
|
||||
loadSound(3, 0xC4523208);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1307Key::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1307Key::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_isClickable) {
|
||||
sendMessage(_parentScene, 0x4826, 0);
|
||||
stRemoveKey();
|
||||
messageResult = 1;
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isClickable = param.asInteger() != 0;
|
||||
break;
|
||||
case 0x2001:
|
||||
setSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex, param.asInteger());
|
||||
stMoveKey();
|
||||
break;
|
||||
case 0x2003:
|
||||
playSound(3);
|
||||
stUnlock();
|
||||
break;
|
||||
case 0x2004:
|
||||
playSound(2);
|
||||
stInsert();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1307Key::suRemoveKey() {
|
||||
if (_pointIndex < kAsScene1307KeyPointsCount) {
|
||||
_x += kAsScene1307KeyPoints[_pointIndex].x;
|
||||
_y += kAsScene1307KeyPoints[_pointIndex].y;
|
||||
updateBounds();
|
||||
_pointIndex++;
|
||||
} else {
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1307Key::suInsertKey() {
|
||||
if (_pointIndex < kAsScene1307KeyPointsCount) {
|
||||
_x -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].x;
|
||||
_y -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].y;
|
||||
updateBounds();
|
||||
_pointIndex++;
|
||||
if (_pointIndex == 7)
|
||||
playSound(0);
|
||||
} else {
|
||||
SetSpriteUpdate(nullptr);
|
||||
sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1307Key::suMoveKey() {
|
||||
if (_pointIndex < kAsScene1307KeyFrameIndicesCount) {
|
||||
_frameIndex += kAsScene1307KeyFrameIndices[_pointIndex];
|
||||
_x = _prevX + (_deltaX * _frameIndex) / kAsScene1307KeyDivValue;
|
||||
_y = _prevY + (_deltaY * _frameIndex) / kAsScene1307KeyDivValue;
|
||||
updateBounds();
|
||||
_pointIndex++;
|
||||
} else {
|
||||
NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
|
||||
_x = pt.x + kAsScene1307KeyXDelta;
|
||||
_y = pt.y + kAsScene1307KeyYDelta;
|
||||
stInsertKey();
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1307Key::stRemoveKey() {
|
||||
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
|
||||
_pointIndex = 0;
|
||||
startAnimation(fileHashes[0], 0, -1);
|
||||
playSound(1);
|
||||
SetSpriteUpdate(&AsScene1307Key::suRemoveKey);
|
||||
}
|
||||
|
||||
void AsScene1307Key::stInsertKey() {
|
||||
_pointIndex = 0;
|
||||
sendMessage(_parentScene, NM_PRIORITY_CHANGE, kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
|
||||
setClipRect(_clipRects[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
SetSpriteUpdate(&AsScene1307Key::suInsertKey);
|
||||
}
|
||||
|
||||
void AsScene1307Key::stMoveKey() {
|
||||
NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
|
||||
int16 newX = pt.x + kAsScene1307KeyXDelta;
|
||||
int16 newY = pt.y + kAsScene1307KeyYDelta;
|
||||
sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1000);
|
||||
setClipRect(0, 0, 640, 480);
|
||||
_prevX = _x;
|
||||
_prevY = _y;
|
||||
if (newX == _x && newY == _y) {
|
||||
stInsertKey();
|
||||
} else {
|
||||
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
|
||||
_pointIndex = 0;
|
||||
_frameIndex = 0;
|
||||
_deltaX = newX - _x;
|
||||
_deltaY = newY - _y;
|
||||
startAnimation(fileHashes[0], 0, -1);
|
||||
SetSpriteUpdate(&AsScene1307Key::suMoveKey);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1307Key::stUnlock() {
|
||||
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
|
||||
startAnimation(fileHashes[1], 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
|
||||
void AsScene1307Key::stInsert() {
|
||||
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
|
||||
startAnimation(fileHashes[2], 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
|
||||
AsScene1308JaggyDoor::AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 0xBA0AE050, 1100, 320, 240), _parentScene(parentScene) {
|
||||
|
||||
setVisible(false);
|
||||
stopAnimation();
|
||||
SetMessageHandler(&AsScene1308JaggyDoor::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1308JaggyDoor::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
stOpenDoor();
|
||||
break;
|
||||
case NM_KLAYMEN_CLOSE_DOOR:
|
||||
stCloseDoor();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1308JaggyDoor::stOpenDoor() {
|
||||
startAnimation(0xBA0AE050, 0, -1);
|
||||
setVisible(true);
|
||||
playSound(0, calcHash("fxDoorOpen38"));
|
||||
NextState(&AsScene1308JaggyDoor::stOpenDoorDone);
|
||||
}
|
||||
|
||||
void AsScene1308JaggyDoor::stOpenDoorDone() {
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
void AsScene1308JaggyDoor::stCloseDoor() {
|
||||
startAnimation(0xBA0AE050, -1, -1);
|
||||
_playBackwards = true;
|
||||
setVisible(true);
|
||||
playSound(0, calcHash("fxDoorClose38"));
|
||||
NextState(&AsScene1308JaggyDoor::stCloseDoorDone);
|
||||
}
|
||||
|
||||
void AsScene1308JaggyDoor::stCloseDoorDone() {
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
stopAnimation();
|
||||
}
|
||||
|
||||
AsScene1308KeyboardDoor::AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 0xA08A0851, 1100, 320, 240), _parentScene(parentScene) {
|
||||
|
||||
playSound(0, 0x51456049);
|
||||
SetMessageHandler(&AsScene1308KeyboardDoor::handleMessage);
|
||||
NextState(&AsScene1308KeyboardDoor::stFallingKeys);
|
||||
}
|
||||
|
||||
uint32 AsScene1308KeyboardDoor::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1308KeyboardDoor::stFallingKeys() {
|
||||
startAnimation(0x6238B191, 0, -1);
|
||||
_x = 580;
|
||||
_y = 383;
|
||||
NextState(&AsScene1308KeyboardDoor::stFallingKeysDone);
|
||||
}
|
||||
|
||||
void AsScene1308KeyboardDoor::stFallingKeysDone() {
|
||||
sendMessage(_parentScene, 0x2004, 0);
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
AsScene1308LightWallSymbols::AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 0x80180A10, 100, 320, 240), _parentScene(parentScene) {
|
||||
|
||||
setVisible(false);
|
||||
stopAnimation();
|
||||
Entity::_priority = 1200;
|
||||
SetMessageHandler(&AsScene1308LightWallSymbols::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1308LightWallSymbols::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_POSITION_CHANGE:
|
||||
stFadeIn();
|
||||
break;
|
||||
case 0x2003:
|
||||
stFadeOut();
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1308LightWallSymbols::stFadeIn() {
|
||||
startAnimation(0x80180A10, 0, -1);
|
||||
setVisible(true);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
|
||||
void AsScene1308LightWallSymbols::stFadeOut() {
|
||||
startAnimation(0x80180A10, -1, -1);
|
||||
_playBackwards = true;
|
||||
NextState(&AsScene1308LightWallSymbols::stFadeOutDone);
|
||||
}
|
||||
|
||||
void AsScene1308LightWallSymbols::stFadeOutDone() {
|
||||
sendMessage(_parentScene, 0x2003, 0);
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
SsScene1308Number::SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index)
|
||||
: StaticSprite(vm, fileHash, 100) {
|
||||
|
||||
setVisible(false);
|
||||
_x = _spriteResource.getPosition().x + index * 20;
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
AsScene1308Mouse::AsScene1308Mouse(NeverhoodEngine *vm)
|
||||
: AnimatedSprite(vm, 1100) {
|
||||
|
||||
_x = 286;
|
||||
_y = 429;
|
||||
createSurface1(0xA282C472, 100);
|
||||
startAnimation(0xA282C472, 0, -1);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1308Mouse::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1308Mouse::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x66382026)
|
||||
playSound(0, 0x0CD84468);
|
||||
else if (param.asInteger() == 0x6E28061C)
|
||||
playSound(0, 0x78C8402C);
|
||||
else if (param.asInteger() == 0x462F0410)
|
||||
playSound(0, 0x60984E28);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene1303::KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1303::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4804:
|
||||
GotoState(&Klaymen::stPeekWall1);
|
||||
break;
|
||||
case 0x483B:
|
||||
GotoState(&Klaymen::stPeekWallReturn);
|
||||
break;
|
||||
case 0x483C:
|
||||
GotoState(&Klaymen::stPeekWall2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
KmScene1304::KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
KmScene1305::KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4804:
|
||||
GotoState(&KmScene1305::stCrashDown);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KmScene1305::stCrashDown() {
|
||||
playSound(0, 0x41648271);
|
||||
_busyStatus = 1;
|
||||
_acceptInput = false;
|
||||
startAnimationByHash(0x000BAB02, 0x88003000, 0);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetSpriteUpdate(nullptr);
|
||||
SetMessageHandler(&Klaymen::hmLowLevelAnimation);
|
||||
NextState(&KmScene1305::stCrashDownFinished);
|
||||
}
|
||||
|
||||
void KmScene1305::stCrashDownFinished() {
|
||||
setDoDeltaX(2);
|
||||
stTryStandIdle();
|
||||
}
|
||||
|
||||
KmScene1306::KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case NM_KLAYMEN_PRESS_BUTTON:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPressButton);
|
||||
else if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPressFloorButton);
|
||||
else
|
||||
GotoState(&Klaymen::stPressButtonSide);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_INSERT_DISK:
|
||||
GotoState(&Klaymen::stInsertDisk);
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTurnToUse);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stReturnFromUse);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAboutAfter);
|
||||
else if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stWonderAboutHalf);
|
||||
else if (param.asInteger() == 4)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else if (param.asInteger() == 3)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x482D:
|
||||
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x482E:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWalkToFrontNoStep);
|
||||
else
|
||||
GotoState(&Klaymen::stWalkToFront);
|
||||
break;
|
||||
case 0x482F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stTurnToFront);
|
||||
else
|
||||
GotoState(&Klaymen::stTurnToBack);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2000, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
case 0x483D:
|
||||
teleporterAppear(0xEE084A04);
|
||||
break;
|
||||
case 0x483E:
|
||||
teleporterDisappear(0xB86A4274);
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene1308::KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case NM_KLAYMEN_MOVE_OBJECT:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
|
||||
else
|
||||
GotoState(&Klaymen::stMoveObjectFaceObject);
|
||||
break;
|
||||
case 0x480D:
|
||||
GotoState(&Klaymen::stUseLever);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_INSERT_DISK:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stInsertKey);
|
||||
else
|
||||
GotoState(&Klaymen::stInsertDisk);
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
GotoState(&Klaymen::stTurnToUse);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
GotoState(&Klaymen::stReturnFromUse);
|
||||
break;
|
||||
case NM_KLAYMEN_RELEASE_LEVER:
|
||||
GotoState(&Klaymen::stReleaseLever);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
198
engines/neverhood/modules/module1300_sprites.h
Normal file
198
engines/neverhood/modules/module1300_sprites.h
Normal file
@@ -0,0 +1,198 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1300_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1300_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class AsScene1302Bridge : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stLowerBridge();
|
||||
void stRaiseBridge();
|
||||
void cbLowerBridgeEvent();
|
||||
};
|
||||
|
||||
class SsScene1302Fence : public StaticSprite {
|
||||
public:
|
||||
SsScene1302Fence(NeverhoodEngine *vm);
|
||||
protected:
|
||||
int16 _firstY;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suMoveDown();
|
||||
void suMoveUp();
|
||||
};
|
||||
|
||||
class AsScene1303Balloon : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmBalloonPopped(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stPopBalloon();
|
||||
};
|
||||
|
||||
class AsScene1304Needle : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1306Elevator : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
AnimatedSprite *_asElevatorDoor;
|
||||
bool _isUp;
|
||||
bool _isDown;
|
||||
int _countdown;
|
||||
void update();
|
||||
void upGoingDown();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stGoingUp();
|
||||
void cbGoingUpEvent();
|
||||
void stGoingDown();
|
||||
void cbGoingDownEvent();
|
||||
};
|
||||
|
||||
class AsScene1307Key : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
NPointArray *_pointList;
|
||||
uint _pointIndex;
|
||||
int _frameIndex;
|
||||
uint _keyIndex;
|
||||
NRect *_clipRects;
|
||||
bool _isClickable;
|
||||
int16 _prevX, _prevY;
|
||||
int16 _deltaX, _deltaY;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suRemoveKey();
|
||||
void suInsertKey();
|
||||
void suMoveKey();
|
||||
void stRemoveKey();
|
||||
void stInsertKey();
|
||||
void stMoveKey();
|
||||
void stUnlock();
|
||||
void stInsert();
|
||||
};
|
||||
|
||||
class AsScene1308JaggyDoor : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOpenDoor();
|
||||
void stOpenDoorDone();
|
||||
void stCloseDoor();
|
||||
void stCloseDoorDone();
|
||||
};
|
||||
|
||||
class AsScene1308KeyboardDoor : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stFallingKeys();
|
||||
void stFallingKeysDone();
|
||||
};
|
||||
|
||||
class AsScene1308LightWallSymbols : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stFadeIn();
|
||||
void stFadeOut();
|
||||
void stFadeOutDone();
|
||||
};
|
||||
|
||||
class SsScene1308Number : public StaticSprite {
|
||||
public:
|
||||
SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index);
|
||||
};
|
||||
|
||||
class AsScene1308Mouse : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1308Mouse(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene1303 : public Klaymen {
|
||||
public:
|
||||
KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1304 : public Klaymen {
|
||||
public:
|
||||
KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1305 : public Klaymen {
|
||||
public:
|
||||
KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void stCrashDown();
|
||||
void stCrashDownFinished();
|
||||
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1306 : public Klaymen {
|
||||
public:
|
||||
KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1308 : public Klaymen {
|
||||
public:
|
||||
KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1300_SPRITES_H */
|
||||
771
engines/neverhood/modules/module1400.cpp
Normal file
771
engines/neverhood/modules/module1400.cpp
Normal file
@@ -0,0 +1,771 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/diskplayerscene.h"
|
||||
#include "neverhood/gamemodule.h"
|
||||
#include "neverhood/modules/module1000_sprites.h"
|
||||
#include "neverhood/modules/module1200_sprites.h"
|
||||
#include "neverhood/modules/module1400.h"
|
||||
#include "neverhood/modules/module1400_sprites.h"
|
||||
#include "neverhood/modules/module2100_sprites.h"
|
||||
#include "neverhood/modules/module2200_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module1400::Module1400(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
_vm->_soundMan->addMusic(0x00AD0012, 0x06333232);
|
||||
_vm->_soundMan->addMusic(0x00AD0012, 0x624A220E);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else
|
||||
createScene(0, 0);
|
||||
|
||||
}
|
||||
|
||||
Module1400::~Module1400() {
|
||||
_vm->_soundMan->deleteMusicGroup(0x00AD0012);
|
||||
}
|
||||
|
||||
void Module1400::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1400::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_vm->_soundMan->startMusic(0x06333232, 0, 2);
|
||||
_childObject = new Scene1401(_vm, this, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_vm->_soundMan->stopMusic(0x06333232, 0, 2);
|
||||
_vm->_soundMan->stopMusic(0x624A220E, 0, 2);
|
||||
_childObject = new Scene1402(_vm, this, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
_vm->_soundMan->stopMusic(0x06333232, 0, 2);
|
||||
_vm->_soundMan->startMusic(0x624A220E, 0, 2);
|
||||
_childObject = new Scene1403(_vm, this, which);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
_vm->_soundMan->startMusic(0x06333232, 0, 2);
|
||||
_childObject = new Scene1404(_vm, this, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_vm->_soundMan->startMusic(0x06333232, 0, 2);
|
||||
_childObject = new Scene1405(_vm, this);
|
||||
break;
|
||||
case 5:
|
||||
_vm->gameState().sceneNum = 5;
|
||||
_vm->_soundMan->stopMusic(0x06333232, 0, 2);
|
||||
_childObject = new DiskplayerScene(_vm, this, 2);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
_vm->_soundMan->stopMusic(0x06333232, 0, 2);
|
||||
_childObject = new Scene1407(_vm, this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1400::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1400::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(1, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(3, 0);
|
||||
else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 1)
|
||||
createScene(2, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(6, -1);
|
||||
else
|
||||
createScene(0, 1);
|
||||
break;
|
||||
case 2:
|
||||
createScene(1, 1);
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 1)
|
||||
createScene(4, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(5, -1);
|
||||
else
|
||||
createScene(0, 2);
|
||||
break;
|
||||
case 4:
|
||||
createScene(3, 1);
|
||||
break;
|
||||
case 5:
|
||||
createScene(3, 2);
|
||||
break;
|
||||
case 6:
|
||||
createScene(1, 2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene1401::Scene1401(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _projectorBorderFlag(false), _ssFloorButton(nullptr), _asProjector(nullptr),
|
||||
_asPipe(nullptr), _asMouse(nullptr), _asCheese(nullptr), _asBackDoor(nullptr),
|
||||
_sprite1(nullptr), _sprite2(nullptr), _sprite3(nullptr), _ssButton(nullptr) {
|
||||
|
||||
SetMessageHandler(&Scene1401::handleMessage);
|
||||
SetUpdateHandler(&Scene1401::update);
|
||||
|
||||
setRectList(0x004B6758);
|
||||
setBackground(0x08221FA5);
|
||||
setPalette(0x08221FA5);
|
||||
insertScreenMouse(0x21FA108A);
|
||||
|
||||
_ssFloorButton = insertSprite<SsCommonFloorButton>(this, 0x980F3124, 0x12192892, 100, 0);
|
||||
_asPipe = insertSprite<AsScene1401Pipe>();
|
||||
|
||||
if (!getGlobalVar(V_MOUSE_SUCKED_IN)) {
|
||||
_asMouse = insertSprite<AsScene1401Mouse>();
|
||||
_asCheese = insertSprite<AsScene1401Cheese>();
|
||||
}
|
||||
|
||||
_sprite3 = insertStaticSprite(0xA82BA811, 1100);
|
||||
insertStaticSprite(0x0A116C60, 1100);
|
||||
_ssButton = insertSprite<SsCommonButtonSprite>(this, 0xB84B1100, 100, 0);
|
||||
_sprite1 = insertStaticSprite(0x38EA100C, 1005);
|
||||
_sprite2 = insertStaticSprite(0x98D0223C, 1200);
|
||||
_sprite2->setVisible(false);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1401>(380, 447);
|
||||
setMessageList(0x004B65C8);
|
||||
_sprite1->setVisible(false);
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene1401>(0, 447);
|
||||
setMessageList(0x004B65D0);
|
||||
_sprite1->setVisible(false);
|
||||
} else if (which == 2) {
|
||||
// Klaymen entering from the right
|
||||
insertKlaymen<KmScene1401>(660, 447);
|
||||
setMessageList(0x004B65D8);
|
||||
_sprite1->setVisible(false);
|
||||
} else {
|
||||
// Klaymen entering from the back
|
||||
insertKlaymen<KmScene1401>(290, 413);
|
||||
setMessageList(0x004B65E8);
|
||||
_sprite1->setVisible(false);
|
||||
}
|
||||
|
||||
if (getGlobalVar(V_PROJECTOR_LOCATION) == 2) {
|
||||
_asProjector = insertSprite<AsCommonProjector>(this, _klaymen, _asPipe);
|
||||
addCollisionSprite(_asProjector);
|
||||
if (getGlobalVar(V_PROJECTOR_SLOT) == 6) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
_klaymen->setX(_asProjector->getX() + 100);
|
||||
_klaymen->updateBounds();
|
||||
setMessageList(0x004B6670);
|
||||
} else if (getGlobalVar(V_PROJECTOR_SLOT) == 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
_klaymen->setX(_asProjector->getX() - 100);
|
||||
_klaymen->updateBounds();
|
||||
setMessageList(0x004B6670);
|
||||
}
|
||||
_asProjector->setClipRect(_sprite3->getDrawRect().x, _sprite2->getDrawRect().y, 640, 480);
|
||||
}
|
||||
|
||||
_klaymen->setClipRect(_sprite3->getDrawRect().x, 0, 640, 480);
|
||||
|
||||
if (which == 0 && _asProjector)
|
||||
sendMessage(_asProjector, NM_MOVE_TO_FRONT, 0);
|
||||
|
||||
_asBackDoor = insertSprite<AsScene1401BackDoor>(_klaymen, which == 0);
|
||||
|
||||
}
|
||||
|
||||
void Scene1401::update() {
|
||||
Scene::update();
|
||||
if (_asProjector && !_projectorBorderFlag && _asProjector->getY() < 360) {
|
||||
_sprite2->setVisible(true);
|
||||
_projectorBorderFlag = true;
|
||||
} else
|
||||
_sprite2->setVisible(false);
|
||||
}
|
||||
|
||||
uint32 Scene1401::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x02144CB1)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssFloorButton);
|
||||
else if (param.asInteger() == 0x402064D8)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssButton);
|
||||
else if (param.asInteger() == 0x01C66840) {
|
||||
if (sendMessage(_asBackDoor, 0x2001, 0) != 0)
|
||||
setMessageList(0x004B6690);
|
||||
else
|
||||
setMessageList(0x004B66B0);
|
||||
}
|
||||
break;
|
||||
case NM_SCENE_LEAVE:
|
||||
if (param.asInteger() != 0)
|
||||
leaveScene(2);
|
||||
else
|
||||
leaveScene(1);
|
||||
break;
|
||||
case 0x480B:
|
||||
if (sender == _ssFloorButton) {
|
||||
sendMessage(_asPipe, 0x2000, 0);
|
||||
if (!getGlobalVar(V_MOUSE_SUCKED_IN)) {
|
||||
sendMessage(_asMouse, 0x4839, 0);
|
||||
sendMessage(_asCheese, 0x4839, 0);
|
||||
setGlobalVar(V_MOUSE_SUCKED_IN, 1);
|
||||
}
|
||||
if (_asProjector && _asProjector->getX() > 404 && _asProjector->getX() < 504)
|
||||
sendMessage(_asProjector , 0x4839, 0);
|
||||
} else if (sender == _ssButton)
|
||||
sendMessage(_asBackDoor, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asProjector) {
|
||||
if (sendMessage(_asProjector, 0x480C, _klaymen->getX() > _asProjector->getX() ? 1 : 0) != 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
setMessageList2(0x004B6658);
|
||||
} else
|
||||
setMessageList2(0x004B65F0);
|
||||
}
|
||||
break;
|
||||
case NM_MOVE_TO_BACK:
|
||||
_sprite1->setVisible(true);
|
||||
if (_asProjector)
|
||||
sendMessage(_asProjector, NM_MOVE_TO_FRONT, 0);
|
||||
break;
|
||||
case NM_MOVE_TO_FRONT:
|
||||
_sprite1->setVisible(false);
|
||||
if (_asProjector)
|
||||
sendMessage(_asProjector, NM_MOVE_TO_BACK, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Scene1402::Scene1402(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _isShaking(false), _asPuzzleBox(nullptr), _asProjector(nullptr) {
|
||||
|
||||
SetMessageHandler(&Scene1402::handleMessage);
|
||||
|
||||
_vm->_screen->setYOffset(0);
|
||||
|
||||
setBackground(0x231482F0);
|
||||
setBackgroundY(-10);
|
||||
setPalette(0x231482F0);
|
||||
_palette->addPalette(0x91D3A391, 0, 64, 0);
|
||||
insertScreenMouse(0x482F4239);
|
||||
|
||||
_ssBridgePart1 = insertSprite<SsScene1402BridgePart>(0x15402D64, 1100);
|
||||
_ssBridgePart2 = insertSprite<SsScene1402BridgePart>(0x10A02120, 1100);
|
||||
_ssBridgePart3 = insertSprite<SsScene1402BridgePart>(0x60882BE0, 1100);
|
||||
|
||||
if (getGlobalVar(V_MOUSE_PUZZLE_SOLVED))
|
||||
setRectList(0x004B0C48);
|
||||
else
|
||||
setRectList(0x004B0C98);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1402>(377, 391);
|
||||
setMessageList(0x004B0B48);
|
||||
if (!getGlobalVar(V_MOUSE_PUZZLE_SOLVED))
|
||||
_asPuzzleBox = insertSprite<AsScene1402PuzzleBox>(this, 0);
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene1402>(42, 391);
|
||||
setMessageList(0x004B0B50);
|
||||
} else if (which == 2) {
|
||||
// Klaymen returning from the puzzle box
|
||||
insertKlaymen<KmScene1402>(377, 391);
|
||||
setMessageList(0x004B0B60);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
if (getGlobalVar(V_MOUSE_PUZZLE_SOLVED)) {
|
||||
_asPuzzleBox = insertSprite<AsScene1402PuzzleBox>(this, 1);
|
||||
clearRectList();
|
||||
showMouse(false);
|
||||
startShaking();
|
||||
} else
|
||||
_asPuzzleBox = insertSprite<AsScene1402PuzzleBox>(this, 0);
|
||||
} else {
|
||||
// Klaymen entering from the right
|
||||
insertKlaymen<KmScene1402>(513, 391);
|
||||
setMessageList(0x004B0B58);
|
||||
if (!getGlobalVar(V_MOUSE_PUZZLE_SOLVED)) {
|
||||
_asPuzzleBox = insertSprite<AsScene1402PuzzleBox>(this, 2);
|
||||
startShaking();
|
||||
}
|
||||
}
|
||||
|
||||
if (_asPuzzleBox)
|
||||
_asPuzzleBox->setClipRect(0, 0, 640, _ssBridgePart3->getDrawRect().y2());
|
||||
|
||||
if (getGlobalVar(V_PROJECTOR_LOCATION) == 1) {
|
||||
_asProjector = insertSprite<AsCommonProjector>(this, _klaymen, (Sprite*)nullptr);
|
||||
addCollisionSprite(_asProjector);
|
||||
if (getGlobalVar(V_PROJECTOR_SLOT) == 4) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
_klaymen->setX(_asProjector->getX() + 100);
|
||||
_klaymen->updateBounds();
|
||||
setMessageList(0x004B0BD0);
|
||||
} else if (getGlobalVar(V_PROJECTOR_SLOT) == 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
_klaymen->setX(_asProjector->getX() - 100);
|
||||
_klaymen->updateBounds();
|
||||
setMessageList(0x004B0BD0);
|
||||
}
|
||||
_asProjector->setClipRect(_ssBridgePart1->getDrawRect().x, 0, _ssBridgePart2->getDrawRect().x, _ssBridgePart3->getDrawRect().y2());
|
||||
}
|
||||
|
||||
_klaymen->setClipRect(_ssBridgePart1->getDrawRect().x, 0, _ssBridgePart2->getDrawRect().x2(), _ssBridgePart3->getDrawRect().y2());
|
||||
|
||||
}
|
||||
|
||||
void Scene1402::upShaking() {
|
||||
if (_isShaking) {
|
||||
setBackgroundY(_vm->_rnd->getRandomNumber(10 - 1) - 10);
|
||||
_vm->_screen->setYOffset(-10 - getBackgroundY());
|
||||
} else {
|
||||
setBackgroundY(-10);
|
||||
_vm->_screen->setYOffset(0);
|
||||
SetUpdateHandler(&Scene::update);
|
||||
}
|
||||
Scene::update();
|
||||
if (_asPuzzleBox)
|
||||
_asPuzzleBox->setClipRect(0, 0, 640, _ssBridgePart3->getDrawRect().y2());
|
||||
_klaymen->setClipRect(_ssBridgePart1->getDrawRect().x, 0, _ssBridgePart2->getDrawRect().x2(), _ssBridgePart3->getDrawRect().y2());
|
||||
}
|
||||
|
||||
uint32 Scene1402::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x00F43389) {
|
||||
if (getGlobalVar(V_MOUSE_PUZZLE_SOLVED))
|
||||
leaveScene(0);
|
||||
else {
|
||||
clearRectList();
|
||||
_klaymen->setVisible(false);
|
||||
showMouse(false);
|
||||
sendMessage(_asPuzzleBox, NM_POSITION_CHANGE, 0);
|
||||
startShaking();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_SCENE_LEAVE:
|
||||
if (param.asInteger())
|
||||
leaveScene(0);
|
||||
else
|
||||
leaveScene(1);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
stopShaking();
|
||||
showMouse(true);
|
||||
setRectList(0x004B0C48);
|
||||
break;
|
||||
case 0x2001:
|
||||
stopShaking();
|
||||
leaveScene(0);
|
||||
break;
|
||||
case 0x2003:
|
||||
stopShaking();
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asProjector) {
|
||||
if (sendMessage(_asProjector, 0x480C, _klaymen->getX() > _asProjector->getX() ? 1 : 0) != 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
setMessageList2(0x004B0BB8);
|
||||
} else
|
||||
setMessageList2(0x004B0B68);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Scene1402::startShaking() {
|
||||
_isShaking = true;
|
||||
SetUpdateHandler(&Scene1402::upShaking);
|
||||
}
|
||||
|
||||
void Scene1402::stopShaking() {
|
||||
_isShaking = false;
|
||||
}
|
||||
|
||||
Scene1407::Scene1407(NeverhoodEngine *vm, Module *parentModule)
|
||||
: Scene(vm, parentModule), _puzzleSolvedCountdown(0), _resetButtonCountdown(0) {
|
||||
|
||||
SetMessageHandler(&Scene1407::handleMessage);
|
||||
SetUpdateHandler(&Scene1407::update);
|
||||
|
||||
setBackground(0x00442225);
|
||||
setPalette(0x00442225);
|
||||
insertPuzzleMouse(0x4222100C, 20, 620);
|
||||
|
||||
_asMouse = insertSprite<AsScene1407Mouse>(this);
|
||||
_ssResetButton = insertStaticSprite(0x12006600, 100);
|
||||
_ssResetButton->setVisible(false);
|
||||
|
||||
}
|
||||
|
||||
void Scene1407::update() {
|
||||
Scene::update();
|
||||
if (_puzzleSolvedCountdown != 0 && (--_puzzleSolvedCountdown == 0))
|
||||
leaveScene(1);
|
||||
else if (_resetButtonCountdown != 0 && (--_resetButtonCountdown == 0))
|
||||
_ssResetButton->setVisible(false);
|
||||
}
|
||||
|
||||
uint32 Scene1407::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (_puzzleSolvedCountdown == 0) {
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
|
||||
// Exit scene
|
||||
leaveScene(0);
|
||||
} else if (param.asPoint().x >= 75 && param.asPoint().x <= 104 &&
|
||||
param.asPoint().y >= 62 && param.asPoint().y <= 90) {
|
||||
// The reset button was clicked
|
||||
sendMessage(_asMouse, 0x2001, 0);
|
||||
_ssResetButton->setVisible(true);
|
||||
playSound(0, 0x44045000);
|
||||
_resetButtonCountdown = 12;
|
||||
} else {
|
||||
// Handle the mouse
|
||||
sendMessage(_asMouse, messageNum, param);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
// The mouse got the cheese (nomnom)
|
||||
setGlobalVar(V_MOUSE_PUZZLE_SOLVED, 1);
|
||||
playSound(0, 0x68E25540);
|
||||
showMouse(false);
|
||||
_puzzleSolvedCountdown = 72;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Scene1403::Scene1403(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _asProjector(nullptr), _isProjecting(false) {
|
||||
|
||||
SetMessageHandler(&Scene1403::handleMessage);
|
||||
|
||||
setRectList(0x004B1FF8);
|
||||
setBackground(0x2110A234);
|
||||
setPalette(0x2110A234);
|
||||
insertScreenMouse(0x0A230219);
|
||||
|
||||
_sprite1 = insertStaticSprite(0x01102A33, 100);
|
||||
_sprite1->setVisible(false);
|
||||
_sprite2 = insertStaticSprite(0x04442520, 995);
|
||||
_sprite3 = insertStaticSprite(0x08742271, 995);
|
||||
_asTape1 = insertSprite<AsScene1201Tape>(this, 12, 1100, 201, 468, 0x9148A011);
|
||||
addCollisionSprite(_asTape1);
|
||||
_asTape1->setRepl(64, 0);
|
||||
_asTape2 = insertSprite<AsScene1201Tape>(this, 16, 1100, 498, 468, 0x9048A093);
|
||||
addCollisionSprite(_asTape2);
|
||||
_asTape2->setRepl(64, 0);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1403>(380, 463);
|
||||
setMessageList(0x004B1F18);
|
||||
} else {
|
||||
// Klaymen entering from the right
|
||||
insertKlaymen<KmScene1403>(640, 463);
|
||||
setMessageList(0x004B1F20);
|
||||
}
|
||||
_klaymen->setRepl(64, 0);
|
||||
|
||||
if (getGlobalVar(V_PROJECTOR_LOCATION) == 0) {
|
||||
_asProjector = insertSprite<AsCommonProjector>(this, _klaymen, (Sprite*)nullptr);
|
||||
addCollisionSprite(_asProjector);
|
||||
if (getGlobalVar(V_PROJECTOR_SLOT) == 4) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
_klaymen->setX(_asProjector->getX() + 100);
|
||||
_klaymen->updateBounds();
|
||||
setMessageList(0x004B1F70);
|
||||
}
|
||||
_asProjector->setClipRect(0, 0, 640, _sprite2->getDrawRect().y2());
|
||||
_asProjector->setRepl(64, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene1403::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x88C11390) {
|
||||
setRectList(0x004B2008);
|
||||
_isProjecting = true;
|
||||
} else if (param.asInteger() == 0x08821382) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
setRectList(0x004B1FF8);
|
||||
_isProjecting = false;
|
||||
}
|
||||
break;
|
||||
case NM_SCENE_LEAVE:
|
||||
leaveScene(0);
|
||||
break;
|
||||
case NM_PRIORITY_CHANGE:
|
||||
if (sender == _asProjector) {
|
||||
if (param.asInteger() >= 1000)
|
||||
setSurfacePriority(_sprite3->getSurface(), 1100);
|
||||
else
|
||||
setSurfacePriority(_sprite3->getSurface(), 995);
|
||||
}
|
||||
break;
|
||||
case NM_KLAYMEN_RAISE_LEVER:
|
||||
_sprite1->setVisible(false);
|
||||
break;
|
||||
case NM_KLAYMEN_LOWER_LEVER:
|
||||
_sprite1->setVisible(true);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asProjector) {
|
||||
if (_isProjecting)
|
||||
setMessageList2(0x004B1FA8);
|
||||
else if (param.asInteger() == 1) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
setMessageList2(0x004B1F88);
|
||||
} else if (sendMessage(_asProjector, 0x480C, _klaymen->getX() > _asProjector->getX() ? 1 : 0) != 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
setMessageList2(0x004B1F58);
|
||||
} else
|
||||
setMessageList2(0x004B1F28);
|
||||
} else if (sender == _asTape1 || sender == _asTape2) {
|
||||
if (_isProjecting)
|
||||
setMessageList2(0x004B1FA8);
|
||||
else if (_messageListStatus != 2) {
|
||||
sendEntityMessage(_klaymen, 0x1014, sender);
|
||||
setMessageList2(0x004B1FB8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Scene1404::Scene1404(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _asProjector(nullptr), _asKey(nullptr) {
|
||||
|
||||
if (getGlobalVar(V_HAS_FINAL_KEY) && getGlobalVar(V_KEY3_LOCATION) == 0)
|
||||
setGlobalVar(V_KEY3_LOCATION, 5);
|
||||
|
||||
SetMessageHandler(&Scene1404::handleMessage);
|
||||
|
||||
setRectList(0x004B8D80);
|
||||
setBackground(0xAC0B006F);
|
||||
setPalette(0xAC0B006F);
|
||||
_palette->addPalette(0x00801510, 0, 65, 0);
|
||||
insertScreenMouse(0xB006BAC8);
|
||||
|
||||
if (getGlobalVar(V_KEY3_LOCATION) == 5) {
|
||||
_asKey = insertSprite<AsCommonKey>(this, 2, 1100, 267, 411);
|
||||
addCollisionSprite(_asKey);
|
||||
}
|
||||
|
||||
_sprite1 = insertStaticSprite(0x1900A1F8, 1100);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 14, 1100, 281, 411, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1404>(376, 406);
|
||||
setMessageList(0x004B8C28);
|
||||
} else if (which == 1) {
|
||||
// Klaymen returning from the tiles puzzle
|
||||
insertKlaymen<KmScene1404>(376, 406);
|
||||
setMessageList(0x004B8C30);
|
||||
} else if (which == 2) {
|
||||
// Klaymen returning from the diskplayer
|
||||
if (getGlobalVar(V_KLAYMEN_IS_DELTA_X)) {
|
||||
insertKlaymen<KmScene1404>(347, 406);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
} else {
|
||||
insertKlaymen<KmScene1404>(187, 406);
|
||||
}
|
||||
setMessageList(0x004B8D28);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene1404>(30, 406);
|
||||
setMessageList(0x004B8C38);
|
||||
}
|
||||
|
||||
if (getGlobalVar(V_PROJECTOR_LOCATION) == 3) {
|
||||
_asProjector = insertSprite<AsCommonProjector>(this, _klaymen, (Sprite*)nullptr);
|
||||
addCollisionSprite(_asProjector);
|
||||
if (getGlobalVar(V_PROJECTOR_SLOT) == 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
_klaymen->setX(_asProjector->getX() - 100);
|
||||
_klaymen->updateBounds();
|
||||
setMessageList(0x004B8CB8);
|
||||
}
|
||||
_asProjector->setClipRect(_sprite1->getDrawRect().x, 0, 640, 480);
|
||||
}
|
||||
|
||||
_klaymen->setClipRect(_sprite1->getDrawRect().x, 0, 640, 480);
|
||||
|
||||
}
|
||||
|
||||
Scene1404::~Scene1404() {
|
||||
setGlobalVar(V_KLAYMEN_IS_DELTA_X, _klaymen->isDoDeltaX() ? 1 : 0);
|
||||
}
|
||||
|
||||
uint32 Scene1404::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x410650C2) {
|
||||
if (_asProjector && _asProjector->getX() == 220)
|
||||
setMessageList(0x004B8C40);
|
||||
else
|
||||
setMessageList(0x004B8CE8);
|
||||
}
|
||||
break;
|
||||
case NM_SCENE_LEAVE:
|
||||
leaveScene(0);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asProjector) {
|
||||
if (sendMessage(_asProjector, 0x480C, _klaymen->getX() > _asProjector->getX() ? 1 : 0) != 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
setMessageList2(0x004B8CA0);
|
||||
} else
|
||||
setMessageList2(0x004B8C40);
|
||||
} else if (sender == _asTape && _messageListStatus != 2) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTape);
|
||||
setMessageList(0x004B8CD0);
|
||||
} else if (sender == _asKey && _messageListStatus != 2) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asKey);
|
||||
setMessageList(0x004B8D18);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Scene1405::Scene1405(NeverhoodEngine *vm, Module *parentModule)
|
||||
: Scene(vm, parentModule), _selectFirstTile(true), _tilesLeft(48), _countdown(0) {
|
||||
|
||||
_vm->gameModule()->initMemoryPuzzle();
|
||||
|
||||
SetUpdateHandler(&Scene1405::update);
|
||||
SetMessageHandler(&Scene1405::handleMessage);
|
||||
|
||||
setBackground(0x0C0C007D);
|
||||
setPalette(0x0C0C007D);
|
||||
insertPuzzleMouse(0xC00790C8, 20, 620);
|
||||
|
||||
for (uint32 tileIndex = 0; tileIndex < 48; tileIndex++) {
|
||||
_tiles[tileIndex] = insertSprite<AsScene1405Tile>(this, tileIndex);
|
||||
addCollisionSprite(_tiles[tileIndex]);
|
||||
if (getSubVar(VA_IS_TILE_MATCH, tileIndex))
|
||||
_tilesLeft--;
|
||||
}
|
||||
|
||||
loadSound(0, 0x68E25540);
|
||||
}
|
||||
|
||||
void Scene1405::update() {
|
||||
Scene::update();
|
||||
// Check if the player chose a wrong tile, in which case the whole grid gets reset
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
_tilesLeft = 48;
|
||||
_tiles[_firstTileIndex]->hide(true);
|
||||
_tiles[_secondTileIndex]->hide(false);
|
||||
for (uint32 i = 0; i < 48; i++) {
|
||||
if (getSubVar(VA_IS_TILE_MATCH, i)) {
|
||||
_tiles[i]->hide(false);
|
||||
setSubVar(VA_IS_TILE_MATCH, i, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene1405::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
|
||||
leaveScene(0);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (_selectFirstTile) {
|
||||
_firstTileIndex = param.asInteger();
|
||||
_selectFirstTile = false;
|
||||
} else {
|
||||
_secondTileIndex = param.asInteger();
|
||||
if (_firstTileIndex != _secondTileIndex) {
|
||||
_selectFirstTile = true;
|
||||
if (getSubVar(VA_TILE_SYMBOLS, _secondTileIndex) == getSubVar(VA_TILE_SYMBOLS, _firstTileIndex)) {
|
||||
setSubVar(VA_IS_TILE_MATCH, _firstTileIndex, 1);
|
||||
setSubVar(VA_IS_TILE_MATCH, _secondTileIndex, 1);
|
||||
_tilesLeft -= 2;
|
||||
if (_tilesLeft == 0)
|
||||
playSound(0);
|
||||
} else
|
||||
_countdown = 10;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
135
engines/neverhood/modules/module1400.h
Normal file
135
engines/neverhood/modules/module1400.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1400_H
|
||||
#define NEVERHOOD_MODULES_MODULE1400_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1400 : public Module {
|
||||
public:
|
||||
Module1400(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1400() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class AsCommonProjector;
|
||||
class AsScene1201Tape;
|
||||
class AsScene1405Tile;
|
||||
|
||||
class Scene1401 : public Scene {
|
||||
public:
|
||||
Scene1401(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
bool _projectorBorderFlag;
|
||||
Sprite *_ssFloorButton;
|
||||
AsCommonProjector *_asProjector;
|
||||
Sprite *_asPipe;
|
||||
Sprite *_asMouse;
|
||||
Sprite *_asCheese;
|
||||
Sprite *_asBackDoor;
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
Sprite *_ssButton;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1402 : public Scene {
|
||||
public:
|
||||
Scene1402(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_ssBridgePart1;
|
||||
Sprite *_ssBridgePart2;
|
||||
Sprite *_ssBridgePart3;
|
||||
Sprite *_asPuzzleBox;
|
||||
AsCommonProjector *_asProjector;
|
||||
bool _isShaking;
|
||||
void upShaking();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void startShaking();
|
||||
void stopShaking();
|
||||
};
|
||||
|
||||
class Scene1407 : public Scene {
|
||||
public:
|
||||
Scene1407(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
Sprite *_asMouse;
|
||||
Sprite *_ssResetButton;
|
||||
int _puzzleSolvedCountdown;
|
||||
int _resetButtonCountdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1403 : public Scene {
|
||||
public:
|
||||
Scene1403(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
AsScene1201Tape *_asTape1;
|
||||
AsScene1201Tape *_asTape2;
|
||||
AsCommonProjector *_asProjector;
|
||||
bool _isProjecting;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1404 : public Scene {
|
||||
public:
|
||||
Scene1404(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene1404() override;
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_asTape;
|
||||
AsCommonProjector *_asProjector;
|
||||
Sprite *_asKey;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1405 : public Scene {
|
||||
public:
|
||||
Scene1405(NeverhoodEngine *vm, Module *parentModule);
|
||||
int getCountdown() const { return _countdown; }
|
||||
protected:
|
||||
bool _selectFirstTile;
|
||||
int _firstTileIndex;
|
||||
int _secondTileIndex;
|
||||
int _tilesLeft;
|
||||
int _countdown;
|
||||
AsScene1405Tile *_tiles[48];
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1400_H */
|
||||
1159
engines/neverhood/modules/module1400_sprites.cpp
Normal file
1159
engines/neverhood/modules/module1400_sprites.cpp
Normal file
File diff suppressed because it is too large
Load Diff
197
engines/neverhood/modules/module1400_sprites.h
Normal file
197
engines/neverhood/modules/module1400_sprites.h
Normal file
@@ -0,0 +1,197 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1400_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1400_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class AsScene1401Pipe : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1401Pipe(NeverhoodEngine *vm);
|
||||
~AsScene1401Pipe() override;
|
||||
protected:
|
||||
int _countdown1;
|
||||
int _countdown2;
|
||||
void update();
|
||||
void upSuckInProjector();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmSuckInProjector(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stStartSucking();
|
||||
void stDoneSucking();
|
||||
void stSuckInProjector();
|
||||
};
|
||||
|
||||
class AsScene1401Mouse : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1401Mouse(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suSuckedIn();
|
||||
void stSuckedIn();
|
||||
};
|
||||
|
||||
class AsScene1401Cheese : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1401Cheese(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suSuckedIn();
|
||||
void stSuckedIn();
|
||||
};
|
||||
|
||||
class AsScene1401BackDoor : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
|
||||
protected:
|
||||
Sprite *_klaymen;
|
||||
int _countdown;
|
||||
bool _isOpen;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOpenDoor();
|
||||
void stCloseDoor();
|
||||
void stCloseDoorDone();
|
||||
};
|
||||
|
||||
struct AsCommonProjectorItem {
|
||||
NPoint point;
|
||||
int8 maxSlotCount;
|
||||
int8 lockSlotIndex;
|
||||
int8 index1;
|
||||
int8 leftBorderLeaves;
|
||||
int8 rightBorderLeaves;
|
||||
};
|
||||
|
||||
class AsCommonProjector : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe);
|
||||
~AsCommonProjector() override;
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Sprite *_klaymen;
|
||||
Sprite *_asPipe;
|
||||
const AsCommonProjectorItem *_asProjectorItem;
|
||||
int16 _beforeMoveX;
|
||||
bool _lockedInSlot;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmLockedInSlot(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suMoving();
|
||||
void moveProjector();
|
||||
void stSuckedIn();
|
||||
void stIdle();
|
||||
void stMoving();
|
||||
void stStartLockedInSlot();
|
||||
void stStayLockedInSlot();
|
||||
void stStartProjecting();
|
||||
void stLockedInSlot();
|
||||
void stStopProjecting();
|
||||
void stTurnToFront();
|
||||
void stStartSuckedIn();
|
||||
};
|
||||
|
||||
class SsScene1402BridgePart : public StaticSprite {
|
||||
public:
|
||||
SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority);
|
||||
};
|
||||
|
||||
class AsScene1402PuzzleBox : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stMoveUpDone();
|
||||
void stMoveDownDone();
|
||||
void stMoveDownSolvedDone();
|
||||
};
|
||||
|
||||
class AsScene1407Mouse : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int16 _walkDestX;
|
||||
int16 _currSectionIndex;
|
||||
int16 _nextHoleIndex;
|
||||
int _countdown;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suWalkTo();
|
||||
void upGoThroughHole();
|
||||
void stIdleLookAtGoodHole();
|
||||
void stWalkToDest();
|
||||
void stWalkToHole();
|
||||
void stGoThroughHole();
|
||||
void stArriveAtHole();
|
||||
};
|
||||
|
||||
class Scene1405;
|
||||
|
||||
class AsScene1405Tile : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex);
|
||||
void show();
|
||||
void hide(bool playClickSound);
|
||||
protected:
|
||||
Scene1405 *_parentScene;
|
||||
bool _isShowing;
|
||||
uint32 _tileIndex;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene1401 : public Klaymen {
|
||||
public:
|
||||
KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1402 : public Klaymen {
|
||||
public:
|
||||
KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1403 : public Klaymen {
|
||||
public:
|
||||
KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1404 : public Klaymen {
|
||||
public:
|
||||
KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1400_SPRITES_H */
|
||||
137
engines/neverhood/modules/module1500.cpp
Normal file
137
engines/neverhood/modules/module1500.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1500.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module1500::Module1500(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else
|
||||
createScene(3, -1);
|
||||
|
||||
}
|
||||
|
||||
void Module1500::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1500::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene1501(_vm, this, 0x8420221D, 0xA61024C4, 150, 48);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_childObject = new Scene1501(_vm, this, 0x30050A0A, 0x58B45E58, 110, 48);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
sendMessage(_parentModule, 0x0800, 0);
|
||||
createSmackerScene(0x001A0005, true, true, true);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
_childObject = new Scene1501(_vm, this, 0x0CA04202, 0, 110, 48);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1500::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1500::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
createScene(1, -1);
|
||||
break;
|
||||
case 1:
|
||||
createScene(2, -1);
|
||||
break;
|
||||
case 3:
|
||||
createScene(0, -1);
|
||||
break;
|
||||
default:
|
||||
leaveModule(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scene1501
|
||||
|
||||
Scene1501::Scene1501(NeverhoodEngine *vm, Module *parentModule, uint32 backgroundFileHash, uint32 soundFileHash, int countdown2, int countdown3)
|
||||
: Scene(vm, parentModule), _countdown3(countdown3), _countdown2(countdown2), _countdown1(0), _skip(false) {
|
||||
|
||||
SetUpdateHandler(&Scene1501::update);
|
||||
SetMessageHandler(&Scene1501::handleMessage);
|
||||
|
||||
setBackground(backgroundFileHash);
|
||||
setPalette();
|
||||
addEntity(_palette);
|
||||
_palette->addBasePalette(backgroundFileHash, 0, 256, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
|
||||
if (soundFileHash != 0)
|
||||
playSound(0, soundFileHash);
|
||||
|
||||
}
|
||||
|
||||
void Scene1501::update() {
|
||||
Scene::update();
|
||||
if (_countdown1 != 0) {
|
||||
_countdown1--;
|
||||
if (_countdown1 == 0 || _skip) {
|
||||
_vm->_screen->clear();
|
||||
leaveScene(0);
|
||||
}
|
||||
} else if ((_countdown2 != 0 && (--_countdown2 == 0)) || (_countdown2 == 0 && !isSoundPlaying(0)) || _skip) {
|
||||
_countdown1 = 12;
|
||||
_palette->startFadeToBlack(11);
|
||||
}
|
||||
|
||||
if (_countdown3 != 0)
|
||||
_countdown3--;
|
||||
|
||||
if (_countdown3 == 0 && _skip && _countdown1 == 0) {
|
||||
_countdown1 = 12;
|
||||
_palette->startFadeToBlack(11);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene1501::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_KEYPRESS_SPACE:
|
||||
_skip = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
57
engines/neverhood/modules/module1500.h
Normal file
57
engines/neverhood/modules/module1500.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// TODO: I couldn't come up with a better name than 'Module' so far
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1500_H
|
||||
#define NEVERHOOD_MODULES_MODULE1500_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/smackerscene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1500 : public Module {
|
||||
public:
|
||||
Module1500(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene1501 : public Scene {
|
||||
public:
|
||||
Scene1501(NeverhoodEngine *vm, Module *parentModule, uint32 backgroundFileHash, uint32 soundFileHash, int countdown2, int countdown3);
|
||||
protected:
|
||||
int _countdown1;
|
||||
int _countdown2;
|
||||
int _countdown3;
|
||||
bool _skip;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1500_H */
|
||||
609
engines/neverhood/modules/module1600.cpp
Normal file
609
engines/neverhood/modules/module1600.cpp
Normal file
@@ -0,0 +1,609 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/gamemodule.h"
|
||||
#include "neverhood/modules/module1200_sprites.h"
|
||||
#include "neverhood/modules/module1600.h"
|
||||
#include "neverhood/modules/module1600_sprites.h"
|
||||
#include "neverhood/modules/module2200_sprites.h"
|
||||
#include "neverhood/modules/module3000_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule1600SoundList[] = {
|
||||
0x90805C50, 0x90804450, 0xB4005E60,
|
||||
0x91835066, 0x90E14440, 0
|
||||
};
|
||||
|
||||
Module1600::Module1600(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 1)
|
||||
createScene(4, 1);
|
||||
else if (which == 2)
|
||||
createScene(5, 0);
|
||||
else if (which == 3)
|
||||
createScene(6, 1);
|
||||
else if (which == 4)
|
||||
createScene(1, 0);
|
||||
else
|
||||
createScene(0, 0);
|
||||
|
||||
_vm->_soundMan->addSoundList(0x1A008D8, kModule1600SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule1600SoundList, true, 50, 600, 5, 150);
|
||||
_vm->_soundMan->playTwoSounds(0x1A008D8, 0x41861371, 0x43A2507F, 0);
|
||||
|
||||
}
|
||||
|
||||
Module1600::~Module1600() {
|
||||
_vm->_soundMan->deleteGroup(0x1A008D8);
|
||||
}
|
||||
|
||||
void Module1600::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1600::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
createNavigationScene(0x004B39D0, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
createNavigationScene(0x004B3A30, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
createNavigationScene(0x004B3A60, which);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
createNavigationScene(0x004B3A90, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
createNavigationScene(0x004B3B20, which);
|
||||
break;
|
||||
case 5:
|
||||
_vm->gameState().sceneNum = 5;
|
||||
createNavigationScene(0x004B3B50, which);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
createNavigationScene(0x004B3B80, which);
|
||||
break;
|
||||
case 7:
|
||||
_vm->gameState().sceneNum = 7;
|
||||
_childObject = new Scene1608(_vm, this, which);
|
||||
break;
|
||||
case 8:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
_childObject = new Scene1609(_vm, this);
|
||||
break;
|
||||
case 1001:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
if (getGlobalVar(V_TALK_COUNTING_INDEX) == 1)
|
||||
createSmackerScene(0x80050200, true, true, false);
|
||||
else if (getGlobalVar(V_TALK_COUNTING_INDEX) == 2)
|
||||
createSmackerScene(0x80090200, true, true, false);
|
||||
else
|
||||
createSmackerScene(0x80000200, true, true, false);
|
||||
if (getGlobalVar(V_TALK_COUNTING_INDEX) >= 2)
|
||||
setGlobalVar(V_TALK_COUNTING_INDEX, 0);
|
||||
else
|
||||
incGlobalVar(V_TALK_COUNTING_INDEX, +1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1600::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1600::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 0)
|
||||
createScene(2, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(1, 0);
|
||||
else if (_moduleResult == 2)
|
||||
leaveModule(4);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 0)
|
||||
createScene(1001, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(0, 3);
|
||||
break;
|
||||
case 2:
|
||||
if (_moduleResult == 0)
|
||||
createScene(3, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(0, 2);
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 0)
|
||||
createScene(5, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(6, 0);
|
||||
else if (_moduleResult == 3)
|
||||
createScene(2, 1);
|
||||
else if (_moduleResult == 4)
|
||||
createScene(4, 0);
|
||||
break;
|
||||
case 4:
|
||||
if (_moduleResult == 0)
|
||||
leaveModule(1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(3, 1);
|
||||
break;
|
||||
case 5:
|
||||
if (_moduleResult == 0)
|
||||
leaveModule(2);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(3, 3);
|
||||
break;
|
||||
case 6:
|
||||
if (_moduleResult == 0)
|
||||
createScene(8, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(3, 5);
|
||||
break;
|
||||
case 7:
|
||||
createScene(6, 1);
|
||||
break;
|
||||
case 8:
|
||||
if (_moduleResult == 0)
|
||||
createScene(6, 0);
|
||||
else
|
||||
createScene(7, 0);
|
||||
break;
|
||||
case 1001:
|
||||
createScene(1, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _asCar(nullptr), _countdown1(0) {
|
||||
|
||||
setGlobalVar(V_CAR_DELTA_X, 1);
|
||||
|
||||
SetMessageHandler(&Scene1608::hmLowerFloor);
|
||||
|
||||
_asKey = insertSprite<AsCommonKey>(this, 1, 1100, 198, 220);
|
||||
addCollisionSprite(_asKey);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
if (_vm->gameState().which == 1)
|
||||
// Klaymen is in the car
|
||||
which = 1;
|
||||
else {
|
||||
// Klaymen is standing around
|
||||
setRectList(0x004B47D0);
|
||||
insertKlaymen<KmScene1608>(380, 438);
|
||||
_kmScene1608 = _klaymen;
|
||||
_klaymenInCar = false;
|
||||
_sprite1 = insertStaticSprite(0x7D0404E8, 1100);
|
||||
setMessageList(0x004B46A8);
|
||||
setBackground(0x10080E01);
|
||||
setPalette(0x10080E01);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
_klaymen->setClipRect(_sprite1->getDrawRect().x, 0, 640, 480);
|
||||
SetUpdateHandler(&Scene1608::upLowerFloor);
|
||||
insertScreenMouse(0x80E05108);
|
||||
insertStaticSprite(0x4B18F868, 1200);
|
||||
}
|
||||
} else if (which == 0) {
|
||||
// Klaymen entering from the left
|
||||
playSound(0, calcHash("fxDoorOpen23"));
|
||||
_vm->gameState().which = 0;
|
||||
setRectList(0x004B47D0);
|
||||
insertKlaymen<KmScene1608>(0, 438);
|
||||
_kmScene1608 = _klaymen;
|
||||
_klaymenInCar = false;
|
||||
setMessageList(0x004B46B0);
|
||||
setBackground(0x10080E01);
|
||||
setPalette(0x10080E01);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
insertScreenMouse(0x80E05108);
|
||||
_sprite1 = insertStaticSprite(0x7D0404E8, 1100);
|
||||
_klaymen->setClipRect(_sprite1->getDrawRect().x, 0, 640, 480);
|
||||
SetUpdateHandler(&Scene1608::upLowerFloor);
|
||||
insertStaticSprite(0x4B18F868, 1200);
|
||||
} else if (which == 2) {
|
||||
// Klaymen returning from looking through the upper window
|
||||
_vm->gameState().which = 1;
|
||||
_dataResource.load(0x003C0492);
|
||||
_roomPathPoints = _dataResource.getPointArray(calcHash("meArchroArchRoomPath"));
|
||||
setBackground(0x98001604);
|
||||
setPalette(0x98001604);
|
||||
_palette->addPalette("paPodRed", 65, 31, 65);
|
||||
insertScreenMouse(0x01600988);
|
||||
_sprite2 = insertStaticSprite(0x491F38A8, 1100);
|
||||
_asCar = createSprite<AsCommonCar>(this, 375, 227); // Create but don't add to the sprite list yet
|
||||
_asIdleCarLower = insertSprite<AsCommonIdleCarLower>(375, 227);
|
||||
_asIdleCarFull = insertSprite<AsCommonIdleCarFull>(375, 227);
|
||||
_asCar->setVisible(false);
|
||||
if (getGlobalVar(V_KLAYMEN_IS_DELTA_X)) {
|
||||
insertKlaymen<KmScene1608>(373, 220);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
} else
|
||||
insertKlaymen<KmScene1608>(283, 220);
|
||||
_kmScene1608 = _klaymen;
|
||||
setMessageList(0x004B47A8);
|
||||
SetMessageHandler(&Scene1608::hmUpperFloor);
|
||||
SetUpdateHandler(&Scene1608::upUpperFloor);
|
||||
_asCar->setPathPoints(_roomPathPoints);
|
||||
sendMessage(_asCar, NM_POSITION_CHANGE, _roomPathPoints->size() - 1);
|
||||
_sprite3 = insertStaticSprite(0xB47026B0, 1100);
|
||||
_clipRect1.set(_sprite3->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
|
||||
_clipRect3.set(_sprite2->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
|
||||
_clipRect2 = _clipRect1;
|
||||
_clipRect2.y2 = 215;
|
||||
_klaymen->setClipRect(_clipRect1);
|
||||
_asCar->setClipRect(_clipRect1);
|
||||
_asIdleCarLower->setClipRect(_clipRect1);
|
||||
_asIdleCarFull->setClipRect(_clipRect1);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
insertSprite<AsCommonCarConnector>(_asCar)->setClipRect(_clipRect1);
|
||||
_klaymenInCar = false;
|
||||
_carClipFlag = false;
|
||||
_carStatus = 0;
|
||||
setRectList(0x004B4810);
|
||||
}
|
||||
|
||||
// NOTE: Not in the else because 'which' is set to 1 in the true branch
|
||||
if (which == 1) {
|
||||
// Klaymen riding the car
|
||||
_vm->gameState().which = 1;
|
||||
_dataResource.load(0x003C0492);
|
||||
_roomPathPoints = _dataResource.getPointArray(calcHash("meArchroArchRoomPath"));
|
||||
setBackground(0x98001604);
|
||||
setPalette(0x98001604);
|
||||
_palette->addPalette("paPodRed", 65, 31, 65);
|
||||
insertScreenMouse(0x01600988);
|
||||
_asCar = insertSprite<AsCommonCar>(this, 375, 227);
|
||||
_asIdleCarLower = insertSprite<AsCommonIdleCarLower>(375, 227);
|
||||
_asIdleCarFull = insertSprite<AsCommonIdleCarFull>(375, 227);
|
||||
_sprite2 = insertStaticSprite(0x491F38A8, 1100);
|
||||
_kmScene1608 = createSprite<KmScene1608>(this, 439, 220);
|
||||
sendMessage(_kmScene1608, 0x2032, 1);
|
||||
_kmScene1608->setDoDeltaX(1);
|
||||
SetMessageHandler(&Scene1608::hmRidingCar);
|
||||
SetUpdateHandler(&Scene1608::upRidingCar);
|
||||
_asIdleCarLower->setVisible(false);
|
||||
_asIdleCarFull->setVisible(false);
|
||||
_asCar->setPathPoints(_roomPathPoints);
|
||||
sendMessage(_asCar, NM_POSITION_CHANGE, 0);
|
||||
sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 90);
|
||||
_sprite3 = insertStaticSprite(0xB47026B0, 1100);
|
||||
_clipRect1.set(_sprite3->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
|
||||
_clipRect3.set(_sprite2->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
|
||||
_clipRect2 = _clipRect1;
|
||||
_clipRect2.y2 = 215;
|
||||
_kmScene1608->setClipRect(_clipRect1);
|
||||
_asCar->setClipRect(_clipRect3);
|
||||
_asIdleCarLower->setClipRect(_clipRect1);
|
||||
_asIdleCarFull->setClipRect(_clipRect1);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011);
|
||||
// ... addCollisionSprite(_asTape);
|
||||
insertSprite<AsCommonCarConnector>(_asCar)->setClipRect(_clipRect1);
|
||||
_klaymenInCar = true;
|
||||
_carClipFlag = true;
|
||||
_carStatus = 0;
|
||||
}
|
||||
|
||||
_palette->addPalette("paKlayRed", 0, 64, 0);
|
||||
|
||||
}
|
||||
|
||||
Scene1608::~Scene1608() {
|
||||
setGlobalVar(V_KLAYMEN_IS_DELTA_X, _kmScene1608->isDoDeltaX() ? 1 : 0);
|
||||
if (_klaymenInCar)
|
||||
delete _kmScene1608;
|
||||
else
|
||||
delete _asCar;
|
||||
}
|
||||
|
||||
void Scene1608::upLowerFloor() {
|
||||
Scene::update();
|
||||
if (_countdown1 != 0 && (--_countdown1 == 0))
|
||||
leaveScene(0);
|
||||
}
|
||||
|
||||
void Scene1608::upUpperFloor() {
|
||||
Scene::update();
|
||||
if (_carStatus == 1) {
|
||||
removeSurface(_klaymen->getSurface());
|
||||
removeEntity(_klaymen);
|
||||
addSprite(_asCar);
|
||||
_klaymenInCar = true;
|
||||
clearRectList();
|
||||
SetUpdateHandler(&Scene1608::upCarAtHome);
|
||||
SetMessageHandler(&Scene1608::hmCarAtHome);
|
||||
_asIdleCarLower->setVisible(false);
|
||||
_asIdleCarFull->setVisible(false);
|
||||
_asCar->setVisible(true);
|
||||
sendMessage(_asCar, NM_CAR_ENTER, 0);
|
||||
_asCar->handleUpdate();
|
||||
_klaymen = nullptr;
|
||||
_carStatus = 0;
|
||||
}
|
||||
updateKlaymenCliprect();
|
||||
}
|
||||
|
||||
void Scene1608::upCarAtHome() {
|
||||
Scene::update();
|
||||
if (_mouseClicked) {
|
||||
if (_mouseClickPos.x <= 329 && _asCar->getX() == 375 && _asCar->getY() == 227) {
|
||||
sendMessage(_asCar, NM_CAR_LEAVE, 0);
|
||||
SetUpdateHandler(&Scene1608::upGettingOutOfCar);
|
||||
} else {
|
||||
sendPointMessage(_asCar, 0x2004, _mouseClickPos);
|
||||
SetMessageHandler(&Scene1608::hmRidingCar);
|
||||
SetUpdateHandler(&Scene1608::upRidingCar);
|
||||
}
|
||||
_mouseClicked = false;
|
||||
}
|
||||
updateKlaymenCliprect();
|
||||
}
|
||||
|
||||
void Scene1608::upGettingOutOfCar() {
|
||||
Scene::update();
|
||||
if (_carStatus == 2) {
|
||||
_klaymen = _kmScene1608;
|
||||
removeSurface(_asCar->getSurface());
|
||||
removeEntity(_asCar);
|
||||
addSprite(_klaymen);
|
||||
_klaymenInCar = false;
|
||||
SetMessageHandler(&Scene1608::hmUpperFloor);
|
||||
SetUpdateHandler(&Scene1608::upUpperFloor);
|
||||
setRectList(0x004B4810);
|
||||
_asIdleCarLower->setVisible(true);
|
||||
_asIdleCarFull->setVisible(true);
|
||||
_asCar->setVisible(false);
|
||||
setMessageList(0x004B4748);
|
||||
processMessageList();
|
||||
_klaymen->handleUpdate();
|
||||
_carStatus = 0;
|
||||
}
|
||||
updateKlaymenCliprect();
|
||||
}
|
||||
|
||||
void Scene1608::upRidingCar() {
|
||||
Scene::update();
|
||||
if (_mouseClicked) {
|
||||
sendPointMessage(_asCar, 0x2004, _mouseClickPos);
|
||||
_mouseClicked = false;
|
||||
}
|
||||
if (_asCar->getY() < 330) {
|
||||
if (_carClipFlag) {
|
||||
_carClipFlag = false;
|
||||
_asCar->setClipRect(_clipRect1);
|
||||
if (!_asCar->isDoDeltaX())
|
||||
sendMessage(_asCar, NM_CAR_TURN, 0);
|
||||
}
|
||||
} else if (!_carClipFlag) {
|
||||
_carClipFlag = true;
|
||||
_asCar->setClipRect(_clipRect3);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene1608::hmLowerFloor(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x20250B1A) {
|
||||
clearRectList();
|
||||
_klaymen->setVisible(false);
|
||||
showMouse(false);
|
||||
_sprite1->setVisible(false);
|
||||
playSound(0, calcHash("fxDoorClose23"));
|
||||
_countdown1 = 28;
|
||||
}
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asTape) {
|
||||
sendEntityMessage(_kmScene1608, 0x1014, _asTape);
|
||||
setMessageList(0x004B4770);
|
||||
} else if (sender == _asKey)
|
||||
setMessageList(0x004B46C8);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 Scene1608::hmUpperFloor(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x60842040)
|
||||
_carStatus = 1;
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asKey) {
|
||||
sendEntityMessage(_kmScene1608, 0x1014, _asKey);
|
||||
setMessageList(0x004B4760);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 Scene1608::hmRidingCar(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_KLAYMEN_CLIMB_LADDER:
|
||||
leaveScene(1);
|
||||
break;
|
||||
case NM_KLAYMEN_STOP_CLIMBING:
|
||||
SetMessageHandler(&Scene1608::hmCarAtHome);
|
||||
SetUpdateHandler(&Scene1608::upCarAtHome);
|
||||
sendMessage(_asCar, NM_CAR_AT_HOME, 1);
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 Scene1608::hmCarAtHome(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_CAR_LEAVE:
|
||||
_carStatus = 2;
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Scene1608::updateKlaymenCliprect() {
|
||||
if (_kmScene1608->getX() <= 375)
|
||||
_kmScene1608->setClipRect(_clipRect1);
|
||||
else
|
||||
_kmScene1608->setClipRect(_clipRect2);
|
||||
}
|
||||
|
||||
Scene1609::Scene1609(NeverhoodEngine *vm, Module *parentModule)
|
||||
: Scene(vm, parentModule), _countdown1(1), _currentSymbolIndex(0), _symbolPosition(0), _changeCurrentSymbol(true), _isSolved(false) {
|
||||
|
||||
_vm->gameModule()->initCodeSymbolsPuzzle();
|
||||
_noisySymbolIndex = getGlobalVar(V_NOISY_SYMBOL_INDEX);
|
||||
|
||||
SetMessageHandler(&Scene1609::handleMessage);
|
||||
SetUpdateHandler(&Scene1609::update);
|
||||
|
||||
setBackground(0x92124A14);
|
||||
setPalette(0x92124A14);
|
||||
insertPuzzleMouse(0x24A10929, 20, 620);
|
||||
|
||||
for (int symbolPosition = 0; symbolPosition < 12; symbolPosition++)
|
||||
_asSymbols[symbolPosition] = insertSprite<AsScene3011Symbol>(symbolPosition, false);
|
||||
|
||||
_ssButton = insertSprite<SsScene3011Button>(this, true);
|
||||
addCollisionSprite(_ssButton);
|
||||
loadSound(0, 0x68E25540);
|
||||
|
||||
}
|
||||
|
||||
void Scene1609::update() {
|
||||
if (!_isSolved && _countdown1 != 0 && (--_countdown1 == 0)) {
|
||||
if (_changeCurrentSymbol) {
|
||||
_currentSymbolIndex++;
|
||||
if (_currentSymbolIndex >= 12)
|
||||
_currentSymbolIndex = 0;
|
||||
_asSymbols[_symbolPosition]->change(_currentSymbolIndex + 12, _currentSymbolIndex == (int)getSubVar(VA_CODE_SYMBOLS, _noisySymbolIndex));
|
||||
_changeCurrentSymbol = false;
|
||||
_countdown1 = 36;
|
||||
} else {
|
||||
_asSymbols[_symbolPosition]->hide();
|
||||
_changeCurrentSymbol = true;
|
||||
_countdown1 = 12;
|
||||
}
|
||||
}
|
||||
if (_isSolved && !isSoundPlaying(0))
|
||||
leaveScene(1);
|
||||
Scene::update();
|
||||
}
|
||||
|
||||
uint32 Scene1609::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
|
||||
leaveScene(0);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (!_isSolved) {
|
||||
if (_changeCurrentSymbol)
|
||||
_asSymbols[_symbolPosition]->change(_currentSymbolIndex + 12, false);
|
||||
_asSymbols[_symbolPosition]->stopSymbolSound();
|
||||
_symbolPosition++;
|
||||
if (_symbolPosition >= 12) {
|
||||
if (testVars()) {
|
||||
playSound(0);
|
||||
setGlobalVar(V_CODE_SYMBOLS_SOLVED, 1);
|
||||
_isSolved = true;
|
||||
} else {
|
||||
_symbolPosition = 0;
|
||||
for (int i = 0; i < 12; i++)
|
||||
_asSymbols[i]->hide();
|
||||
}
|
||||
}
|
||||
_changeCurrentSymbol = true;
|
||||
_countdown1 = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Scene1609::testVars() {
|
||||
int cmpSymbolIndex = 0;
|
||||
|
||||
// Find the position of the first symbol
|
||||
while ((int)getSubVar(VA_CODE_SYMBOLS, cmpSymbolIndex) != _asSymbols[0]->getSymbolIndex())
|
||||
cmpSymbolIndex++;
|
||||
|
||||
// Check if the entered symbols match
|
||||
for (int enteredSymbolIndex = 0; enteredSymbolIndex < 12; enteredSymbolIndex++) {
|
||||
if ((int)getSubVar(VA_CODE_SYMBOLS, cmpSymbolIndex) != _asSymbols[enteredSymbolIndex]->getSymbolIndex())
|
||||
return false;
|
||||
cmpSymbolIndex++;
|
||||
if (cmpSymbolIndex >= 12)
|
||||
cmpSymbolIndex = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
99
engines/neverhood/modules/module1600.h
Normal file
99
engines/neverhood/modules/module1600.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1600_H
|
||||
#define NEVERHOOD_MODULES_MODULE1600_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1600 : public Module {
|
||||
public:
|
||||
Module1600(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1600() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class AsCommonCar;
|
||||
|
||||
class Scene1608 : public Scene {
|
||||
public:
|
||||
Scene1608(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene1608() override;
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_asKey;
|
||||
Sprite *_asIdleCarLower;
|
||||
Sprite *_asIdleCarFull;
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
Sprite *_asTape;
|
||||
Klaymen *_kmScene1608;
|
||||
NRect _clipRect1;
|
||||
NRect _clipRect2;
|
||||
NRect _clipRect3;
|
||||
int _carStatus;
|
||||
bool _carClipFlag;
|
||||
bool _klaymenInCar;
|
||||
int _countdown1;
|
||||
NPointArray *_roomPathPoints;
|
||||
void upLowerFloor();
|
||||
void upUpperFloor();
|
||||
void upCarAtHome();
|
||||
void upGettingOutOfCar();
|
||||
void upRidingCar();
|
||||
uint32 hmLowerFloor(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmUpperFloor(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmRidingCar(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmCarAtHome(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void updateKlaymenCliprect();
|
||||
};
|
||||
|
||||
class AsScene3011Symbol;
|
||||
|
||||
class Scene1609 : public Scene {
|
||||
friend class Console;
|
||||
public:
|
||||
Scene1609(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
Sprite *_ssButton;
|
||||
AsScene3011Symbol *_asSymbols[12];
|
||||
int _currentSymbolIndex;
|
||||
int _noisySymbolIndex;
|
||||
int _symbolPosition;
|
||||
int _countdown1;
|
||||
bool _changeCurrentSymbol;
|
||||
bool _isSolved;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
bool testVars();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1600_H */
|
||||
944
engines/neverhood/modules/module1600_sprites.cpp
Normal file
944
engines/neverhood/modules/module1600_sprites.cpp
Normal file
@@ -0,0 +1,944 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1600_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
AsCommonCar::AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: AnimatedSprite(vm, 1000), _parentScene(parentScene) {
|
||||
|
||||
createSurface(200, 556, 328);
|
||||
_x = x;
|
||||
_y = y;
|
||||
_destX = x;
|
||||
_destY = y;
|
||||
|
||||
_inMainArea = false;
|
||||
_exitDirection = 0;
|
||||
_currPointIndex = 0;
|
||||
_hasAgainDestPoint = false;
|
||||
_stepError = 0;
|
||||
_hasAgainDestPointIndex = false;
|
||||
_steps = 0;
|
||||
_isBraking = false;
|
||||
_yMoveTotalSteps = 0;
|
||||
_isBusy = false;
|
||||
_isIdle = false;
|
||||
_isMoving = true;
|
||||
_rectFlag = false;
|
||||
_newDeltaXType = -1;
|
||||
_soundCounter = 0;
|
||||
_pathPoints = nullptr;
|
||||
_currMoveDirection = 0;
|
||||
_newMoveDirection = 0;
|
||||
|
||||
startAnimation(0xD4220027, 0, -1);
|
||||
setDoDeltaX(getGlobalVar(V_CAR_DELTA_X));
|
||||
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
|
||||
AsCommonCar::~AsCommonCar() {
|
||||
if (_finalizeStateCb == AnimationCallback(&AsCommonCar::evTurnCarDone))
|
||||
setGlobalVar(V_CAR_DELTA_X, !getGlobalVar(V_CAR_DELTA_X));
|
||||
}
|
||||
|
||||
void AsCommonCar::setPathPoints(NPointArray *pathPoints) {
|
||||
_pathPoints = pathPoints;
|
||||
}
|
||||
|
||||
void AsCommonCar::update() {
|
||||
if (_newDeltaXType >= 0) {
|
||||
setDoDeltaX(_newDeltaXType);
|
||||
_newDeltaXType = -1;
|
||||
}
|
||||
AnimatedSprite::update();
|
||||
if (_hasAgainDestPoint && _yMoveTotalSteps == 0 && !_isBusy) {
|
||||
_hasAgainDestPoint = false;
|
||||
_hasAgainDestPointIndex = false;
|
||||
sendPointMessage(this, 0x2004, _againDestPoint);
|
||||
} else if (_hasAgainDestPointIndex && _yMoveTotalSteps == 0 && !_isBusy) {
|
||||
_hasAgainDestPointIndex = false;
|
||||
sendMessage(this, 0x2003, _againDestPointIndex);
|
||||
}
|
||||
updateMovement();
|
||||
updateSound();
|
||||
}
|
||||
|
||||
void AsCommonCar::upIdle() {
|
||||
update();
|
||||
if (++_idleCounter >= _idleCounterMax)
|
||||
stIdleBlink();
|
||||
updateSound();
|
||||
}
|
||||
|
||||
uint32 AsCommonCar::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_SCENE_LEAVE:
|
||||
SetSpriteUpdate(nullptr);
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
// Set the current position without moving
|
||||
_currPointIndex = param.asInteger();
|
||||
_stepError = 0;
|
||||
_x = pathPoint(_currPointIndex).x;
|
||||
_y = pathPoint(_currPointIndex).y;
|
||||
break;
|
||||
case 0x2003:
|
||||
// Move to a point by its index
|
||||
{
|
||||
int newPointIndex = param.asInteger();
|
||||
if (_yMoveTotalSteps <= 0 && !_isBusy) {
|
||||
_destX = pathPoint(newPointIndex).x;
|
||||
_destY = pathPoint(newPointIndex).y;
|
||||
if (_currPointIndex < newPointIndex) {
|
||||
moveToNextPoint();
|
||||
} else if (_currPointIndex == newPointIndex && _stepError == 0) {
|
||||
if (_currPointIndex == 0) {
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
|
||||
} else if (_currPointIndex == (int)_pathPoints->size()) {
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
}
|
||||
} else {
|
||||
moveToPrevPoint();
|
||||
}
|
||||
} else {
|
||||
_hasAgainDestPointIndex = true;
|
||||
_againDestPointIndex = newPointIndex;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x2004:
|
||||
// Move to the point closest to the parameter point
|
||||
{
|
||||
int minMatchIndex = -1;
|
||||
int minMatchDistance, distance;
|
||||
NPoint pt = param.asPoint();
|
||||
if (_yMoveTotalSteps <= 0 && !_isBusy) {
|
||||
// Check if we're already exiting (or something)
|
||||
if ((pt.x <= 20 && _exitDirection == 1) ||
|
||||
(pt.x >= 620 && _exitDirection == 3) ||
|
||||
(pt.y <= 20 && _exitDirection == 2) ||
|
||||
(pt.y >= 460 && _exitDirection == 4))
|
||||
break;
|
||||
_destX = pt.x;
|
||||
_destY = pt.y;
|
||||
minMatchDistance = calcDistance(_destX, _destY, _x, _y) + 1;
|
||||
for (int i = _currPointIndex + 1; i < (int)_pathPoints->size(); i++) {
|
||||
distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
|
||||
if (distance >= minMatchDistance)
|
||||
break;
|
||||
minMatchDistance = distance;
|
||||
minMatchIndex = i;
|
||||
}
|
||||
for (int i = _currPointIndex; i >= 0; i--) {
|
||||
distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
|
||||
if (distance >= minMatchDistance)
|
||||
break;
|
||||
minMatchDistance = distance;
|
||||
minMatchIndex = i;
|
||||
}
|
||||
if (minMatchIndex == -1) {
|
||||
if (_currPointIndex == 0)
|
||||
moveToPrevPoint();
|
||||
else
|
||||
SetSpriteUpdate(nullptr);
|
||||
} else {
|
||||
if (minMatchIndex > _currPointIndex)
|
||||
moveToNextPoint();
|
||||
else
|
||||
moveToPrevPoint();
|
||||
}
|
||||
} else {
|
||||
_hasAgainDestPoint = true;
|
||||
_againDestPoint = pt;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_CAR_MOVE_TO_PREV_POINT:
|
||||
_yMoveTotalSteps = param.asInteger();
|
||||
_steps = 0;
|
||||
_isBraking = false;
|
||||
_lastDistance = 640;
|
||||
SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
|
||||
break;
|
||||
case NM_CAR_MOVE_TO_NEXT_POINT:
|
||||
_yMoveTotalSteps = param.asInteger();
|
||||
_steps = 0;
|
||||
_isBraking = false;
|
||||
_lastDistance = 640;
|
||||
SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
|
||||
break;
|
||||
case NM_CAR_ENTER:
|
||||
stEnterCar();
|
||||
break;
|
||||
case NM_CAR_LEAVE:
|
||||
stLeaveCar();
|
||||
break;
|
||||
case NM_CAR_TURN:
|
||||
stTurnCar();
|
||||
break;
|
||||
case NM_CAR_AT_HOME:
|
||||
stCarAtHome();
|
||||
_newDeltaXType = param.asInteger();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsCommonCar::hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = AsCommonCar::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (_isBusy && param.asInteger() == 0x025424A2)
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsCommonCar::hmLeaveCar(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
switch (messageNum) {
|
||||
case NM_CAR_ENTER:
|
||||
stEnterCar();
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
sendMessage(_parentScene, NM_CAR_LEAVE, 0);
|
||||
SetMessageHandler(&AsCommonCar::handleMessage);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AsCommonCar::stCarAtHome() {
|
||||
bool doDeltaX = _doDeltaX;
|
||||
SetSpriteUpdate(nullptr);
|
||||
_hasAgainDestPoint = false;
|
||||
_hasAgainDestPointIndex = false;
|
||||
_isBraking = false;
|
||||
_isBusy = false;
|
||||
_isIdle = false;
|
||||
_isMoving = false;
|
||||
_rectFlag = false;
|
||||
NextState(&AsCommonCar::stLeanForwardIdle);
|
||||
startAnimation(0x35698F78, 0, -1);
|
||||
setDoDeltaX(doDeltaX ? 1 : 0);
|
||||
_currMoveDirection = 0;
|
||||
_newMoveDirection = 0;
|
||||
_steps = 0;
|
||||
_idleCounter = 0;
|
||||
_idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
|
||||
SetUpdateHandler(&AsCommonCar::upIdle);
|
||||
SetMessageHandler(&AsCommonCar::handleMessage);
|
||||
FinalizeState(&AsCommonCar::evIdleDone);
|
||||
}
|
||||
|
||||
void AsCommonCar::updateTurnMovement() {
|
||||
if (_turnMoveStatus == 1) {
|
||||
_lastDistance = 640;
|
||||
_isIdle = false;
|
||||
_isBraking = false;
|
||||
SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
|
||||
} else if (_turnMoveStatus == 2) {
|
||||
_lastDistance = 640;
|
||||
_isIdle = false;
|
||||
_isBraking = false;
|
||||
SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
|
||||
}
|
||||
}
|
||||
|
||||
void AsCommonCar::updateMovement() {
|
||||
if (_isBraking && !_isIdle && !_isBusy) {
|
||||
gotoNextState();
|
||||
_isMoving = false;
|
||||
_isIdle = true;
|
||||
startAnimation(0x192ADD30, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
NextState(&AsCommonCar::stLeanForwardIdle);
|
||||
} else if (!_isBraking && _steps && _isIdle) {
|
||||
gotoNextState();
|
||||
_isIdle = false;
|
||||
startAnimation(0x9966B138, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
NextState(&AsCommonCar::stUpdateMoveDirection);
|
||||
} else if (_newMoveDirection != _currMoveDirection && _isMoving && !_isBusy) {
|
||||
gotoNextState();
|
||||
_currMoveDirection = _newMoveDirection;
|
||||
stUpdateMoveDirection();
|
||||
}
|
||||
}
|
||||
|
||||
void AsCommonCar::stEnterCar() {
|
||||
startAnimation(0xA86A9538, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
NextState(&AsCommonCar::stLeanForwardIdle);
|
||||
}
|
||||
|
||||
void AsCommonCar::stLeaveCar() {
|
||||
startAnimation(0xA86A9538, -1, -1);
|
||||
_playBackwards = true;
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmLeaveCar);
|
||||
}
|
||||
|
||||
void AsCommonCar::stLeanForwardIdle() {
|
||||
startAnimation(0x35698F78, 0, -1);
|
||||
_currMoveDirection = 0;
|
||||
_newMoveDirection = 0;
|
||||
_steps = 0;
|
||||
_idleCounter = 0;
|
||||
_idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
|
||||
SetUpdateHandler(&AsCommonCar::upIdle);
|
||||
SetMessageHandler(&AsCommonCar::handleMessage);
|
||||
FinalizeState(&AsCommonCar::evIdleDone);
|
||||
}
|
||||
|
||||
void AsCommonCar::evIdleDone() {
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
}
|
||||
|
||||
void AsCommonCar::stIdleBlink() {
|
||||
startAnimation(0xB579A77C, 0, -1);
|
||||
_idleCounter = 0;
|
||||
_idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
NextState(&AsCommonCar::stLeanForwardIdle);
|
||||
}
|
||||
|
||||
void AsCommonCar::stUpdateMoveDirection() {
|
||||
_isMoving = true;
|
||||
if (_currMoveDirection == 1)
|
||||
startAnimation(0xD4AA03A4, 0, -1);
|
||||
else if (_currMoveDirection == 3)
|
||||
startAnimation(0xD00A1364, 0, -1);
|
||||
else if ((_currMoveDirection == 2 && _doDeltaX) || (_currMoveDirection == 4 && !_doDeltaX))
|
||||
stTurnCar();
|
||||
else
|
||||
startAnimation(0xD4220027, 0, -1);
|
||||
setGlobalVar(V_CAR_DELTA_X, _doDeltaX ? 1 : 0);
|
||||
}
|
||||
|
||||
void AsCommonCar::moveToNextPoint() {
|
||||
if (_currPointIndex >= (int)_pathPoints->size() - 1) {
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
} else {
|
||||
NPoint nextPt = pathPoint(_currPointIndex + 1);
|
||||
NPoint currPt = pathPoint(_currPointIndex);
|
||||
if (ABS(nextPt.y - currPt.y) <= ABS(nextPt.x - currPt.x) &&
|
||||
((_currMoveDirection == 2 && nextPt.x < currPt.x) ||
|
||||
(_currMoveDirection == 4 && nextPt.x >= currPt.x))) {
|
||||
if (_currMoveDirection == 2)
|
||||
_currMoveDirection = 4;
|
||||
else if (_currMoveDirection == 4)
|
||||
_currMoveDirection = 2;
|
||||
if (_isIdle)
|
||||
stTurnCarMoveToNextPoint();
|
||||
else
|
||||
stBrakeMoveToNextPoint();
|
||||
} else {
|
||||
if (_steps == 0) {
|
||||
gotoNextState();
|
||||
_isIdle = false;
|
||||
startAnimation(0x9966B138, 0, -1);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
NextState(&AsCommonCar::stUpdateMoveDirection);
|
||||
}
|
||||
_isBraking = false;
|
||||
SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
|
||||
_lastDistance = 640;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AsCommonCar::stBrakeMoveToNextPoint() {
|
||||
gotoNextState();
|
||||
_isBusy = true;
|
||||
_isBraking = true;
|
||||
startAnimation(0x192ADD30, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
NextState(&AsCommonCar::stTurnCarMoveToNextPoint);
|
||||
}
|
||||
|
||||
void AsCommonCar::stTurnCar() {
|
||||
// Turn to left/right #1
|
||||
gotoNextState();
|
||||
_isBusy = true;
|
||||
startAnimation(0xF46A0324, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
FinalizeState(&AsCommonCar::evTurnCarDone);
|
||||
_turnMoveStatus = 0;
|
||||
updateTurnMovement();
|
||||
}
|
||||
|
||||
void AsCommonCar::stTurnCarMoveToNextPoint() {
|
||||
// Turn to left/right #2
|
||||
gotoNextState();
|
||||
_isBusy = true;
|
||||
startAnimation(0xF46A0324, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
FinalizeState(&AsCommonCar::evTurnCarDone);
|
||||
_turnMoveStatus = 1;
|
||||
updateTurnMovement();
|
||||
}
|
||||
|
||||
void AsCommonCar::stTurnCarMoveToPrevPoint() {
|
||||
// Turn to left/right #3
|
||||
FinalizeState(nullptr);
|
||||
_isBusy = true;
|
||||
startAnimation(0xF46A0324, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
FinalizeState(&AsCommonCar::evTurnCarDone);
|
||||
_turnMoveStatus = 2;
|
||||
updateTurnMovement();
|
||||
}
|
||||
|
||||
void AsCommonCar::moveToPrevPoint() {
|
||||
if (_currPointIndex == 0 && _stepError == 0) {
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
|
||||
} else {
|
||||
NPoint prevPt;
|
||||
NPoint currPt;
|
||||
if (_stepError == 0) {
|
||||
prevPt = pathPoint(_currPointIndex - 1);
|
||||
currPt = pathPoint(_currPointIndex);
|
||||
} else {
|
||||
prevPt = pathPoint(_currPointIndex);
|
||||
currPt = pathPoint(_currPointIndex + 1);
|
||||
}
|
||||
if (ABS(prevPt.y - currPt.y) <= ABS(prevPt.x - currPt.x) &&
|
||||
((_currMoveDirection == 2 && prevPt.x < currPt.x) ||
|
||||
(_currMoveDirection == 4 && prevPt.x >= currPt.x))) {
|
||||
if (_currMoveDirection == 2)
|
||||
_currMoveDirection = 4;
|
||||
else if (_currMoveDirection == 4)
|
||||
_currMoveDirection = 2;
|
||||
if (_isIdle)
|
||||
stTurnCarMoveToPrevPoint();
|
||||
else
|
||||
stBrakeMoveToPrevPoint();
|
||||
} else {
|
||||
if (_steps == 0) {
|
||||
gotoNextState();
|
||||
_isIdle = false;
|
||||
startAnimation(0x9966B138, 0, -1);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
NextState(&AsCommonCar::stUpdateMoveDirection);
|
||||
}
|
||||
_isBraking = false;
|
||||
SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
|
||||
_lastDistance = 640;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AsCommonCar::stBrakeMoveToPrevPoint() {
|
||||
FinalizeState(nullptr);
|
||||
_isBusy = true;
|
||||
_isBraking = true;
|
||||
startAnimation(0x192ADD30, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
NextState(&AsCommonCar::stTurnCarMoveToPrevPoint);
|
||||
}
|
||||
|
||||
void AsCommonCar::evTurnCarDone() {
|
||||
_isBusy = false;
|
||||
setDoDeltaX(2);
|
||||
_newMoveDirection = 0;
|
||||
stUpdateMoveDirection();
|
||||
}
|
||||
|
||||
void AsCommonCar::suMoveToNextPoint() {
|
||||
int16 newX = _x, newY = _y;
|
||||
|
||||
if (_currPointIndex >= (int)_pathPoints->size()) {
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isBraking) {
|
||||
if (_steps <= 0) {
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
return;
|
||||
} else
|
||||
_steps--;
|
||||
} else if (_steps < 11)
|
||||
_steps++;
|
||||
|
||||
bool firstTime = true;
|
||||
_ySteps = _steps;
|
||||
int stepsCtr = _steps;
|
||||
|
||||
while (stepsCtr > 0) {
|
||||
NPoint pt1;
|
||||
NPoint pt2 = pathPoint(_currPointIndex);
|
||||
if (_currPointIndex + 1 >= (int)_pathPoints->size())
|
||||
pt1 = pathPoint(0);
|
||||
else
|
||||
pt1 = pathPoint(_currPointIndex + 1);
|
||||
int16 deltaX = ABS(pt1.x - pt2.x);
|
||||
int16 deltaY = ABS(pt1.y - pt2.y);
|
||||
if (deltaX >= deltaY) {
|
||||
_newMoveDirection = 2;
|
||||
if (pt1.x < pt2.x)
|
||||
_newMoveDirection = 4;
|
||||
if (stepsCtr + _stepError >= deltaX) {
|
||||
stepsCtr -= deltaX;
|
||||
stepsCtr += _stepError;
|
||||
_stepError = 0;
|
||||
_currPointIndex++;
|
||||
if (_currPointIndex == (int)_pathPoints->size() - 1)
|
||||
stepsCtr = 0;
|
||||
newX = pathPoint(_currPointIndex).x;
|
||||
newY = pathPoint(_currPointIndex).y;
|
||||
} else {
|
||||
_stepError += stepsCtr;
|
||||
if (pt1.x >= pt2.x)
|
||||
newX += stepsCtr;
|
||||
else
|
||||
newX -= stepsCtr;
|
||||
if (pt1.y >= pt2.y)
|
||||
newY = pt2.y + (deltaY * _stepError) / deltaX;
|
||||
else
|
||||
newY = pt2.y - (deltaY * _stepError) / deltaX;
|
||||
stepsCtr = 0;
|
||||
}
|
||||
} else {
|
||||
_newMoveDirection = 3;
|
||||
if (pt1.y < pt2.y)
|
||||
_newMoveDirection = 1;
|
||||
if (firstTime) {
|
||||
if (pt1.y >= pt2.y)
|
||||
stepsCtr += 7;
|
||||
else {
|
||||
stepsCtr -= 4;
|
||||
if (stepsCtr < 0)
|
||||
stepsCtr = 0;
|
||||
}
|
||||
_ySteps = stepsCtr;
|
||||
}
|
||||
if (stepsCtr + _stepError >= deltaY) {
|
||||
stepsCtr -= deltaY;
|
||||
stepsCtr += _stepError;
|
||||
_stepError = 0;
|
||||
_currPointIndex++;
|
||||
if (_currPointIndex == (int)_pathPoints->size() - 1)
|
||||
stepsCtr = 0;
|
||||
newX = pathPoint(_currPointIndex).x;
|
||||
newY = pathPoint(_currPointIndex).y;
|
||||
} else {
|
||||
_stepError += stepsCtr;
|
||||
if (pt1.x >= pt2.x)
|
||||
newX = pt2.x + (deltaX * _stepError) / deltaY;
|
||||
else
|
||||
newX = pt2.x - (deltaX * _stepError) / deltaY;
|
||||
if (pt1.y >= pt2.y)
|
||||
newY += stepsCtr;
|
||||
else
|
||||
newY -= stepsCtr;
|
||||
stepsCtr = 0;
|
||||
}
|
||||
}
|
||||
firstTime = false;
|
||||
}
|
||||
|
||||
if (_yMoveTotalSteps != 0) {
|
||||
_x = newX;
|
||||
_y = newY;
|
||||
_yMoveTotalSteps -= _ySteps;
|
||||
if (_yMoveTotalSteps <= 0) {
|
||||
_isBraking = true;
|
||||
_yMoveTotalSteps = 0;
|
||||
}
|
||||
} else {
|
||||
int distance = calcDistance(_destX, _destY, _x, _y);
|
||||
_x = newX;
|
||||
_y = newY;
|
||||
if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
|
||||
_exitDirection = 0;
|
||||
_inMainArea = true;
|
||||
} else if (_inMainArea) {
|
||||
_destX = pathPoint(_pathPoints->size() - 1).x;
|
||||
_destY = pathPoint(_pathPoints->size() - 1).y;
|
||||
_inMainArea = false;
|
||||
if (_x <= 20)
|
||||
_exitDirection = 1;
|
||||
else if (_x >= 620)
|
||||
_exitDirection = 3;
|
||||
else if (_y <= 20)
|
||||
_exitDirection = 2;
|
||||
else if (_y >= 460)
|
||||
_exitDirection = 4;
|
||||
if (_exitDirection != 0 && _isBraking) {
|
||||
_isBraking = false;
|
||||
_steps = 11;
|
||||
}
|
||||
}
|
||||
if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
|
||||
(_exitDirection == 0 && _lastDistance + 20 < distance))
|
||||
_isBraking = true;
|
||||
if (distance < _lastDistance)
|
||||
_lastDistance = distance;
|
||||
if (_currPointIndex == (int)_pathPoints->size() - 1) {
|
||||
_isBraking = true;
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AsCommonCar::suMoveToPrevPoint() {
|
||||
int16 newX = _x, newY = _y;
|
||||
|
||||
if (_currPointIndex == 0 && _stepError == 0) {
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isBraking) {
|
||||
if (_steps <= 0) {
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
return;
|
||||
} else
|
||||
_steps--;
|
||||
} else if (_steps < 11)
|
||||
_steps++;
|
||||
|
||||
bool firstTime = true;
|
||||
_ySteps = _steps;
|
||||
int stepsCtr = _steps;
|
||||
|
||||
while (stepsCtr > 0) {
|
||||
if (_stepError == 0)
|
||||
_currPointIndex--;
|
||||
NPoint pt1;
|
||||
NPoint pt2 = pathPoint(_currPointIndex);
|
||||
if (_currPointIndex + 1 >= (int)_pathPoints->size())
|
||||
pt1 = pathPoint(0);
|
||||
else
|
||||
pt1 = pathPoint(_currPointIndex + 1);
|
||||
int16 deltaX = ABS(pt1.x - pt2.x);
|
||||
int16 deltaY = ABS(pt1.y - pt2.y);
|
||||
if (deltaX >= deltaY) {
|
||||
_newMoveDirection = 4;
|
||||
if (pt1.x < pt2.x)
|
||||
_newMoveDirection = 2;
|
||||
if (_stepError == 0)
|
||||
_stepError = deltaX;
|
||||
if (stepsCtr > _stepError) {
|
||||
stepsCtr -= _stepError;
|
||||
_stepError = 0;
|
||||
if (_currPointIndex == 0)
|
||||
stepsCtr = 0;
|
||||
newX = pathPoint(_currPointIndex).x;
|
||||
newY = pathPoint(_currPointIndex).y;
|
||||
} else {
|
||||
_stepError -= stepsCtr;
|
||||
if (pt1.x >= pt2.x)
|
||||
newX -= stepsCtr;
|
||||
else
|
||||
newX += stepsCtr;
|
||||
if (pt1.y >= pt2.y)
|
||||
newY = pt2.y + (deltaY * _stepError) / deltaX;
|
||||
else
|
||||
newY = pt2.y - (deltaY * _stepError) / deltaX;
|
||||
stepsCtr = 0;
|
||||
}
|
||||
} else {
|
||||
_newMoveDirection = 1;
|
||||
if (pt1.y < pt2.y)
|
||||
_newMoveDirection = 3;
|
||||
if (firstTime) {
|
||||
if (pt1.y >= pt2.y) {
|
||||
stepsCtr -= 4;
|
||||
if (stepsCtr < 0)
|
||||
stepsCtr = 0;
|
||||
} else {
|
||||
stepsCtr += 7;
|
||||
}
|
||||
_ySteps = stepsCtr;
|
||||
}
|
||||
if (_stepError == 0)
|
||||
_stepError = deltaY;
|
||||
if (stepsCtr > _stepError) {
|
||||
stepsCtr -= _stepError;
|
||||
_stepError = 0;
|
||||
if (_currPointIndex == 0)
|
||||
stepsCtr = 0;
|
||||
newX = pathPoint(_currPointIndex).x;
|
||||
newY = pathPoint(_currPointIndex).y;
|
||||
} else {
|
||||
_stepError -= stepsCtr;
|
||||
if (pt1.x >= pt2.x)
|
||||
newX = pt2.x + (deltaX * _stepError) / deltaY;
|
||||
else
|
||||
newX = pt2.x - (deltaX * _stepError) / deltaY;
|
||||
if (pt1.y >= pt2.y)
|
||||
newY -= stepsCtr;
|
||||
else
|
||||
newY += stepsCtr;
|
||||
stepsCtr = 0;
|
||||
}
|
||||
}
|
||||
firstTime = false;
|
||||
}
|
||||
|
||||
if (_yMoveTotalSteps != 0) {
|
||||
_x = newX;
|
||||
_y = newY;
|
||||
_yMoveTotalSteps -= _ySteps;
|
||||
if (_yMoveTotalSteps <= 0) {
|
||||
_isBraking = true;
|
||||
_yMoveTotalSteps = 0;
|
||||
}
|
||||
} else {
|
||||
int distance = calcDistance(_destX, _destY, _x, _y);
|
||||
_x = newX;
|
||||
_y = newY;
|
||||
if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
|
||||
_exitDirection = 0;
|
||||
_inMainArea = true;
|
||||
} else if (_inMainArea) {
|
||||
_destX = pathPoint(0).x;
|
||||
_destY = pathPoint(0).y;
|
||||
_inMainArea = false;
|
||||
if (_x <= 20)
|
||||
_exitDirection = 1;
|
||||
else if (_x >= 620)
|
||||
_exitDirection = 3;
|
||||
else if (_y <= 20)
|
||||
_exitDirection = 2;
|
||||
else if (_y >= 460)
|
||||
_exitDirection = 4;
|
||||
if (_exitDirection != 0 && _isBraking) {
|
||||
_isBraking = false;
|
||||
_steps = 11;
|
||||
}
|
||||
}
|
||||
if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
|
||||
(_exitDirection == 0 && _lastDistance + 20 < distance))
|
||||
_isBraking = true;
|
||||
if (distance < _lastDistance)
|
||||
_lastDistance = distance;
|
||||
if (_currPointIndex == 0 && _stepError == 0) {
|
||||
_isBraking = true;
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AsCommonCar::updateSound() {
|
||||
int maxSoundCounter = 0;
|
||||
_soundCounter++;
|
||||
if (_steps != 0 && !_isIdle) {
|
||||
if (_currMoveDirection == 1)
|
||||
maxSoundCounter = 18 - _steps;
|
||||
else if (_currMoveDirection == 3) {
|
||||
maxSoundCounter = 5 - _steps;
|
||||
if (maxSoundCounter < 1)
|
||||
maxSoundCounter = 1;
|
||||
} else
|
||||
maxSoundCounter = 14 - _steps;
|
||||
} else
|
||||
maxSoundCounter = 21;
|
||||
if (_soundCounter >= maxSoundCounter) {
|
||||
sendMessage(_parentScene, 0x200D, 0);
|
||||
_soundCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
AsCommonIdleCarLower::AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y)
|
||||
: AnimatedSprite(vm, 0x1209E09F, 1100, x, y) {
|
||||
|
||||
setDoDeltaX(1);
|
||||
startAnimation(0x1209E09F, 1, -1);
|
||||
_newStickFrameIndex = 1;
|
||||
}
|
||||
|
||||
AsCommonIdleCarFull::AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y)
|
||||
: AnimatedSprite(vm, 0x1209E09F, 100, x, y) {
|
||||
|
||||
setDoDeltaX(1);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
|
||||
AsCommonCarConnector::AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar)
|
||||
: AnimatedSprite(vm, 1100), _asCar(asCar) {
|
||||
|
||||
createSurface1(0x60281C10, 150);
|
||||
startAnimation(0x60281C10, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
SetUpdateHandler(&AsCommonCarConnector::update);
|
||||
}
|
||||
|
||||
void AsCommonCarConnector::update() {
|
||||
_x = _asCar->getX();
|
||||
_y = _asCar->getY();
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
void Tracks::findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
|
||||
DataResource &dataResource) {
|
||||
const uint trackCount = size();
|
||||
minMatchTrackIndex = -1;
|
||||
minMatchDistance = 640;
|
||||
for (uint trackIndex = 0; trackIndex < trackCount; trackIndex++) {
|
||||
NPointArray *pointList = dataResource.getPointArray((*this)[trackIndex]->trackPointsName);
|
||||
for (uint pointIndex = 0; pointIndex < pointList->size(); pointIndex++) {
|
||||
NPoint testPt = (*pointList)[pointIndex];
|
||||
int distance = calcDistance(testPt.x, testPt.y, pt.x, pt.y);
|
||||
if (distance < minMatchDistance) {
|
||||
minMatchTrackIndex = trackIndex;
|
||||
minMatchDistance = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KmScene1608::KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case 0x2032:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAboutAfter);
|
||||
else if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stWonderAboutHalf);
|
||||
else if (param.asInteger() == 4)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else if (param.asInteger() == 3)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x482D:
|
||||
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2032, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2032, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
125
engines/neverhood/modules/module1600_sprites.h
Normal file
125
engines/neverhood/modules/module1600_sprites.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1600_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1600_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class AsCommonCar : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
~AsCommonCar() override;
|
||||
void setPathPoints(NPointArray *pathPoints);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
NPointArray *_pathPoints;
|
||||
int _newMoveDirection;
|
||||
int _currMoveDirection;
|
||||
int _exitDirection;
|
||||
int _currPointIndex;
|
||||
bool _hasAgainDestPoint;
|
||||
NPoint _againDestPoint;
|
||||
bool _hasAgainDestPointIndex;
|
||||
int _againDestPointIndex;
|
||||
bool _inMainArea;
|
||||
bool _isBraking;
|
||||
bool _isBusy;
|
||||
bool _isIdle;
|
||||
bool _isMoving;
|
||||
bool _rectFlag;
|
||||
int _idleCounter;
|
||||
int _idleCounterMax;
|
||||
int _steps;
|
||||
int _stepError;
|
||||
int _lastDistance;
|
||||
int _yMoveTotalSteps;
|
||||
int _ySteps;
|
||||
int _newDeltaXType;
|
||||
int _soundCounter;
|
||||
int _turnMoveStatus;
|
||||
int16 _destX, _destY;
|
||||
NPoint pathPoint(uint index) { return (*_pathPoints)[index]; }
|
||||
void update();
|
||||
void upIdle();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmLeaveCar(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stCarAtHome();
|
||||
void updateTurnMovement();
|
||||
void updateMovement();
|
||||
void stEnterCar();
|
||||
void stLeaveCar();
|
||||
void stLeanForwardIdle();
|
||||
void evIdleDone();
|
||||
void stIdleBlink();
|
||||
void stUpdateMoveDirection();
|
||||
void stTurnCar();
|
||||
void moveToNextPoint();
|
||||
void stBrakeMoveToNextPoint();
|
||||
void stTurnCarMoveToNextPoint();
|
||||
void moveToPrevPoint();
|
||||
void stBrakeMoveToPrevPoint();
|
||||
void stTurnCarMoveToPrevPoint();
|
||||
void evTurnCarDone();
|
||||
void suMoveToNextPoint();
|
||||
void suMoveToPrevPoint();
|
||||
void updateSound();
|
||||
};
|
||||
|
||||
class AsCommonIdleCarLower : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y);
|
||||
};
|
||||
|
||||
class AsCommonIdleCarFull : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y);
|
||||
};
|
||||
|
||||
class AsCommonCarConnector : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar);
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
void update();
|
||||
};
|
||||
|
||||
class Tracks : public Common::Array<TrackInfo*> {
|
||||
public:
|
||||
void findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
|
||||
DataResource &dataResource);
|
||||
};
|
||||
|
||||
class KmScene1608 : public Klaymen {
|
||||
public:
|
||||
KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1600_SPRITES_H */
|
||||
242
engines/neverhood/modules/module1700.cpp
Normal file
242
engines/neverhood/modules/module1700.cpp
Normal file
@@ -0,0 +1,242 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/gamemodule.h"
|
||||
#include "neverhood/modules/module1700.h"
|
||||
#include "neverhood/modules/module1700_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule1700SoundList[] = {
|
||||
0xB288D450,
|
||||
0x90804450,
|
||||
0x99801500,
|
||||
0xB288D455,
|
||||
0x93825040,
|
||||
0
|
||||
};
|
||||
|
||||
Module1700::Module1700(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
_vm->_soundMan->addMusic(0x04212331, 0x31114225);
|
||||
_vm->_soundMan->addSoundList(0x04212331, kModule1700SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule1700SoundList, true, 50, 600, 5, 150);
|
||||
_vm->_soundMan->playTwoSounds(0x04212331, 0x41861371, 0x43A2507F, 0);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 0)
|
||||
createScene(0, -1);
|
||||
else if (which == 1)
|
||||
createScene(4, 1);
|
||||
else
|
||||
createScene(4, 3);
|
||||
|
||||
}
|
||||
|
||||
Module1700::~Module1700() {
|
||||
_vm->_soundMan->deleteGroup(0x04212331);
|
||||
}
|
||||
|
||||
void Module1700::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1700::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_vm->_soundMan->setSoundListParams(kModule1700SoundList, false, 0, 0, 0, 0);
|
||||
createSmackerScene(0x3028A005, true, true, false);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
createNavigationScene(0x004AE8B8, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
createNavigationScene(0x004AE8E8, which);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
_vm->_soundMan->setSoundListParams(kModule1700SoundList, false, 0, 0, 0, 0);
|
||||
createSmackerScene(0x01190041, true, true, false);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_vm->_soundMan->setSoundListParams(kModule1700SoundList, false, 0, 0, 0, 0);
|
||||
_vm->_soundMan->startMusic(0x31114225, 0, 2);
|
||||
_childObject = new Scene1705(_vm, this, which);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1700::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1700::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->_soundMan->setSoundListParams(kModule1700SoundList, true, 0, 0, 0, 0);
|
||||
createScene(1, 0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 0)
|
||||
createScene(2, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(1, 1);
|
||||
break;
|
||||
case 2:
|
||||
if (_moduleResult == 0)
|
||||
createScene(3, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(1, 1);
|
||||
else if (_moduleResult == 2) {
|
||||
if (!isSoundPlaying(0)) {
|
||||
setSoundVolume(0, 60);
|
||||
playSound(0, 0x58B45E58);
|
||||
}
|
||||
createScene(2, 2);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
createScene(4, 0);
|
||||
break;
|
||||
case 4:
|
||||
leaveModule(1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const uint32 kScene1705FileHashes[] = {
|
||||
0x910EA801, 0x920EA801, 0x940EA801,
|
||||
0x980EA801, 0x800EA801, 0xB00EA801,
|
||||
0xD00EA801, 0x100EA801, 0x900EA800,
|
||||
0xD10EA801, 0x110EA801, 0x910EA800
|
||||
};
|
||||
|
||||
Scene1705::Scene1705(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _paletteArea(1) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
setGlobalVar(V_FELL_DOWN_HOLE, 1);
|
||||
_vm->gameModule()->initCannonSymbolsPuzzle();
|
||||
|
||||
SetMessageHandler(&Scene1705::handleMessage);
|
||||
SetUpdateHandler(&Scene1705::update);
|
||||
|
||||
setHitRects(0x004B69D8);
|
||||
setBackground(0x03118226);
|
||||
setPalette(0x03118226);
|
||||
_palette->addBasePalette(0x91D3A391, 0, 64, 0);
|
||||
_palette->copyBasePalette(0, 256, 0);
|
||||
addEntity(_palette);
|
||||
insertScreenMouse(0x18222039);
|
||||
|
||||
insertSprite<SsScene1705WallSymbol>(kScene1705FileHashes[getSubVar(VA_GOOD_CANNON_SYMBOLS_2, 0)], 0);
|
||||
insertSprite<SsScene1705WallSymbol>(kScene1705FileHashes[getSubVar(VA_GOOD_CANNON_SYMBOLS_2, 1)], 1);
|
||||
insertSprite<SsScene1705WallSymbol>(kScene1705FileHashes[getSubVar(VA_GOOD_CANNON_SYMBOLS_2, 2)], 2);
|
||||
_sprite = insertStaticSprite(0x31313A22, 1100);
|
||||
_ssTape = insertSprite<SsScene1705Tape>(this, 15, 1100, 238, 439, 0x02363852);
|
||||
addCollisionSprite(_ssTape);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1705>(231, 434);
|
||||
setMessageList(0x004B69E8);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
_klaymen->setClipRect(0, 0, _sprite->getDrawRect().x2(), 480);
|
||||
} else if (which == 1) {
|
||||
// Klaymen teleporting in
|
||||
insertKlaymen<KmScene1705>(431, 434);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B6A08, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
_klaymen->setClipRect(0, 0, _sprite->getDrawRect().x2(), 480);
|
||||
} else if (which == 2) {
|
||||
// Klaymen teleporting out
|
||||
insertKlaymen<KmScene1705>(431, 434);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B6AA0, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
_klaymen->setClipRect(0, 0, _sprite->getDrawRect().x2(), 480);
|
||||
} else if (which == 3) {
|
||||
// Klaymen returning from teleporter console
|
||||
insertKlaymen<KmScene1705>(431, 434);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B6A18, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
_klaymen->setClipRect(0, 0, _sprite->getDrawRect().x2(), 480);
|
||||
} else {
|
||||
// Klaymen falling through the hole
|
||||
insertKlaymen<KmScene1705>(231, 74);
|
||||
sendMessage(_klaymen, 0x2000, 0);
|
||||
setMessageList(0x004B69F0);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
tempSprite = insertStaticSprite(0x30303822, 1100);
|
||||
_klaymen->setClipRect(0, tempSprite->getDrawRect().y, _sprite->getDrawRect().x2(), 480);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Scene1705::update() {
|
||||
Scene::update();
|
||||
if (_klaymen->getX() < 224 && _paletteArea != 0) {
|
||||
_palette->addBasePalette(0xF2210C15, 0, 64, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
_paletteArea = 0;
|
||||
} else if (_klaymen->getX() >= 224 && _paletteArea == 0) {
|
||||
_palette->addBasePalette(0x91D3A391, 0, 64, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
_paletteArea = 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene1705::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (param.asInteger()) {
|
||||
setRectList(0x004B6B40);
|
||||
_klaymen->setKlaymenIdleTable3();
|
||||
} else {
|
||||
setRectList(0x004B6B30);
|
||||
_klaymen->setKlaymenIdleTable1();
|
||||
}
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _ssTape && _klaymen->getX() <= 318) {
|
||||
sendEntityMessage(_klaymen, 0x1014, sender);
|
||||
setMessageList(0x004B6AC0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
54
engines/neverhood/modules/module1700.h
Normal file
54
engines/neverhood/modules/module1700.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1700_H
|
||||
#define NEVERHOOD_MODULES_MODULE1700_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1700 : public Module {
|
||||
public:
|
||||
Module1700(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1700() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene1705 : public Scene {
|
||||
public:
|
||||
Scene1705(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_sprite;
|
||||
Sprite *_ssTape;
|
||||
int _paletteArea;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1700_H */
|
||||
159
engines/neverhood/modules/module1700_sprites.cpp
Normal file
159
engines/neverhood/modules/module1700_sprites.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1700_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
SsScene1705WallSymbol::SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex)
|
||||
: StaticSprite(vm, fileHash, 100) {
|
||||
|
||||
_x = _spriteResource.getPosition().x + symbolIndex * 30;
|
||||
_y = _spriteResource.getPosition().y + 160;
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
SsScene1705Tape::SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash)
|
||||
: StaticSprite(vm, fileHash, surfacePriority, x - 24, y - 4), _parentScene(parentScene), _tapeIndex(tapeIndex) {
|
||||
|
||||
if (!getSubVar(VA_HAS_TAPE, _tapeIndex) && !getSubVar(VA_IS_TAPE_INSERTED, _tapeIndex)) {
|
||||
SetMessageHandler(&SsScene1705Tape::handleMessage);
|
||||
} else {
|
||||
setVisible(false);
|
||||
SetMessageHandler(nullptr);
|
||||
}
|
||||
_collisionBoundsOffset = _drawOffset;
|
||||
_collisionBoundsOffset.x -= 4;
|
||||
_collisionBoundsOffset.y -= 8;
|
||||
_collisionBoundsOffset.width += 8;
|
||||
_collisionBoundsOffset.height += 16;
|
||||
Sprite::updateBounds();
|
||||
}
|
||||
|
||||
uint32 SsScene1705Tape::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, 0x4826, 0);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case NM_KLAYMEN_USE_OBJECT:
|
||||
setSubVar(VA_HAS_TAPE, _tapeIndex, 1);
|
||||
setVisible(false);
|
||||
SetMessageHandler(nullptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene1705::KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4803:
|
||||
GotoState(&Klaymen::stFallSkipJump);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter) {
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
}
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAboutAfter);
|
||||
else if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stWonderAboutHalf);
|
||||
else if (param.asInteger() == 4)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else if (param.asInteger() == 3)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2000, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
case 0x483D:
|
||||
teleporterAppear(0x5E0A4905);
|
||||
break;
|
||||
case 0x483E:
|
||||
teleporterDisappear(0xD86E4477);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
54
engines/neverhood/modules/module1700_sprites.h
Normal file
54
engines/neverhood/modules/module1700_sprites.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1700_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1700_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class SsScene1705WallSymbol : public StaticSprite {
|
||||
public:
|
||||
SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex);
|
||||
};
|
||||
|
||||
class SsScene1705Tape : public StaticSprite {
|
||||
public:
|
||||
SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 _tapeIndex;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene1705 : public Klaymen {
|
||||
public:
|
||||
KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1700_SPRITES_H */
|
||||
187
engines/neverhood/modules/module1800.cpp
Normal file
187
engines/neverhood/modules/module1800.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/diskplayerscene.h"
|
||||
#include "neverhood/menumodule.h"
|
||||
#include "neverhood/navigationscene.h"
|
||||
#include "neverhood/modules/module1800.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule1800SoundList[] = {
|
||||
0x16805548,
|
||||
0x16805048,
|
||||
0xD0E14441,
|
||||
0x90E090C2,
|
||||
0x90E1D0C2,
|
||||
0x90E2D0C2,
|
||||
0
|
||||
};
|
||||
|
||||
Module1800::Module1800(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
_vm->_soundMan->addSoundList(0x04A14718, kModule1800SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule1800SoundList, true, 50, 600, 10, 150);
|
||||
_vm->_soundMan->playTwoSounds(0x04A14718, 0x8A382B55, 0x0C242F1D, 0);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 2)
|
||||
createScene(5, 0);
|
||||
else if (which == 3)
|
||||
createScene(0, 0);
|
||||
else
|
||||
createScene(3, 1);
|
||||
|
||||
}
|
||||
|
||||
Module1800::~Module1800() {
|
||||
_vm->_soundMan->deleteGroup(0x04A14718);
|
||||
}
|
||||
|
||||
void Module1800::createScene(int sceneNum, int which) {
|
||||
static const byte kNavigationTypes00[] = {1, 0, 2, 0};
|
||||
static const byte kNavigationTypes01[] = {5};
|
||||
debug(1, "Module1800::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
createNavigationScene(0x004AFD38, which, kNavigationTypes00);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
createNavigationScene(0x004AFD98, which, kNavigationTypes01);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
createSmackerScene(0x006C0085, true, true, false);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
createNavigationScene(0x004AFDB0, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
createNavigationScene(0x004AFDE0, which);
|
||||
break;
|
||||
case 5:
|
||||
_vm->gameState().sceneNum = 5;
|
||||
createNavigationScene(0x004AFE40, which);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
_vm->_soundMan->deleteGroup(0x04A14718);
|
||||
createSmackerScene(0x08D84010, true, true, false);
|
||||
break;
|
||||
case 7:
|
||||
_vm->gameState().sceneNum = 7;
|
||||
_vm->_soundMan->setSoundListParams(kModule1800SoundList, false, 0, 0, 0, 0);
|
||||
createSmackerScene(0x0168B121, true, true, false);
|
||||
break;
|
||||
case 8:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
_childObject = new CreditsScene(_vm, this, false);
|
||||
break;
|
||||
case 1009:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
// NOTE: Newly introduced sceneNum 1009 (was duplicate 3 with own update handler)
|
||||
createSmackerScene(0x0A840C01, true, true, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1800::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1800::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(4, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(1, -1);
|
||||
else if (_moduleResult == 3)
|
||||
createScene(3, 0);
|
||||
break;
|
||||
case 1:
|
||||
if (_navigationAreaType == 3)
|
||||
createScene(7, -1);
|
||||
else
|
||||
createScene(2, -1);
|
||||
break;
|
||||
case 2:
|
||||
createScene(0, 2);
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 0)
|
||||
createScene(1009, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(0, 1);
|
||||
break;
|
||||
case 4:
|
||||
if (_moduleResult == 0)
|
||||
createScene(6, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(5, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(0, 3);
|
||||
else if (_moduleResult == 3)
|
||||
createScene(4, 3);
|
||||
break;
|
||||
case 5:
|
||||
if (_moduleResult == 0)
|
||||
leaveModule(2);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(4, 3);
|
||||
break;
|
||||
case 6:
|
||||
createScene(8, -1);
|
||||
break;
|
||||
case 7:
|
||||
leaveModule(3);
|
||||
break;
|
||||
case 8:
|
||||
// NOTE: After Klaymen jumped into the hole and died...
|
||||
leaveModule(1);
|
||||
break;
|
||||
case 1009:
|
||||
leaveModule(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 2)
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
45
engines/neverhood/modules/module1800.h
Normal file
45
engines/neverhood/modules/module1800.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1800_H
|
||||
#define NEVERHOOD_MODULES_MODULE1800_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module1800
|
||||
|
||||
class Module1800 : public Module {
|
||||
public:
|
||||
Module1800(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1800() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1800_H */
|
||||
264
engines/neverhood/modules/module1900.cpp
Normal file
264
engines/neverhood/modules/module1900.cpp
Normal file
@@ -0,0 +1,264 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1900.h"
|
||||
#include "neverhood/modules/module1900_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule1900SoundList[] = {
|
||||
0xB4005E60,
|
||||
0x91835066,
|
||||
0x90E14440,
|
||||
0
|
||||
};
|
||||
|
||||
Module1900::Module1900(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
// NOTE: The original has a Scene1908 here as well but it's not used here but in another module...
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else
|
||||
createScene(0, 0);
|
||||
|
||||
_vm->_soundMan->addSoundList(0x04E1C09C, kModule1900SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule1900SoundList, true, 50, 600, 5, 150);
|
||||
|
||||
}
|
||||
|
||||
Module1900::~Module1900() {
|
||||
_vm->_soundMan->deleteGroup(0x04E1C09C);
|
||||
}
|
||||
|
||||
void Module1900::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1900::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene1901(_vm, this, which);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
_childObject = new Scene1907(_vm, this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1900::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1900::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(6, 0);
|
||||
else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 6:
|
||||
createScene(0, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene1901::Scene1901(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
setRectList(0x004B34C8);
|
||||
|
||||
setBackground(0x01303227);
|
||||
setPalette(0x01303227);
|
||||
insertScreenMouse(0x0322301B);
|
||||
|
||||
insertStaticSprite(0x42213133, 1100);
|
||||
|
||||
if (!getGlobalVar(V_STAIRS_PUZZLE_SOLVED))
|
||||
insertStaticSprite(0x40A40168, 100);
|
||||
else if (getGlobalVar(V_STAIRS_DOWN)) {
|
||||
insertStaticSprite(0x124404C4, 100);
|
||||
setGlobalVar(V_STAIRS_DOWN_ONCE, 1);
|
||||
} else
|
||||
insertStaticSprite(0x02840064, 100);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1901>(120, 380);
|
||||
setMessageList(0x004B3408);
|
||||
} else if (which == 1) {
|
||||
// Klaymen returning from the puzzle
|
||||
insertKlaymen<KmScene1901>(372, 380);
|
||||
setMessageList(0x004B3410);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene1901>(0, 380);
|
||||
setMessageList(0x004B3400);
|
||||
}
|
||||
|
||||
tempSprite = insertStaticSprite(0x4830A402, 1100);
|
||||
_klaymen->setClipRect(tempSprite->getDrawRect().x, 0, 640, 480);
|
||||
|
||||
}
|
||||
|
||||
Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule)
|
||||
: Scene(vm, parentModule), _currMovingSymbolIndex(0), _pluggedInCount(0),
|
||||
_moveDownCountdown(0), _moveUpCountdown(0), _countdown3(0), _hasPlugInFailed(false) {
|
||||
|
||||
setBackground(0x20628E05);
|
||||
setPalette(0x20628E05);
|
||||
|
||||
for (int i = 0; i < 9; i++)
|
||||
_positionFree[i] = true;
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
_asSymbols[i] = insertSprite<AsScene1907Symbol>(this, i, getRandomPositionIndex());
|
||||
addCollisionSprite(_asSymbols[i]);
|
||||
}
|
||||
|
||||
_ssUpDownButton = insertSprite<SsScene1907UpDownButton>(this, _asSymbols[8]);
|
||||
addCollisionSprite(_ssUpDownButton);
|
||||
|
||||
_asWaterHint = insertSprite<AsScene1907WaterHint>();
|
||||
|
||||
insertPuzzleMouse(0x28E0120E, 20, 620);
|
||||
|
||||
SetMessageHandler(&Scene1907::handleMessage);
|
||||
SetUpdateHandler(&Scene1907::update);
|
||||
|
||||
if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED))
|
||||
_pluggedInCount = 9;
|
||||
|
||||
loadSound(0, 0x72004A10);
|
||||
loadSound(1, 0x22082A12);
|
||||
loadSound(2, 0x21100A10);
|
||||
loadSound(3, 0x68E25540);
|
||||
|
||||
}
|
||||
|
||||
void Scene1907::update() {
|
||||
Scene::update();
|
||||
|
||||
if (_hasPlugInFailed) {
|
||||
int fallOffDelay = 0;
|
||||
_hasPlugInFailed = false;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
AsScene1907Symbol *asSymbol = _asSymbols[8 - i];
|
||||
if (asSymbol->isPluggedIn()) {
|
||||
asSymbol->fallOff(getRandomPositionIndex(), fallOffDelay);
|
||||
fallOffDelay += _vm->_rnd->getRandomNumber(10 - 1) + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_moveDownCountdown != 0 && (--_moveDownCountdown == 0)) {
|
||||
_asSymbols[_currMovingSymbolIndex]->moveDown();
|
||||
if (_currMovingSymbolIndex > 0) {
|
||||
_moveDownCountdown = 2;
|
||||
_currMovingSymbolIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
if (_moveUpCountdown != 0 && (--_moveUpCountdown == 0)) {
|
||||
_moveDownCountdown = 0;
|
||||
for (int i = 0; i < 9; i++)
|
||||
_asSymbols[i]->moveUp();
|
||||
}
|
||||
|
||||
if (_countdown3 != 0 && (--_countdown3 == 0)) {
|
||||
_asWaterHint->show();
|
||||
_moveUpCountdown = 4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene1907::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) &&
|
||||
!_hasPlugInFailed && _moveDownCountdown == 0 && _moveUpCountdown == 0 && _countdown3 == 0) {
|
||||
leaveScene(0);
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (getGlobalVar(V_STAIRS_DOWN)) {
|
||||
playSound(0);
|
||||
for (int i = 0; i < 9; i++)
|
||||
_asSymbols[i]->moveUp();
|
||||
_ssUpDownButton->setToUpPosition();
|
||||
setGlobalVar(V_STAIRS_DOWN, 0);
|
||||
} else {
|
||||
if (!getGlobalVar(V_WALL_BROKEN)) {
|
||||
playSound(2);
|
||||
_countdown3 = 5;
|
||||
} else {
|
||||
playSound(1);
|
||||
_ssUpDownButton->setToDownPosition();
|
||||
setGlobalVar(V_STAIRS_DOWN, 1);
|
||||
}
|
||||
_moveDownCountdown = 1;
|
||||
_currMovingSymbolIndex = 8;
|
||||
}
|
||||
break;
|
||||
case 0x2001:
|
||||
playSound(3);
|
||||
setGlobalVar(V_STAIRS_PUZZLE_SOLVED, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Scene1907::plugInFailed() {
|
||||
_pluggedInCount = 0;
|
||||
_hasPlugInFailed = true;
|
||||
}
|
||||
|
||||
int Scene1907::getRandomPositionIndex() {
|
||||
bool found = false;
|
||||
int index = 0;
|
||||
// Check if any position is free
|
||||
for (int i = 0; i < 9; i++)
|
||||
if (_positionFree[i])
|
||||
found = true;
|
||||
if (found) {
|
||||
// Get a random free position
|
||||
found = false;
|
||||
while (!found) {
|
||||
index = _vm->_rnd->getRandomNumber(9 - 1);
|
||||
if (_positionFree[index])
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
75
engines/neverhood/modules/module1900.h
Normal file
75
engines/neverhood/modules/module1900.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1900_H
|
||||
#define NEVERHOOD_MODULES_MODULE1900_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1900 : public Module {
|
||||
public:
|
||||
Module1900(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1900() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene1901 : public Scene {
|
||||
public:
|
||||
Scene1901(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
};
|
||||
|
||||
class AsScene1907Symbol;
|
||||
class SsScene1907UpDownButton;
|
||||
class AsScene1907WaterHint;
|
||||
|
||||
class Scene1907 : public Scene {
|
||||
public:
|
||||
Scene1907(NeverhoodEngine *vm, Module *parentModule);
|
||||
void plugInFailed();
|
||||
void setPositionFree(int index, bool value) { _positionFree[index] = value; }
|
||||
int getNextPosition() { return _pluggedInCount++; }
|
||||
protected:
|
||||
AsScene1907Symbol *_asSymbols[9];
|
||||
SsScene1907UpDownButton *_ssUpDownButton;
|
||||
AsScene1907WaterHint *_asWaterHint;
|
||||
int _currMovingSymbolIndex;
|
||||
int _pluggedInCount;
|
||||
int _moveDownCountdown;
|
||||
int _moveUpCountdown;
|
||||
int _countdown3;
|
||||
bool _hasPlugInFailed;
|
||||
bool _positionFree[9];
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
int getRandomPositionIndex();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1900_H */
|
||||
466
engines/neverhood/modules/module1900_sprites.cpp
Normal file
466
engines/neverhood/modules/module1900_sprites.cpp
Normal file
@@ -0,0 +1,466 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1900.h"
|
||||
#include "neverhood/modules/module1900_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const NPoint kAsScene1907SymbolGroundPositions[] = {
|
||||
{160, 310}, { 90, 340}, {210, 335},
|
||||
{210, 380}, {310, 340}, {290, 400},
|
||||
{400, 375}, {370, 435}, {475, 415}
|
||||
};
|
||||
|
||||
static const NPoint kAsScene1907SymbolPluggedInPositions[] = {
|
||||
{275, 125}, {244, 125}, {238, 131},
|
||||
{221, 135}, {199, 136}, {168, 149},
|
||||
{145, 152}, {123, 154}, {103, 157}
|
||||
};
|
||||
|
||||
static const NPoint kAsScene1907SymbolGroundHitPositions[] = {
|
||||
{275, 299}, {244, 299}, {238, 305},
|
||||
{221, 309}, {199, 310}, {168, 323},
|
||||
{145, 326}, {123, 328}, {103, 331}
|
||||
};
|
||||
|
||||
static const NPoint kAsScene1907SymbolPluggedInDownPositions[] = {
|
||||
{275, 136}, {244, 156}, {238, 183},
|
||||
{221, 207}, {199, 228}, {168, 262},
|
||||
{145, 285}, {123, 307}, {103, 331}
|
||||
};
|
||||
|
||||
static const uint32 kAsScene1907SymbolFileHashes[] = {
|
||||
0x006A1034, 0x006A1010, 0x006A1814,
|
||||
0x006A1016, 0x006A0014, 0x002A1014,
|
||||
0x00EA1014, 0x206A1014, 0x046A1414
|
||||
};
|
||||
|
||||
bool AsScene1907Symbol::_plugInFailed = false;
|
||||
int AsScene1907Symbol::_plugInTryCount = 0;
|
||||
|
||||
AsScene1907Symbol::AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex)
|
||||
: AnimatedSprite(vm, 1000 - positionIndex), _parentScene(parentScene), _elementIndex(elementIndex), _isMoving(false) {
|
||||
|
||||
_plugInFailed = false;
|
||||
_plugInTryCount = 0;
|
||||
|
||||
if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
|
||||
_isPluggedIn = true;
|
||||
_currPositionIndex = elementIndex;
|
||||
if (!getGlobalVar(V_STAIRS_DOWN)) {
|
||||
_x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
|
||||
_y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
|
||||
} else {
|
||||
_x = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].x;
|
||||
_y = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].y;
|
||||
}
|
||||
createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
} else {
|
||||
_isPluggedIn = false;
|
||||
_currPositionIndex = positionIndex;
|
||||
loadSound(0, 0x74231924);
|
||||
loadSound(1, 0x36691914);
|
||||
loadSound(2, 0x5421D806);
|
||||
_parentScene->setPositionFree(_currPositionIndex, false);
|
||||
_x = kAsScene1907SymbolGroundPositions[_currPositionIndex].x;
|
||||
_y = kAsScene1907SymbolGroundPositions[_currPositionIndex].y;
|
||||
createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
_collisionBoundsOffset.set(0, 0, 80, 80);
|
||||
Sprite::updateBounds();
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1907Symbol::handleMessage);
|
||||
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::update() {
|
||||
updateAnim();
|
||||
handleSpriteUpdate();
|
||||
updatePosition();
|
||||
if (_plugInFailed && _plugInTryCount == 0)
|
||||
_plugInFailed = false;
|
||||
}
|
||||
|
||||
uint32 AsScene1907Symbol::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (!_isPluggedIn && !_plugInFailed) {
|
||||
tryToPlugIn();
|
||||
messageResult = 1;
|
||||
} else
|
||||
messageResult = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1907Symbol::hmTryToPlugIn(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::suTryToPlugIn() {
|
||||
_currStep++;
|
||||
_x -= _deltaX;
|
||||
_y -= _deltaY;
|
||||
if (_currStep == 16) {
|
||||
_x -= _smallDeltaX;
|
||||
_y -= _smallDeltaY;
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::suFallOff() {
|
||||
if (_fallOffDelay != 0) {
|
||||
_fallOffDelay--;
|
||||
} else {
|
||||
_y += _yAccel;
|
||||
_yAccel += 8;
|
||||
if (_y >= kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
|
||||
_y = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y;
|
||||
stFallOffHitGround();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::suFallOffHitGround() {
|
||||
|
||||
if (_x == _someX - _xBreak)
|
||||
_x -= _smallDeltaX;
|
||||
else
|
||||
_x -= _deltaX;
|
||||
|
||||
if (_y == kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
|
||||
_y -= _someY;
|
||||
}
|
||||
|
||||
if (_currStep < 8) {
|
||||
_y -= _yAccel;
|
||||
_yAccel -= 4;
|
||||
if (_yAccel < 0)
|
||||
_yAccel = 0;
|
||||
} else if (_currStep < 15) {
|
||||
_y += _yAccel;
|
||||
_yAccel += 4;
|
||||
} else {
|
||||
_y = kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
|
||||
cbFallOffHitGroundEvent();
|
||||
}
|
||||
|
||||
_currStep++;
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::suMoveDown() {
|
||||
_y += _yIncr;
|
||||
if (_yIncr < 11)
|
||||
_yIncr++;
|
||||
if (_y >= kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y) {
|
||||
_y = kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y;
|
||||
_isMoving = false;
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::suMoveUp() {
|
||||
_y -= _yIncr;
|
||||
if (getGlobalVar(V_WALL_BROKEN)) {
|
||||
if (_y - (9 + (_elementIndex > 5 ? 31 : 0)) < kAsScene1907SymbolPluggedInPositions[_elementIndex].y)
|
||||
_yIncr--;
|
||||
else
|
||||
_yIncr++;
|
||||
} else
|
||||
_yIncr = 2;
|
||||
if (_yIncr > 9)
|
||||
_yIncr = 9;
|
||||
else if (_yIncr < 1)
|
||||
_yIncr = 1;
|
||||
if (_y < kAsScene1907SymbolPluggedInPositions[_elementIndex].y) {
|
||||
_y = kAsScene1907SymbolPluggedInPositions[_elementIndex].y;
|
||||
_isMoving = false;
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::tryToPlugIn() {
|
||||
_isPluggedIn = true;
|
||||
_plugInTryCount++;
|
||||
_newPositionIndex = _parentScene->getNextPosition();
|
||||
_parentScene->setPositionFree(_currPositionIndex, true);
|
||||
sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1100 + _newPositionIndex);
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
|
||||
SetUpdateHandler(&AsScene1907Symbol::update);
|
||||
SetMessageHandler(&AsScene1907Symbol::hmTryToPlugIn);
|
||||
SetSpriteUpdate(&AsScene1907Symbol::suTryToPlugIn);
|
||||
_currStep = 0;
|
||||
_deltaX = (_x - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x) / 16;
|
||||
_smallDeltaX = _x - _deltaX * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x;
|
||||
_deltaY = (_y - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y) / 16;
|
||||
_smallDeltaY = _y - _deltaY * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y;
|
||||
if (_elementIndex == _newPositionIndex) {
|
||||
NextState(&AsScene1907Symbol::stPlugIn);
|
||||
} else {
|
||||
_plugInFailed = true;
|
||||
NextState(&AsScene1907Symbol::stPlugInFail);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::fallOff(int newPositionIndex, int fallOffDelay) {
|
||||
_isPluggedIn = false;
|
||||
_newPositionIndex = newPositionIndex;
|
||||
_fallOffDelay = fallOffDelay;
|
||||
_parentScene->setPositionFree(_newPositionIndex, false);
|
||||
_x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
|
||||
_y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
|
||||
_someX = _x;
|
||||
_someY = _y;
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, 0);
|
||||
_playBackwards = true;
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
_currStep = 0;
|
||||
_yAccel = 1;
|
||||
SetUpdateHandler(&AsScene1907Symbol::update);
|
||||
SetMessageHandler(&AsScene1907Symbol::handleMessage);
|
||||
SetSpriteUpdate(&AsScene1907Symbol::suFallOff);
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::stFallOffHitGround() {
|
||||
playSound(1);
|
||||
sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1000 + _newPositionIndex);
|
||||
Entity::_priority = 1000 - _newPositionIndex;
|
||||
_parentScene->removeCollisionSprite(this);
|
||||
_parentScene->addCollisionSprite(this);
|
||||
SetSpriteUpdate(&AsScene1907Symbol::suFallOffHitGround);
|
||||
NextState(&AsScene1907Symbol::cbFallOffHitGroundEvent);
|
||||
_newStickFrameIndex = 0;
|
||||
_currStep = 0;
|
||||
_yAccel = 30;
|
||||
_deltaX = (_x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x) / 15;
|
||||
_xBreak = _deltaX * 15;
|
||||
_smallDeltaX = _x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x - _xBreak;
|
||||
_someY = 0;
|
||||
if (kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y > kAsScene1907SymbolGroundPositions[_newPositionIndex].y)
|
||||
_someY = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y - kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::cbFallOffHitGroundEvent() {
|
||||
_currPositionIndex = _newPositionIndex;
|
||||
if (_plugInTryCount > 0)
|
||||
_plugInTryCount--;
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1907Symbol::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
updateBounds();
|
||||
playSound(2);
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::stPlugIn() {
|
||||
playSound(0);
|
||||
_currPositionIndex = _newPositionIndex;
|
||||
stopAnimation();
|
||||
SetMessageHandler(&AsScene1907Symbol::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
if (_elementIndex == 8)
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::stPlugInFail() {
|
||||
_currPositionIndex = _newPositionIndex;
|
||||
stopAnimation();
|
||||
_parentScene->plugInFailed();
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::moveUp() {
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
|
||||
stopAnimation();
|
||||
SetMessageHandler(&AsScene1907Symbol::handleMessage);
|
||||
SetSpriteUpdate(&AsScene1907Symbol::suMoveUp);
|
||||
_yIncr = 1;
|
||||
_isMoving = true;
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::moveDown() {
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
|
||||
stopAnimation();
|
||||
SetMessageHandler(&AsScene1907Symbol::handleMessage);
|
||||
SetSpriteUpdate(&AsScene1907Symbol::suMoveDown);
|
||||
_yIncr = 4;
|
||||
_isMoving = true;
|
||||
}
|
||||
|
||||
SsScene1907UpDownButton::SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol)
|
||||
: StaticSprite(vm, 1400), _parentScene(parentScene), _asScene1907Symbol(asScene1907Symbol),
|
||||
_countdown1(0) {
|
||||
|
||||
loadSprite(0x64516424, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1400);
|
||||
setVisible(false);
|
||||
loadSound(0, 0x44061000);
|
||||
SetUpdateHandler(&SsScene1907UpDownButton::update);
|
||||
SetMessageHandler(&SsScene1907UpDownButton::handleMessage);
|
||||
if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
|
||||
if (getGlobalVar(V_STAIRS_DOWN))
|
||||
setToDownPosition();
|
||||
else
|
||||
setToUpPosition();
|
||||
}
|
||||
}
|
||||
|
||||
void SsScene1907UpDownButton::update() {
|
||||
updatePosition();
|
||||
if (_countdown1 != 0 && (--_countdown1 == 0)) {
|
||||
setVisible(false);
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene1907UpDownButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_countdown1 == 0 && !_asScene1907Symbol->isMoving() && getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
|
||||
setVisible(true);
|
||||
_countdown1 = 4;
|
||||
updatePosition();
|
||||
playSound(0);
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void SsScene1907UpDownButton::setToUpPosition() {
|
||||
_y = _spriteResource.getPosition().y;
|
||||
updateBounds();
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
void SsScene1907UpDownButton::setToDownPosition() {
|
||||
_y = _spriteResource.getPosition().y + 174;
|
||||
updateBounds();
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
AsScene1907WaterHint::AsScene1907WaterHint(NeverhoodEngine *vm)
|
||||
: AnimatedSprite(vm, 1400) {
|
||||
|
||||
createSurface1(0x110A1061, 1500);
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
startAnimation(0x110A1061, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
setVisible(false);
|
||||
_needRefresh = true;
|
||||
AnimatedSprite::updatePosition();
|
||||
SetUpdateHandler(&AsScene1907WaterHint::update);
|
||||
SetMessageHandler(&Sprite::handleMessage);
|
||||
}
|
||||
|
||||
void AsScene1907WaterHint::update() {
|
||||
updateAnim();
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
uint32 AsScene1907WaterHint::hmShowing(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1907WaterHint::show() {
|
||||
setVisible(true);
|
||||
startAnimation(0x110A1061, 0, -1);
|
||||
SetMessageHandler(&AsScene1907WaterHint::hmShowing);
|
||||
NextState(&AsScene1907WaterHint::hide);
|
||||
}
|
||||
|
||||
void AsScene1907WaterHint::hide() {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
SetMessageHandler(&Sprite::handleMessage);
|
||||
}
|
||||
|
||||
KmScene1901::KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
GotoState(&Klaymen::stTurnToUse);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
GotoState(&Klaymen::stReturnFromUse);
|
||||
break;
|
||||
case 0x482D:
|
||||
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
106
engines/neverhood/modules/module1900_sprites.h
Normal file
106
engines/neverhood/modules/module1900_sprites.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1900_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1900_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Scene1907;
|
||||
|
||||
class AsScene1907Symbol : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex);
|
||||
void moveUp();
|
||||
void moveDown();
|
||||
void fallOff(int newPositionIndex, int fallOffDelay);
|
||||
bool isPluggedIn() { return _isPluggedIn; }
|
||||
bool isMoving() { return _isMoving; }
|
||||
protected:
|
||||
Scene1907 *_parentScene;
|
||||
int _elementIndex;
|
||||
int _currPositionIndex;
|
||||
int _newPositionIndex;
|
||||
bool _isPluggedIn;
|
||||
bool _isMoving;
|
||||
int _someX, _someY;
|
||||
int _xBreak;
|
||||
int _currStep;
|
||||
int _yAccel;
|
||||
int _yIncr;
|
||||
int _fallOffDelay;
|
||||
int _deltaX, _smallDeltaX;
|
||||
int _deltaY, _smallDeltaY;
|
||||
// Dumb, change if possible
|
||||
static bool _plugInFailed;
|
||||
static int _plugInTryCount;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmTryToPlugIn(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suTryToPlugIn();
|
||||
void suFallOff();
|
||||
void suFallOffHitGround();
|
||||
void suMoveDown();
|
||||
void suMoveUp();
|
||||
void tryToPlugIn();
|
||||
void stFallOffHitGround();
|
||||
void cbFallOffHitGroundEvent();
|
||||
void stPlugIn();
|
||||
void stPlugInFail();
|
||||
};
|
||||
|
||||
class AsScene1907WaterHint : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1907WaterHint(NeverhoodEngine *vm);
|
||||
void show();
|
||||
protected:
|
||||
void update();
|
||||
uint32 hmShowing(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void hide();
|
||||
};
|
||||
|
||||
class SsScene1907UpDownButton : public StaticSprite {
|
||||
public:
|
||||
SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol);
|
||||
void setToUpPosition();
|
||||
void setToDownPosition();
|
||||
protected:
|
||||
Scene1907 *_parentScene;
|
||||
AsScene1907Symbol *_asScene1907Symbol;
|
||||
int _countdown1;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene1901 : public Klaymen {
|
||||
public:
|
||||
KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1900_SPRITES_H */
|
||||
165
engines/neverhood/modules/module2000.cpp
Normal file
165
engines/neverhood/modules/module2000.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2000.h"
|
||||
#include "neverhood/modules/module2000_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module2000::Module2000(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 0)
|
||||
createScene(0, 1);
|
||||
else if (which == 1)
|
||||
createScene(0, 3);
|
||||
|
||||
}
|
||||
|
||||
Module2000::~Module2000() {
|
||||
_vm->_soundMan->deleteGroup(0x81293110);
|
||||
}
|
||||
|
||||
void Module2000::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module2000::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene2001(_vm, this, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
createNavigationScene(getGlobalVar(V_WORLDS_JOINED) ? 0x004B7B48 : 0x004B7B00, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
setGlobalVar(V_WORLDS_JOINED, 1);
|
||||
setSubVar(V_TELEPORTER_DEST_AVAILABLE, 1, 1);
|
||||
createSmackerScene(0x204B2031, true, true, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module2000::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module2000::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
leaveModule(0);
|
||||
else
|
||||
createScene(1, 0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 0) {
|
||||
if (getGlobalVar(V_WORLDS_JOINED))
|
||||
createScene(1, 0);
|
||||
else
|
||||
createScene(2, -1);
|
||||
} else if (_moduleResult == 1)
|
||||
createScene(1, 1);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(0, 0);
|
||||
break;
|
||||
case 2:
|
||||
createScene(1, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scene2001
|
||||
|
||||
Scene2001::Scene2001(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetMessageHandler(&Scene2001::handleMessage);
|
||||
|
||||
setBackground(0xA6417244);
|
||||
setPalette(0xA6417244);
|
||||
insertScreenMouse(0x17240A6C);
|
||||
|
||||
tempSprite = insertStaticSprite(0x0D641724, 1100);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene2001>(300, 345);
|
||||
setMessageList(0x004B3538);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
} else if (which == 1) {
|
||||
// Klaymen teleporting in
|
||||
insertKlaymen<KmScene2001>(116, 345);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B3540, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
} else if (which == 2) {
|
||||
// Klaymen teleporting out
|
||||
insertKlaymen<KmScene2001>(116, 345);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B35F0, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
} else if (which == 3) {
|
||||
// Klaymen returning from teleporter console
|
||||
insertKlaymen<KmScene2001>(116, 345);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B3550, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
} else {
|
||||
// Klaymen standing around
|
||||
insertKlaymen<KmScene2001>(390, 345);
|
||||
setMessageList(0x004B3530);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
}
|
||||
|
||||
_klaymen->setClipRect(tempSprite->getDrawRect().x, 0, 640, 480);
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene2001::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (param.asInteger()) {
|
||||
setRectList(0x004B3680);
|
||||
_klaymen->setKlaymenIdleTable3();
|
||||
} else {
|
||||
setRectList(0x004B3670);
|
||||
_klaymen->setKlaymenIdleTable1();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
51
engines/neverhood/modules/module2000.h
Normal file
51
engines/neverhood/modules/module2000.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2000_H
|
||||
#define NEVERHOOD_MODULES_MODULE2000_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module2000 : public Module {
|
||||
public:
|
||||
Module2000(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2000() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene2001 : public Scene {
|
||||
public:
|
||||
Scene2001(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2000_H */
|
||||
93
engines/neverhood/modules/module2000_sprites.cpp
Normal file
93
engines/neverhood/modules/module2000_sprites.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2000_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
KmScene2001::KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene2001::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4804:
|
||||
if (param.asInteger() != 0) {
|
||||
_destX = param.asInteger();
|
||||
GotoState(&Klaymen::stWalkingFirst);
|
||||
} else
|
||||
GotoState(&Klaymen::stPeekWall);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2000, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
case 0x483D:
|
||||
teleporterAppear(0xBE68CC54);
|
||||
break;
|
||||
case 0x483E:
|
||||
teleporterDisappear(0x18AB4ED4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
40
engines/neverhood/modules/module2000_sprites.h
Normal file
40
engines/neverhood/modules/module2000_sprites.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2000_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2000_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class KmScene2001 : public Klaymen {
|
||||
public:
|
||||
KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2000_SPRITES_H */
|
||||
223
engines/neverhood/modules/module2100.cpp
Normal file
223
engines/neverhood/modules/module2100.cpp
Normal file
@@ -0,0 +1,223 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1200_sprites.h"
|
||||
#include "neverhood/modules/module2100.h"
|
||||
#include "neverhood/modules/module2100_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module2100::Module2100(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
_vm->_soundMan->addMusic(0x10A10C14, 0x11482B95);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 1)
|
||||
createScene(0, 0);
|
||||
else if (which == 2)
|
||||
createScene(0, 3);
|
||||
else
|
||||
createScene(0, 1);
|
||||
|
||||
}
|
||||
|
||||
Module2100::~Module2100() {
|
||||
_vm->_soundMan->deleteMusicGroup(0x10A10C14);
|
||||
}
|
||||
|
||||
void Module2100::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module2100::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_vm->_soundMan->startMusic(0x11482B95, 0, 1);
|
||||
_childObject = new Scene2101(_vm, this, which);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module2100::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module2100::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1) {
|
||||
setGlobalVar(V_DOOR_PASSED, 1);
|
||||
leaveModule(0);
|
||||
} else {
|
||||
leaveModule(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene2101::Scene2101(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetMessageHandler(&Scene2101::handleMessage);
|
||||
SetUpdateHandler(&Scene2101::update);
|
||||
|
||||
setBackground(0x44242305);
|
||||
setPalette(0x44242305);
|
||||
insertScreenMouse(0x4230144A);
|
||||
|
||||
insertStaticSprite(0x00502330, 1100);
|
||||
tempSprite = insertStaticSprite(0x78492010, 1100);
|
||||
_ssFloorButton = insertSprite<SsCommonFloorButton>(this, 0x72427010, 0x32423010, 200, 0);
|
||||
_asTape1 = insertSprite<AsScene1201Tape>(this, 18, 1100, 412, 443, 0x9148A011);
|
||||
addCollisionSprite(_asTape1);
|
||||
_asTape2 = insertSprite<AsScene1201Tape>(this, 11, 1100, 441, 443, 0x9048A093);
|
||||
addCollisionSprite(_asTape2);
|
||||
|
||||
if (which < 0) {
|
||||
insertKlaymen<KmScene2101>(380, 438);
|
||||
setMessageList(0x004B8E48);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
_asDoor = insertSprite<AsScene2101Door>(false);
|
||||
_doorStatus = 1;
|
||||
_countdown1 = 0;
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the right
|
||||
insertKlaymen<KmScene2101>(640, 438);
|
||||
setMessageList(0x004B8E50);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
_asDoor = insertSprite<AsScene2101Door>(true);
|
||||
_doorStatus = 2;
|
||||
_countdown1 = 48;
|
||||
} else if (which == 2) {
|
||||
// Klaymen teleporting out
|
||||
insertKlaymen<KmScene2101>(115, 438);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B8F58);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
_asDoor = insertSprite<AsScene2101Door>(false);
|
||||
_doorStatus = 1;
|
||||
_countdown1 = 0;
|
||||
} else if (which == 3) {
|
||||
// Klaymen returning from the teleporter console
|
||||
insertKlaymen<KmScene2101>(115, 438);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B8EB0);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
_asDoor = insertSprite<AsScene2101Door>(false);
|
||||
_doorStatus = 1;
|
||||
_countdown1 = 0;
|
||||
} else {
|
||||
// Klaymen teleporting in
|
||||
insertKlaymen<KmScene2101>(115, 438);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B8EA0);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
_asDoor = insertSprite<AsScene2101Door>(false);
|
||||
_doorStatus = 1;
|
||||
_countdown1 = 0;
|
||||
}
|
||||
|
||||
_asHitByDoorEffect = insertSprite<AsScene2101HitByDoorEffect>(_klaymen);
|
||||
_klaymen->setClipRect(0, 0, tempSprite->getDrawRect().x2(), 480);
|
||||
|
||||
}
|
||||
|
||||
void Scene2101::update() {
|
||||
if (_countdown1 != 0) {
|
||||
if (_doorStatus == 2) {
|
||||
if (--_countdown1 == 0) {
|
||||
sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
|
||||
_doorStatus = 1;
|
||||
}
|
||||
} else {
|
||||
if (_klaymen->getX() > 575)
|
||||
_canAcceptInput = false;
|
||||
if (--_countdown1 == 0) {
|
||||
if (_klaymen->getX() < 480) {
|
||||
sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
|
||||
_doorStatus = 1;
|
||||
} else if (_klaymen->getX() >= 480 && _klaymen->getX() <= 575) {
|
||||
_klaymen->setDoDeltaX(0);
|
||||
setMessageList2(0x004B8F48);
|
||||
sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
|
||||
sendMessage(_asHitByDoorEffect, 0x2001, 0);
|
||||
_doorStatus = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (_doorStatus == 1 && _messageValue >= 0 && _klaymen->getX() > 470 && !isMessageList2(0x004B8F48))
|
||||
setMessageList2(0x004B8F50);
|
||||
Scene::update();
|
||||
}
|
||||
|
||||
uint32 Scene2101::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x02144CB1)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssFloorButton);
|
||||
else if (param.asInteger() == 0x21E64A00) {
|
||||
if (_doorStatus == 0)
|
||||
setMessageList(0x004B8E80);
|
||||
else
|
||||
setMessageList(0x004B8EC8);
|
||||
} else if (param.asInteger() == 0x41442820)
|
||||
cancelMessageList();
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (param.asInteger() != 0) {
|
||||
setRectList(0x004B9008);
|
||||
_klaymen->setKlaymenIdleTable3();
|
||||
} else {
|
||||
setRectList(0x004B8FF8);
|
||||
_klaymen->setKlaymenIdleTable1();
|
||||
}
|
||||
break;
|
||||
case 0x480B:
|
||||
if (sender == _ssFloorButton && _doorStatus == 1) {
|
||||
sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
_doorStatus = 0;
|
||||
_countdown1 = 90;
|
||||
}
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asTape1 || sender == _asTape2) {
|
||||
if (_klaymen->getX() >= 228 && _klaymen->getX() <= 500) {
|
||||
sendEntityMessage(_klaymen, 0x1014, sender);
|
||||
setMessageList(0x004B8F78);
|
||||
} else if (_klaymen->getX() < 228)
|
||||
setMessageList2(0x004B8F00);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
59
engines/neverhood/modules/module2100.h
Normal file
59
engines/neverhood/modules/module2100.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2100_H
|
||||
#define NEVERHOOD_MODULES_MODULE2100_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module2100 : public Module {
|
||||
public:
|
||||
Module2100(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2100() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene2101 : public Scene {
|
||||
public:
|
||||
Scene2101(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_ssFloorButton;
|
||||
Sprite *_asTape1;
|
||||
Sprite *_asTape2;
|
||||
Sprite *_asDoor;
|
||||
Sprite *_asHitByDoorEffect;
|
||||
int _countdown1;
|
||||
int _doorStatus;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2100_H */
|
||||
269
engines/neverhood/modules/module2100_sprites.cpp
Normal file
269
engines/neverhood/modules/module2100_sprites.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2100_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
AsScene2101Door::AsScene2101Door(NeverhoodEngine *vm, bool isOpen)
|
||||
: AnimatedSprite(vm, 1100) {
|
||||
|
||||
createSurface(100, 328, 347);
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene2101Door::handleMessage);
|
||||
if (isOpen) {
|
||||
startAnimation(0x0C202B9C, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
} else
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
uint32 AsScene2101Door::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
stOpenDoor();
|
||||
break;
|
||||
case NM_KLAYMEN_CLOSE_DOOR:
|
||||
stCloseDoor();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene2101Door::stOpenDoor() {
|
||||
startAnimation(0x0C202B9C, 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
setVisible(true);
|
||||
playSound(0, calcHash("fxDoorOpen32"));
|
||||
}
|
||||
|
||||
void AsScene2101Door::stCloseDoor() {
|
||||
startAnimation(0xC222A8D4, 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
setVisible(true);
|
||||
playSound(0, calcHash("fxDoorClose32"));
|
||||
NextState(&AsScene2101Door::stCloseDoorDone);
|
||||
}
|
||||
|
||||
void AsScene2101Door::stCloseDoorDone() {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
AsScene2101HitByDoorEffect::AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen)
|
||||
: AnimatedSprite(vm, 1400), _klaymen(klaymen) {
|
||||
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene2101HitByDoorEffect::handleMessage);
|
||||
createSurface(1200, 88, 165);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
uint32 AsScene2101HitByDoorEffect::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x2001:
|
||||
_x = _klaymen->getX();
|
||||
_y = _klaymen->getY() - 132;
|
||||
startAnimation(0x0422255A, 0, -1);
|
||||
setVisible(true);
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
SsCommonFloorButton::SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
|
||||
: StaticSprite(vm, 1100), _parentScene(parentScene), _countdown(0),
|
||||
_fileHash1(fileHash1), _fileHash2(fileHash2), _soundFileHash(soundFileHash) {
|
||||
|
||||
SetUpdateHandler(&SsCommonFloorButton::update);
|
||||
SetMessageHandler(&SsCommonFloorButton::handleMessage);
|
||||
if (_soundFileHash == 0)
|
||||
_soundFileHash = 0x44141000;
|
||||
createSurface(1010, 61, 30);
|
||||
if (_fileHash1)
|
||||
loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
|
||||
else
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
void SsCommonFloorButton::update() {
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
|
||||
if (_fileHash1)
|
||||
loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
|
||||
else
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsCommonFloorButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x480B:
|
||||
sendMessage(_parentScene, 0x480B, 0);
|
||||
setVisible(true);
|
||||
sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
|
||||
loadSprite(_fileHash2, kSLFDefDrawOffset | kSLFDefPosition);
|
||||
_countdown = 16;
|
||||
playSound(0, _soundFileHash);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene2101::KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4811:
|
||||
GotoState(&KmScene2101::stHitByDoor);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case NM_KLAYMEN_PRESS_BUTTON:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPressButton);
|
||||
else if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPressFloorButton);
|
||||
else
|
||||
GotoState(&Klaymen::stPressButtonSide);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2000, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
case 0x483D:
|
||||
teleporterAppear(0xFF290E30);
|
||||
break;
|
||||
case 0x483E:
|
||||
teleporterDisappear(0x9A28CA1C);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 KmScene2101::hmHitByDoor(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
|
||||
int16 speedUpFrameIndex;
|
||||
switch (messageNum) {
|
||||
case 0x1008:
|
||||
speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
|
||||
if (_currFrameIndex < speedUpFrameIndex) {
|
||||
startAnimation(0x35AA8059, speedUpFrameIndex, -1);
|
||||
_y = 438;
|
||||
}
|
||||
messageResult = 0;
|
||||
break;
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x1A1A0785) {
|
||||
playSound(0, 0x40F0A342);
|
||||
} else if (param.asInteger() == 0x60428026) {
|
||||
playSound(0, 0x40608A59);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void KmScene2101::stHitByDoor() {
|
||||
_busyStatus = 1;
|
||||
_acceptInput = false;
|
||||
startAnimation(0x35AA8059, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene2101::hmHitByDoor);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
playSound(0, 0x402E82D4);
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
74
engines/neverhood/modules/module2100_sprites.h
Normal file
74
engines/neverhood/modules/module2100_sprites.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2100_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2100_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class AsScene2101Door : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2101Door(NeverhoodEngine *vm, bool isOpen);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOpenDoor();
|
||||
void stCloseDoor();
|
||||
void stCloseDoorDone();
|
||||
};
|
||||
|
||||
class AsScene2101HitByDoorEffect : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen);
|
||||
protected:
|
||||
Sprite *_klaymen;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsCommonFloorButton : public StaticSprite {
|
||||
public:
|
||||
SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 _soundFileHash;
|
||||
uint32 _fileHash1, _fileHash2;
|
||||
int16 _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene2101 : public Klaymen {
|
||||
public:
|
||||
KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
|
||||
void stHitByDoor();
|
||||
uint32 hmHitByDoor(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2100_SPRITES_H */
|
||||
1771
engines/neverhood/modules/module2200.cpp
Normal file
1771
engines/neverhood/modules/module2200.cpp
Normal file
File diff suppressed because it is too large
Load Diff
201
engines/neverhood/modules/module2200.h
Normal file
201
engines/neverhood/modules/module2200.h
Normal file
@@ -0,0 +1,201 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2200_H
|
||||
#define NEVERHOOD_MODULES_MODULE2200_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/modules/module1000.h"
|
||||
#include "neverhood/graphics.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module2200 : public Module {
|
||||
public:
|
||||
Module2200(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2200() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
void createHallOfRecordsScene(int which, uint32 hallOfRecordsInfoId);
|
||||
bool shouldSkipHall();
|
||||
};
|
||||
|
||||
class Scene2201 : public Scene {
|
||||
public:
|
||||
Scene2201(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2201() override;
|
||||
protected:
|
||||
NRect _clipRects[2];
|
||||
Sprite *_ssDoorLight;
|
||||
Sprite *_asDoor;
|
||||
Sprite *_ssDoorButton;
|
||||
Sprite *_asTape;
|
||||
bool _isSoundPlaying;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2202 : public Scene {
|
||||
public:
|
||||
Scene2202(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2202() override;
|
||||
protected:
|
||||
Sprite *_ssMovingCube;
|
||||
Sprite *_ssDoneMovingCube;
|
||||
bool _isCubeMoving;
|
||||
int16 _movingCubePosition;
|
||||
int _surfacePriority;
|
||||
bool _leaveScene;
|
||||
bool _isSolved;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
int16 getFreeCubePosition(int16 index);
|
||||
bool testIsSolved();
|
||||
};
|
||||
|
||||
class Scene2203 : public Scene {
|
||||
public:
|
||||
Scene2203(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2203() override;
|
||||
protected:
|
||||
Sprite *_asLeftDoor;
|
||||
Sprite *_asRightDoor;
|
||||
Sprite *_ssSmallLeftDoor;
|
||||
Sprite *_ssSmallRightDoor;
|
||||
Sprite *_asTape;
|
||||
Sprite *_asKey;
|
||||
NRect _leftDoorClipRect;
|
||||
NRect _rightDoorClipRect;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsCommonPressButton;
|
||||
|
||||
class Scene2205 : public Scene {
|
||||
public:
|
||||
Scene2205(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
SsCommonPressButton *_ssLightSwitch;
|
||||
Sprite *_ssDoorFrame;
|
||||
bool _isKlaymenInLight;
|
||||
bool _isLightOn;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2206 : public Scene {
|
||||
public:
|
||||
Scene2206(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2206() override;
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
Sprite *_asDoorSpikes;
|
||||
Sprite *_ssButton;
|
||||
Sprite *_asPlatform;
|
||||
Sprite *_ssTestTube;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void klaymenInFrontSpikes();
|
||||
void klaymenBehindSpikes();
|
||||
void readClickedColumn();
|
||||
};
|
||||
|
||||
class Scene2207 : public Scene {
|
||||
public:
|
||||
Scene2207(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
Sprite *_asElevator;
|
||||
Sprite *_ssMaskPart1;
|
||||
Sprite *_ssMaskPart2;
|
||||
Sprite *_ssMaskPart3;
|
||||
Sprite *_asTape;
|
||||
Sprite *_asLever;
|
||||
Sprite *_asWallRobotAnimation;
|
||||
Sprite *_asWallCannonAnimation;
|
||||
Sprite *_ssButton;
|
||||
int _elevatorSurfacePriority;
|
||||
bool _klaymenAtElevator;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 handleMessage2(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2208 : public Scene {
|
||||
public:
|
||||
Scene2208(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2208() override;
|
||||
protected:
|
||||
FontSurface *_fontSurface;
|
||||
BaseSurface *_backgroundSurface;
|
||||
BaseSurface *_topBackgroundSurface;
|
||||
BaseSurface *_bottomBackgroundSurface;
|
||||
TextResource _textResource;
|
||||
int16 _backgroundScrollY;
|
||||
int16 _newRowIndex;
|
||||
int16 _currRowIndex;
|
||||
int16 _rowScrollY;
|
||||
int16 _maxRowIndex;
|
||||
int16 _visibleRowsCount;
|
||||
Common::Array<const char*> _strings;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void drawRow(int16 rowIndex);
|
||||
};
|
||||
|
||||
class Scene2242 : public Scene {
|
||||
public:
|
||||
Scene2242(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2242() override;
|
||||
protected:
|
||||
Sprite *_asTape;
|
||||
bool _isKlaymenInLight;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void readClickedColumn();
|
||||
};
|
||||
|
||||
class HallOfRecordsScene : public Scene {
|
||||
public:
|
||||
HallOfRecordsScene(NeverhoodEngine *vm, Module *parentModule, int which, uint32 hallOfRecordsInfoId);
|
||||
~HallOfRecordsScene() override;
|
||||
protected:
|
||||
HallOfRecordsInfo *_hallOfRecordsInfo;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void readClickedColumn();
|
||||
};
|
||||
|
||||
class Scene2247 : public Scene {
|
||||
public:
|
||||
Scene2247(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2247() override;
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void readClickedColumn();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2200_H */
|
||||
1471
engines/neverhood/modules/module2200_sprites.cpp
Normal file
1471
engines/neverhood/modules/module2200_sprites.cpp
Normal file
File diff suppressed because it is too large
Load Diff
274
engines/neverhood/modules/module2200_sprites.h
Normal file
274
engines/neverhood/modules/module2200_sprites.h
Normal file
@@ -0,0 +1,274 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2200_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2200_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/graphics.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const NPoint kSsScene2201PuzzleCubePoints[] = {
|
||||
{305, 305}, {321, 305}, {336, 305}, {305, 319},
|
||||
{321, 319}, {336, 319}, {305, 332}, {321, 332},
|
||||
{336, 333}
|
||||
};
|
||||
|
||||
static const uint32 kSsScene2201PuzzleCubeFileHashes[] = {
|
||||
0x88134A44, 0xAA124340, 0xB8124602, 0xA902464C,
|
||||
0x890A4244, 0xA8124642, 0xB812C204, 0x381A4A4C
|
||||
};
|
||||
|
||||
class AsScene2201CeilingFan : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2201CeilingFan(NeverhoodEngine *vm);
|
||||
};
|
||||
|
||||
class AsScene2201Door : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen);
|
||||
protected:
|
||||
Klaymen *_klaymen;
|
||||
Sprite *_ssDoorLight;
|
||||
bool _isOpen;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOpenDoor();
|
||||
void stCloseDoor();
|
||||
};
|
||||
|
||||
class SsScene2201PuzzleCube : public StaticSprite {
|
||||
public:
|
||||
SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex);
|
||||
};
|
||||
|
||||
class SsScene2202PuzzleCube : public StaticSprite {
|
||||
public:
|
||||
SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int16 _cubeSymbol;
|
||||
int16 _cubePosition;
|
||||
int16 _newX, _newY;
|
||||
int16 _xDelta, _yDelta;
|
||||
int16 _xIncr;
|
||||
int16 _yIncr;
|
||||
int16 _errValue;
|
||||
int16 _counter;
|
||||
int16 _xFlagPos;
|
||||
bool _counterDirection;
|
||||
bool _isMoving;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suMoveCubeX();
|
||||
void suMoveCubeY();
|
||||
void moveCube(int16 newCubePosition);
|
||||
void stopMoving();
|
||||
};
|
||||
|
||||
class AsCommonKey : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _keyIndex;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2203Door : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Sprite *_otherDoor;
|
||||
uint _doorIndex;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void openDoor();
|
||||
void closeDoor();
|
||||
};
|
||||
|
||||
class SsScene2205DoorFrame : public StaticSprite {
|
||||
public:
|
||||
SsScene2205DoorFrame(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2206DoorSpikes : public StaticSprite {
|
||||
public:
|
||||
AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash);
|
||||
protected:
|
||||
int _deltaIndex;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suOpen();
|
||||
void suClose();
|
||||
};
|
||||
|
||||
class AsScene2206Platform : public StaticSprite {
|
||||
public:
|
||||
AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash);
|
||||
protected:
|
||||
int16 _yDelta;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suMoveDown();
|
||||
};
|
||||
|
||||
class SsScene2206TestTube : public StaticSprite {
|
||||
public:
|
||||
SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2207Elevator : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene);
|
||||
~AsScene2207Elevator() override;
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
NPointArray *_pointArray;
|
||||
int16 _pointIndex;
|
||||
int16 _destPointIndex, _destPointIndexDelta;
|
||||
bool _isMoving;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suSetPosition();
|
||||
void moveToY(int16 y);
|
||||
};
|
||||
|
||||
class AsScene2207Lever : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stLeverDown();
|
||||
void stLeverDownEvent();
|
||||
void stLeverUp();
|
||||
void stLeverUpEvent();
|
||||
};
|
||||
|
||||
class AsScene2207WallRobotAnimation : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene);
|
||||
~AsScene2207WallRobotAnimation() override;
|
||||
protected:
|
||||
bool _idle;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stStartAnimation();
|
||||
void stStopAnimation();
|
||||
void cbStopAnimation();
|
||||
};
|
||||
|
||||
class AsScene2207WallCannonAnimation : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2207WallCannonAnimation(NeverhoodEngine *vm);
|
||||
protected:
|
||||
bool _idle;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stStartAnimation();
|
||||
void stStopAnimation();
|
||||
void cbStopAnimation();
|
||||
};
|
||||
|
||||
class SsScene2207Symbol : public StaticSprite {
|
||||
public:
|
||||
SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index);
|
||||
};
|
||||
|
||||
class KmScene2201 : public Klaymen {
|
||||
public:
|
||||
KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2203 : public Klaymen {
|
||||
public:
|
||||
KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void stClayDoorOpen();
|
||||
uint32 hmClayDoorOpen(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2205 : public Klaymen {
|
||||
public:
|
||||
KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void xUpdate() override;
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2206 : public Klaymen {
|
||||
public:
|
||||
KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
~KmScene2206() override;
|
||||
protected:
|
||||
void stRidePlatformDown();
|
||||
void suRidePlatformDown();
|
||||
|
||||
void xUpdate() override;
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2207 : public Klaymen {
|
||||
public:
|
||||
KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2242 : public Klaymen {
|
||||
public:
|
||||
KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void xUpdate() override;
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmHallOfRecords : public Klaymen {
|
||||
public:
|
||||
KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void xUpdate() override;
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2247 : public Klaymen {
|
||||
public:
|
||||
KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void xUpdate() override;
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2200_SPRITES_H */
|
||||
191
engines/neverhood/modules/module2300.cpp
Normal file
191
engines/neverhood/modules/module2300.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/navigationscene.h"
|
||||
#include "neverhood/modules/module2300.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule2300SoundList[] = {
|
||||
0x90805C50, 0x90804450, 0xB4005E60, 0x91835066,
|
||||
0x90E14440, 0x90F0D1C3, 0
|
||||
};
|
||||
|
||||
Module2300::Module2300(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule), _waterfallSoundVolume(0) {
|
||||
|
||||
_vm->_soundMan->addSoundList(0x1A214010, kModule2300SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule2300SoundList, true, 50, 600, 10, 150);
|
||||
|
||||
_isWaterfallRunning = getGlobalVar(V_WALL_BROKEN) != 1;
|
||||
|
||||
if (_isWaterfallRunning) {
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 0);
|
||||
_vm->_soundMan->playSoundLooping(0x90F0D1C3);
|
||||
} else {
|
||||
_vm->_soundMan->setSoundParams(0x90F0D1C3, false, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
_vm->_soundMan->playTwoSounds(0x1A214010, 0x48498E46, 0x50399F64, 0);
|
||||
_vm->_soundMan->playTwoSounds(0x1A214010, 0x41861371, 0x43A2507F, 0);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 1)
|
||||
createScene(2, 0);
|
||||
else if (which == 2)
|
||||
createScene(3, 0);
|
||||
else if (which == 3)
|
||||
createScene(4, -1);
|
||||
else if (which == 4)
|
||||
createScene(1, 3);
|
||||
else
|
||||
createScene(0, 1);
|
||||
|
||||
}
|
||||
|
||||
Module2300::~Module2300() {
|
||||
_vm->_soundMan->deleteGroup(0x1A214010);
|
||||
}
|
||||
|
||||
void Module2300::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module2300::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
createNavigationScene(0x004B67B8, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
createNavigationScene(0x004B67E8, which);
|
||||
if (_isWaterfallRunning) {
|
||||
_waterfallSoundVolume = 15;
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 15);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
createNavigationScene(0x004B6878, which);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
if (getGlobalVar(V_WALL_BROKEN))
|
||||
createNavigationScene(0x004B68F0, which);
|
||||
else {
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
|
||||
createNavigationScene(0x004B68A8, which);
|
||||
if (_isWaterfallRunning) {
|
||||
_waterfallSoundVolume = 87;
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 87);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(true);
|
||||
createSmackerScene(0x20080A0B, true, true, false);
|
||||
break;
|
||||
case 9999:
|
||||
createDemoScene();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module2300::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module2300::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(1, 4);
|
||||
else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 1)
|
||||
createScene(0, 0);
|
||||
else if (_vm->isDemo() && !(_vm->isBigDemo() && _moduleResult == 4))
|
||||
createScene(9999, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(2, 1);
|
||||
else if (_moduleResult == 3)
|
||||
createScene(1, 3);
|
||||
else if (_moduleResult == 4)
|
||||
createScene(3, 1);
|
||||
else if (_moduleResult == 5)
|
||||
leaveModule(3);
|
||||
else
|
||||
leaveModule(4);
|
||||
break;
|
||||
case 2:
|
||||
if (_moduleResult == 1)
|
||||
leaveModule(1);
|
||||
else
|
||||
createScene(1, 5);
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 1)
|
||||
leaveModule(2);
|
||||
else
|
||||
createScene(1, 1);
|
||||
break;
|
||||
case 4:
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(false);
|
||||
createScene(1, 2);
|
||||
break;
|
||||
case 9999:
|
||||
createScene(1, -1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (_sceneNum) {
|
||||
case 1:
|
||||
if (_isWaterfallRunning && navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 4 &&
|
||||
navigationScene()->getFrameNumber() % 2) {
|
||||
_waterfallSoundVolume++;
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
|
||||
}
|
||||
if (navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 0 &&
|
||||
navigationScene()->getFrameNumber() == 50) {
|
||||
_vm->_soundMan->playTwoSounds(0x1A214010, 0x48498E46, 0x50399F64, 0);
|
||||
_vm->_soundMan->setSoundVolume(0x48498E46, 70);
|
||||
_vm->_soundMan->setSoundVolume(0x50399F64, 70);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (_isWaterfallRunning && navigationScene()->isWalkingForward() && navigationScene()->getFrameNumber() % 2) {
|
||||
_waterfallSoundVolume--;
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
47
engines/neverhood/modules/module2300.h
Normal file
47
engines/neverhood/modules/module2300.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2300_H
|
||||
#define NEVERHOOD_MODULES_MODULE2300_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module2300
|
||||
|
||||
class Module2300 : public Module {
|
||||
public:
|
||||
Module2300(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2300() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
int _waterfallSoundVolume;
|
||||
bool _isWaterfallRunning;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2300_H */
|
||||
675
engines/neverhood/modules/module2400.cpp
Normal file
675
engines/neverhood/modules/module2400.cpp
Normal file
@@ -0,0 +1,675 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1000_sprites.h"
|
||||
#include "neverhood/modules/module1200_sprites.h"
|
||||
#include "neverhood/modules/module2400.h"
|
||||
#include "neverhood/modules/module2100_sprites.h"
|
||||
#include "neverhood/modules/module2200_sprites.h"
|
||||
#include "neverhood/modules/module2400_sprites.h"
|
||||
#include "neverhood/modules/module2800_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module2400::Module2400(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
_vm->_soundMan->addMusic(0x202D1010, 0xB110382D);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else
|
||||
createScene(0, 0);
|
||||
|
||||
}
|
||||
|
||||
Module2400::~Module2400() {
|
||||
_vm->_soundMan->deleteMusicGroup(0x202D1010);
|
||||
}
|
||||
|
||||
void Module2400::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module2400::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_vm->_soundMan->stopMusic(0xB110382D, 0, 0);
|
||||
_childObject = new Scene2401(_vm, this, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_vm->_soundMan->startMusic(0xB110382D, 0, 2);
|
||||
_childObject = new Scene2402(_vm, this, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
_vm->_soundMan->startMusic(0xB110382D, 0, 0);
|
||||
_childObject = new Scene2403(_vm, this, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_vm->_soundMan->stopMusic(0xB110382D, 0, 2);
|
||||
_childObject = new DiskplayerScene(_vm, this, 0);
|
||||
break;
|
||||
case 5:
|
||||
_vm->gameState().sceneNum = 5;
|
||||
_vm->_soundMan->startMusic(0xB110382D, 0, 2);
|
||||
_childObject = new Scene2406(_vm, this, which);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
_vm->_soundMan->stopMusic(0xB110382D, 0, 2);
|
||||
createSmackerScene(0x20D80001, true, true, false);
|
||||
break;
|
||||
case 7:
|
||||
_vm->gameState().sceneNum = 7;
|
||||
createStaticScene(0x81523218, 0x2321C81D);
|
||||
break;
|
||||
case 8:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
createStaticScene(0x08100210, 0x00214089);
|
||||
break;
|
||||
case 9:
|
||||
_vm->gameState().sceneNum = 9;
|
||||
createStaticScene(0x8C020505, 0x205018C8);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module2400::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module2400::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(1, 0);
|
||||
else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 1)
|
||||
createScene(5, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(7, -1);
|
||||
else
|
||||
createScene(0, 1);
|
||||
break;
|
||||
case 2:
|
||||
if (_moduleResult == 1)
|
||||
createScene(9, -1);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(6, -1);
|
||||
else
|
||||
createScene(5, 1);
|
||||
break;
|
||||
case 4:
|
||||
createScene(5, 2);
|
||||
break;
|
||||
case 5:
|
||||
if (_moduleResult == 1)
|
||||
createScene(2, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(4, 0);
|
||||
else if (_moduleResult == 3)
|
||||
createScene(8, -1);
|
||||
else
|
||||
createScene(1, 1);
|
||||
break;
|
||||
case 6:
|
||||
createScene(2, 2);
|
||||
break;
|
||||
case 7:
|
||||
createScene(1, 2);
|
||||
break;
|
||||
case 8:
|
||||
createScene(5, 3);
|
||||
break;
|
||||
case 9:
|
||||
createScene(2, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const NPoint kScene2401Points[] = {
|
||||
{384, 389}, {406, 389}, {429, 389},
|
||||
{453, 389}, {477, 389}
|
||||
};
|
||||
|
||||
static const uint32 kScene2401FileHashes1[] = {
|
||||
0x02842920, 0x02882920, 0x02902920,
|
||||
0x02A02920, 0x02C02920, 0x02002920,
|
||||
0x03802920, 0x00802920, 0x06802920,
|
||||
0x03842920
|
||||
};
|
||||
|
||||
static const uint32 kScene2401FileHashes2[] = {
|
||||
0xD0910020, 0xD0910038, 0xD0910008,
|
||||
0xD0910068, 0xD09100A8, 0
|
||||
};
|
||||
|
||||
static const NRect kScene2401Rects[] = {
|
||||
{ 369, 331, 394, 389 },
|
||||
{ 395, 331, 419, 389 },
|
||||
{ 420, 331, 441, 389 },
|
||||
{ 442, 331, 464, 389 },
|
||||
{ 465, 331, 491, 389 }
|
||||
};
|
||||
|
||||
Scene2401::Scene2401(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _countdown1(0), _countdown2(0), _unkFlag(false),
|
||||
_soundToggle(false), _asWaterSpitIndex(0) {
|
||||
|
||||
_vm->gameModule()->initWaterPipesPuzzle();
|
||||
|
||||
SetMessageHandler(&Scene2401::handleMessage);
|
||||
SetUpdateHandler(&Scene2401::update);
|
||||
|
||||
setRectList(0x004B3140);
|
||||
setBackground(0x8C030206);
|
||||
setPalette(0x8C030206);
|
||||
addEntity(_palette);
|
||||
_palette->addBasePalette(0x8C030206, 0, 256, 0);
|
||||
_palette->addPalette(0x91D3A391, 0, 65, 0);
|
||||
insertScreenMouse(0x302028C8);
|
||||
|
||||
_sprite1 = insertStaticSprite(0x2E068A23, 200);
|
||||
insertStaticSprite(0x401410A6, 200);
|
||||
_asFlowingWater = insertSprite<AsScene2401FlowingWater>();
|
||||
insertStaticSprite(0x90C0A4B4, 200);
|
||||
_ssButton = insertSprite<SsCommonButtonSprite>(this, 0x0092916A, 100, 0);
|
||||
_ssFloorButton = insertSprite<SsCommonFloorButton>(this, 0x28001120, 0x00911068, 100, 0);
|
||||
|
||||
for (uint i = 0; i < 5; i++)
|
||||
_asWaterFlushing[i] = insertSprite<AsScene2401WaterFlushing>(kScene2401Points[i].x, kScene2401Points[i].y);
|
||||
|
||||
for (uint i = 0; i < 10; i++) {
|
||||
_ssWaterPipes[i] = insertStaticSprite(kScene2401FileHashes1[i], 300);
|
||||
_ssWaterPipes[i]->setVisible(false);
|
||||
}
|
||||
|
||||
_asWaterSpit[0] = insertSprite<AsScene2401WaterSpit>();
|
||||
_asWaterSpit[1] = insertSprite<AsScene2401WaterSpit>();
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene2401>(200, 447);
|
||||
setMessageList(0x004B2F70);
|
||||
_asDoor = insertSprite<AsScene2401Door>(false);
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the back
|
||||
insertKlaymen<KmScene2401>(280, 413);
|
||||
setMessageList(0x004B2F80);
|
||||
_palette->addBasePalette(0xB103B604, 0, 65, 0);
|
||||
_palette->addPalette(0xB103B604, 0, 65, 0);
|
||||
_asDoor = insertSprite<AsScene2401Door>(true);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene2401>(-20, 447);
|
||||
setMessageList(0x004B2F78);
|
||||
_asDoor = insertSprite<AsScene2401Door>(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Scene2401::update() {
|
||||
|
||||
if (_countdown1 != 0 && (--_countdown1) == 0) {
|
||||
if (_pipeStatus > 0 && _pipeStatus <= 10)
|
||||
_ssWaterPipes[_pipeStatus - 1]->setVisible(false);
|
||||
if (_pipeStatus >= 10) {
|
||||
bool puzzleSolved = true, waterInside = false;
|
||||
for (uint pipeIndex = 0; pipeIndex < 5; pipeIndex++) {
|
||||
if (getSubVar(VA_CURR_WATER_PIPES_LEVEL, pipeIndex) != getSubVar(VA_GOOD_WATER_PIPES_LEVEL, pipeIndex))
|
||||
puzzleSolved = false;
|
||||
if (getSubVar(VA_CURR_WATER_PIPES_LEVEL, pipeIndex) != 0)
|
||||
waterInside = true;
|
||||
}
|
||||
if (puzzleSolved) {
|
||||
setGlobalVar(V_NOTES_DOOR_UNLOCKED, 1);
|
||||
setGlobalVar(V_NOTES_PUZZLE_SOLVED, 1);
|
||||
sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
} else if (waterInside) {
|
||||
playPipeSound(0xD0431020);
|
||||
for (uint i = 0; i < 5; i++) {
|
||||
sendMessage(_asWaterFlushing[i], NM_POSITION_CHANGE, getSubVar(VA_CURR_WATER_PIPES_LEVEL, i));
|
||||
setSubVar(VA_CURR_WATER_PIPES_LEVEL, i, 0);
|
||||
}
|
||||
}
|
||||
} else if (_pipeStatus >= 5) {
|
||||
_ssWaterPipes[_pipeStatus]->setVisible(true);
|
||||
_countdown1 = 8;
|
||||
playPipeSound(kScene2401FileHashes2[getSubVar(VA_CURR_WATER_PIPES_LEVEL, _pipeStatus - 5)]);
|
||||
} else {
|
||||
_ssWaterPipes[_pipeStatus]->setVisible(true);
|
||||
_countdown1 = _pipeStatus == 4 ? 16 : 8;
|
||||
playPipeSound(kScene2401FileHashes2[getSubVar(VA_GOOD_WATER_PIPES_LEVEL, _pipeStatus)]);
|
||||
}
|
||||
_pipeStatus++;
|
||||
}
|
||||
|
||||
if (_countdown2 != 0 && (--_countdown2) == 0)
|
||||
sendMessage(_asFlowingWater, 0x2003, 0);
|
||||
|
||||
Scene::update();
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene2401::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x402064D8)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssButton);
|
||||
else if (param.asInteger() == 0x02144CB1)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssFloorButton);
|
||||
else if (param.asInteger() == 0x11C40840) {
|
||||
if (getGlobalVar(V_NOTES_DOOR_UNLOCKED) && sendMessage(_asDoor, 0x2004, 0))
|
||||
setMessageList(0x004B3090);
|
||||
else
|
||||
setMessageList(0x004B30B0);
|
||||
} else if (param.asInteger() == 0x412722C0) {
|
||||
if (_countdown2 > 0 && getGlobalVar(V_HAS_TEST_TUBE)) {
|
||||
_countdown2 = 144;
|
||||
setMessageList(0x004B3020);
|
||||
} else
|
||||
setMessageList(0x004B3050);
|
||||
} else if (param.asInteger() == 0x21142050) {
|
||||
if (_unkFlag && _countdown1 == 0 && !getGlobalVar(V_NOTES_PUZZLE_SOLVED))
|
||||
setMessageList(0x004B2FA8);
|
||||
else
|
||||
setMessageList(0x004B2FC8);
|
||||
} else if (param.asInteger() == 0x87441031)
|
||||
setSurfacePriority(_sprite1->getSurface(), 1100);
|
||||
else if (param.asInteger() == 0x80C40322) {
|
||||
setSurfacePriority(_sprite1->getSurface(), 200);
|
||||
cancelMessageList();
|
||||
_unkFlag = true;
|
||||
} else if (param.asInteger() == 0x09C4B40A && _countdown2 > 12)
|
||||
_countdown2 = 12;
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
messageResult = 0;
|
||||
for (uint32 i = 0; i < 5; i++)
|
||||
if (kScene2401Rects[i].contains(_mouseClickPos.x, _mouseClickPos.y)) {
|
||||
messageResult = i;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x2001:
|
||||
sendMessage(_asWaterSpit[_asWaterSpitIndex], 0x2000, param.asInteger());
|
||||
_asWaterSpitIndex = (_asWaterSpitIndex + 1) & 1;
|
||||
incSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger(), 1);
|
||||
if (getSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger()) >= 5)
|
||||
setSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger(), 4);
|
||||
break;
|
||||
case 0x480B:
|
||||
if (sender == _ssButton) {
|
||||
_pipeStatus = 0;
|
||||
_countdown1 = 8;
|
||||
} else if (sender == _ssFloorButton && getGlobalVar(V_WATER_RUNNING)) {
|
||||
_countdown2 = 144;
|
||||
sendMessage(_asFlowingWater, NM_POSITION_CHANGE, 0);
|
||||
playSound(0, 0xE1130324);
|
||||
}
|
||||
break;
|
||||
case NM_MOVE_TO_BACK:
|
||||
_palette->addBasePalette(0xB103B604, 0, 65, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
break;
|
||||
case NM_MOVE_TO_FRONT:
|
||||
_palette->addBasePalette(0x91D3A391, 0, 65, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void Scene2401::playPipeSound(uint32 fileHash) {
|
||||
playSound(_soundToggle ? 0 : 1, fileHash);
|
||||
_soundToggle = !_soundToggle;
|
||||
}
|
||||
|
||||
static const uint32 kScene2402FileHashes[] = {
|
||||
0xD0910020, 0xD0910038, 0xD0910008,
|
||||
0xD0910068, 0xD09100A8
|
||||
};
|
||||
|
||||
Scene2402::Scene2402(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _countdown(0), _soundToggle(false) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetMessageHandler(&Scene2402::handleMessage);
|
||||
SetUpdateHandler(&Scene2402::update);
|
||||
|
||||
setRectList(0x004AF900);
|
||||
setBackground(0x81660220);
|
||||
setPalette(0x81660220);
|
||||
insertScreenMouse(0x6022481E);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 9, 1100, 286, 409, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
_ssButton = insertSprite<SsCommonButtonSprite>(this, 0x15288120, 100, 0);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene2402>(198, 404);
|
||||
setMessageList(0x004AF7C8);
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the right
|
||||
insertKlaymen<KmScene2402>(660, 404);
|
||||
setMessageList(0x004AF7D8);
|
||||
} else if (which == 2) {
|
||||
// Klaymen returning from looking through the window
|
||||
insertKlaymen<KmScene2402>(409, 404);
|
||||
_klaymen->setDoDeltaX(getGlobalVar(V_KLAYMEN_IS_DELTA_X) ? 1 : 0);
|
||||
setMessageList(0x004AF888);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene2402>(0, 404);
|
||||
setMessageList(0x004AF7D0);
|
||||
}
|
||||
|
||||
tempSprite = insertStaticSprite(0x081A60A8, 1100);
|
||||
_ssDoorFrame = (StaticSprite*)insertStaticSprite(0x406C0AE0, 1100);
|
||||
_klaymen->setClipRect(_ssDoorFrame->getDrawRect().x, 0, 639, tempSprite->getDrawRect().y2());
|
||||
_asDoor = insertSprite<AsScene2402Door>(this, which == 0);
|
||||
insertSprite<AsScene2402TV>(_klaymen);
|
||||
insertStaticSprite(0x3A01A020, 200);
|
||||
|
||||
}
|
||||
|
||||
Scene2402::~Scene2402() {
|
||||
setGlobalVar(V_KLAYMEN_IS_DELTA_X, _klaymen->isDoDeltaX() ? 1 : 0);
|
||||
}
|
||||
|
||||
void Scene2402::update() {
|
||||
if (_countdown != 0 && (--_countdown) == 0) {
|
||||
if (_pipeStatus >= 10) {
|
||||
sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
_ssDoorFrame->loadSprite(0x00B415E0, kSLFDefDrawOffset | kSLFDefPosition);
|
||||
} else if (_pipeStatus >= 5) {
|
||||
_countdown = 8;
|
||||
playPipeSound(kScene2402FileHashes[getSubVar(VA_CURR_WATER_PIPES_LEVEL, _pipeStatus - 5)]);
|
||||
} else {
|
||||
_countdown = _pipeStatus == 4 ? 16 : 8;
|
||||
playPipeSound(kScene2402FileHashes[getSubVar(VA_GOOD_WATER_PIPES_LEVEL, _pipeStatus)]);
|
||||
}
|
||||
_pipeStatus++;
|
||||
}
|
||||
Scene::update();
|
||||
}
|
||||
|
||||
uint32 Scene2402::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x402064D8)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssButton);
|
||||
else if (param.asInteger() == 0x01C66840) {
|
||||
if (sendMessage(_asDoor, 0x2000, 0))
|
||||
setMessageList(0x004AF800);
|
||||
else
|
||||
setMessageList(0x004AF818);
|
||||
}
|
||||
break;
|
||||
case 0x2001:
|
||||
_ssDoorFrame->loadSprite(0x406C0AE0, kSLFDefDrawOffset | kSLFDefPosition);
|
||||
break;
|
||||
case 0x480B:
|
||||
if (sender == _ssButton) {
|
||||
_pipeStatus = 0;
|
||||
_countdown = 8;
|
||||
}
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asTape) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTape);
|
||||
setMessageList(0x004AF890);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void Scene2402::playPipeSound(uint32 fileHash) {
|
||||
playSound(_soundToggle ? 0 : 1, fileHash);
|
||||
_soundToggle = !_soundToggle;
|
||||
}
|
||||
|
||||
Scene2403::Scene2403(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
Sprite *tempSprite1, *tempSprite2, *tempSprite3;
|
||||
|
||||
SetMessageHandler(&Scene2403::handleMessage);
|
||||
setBackground(0x0C05060C);
|
||||
setPalette(0x0C05060C);
|
||||
_palette->addPalette(0x414364B0, 0, 65, 0);
|
||||
insertScreenMouse(0x506080C8);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 2, 1100, 480, 454, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
_asLightCord = insertSprite<AsScene2803LightCord>(this, 0xA1095A10, 0x836D3813, 368, 200);
|
||||
_asLightCord->setClipRect(0, 25, 640, 480);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2403>(220, 449);
|
||||
setMessageList(0x004B5C98);
|
||||
setRectList(0x004B5E18);
|
||||
} else if (which == 1) {
|
||||
// Klaymen returning from looking through the window
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2403>(433, 449);
|
||||
setMessageList(0x004B5D70);
|
||||
setRectList(0x004B5E18);
|
||||
} else if (which == 2) {
|
||||
// Klaymen standing around after the critter video
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2403>(440, 449);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
setMessageList(0x004B5C98);
|
||||
setRectList(0x004B5E18);
|
||||
} else {
|
||||
// Klaymen coming up from ladder
|
||||
_isClimbingLadder = true;
|
||||
insertKlaymen<KmScene2403>(122, 599);
|
||||
setMessageList(0x004B5CA0);
|
||||
setRectList(0x004B5E28);
|
||||
}
|
||||
|
||||
_ssButton = insertSprite<SsCommonButtonSprite>(this, 0x3130B0EB, 100, 0);
|
||||
tempSprite1 = insertStaticSprite(0x20C24220, 1100);
|
||||
tempSprite2 = insertStaticSprite(0x03080900, 1300);
|
||||
tempSprite3 = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
tempSprite3->setClipRect(tempSprite1->getDrawRect().x, 0, 640, tempSprite2->getDrawRect().y2());
|
||||
_klaymen->setClipRect(tempSprite1->getDrawRect().x, 0, 640, tempSprite2->getDrawRect().y2());
|
||||
loadSound(1, calcHash("fxFogHornSoft"));
|
||||
}
|
||||
|
||||
uint32 Scene2403::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x040424D0)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssButton);
|
||||
else if (param.asInteger() == 0x180CE614)
|
||||
sendEntityMessage(_klaymen, 0x1014, _asLightCord);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isClimbingLadder = true;
|
||||
setRectList(0x004B5E28);
|
||||
break;
|
||||
case 0x2001:
|
||||
_isClimbingLadder = false;
|
||||
setRectList(0x004B5E18);
|
||||
break;
|
||||
case 0x480B:
|
||||
if (sender == _ssButton) {
|
||||
if (getSubVar(VA_LOCKS_DISABLED, 0x304008D2)) {
|
||||
setSubVar(VA_LOCKS_DISABLED, 0x304008D2, 0);
|
||||
playSound(0, calcHash("fx3LocksDisable"));
|
||||
} else {
|
||||
setSubVar(VA_LOCKS_DISABLED, 0x304008D2, 1);
|
||||
playSound(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_KLAYMEN_LOWER_LEVER:
|
||||
if (sender == _asLightCord)
|
||||
leaveScene(2);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asTape && !_isClimbingLadder) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTape);
|
||||
setMessageList(0x004B5D98);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
Scene2406::Scene2406(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
Sprite *tempSprite1, *tempSprite2;
|
||||
|
||||
if (getGlobalVar(V_HAS_FINAL_KEY) && getGlobalVar(V_KEY3_LOCATION) == 0)
|
||||
setGlobalVar(V_KEY3_LOCATION, 2);
|
||||
|
||||
SetMessageHandler(&Scene2406::handleMessage);
|
||||
|
||||
setRectList(0x004B78C8);
|
||||
insertScreenMouse(0xB03001A8);
|
||||
|
||||
if (getGlobalVar(V_KEY3_LOCATION) == 2) {
|
||||
_asKey = insertSprite<AsCommonKey>(this, 2, 1100, 560, 409);
|
||||
addCollisionSprite(_asKey);
|
||||
}
|
||||
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 5, 1100, 456, 409, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
tempSprite2 = insertStaticSprite(0x19625293, 1100);
|
||||
_clipRects[0].x1 = 0;
|
||||
_clipRects[0].y1 = 0;
|
||||
_clipRects[0].x2 = tempSprite2->getDrawRect().x2();
|
||||
_clipRects[0].y2 = 480;
|
||||
|
||||
if (getGlobalVar(V_SPIKES_RETRACTED)) {
|
||||
setBackground(0x1A0B0304);
|
||||
setPalette(0x1A0B0304);
|
||||
tempSprite1 = insertStaticSprite(0x32923922, 1100);
|
||||
} else {
|
||||
setBackground(0x0A038595);
|
||||
setPalette(0x0A038595);
|
||||
tempSprite1 = insertStaticSprite(0x1712112A, 1100);
|
||||
}
|
||||
|
||||
tempSprite2 = insertStaticSprite(0x22300924, 1300);
|
||||
_clipRects[1].x1 = tempSprite1->getDrawRect().x;
|
||||
_clipRects[1].y1 = tempSprite2->getDrawRect().y;
|
||||
_clipRects[1].x2 = 640;
|
||||
_clipRects[1].y2 = 480;
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2406>(307, 404, _clipRects, 2);
|
||||
setMessageList(0x004B76C8);
|
||||
setRectList(0x004B78C8);
|
||||
} else if (which == 1) {
|
||||
// Klaymen coming down the ladder
|
||||
_isClimbingLadder = true;
|
||||
insertKlaymen<KmScene2406>(253, -16, _clipRects, 2);
|
||||
setMessageList(0x004B76D8);
|
||||
setRectList(0x004B78D8);
|
||||
} else if (which == 2) {
|
||||
// Klaymen returning from the diskplayer
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2406>(480, 404, _clipRects, 2);
|
||||
setMessageList(0x004B77C0);
|
||||
setRectList(0x004B78C8);
|
||||
} else if (which == 3) {
|
||||
// Klaymen returning from looking through the window
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2406>(387, 404, _clipRects, 2);
|
||||
setMessageList(0x004B7810);
|
||||
setRectList(0x004B78C8);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2406>(0, 404, _clipRects, 2);
|
||||
setMessageList(0x004B76D0);
|
||||
setRectList(0x004B78C8);
|
||||
}
|
||||
|
||||
tempSprite2 = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
tempSprite2->setClipRect(_clipRects[1]);
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene2406::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x41062804) {
|
||||
if (getGlobalVar(V_SPIKES_RETRACTED))
|
||||
setMessageList(0x004B7758);
|
||||
else
|
||||
setMessageList(0x004B7738);
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isClimbingLadder = true;
|
||||
setRectList(0x004B78D8);
|
||||
break;
|
||||
case 0x2001:
|
||||
_isClimbingLadder = false;
|
||||
setRectList(0x004B78C8);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asTape && !_isClimbingLadder) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTape);
|
||||
setMessageList(0x004B77C8);
|
||||
} else if (sender == _asKey && !_isClimbingLadder) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asKey);
|
||||
setMessageList(0x004B77D8);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
111
engines/neverhood/modules/module2400.h
Normal file
111
engines/neverhood/modules/module2400.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2400_H
|
||||
#define NEVERHOOD_MODULES_MODULE2400_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/gamemodule.h"
|
||||
#include "neverhood/diskplayerscene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module2400
|
||||
|
||||
class Module2400 : public Module {
|
||||
public:
|
||||
Module2400(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2400() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2401 : public Scene {
|
||||
public:
|
||||
Scene2401(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_asFlowingWater;
|
||||
Sprite *_ssButton;
|
||||
Sprite *_ssFloorButton;
|
||||
Sprite *_asWaterSpit[2];
|
||||
Sprite *_ssWaterPipes[10];
|
||||
Sprite *_asWaterFlushing[5];
|
||||
Sprite *_asDoor;
|
||||
bool _soundToggle;
|
||||
bool _unkFlag;
|
||||
int _countdown1;
|
||||
int _countdown2;
|
||||
int _pipeStatus;
|
||||
int _asWaterSpitIndex;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void playPipeSound(uint32 fileHash);
|
||||
};
|
||||
|
||||
class Scene2402 : public Scene {
|
||||
public:
|
||||
Scene2402(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2402() override;
|
||||
protected:
|
||||
Sprite *_asDoor;
|
||||
Sprite *_ssButton;
|
||||
Sprite *_asTape;
|
||||
StaticSprite *_ssDoorFrame;
|
||||
int _pipeStatus;
|
||||
int _countdown;
|
||||
bool _soundToggle;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void playPipeSound(uint32 fileHash);
|
||||
};
|
||||
|
||||
class Scene2403 : public Scene {
|
||||
public:
|
||||
Scene2403(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_ssButton;
|
||||
Sprite *_asTape;
|
||||
Sprite *_asKey;
|
||||
Sprite *_asLightCord;
|
||||
bool _isClimbingLadder;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2406 : public Scene {
|
||||
public:
|
||||
Scene2406(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_asTape;
|
||||
Sprite *_asKey;
|
||||
NRect _clipRects[2];
|
||||
bool _isClimbingLadder;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2400_H */
|
||||
762
engines/neverhood/modules/module2400_sprites.cpp
Normal file
762
engines/neverhood/modules/module2400_sprites.cpp
Normal file
@@ -0,0 +1,762 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2400_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kAsScene2401WaterSpitFileHashes2[] = {
|
||||
0x5C044690, 0x5C644690, 0x5CA44690,
|
||||
0x5D244690, 0x5E244690
|
||||
};
|
||||
|
||||
static const uint32 kAsScene2401WaterSpitFileHashes1[] = {
|
||||
0xF4418408, 0xF4418808, 0xF4419008,
|
||||
0xF441A008, 0xCD4F8411
|
||||
};
|
||||
|
||||
AsScene2401WaterSpit::AsScene2401WaterSpit(NeverhoodEngine *vm)
|
||||
: AnimatedSprite(vm, 1200) {
|
||||
|
||||
_x = 240;
|
||||
_y = 447;
|
||||
createSurface(100, 146, 74);
|
||||
setVisible(false);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene2401WaterSpit::handleMessage);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
}
|
||||
|
||||
uint32 AsScene2401WaterSpit::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x120A0013)
|
||||
playSound(0, kAsScene2401WaterSpitFileHashes1[_soundIndex]);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_x = 240;
|
||||
_y = 447;
|
||||
_soundIndex = getSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger());
|
||||
startAnimation(kAsScene2401WaterSpitFileHashes2[param.asInteger()], 0, -1);
|
||||
setVisible(true);
|
||||
playSound(0, 0x48640244);
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene2401FlowingWater::AsScene2401FlowingWater(NeverhoodEngine *vm)
|
||||
: AnimatedSprite(vm, 1200), _isWaterFlowing(false) {
|
||||
|
||||
_x = 88;
|
||||
_y = 421;
|
||||
createSurface1(0x10203116, 100);
|
||||
setVisible(false);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene2401FlowingWater::handleMessage);
|
||||
}
|
||||
|
||||
AsScene2401FlowingWater::~AsScene2401FlowingWater() {
|
||||
_vm->_soundMan->deleteSoundGroup(0x40F11C09);
|
||||
}
|
||||
|
||||
uint32 AsScene2401FlowingWater::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (_isWaterFlowing && param.asInteger() == 0x02421405)
|
||||
startAnimationByHash(0x10203116, 0x01084280, 0);
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
if (!_isWaterFlowing) {
|
||||
_vm->_soundMan->addSound(0x40F11C09, 0x980C1420);
|
||||
_vm->_soundMan->playSoundLooping(0x980C1420);
|
||||
startAnimation(0x10203116, 0, -1);
|
||||
setVisible(true);
|
||||
_isWaterFlowing = true;
|
||||
}
|
||||
break;
|
||||
case 0x2003:
|
||||
_vm->_soundMan->deleteSound(0x980C1420);
|
||||
_isWaterFlowing = false;
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene2401WaterFlushing::AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y)
|
||||
: AnimatedSprite(vm, 1200), _countdown(0), _flushLoopCount(0) {
|
||||
|
||||
_x = x;
|
||||
_y = y;
|
||||
createSurface1(0xB8596884, 100);
|
||||
setVisible(false);
|
||||
SetUpdateHandler(&AsScene2401WaterFlushing::update);
|
||||
SetMessageHandler(&AsScene2401WaterFlushing::handleMessage);
|
||||
}
|
||||
|
||||
void AsScene2401WaterFlushing::update() {
|
||||
if (_countdown != 0 && (--_countdown) == 0) {
|
||||
setDoDeltaX(_vm->_rnd->getRandomNumber(1));
|
||||
startAnimation(0xB8596884, 0, -1);
|
||||
setVisible(true);
|
||||
}
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
uint32 AsScene2401WaterFlushing::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (_flushLoopCount > 0 && param.asInteger() == 0x02421405) {
|
||||
startAnimationByHash(0xB8596884, 0x01084280, 0);
|
||||
_flushLoopCount--;
|
||||
}
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
if (param.asInteger() > 0) {
|
||||
_flushLoopCount = param.asInteger() - 1;
|
||||
_countdown = _vm->_rnd->getRandomNumber(3) + 1;
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene2401Door::AsScene2401Door(NeverhoodEngine *vm, bool isOpen)
|
||||
: AnimatedSprite(vm, 1100), _countdown(0), _isOpen(isOpen) {
|
||||
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
createSurface1(0x44687810, 100);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
if (_isOpen) {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
_countdown = 48;
|
||||
} else {
|
||||
startAnimation(0x44687810, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
SetUpdateHandler(&AsScene2401Door::update);
|
||||
SetMessageHandler(&AsScene2401Door::handleMessage);
|
||||
}
|
||||
|
||||
void AsScene2401Door::update() {
|
||||
if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
|
||||
_isOpen = false;
|
||||
setVisible(true);
|
||||
startAnimation(0x44687810, -1, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
_playBackwards = true;
|
||||
playSound(0, calcHash("fxDoorClose38"));
|
||||
}
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
uint32 AsScene2401Door::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x2004:
|
||||
if (_isOpen)
|
||||
_countdown = 168;
|
||||
messageResult = _isOpen ? 1 : 0;
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
if (!_isOpen) {
|
||||
_countdown = 168;
|
||||
_isOpen = true;
|
||||
setVisible(true);
|
||||
startAnimation(0x44687810, 0, -1);
|
||||
playSound(0, calcHash("fxDoorOpen38"));
|
||||
NextState(&AsScene2401Door::stDoorOpenFinished);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene2401Door::stDoorOpenFinished() {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
AsScene2402Door::AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _isOpen(isOpen), _countdown(0) {
|
||||
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
createSurface1(0x80495831, 100);
|
||||
if (_isOpen) {
|
||||
startAnimation(0x80495831, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
_countdown = 48;
|
||||
} else {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
SetUpdateHandler(&AsScene2402Door::update);
|
||||
SetMessageHandler(&AsScene2402Door::handleMessage);
|
||||
}
|
||||
|
||||
void AsScene2402Door::update() {
|
||||
if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
|
||||
_isOpen = false;
|
||||
setVisible(true);
|
||||
startAnimation(0x80495831, -1, -1);
|
||||
_playBackwards = true;
|
||||
playSound(0, calcHash("fxDoorClose38"));
|
||||
NextState(&AsScene2402Door::stDoorClosingFinished);
|
||||
}
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
uint32 AsScene2402Door::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (_isOpen)
|
||||
_countdown = 144;
|
||||
messageResult = _isOpen ? 1 : 0;
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
_countdown = 144;
|
||||
_isOpen = true;
|
||||
setVisible(true);
|
||||
startAnimation(0x80495831, 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
playSound(0, calcHash("fxDoorOpen38"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene2402Door::stDoorClosingFinished() {
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
AsScene2402TV::AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen)
|
||||
: AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown1(0), _countdown2(0) {
|
||||
|
||||
_x = 260;
|
||||
_y = 210;
|
||||
createSurface(100, 127, 90);
|
||||
setDoDeltaX(1);
|
||||
SetMessageHandler(&Sprite::handleMessage);
|
||||
if (!getGlobalVar(V_TV_JOKE_TOLD)) {
|
||||
loadSound(0, 0x58208810);
|
||||
_countdown1 = 48;
|
||||
startAnimation(0x4919397A, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
SetUpdateHandler(&AsScene2402TV::upWait);
|
||||
} else {
|
||||
int16 frameIndex;
|
||||
if (_klaymen->getX() > 320)
|
||||
_currFrameIndex = 29;
|
||||
frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
|
||||
startAnimation(0x050A0103, frameIndex, -1);
|
||||
_newStickFrameIndex = frameIndex;
|
||||
_countdown1 = 0;
|
||||
SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
|
||||
}
|
||||
}
|
||||
|
||||
AsScene2402TV::~AsScene2402TV() {
|
||||
_vm->_soundMan->deleteSoundGroup(0x01520123);
|
||||
}
|
||||
|
||||
void AsScene2402TV::upWait() {
|
||||
if (_countdown1 != 0 && (--_countdown1) == 0) {
|
||||
startAnimation(0x4919397A, 0, -1);
|
||||
SetMessageHandler(&AsScene2402TV::hmJoke);
|
||||
NextState(&AsScene2402TV::stJokeFinished);
|
||||
}
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
void AsScene2402TV::upFocusKlaymen() {
|
||||
int16 frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
|
||||
if (frameIndex != _currFrameIndex) {
|
||||
if (frameIndex > _currFrameIndex)
|
||||
_currFrameIndex++;
|
||||
else if (frameIndex < _currFrameIndex)
|
||||
_currFrameIndex--;
|
||||
startAnimation(0x050A0103, _currFrameIndex, -1);
|
||||
_newStickFrameIndex = _currFrameIndex;
|
||||
if (_countdown2 == 0) {
|
||||
_vm->_soundMan->addSound(0x01520123, 0xC42D4528);
|
||||
_vm->_soundMan->playSoundLooping(0xC42D4528);
|
||||
}
|
||||
_countdown2 = 5;
|
||||
} else if (_countdown2 != 0 && (--_countdown2 == 0))
|
||||
_vm->_soundMan->deleteSound(0xC42D4528);
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
void AsScene2402TV::stJokeFinished() {
|
||||
setGlobalVar(V_TV_JOKE_TOLD, 1);
|
||||
startAnimation(0x050A0103, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
|
||||
}
|
||||
|
||||
uint32 AsScene2402TV::hmJoke(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x431EA0B0)
|
||||
playSound(0);
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene2401::KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y),
|
||||
_canSpitPipe(false), _contSpitPipe(false), _readyToSpit(false),
|
||||
_spitPipeIndex(0), _spitDestPipeIndex(0), _spitContDestPipeIndex(0) {
|
||||
|
||||
// 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 NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case NM_KLAYMEN_PRESS_BUTTON:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPressButton);
|
||||
else if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPressFloorButton);
|
||||
else
|
||||
GotoState(&Klaymen::stPressButtonSide);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x482D:
|
||||
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x482E:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWalkToFrontNoStep);
|
||||
else
|
||||
GotoState(&Klaymen::stWalkToFront);
|
||||
break;
|
||||
case 0x482F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stTurnToFront);
|
||||
else
|
||||
GotoState(&Klaymen::stTurnToBack);
|
||||
break;
|
||||
case 0x4832:
|
||||
GotoState(&Klaymen::stUseTube);
|
||||
break;
|
||||
case 0x4833:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
else {
|
||||
_spitPipeIndex = sendMessage(_parentScene, 0x2000, 0);
|
||||
GotoState(&KmScene2401::stTrySpitIntoPipe);
|
||||
}
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 KmScene2401::hmSpit(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x16401CA6) {
|
||||
_canSpitPipe = true;
|
||||
if (_contSpitPipe)
|
||||
spitIntoPipe();
|
||||
} else if (param.asInteger() == 0xC11C0008) {
|
||||
_canSpitPipe = false;
|
||||
_acceptInput = false;
|
||||
_readyToSpit = false;
|
||||
} else if (param.asInteger() == 0x018A0001) {
|
||||
sendMessage(_parentScene, 0x2001, _spitDestPipeIndex);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void KmScene2401::stTrySpitIntoPipe() {
|
||||
if (_readyToSpit) {
|
||||
_contSpitPipe = true;
|
||||
_spitContDestPipeIndex = _spitPipeIndex;
|
||||
if (_canSpitPipe)
|
||||
spitIntoPipe();
|
||||
} else if (!stStartAction(AnimationCallback(&KmScene2401::stTrySpitIntoPipe))) {
|
||||
_busyStatus = 2;
|
||||
_acceptInput = true;
|
||||
_spitDestPipeIndex = _spitPipeIndex;
|
||||
_readyToSpit = true;
|
||||
_canSpitPipe = false;
|
||||
_contSpitPipe = false;
|
||||
startAnimation(0x1808B150, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene2401::hmSpit);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void KmScene2401::spitIntoPipe() {
|
||||
_contSpitPipe = false;
|
||||
_spitDestPipeIndex = _spitContDestPipeIndex;
|
||||
_canSpitPipe = false;
|
||||
_acceptInput = false;
|
||||
startAnimation(0x1B08B553, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene2401::hmSpit);
|
||||
SetSpriteUpdate(nullptr);
|
||||
NextState(&KmScene2401::stContSpitIntoPipe);
|
||||
}
|
||||
|
||||
void KmScene2401::stContSpitIntoPipe() {
|
||||
_canSpitPipe = true;
|
||||
_acceptInput = true;
|
||||
startAnimationByHash(0x1808B150, 0x16401CA6, 0);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene2401::hmSpit);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
|
||||
KmScene2402::KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene2402::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (!getGlobalVar(V_TV_JOKE_TOLD))
|
||||
GotoState(&Klaymen::stStandWonderAbout);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4804:
|
||||
if (param.asInteger() != 0) {
|
||||
_destX = param.asInteger();
|
||||
GotoState(&Klaymen::stWalkingFirst);
|
||||
} else
|
||||
GotoState(&Klaymen::stPeekWall);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case NM_KLAYMEN_PRESS_BUTTON:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPressButton);
|
||||
else if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPressFloorButton);
|
||||
else
|
||||
GotoState(&Klaymen::stPressButtonSide);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stWonderAboutHalf);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAboutAfter);
|
||||
else if (param.asInteger() == 3)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else if (param.asInteger() == 4)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene2403::KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene2403::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x480D:
|
||||
GotoState(&Klaymen::stPullCord);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case NM_KLAYMEN_PRESS_BUTTON:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPressButton);
|
||||
else if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPressFloorButton);
|
||||
else
|
||||
GotoState(&Klaymen::stPressButtonSide);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stWonderAboutHalf);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAboutAfter);
|
||||
else if (param.asInteger() == 3)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else if (param.asInteger() == 4)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x4820:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
GotoState(&Klaymen::stContinueClimbLadderUp);
|
||||
break;
|
||||
case 0x4821:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_destY = param.asInteger();
|
||||
GotoState(&Klaymen::stStartClimbLadderDown);
|
||||
break;
|
||||
case 0x4822:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_destY = param.asInteger();
|
||||
GotoState(&Klaymen::stStartClimbLadderUp);
|
||||
break;
|
||||
case 0x4823:
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
GotoState(&Klaymen::stClimbLadderHalf);
|
||||
break;
|
||||
case 0x482D:
|
||||
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene2406::KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
_surface->setClipRects(clipRects, clipRectsCount);
|
||||
}
|
||||
|
||||
uint32 KmScene2406::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4804:
|
||||
if (param.asInteger() != 0) {
|
||||
_destX = param.asInteger();
|
||||
GotoState(&Klaymen::stWalkingFirst);
|
||||
} else
|
||||
GotoState(&Klaymen::stPeekWall);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_INSERT_DISK:
|
||||
GotoState(&Klaymen::stInsertDisk);
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
GotoState(&Klaymen::stTurnToUse);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
GotoState(&Klaymen::stReturnFromUse);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stWonderAboutHalf);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAboutAfter);
|
||||
else if (param.asInteger() == 3)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else if (param.asInteger() == 4)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x4820:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
GotoState(&Klaymen::stContinueClimbLadderUp);
|
||||
break;
|
||||
case 0x4821:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_destY = param.asInteger();
|
||||
GotoState(&Klaymen::stStartClimbLadderDown);
|
||||
break;
|
||||
case 0x4822:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_destY = param.asInteger();
|
||||
GotoState(&Klaymen::stStartClimbLadderUp);
|
||||
break;
|
||||
case 0x4823:
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
GotoState(&Klaymen::stClimbLadderHalf);
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
138
engines/neverhood/modules/module2400_sprites.h
Normal file
138
engines/neverhood/modules/module2400_sprites.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2400_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2400_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/gamemodule.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class AsScene2401WaterSpit : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2401WaterSpit(NeverhoodEngine *vm);
|
||||
protected:
|
||||
int _soundIndex;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2401FlowingWater : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2401FlowingWater(NeverhoodEngine *vm);
|
||||
~AsScene2401FlowingWater() override;
|
||||
protected:
|
||||
bool _isWaterFlowing;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2401WaterFlushing : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y);
|
||||
protected:
|
||||
int _countdown;
|
||||
int _flushLoopCount;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2401Door : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2401Door(NeverhoodEngine *vm, bool isOpen);
|
||||
protected:
|
||||
int _countdown;
|
||||
bool _isOpen;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stDoorOpenFinished();
|
||||
};
|
||||
|
||||
class AsScene2402Door : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _countdown;
|
||||
bool _isOpen;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stDoorClosingFinished();
|
||||
};
|
||||
|
||||
class AsScene2402TV : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen);
|
||||
~AsScene2402TV() override;
|
||||
protected:
|
||||
Klaymen *_klaymen;
|
||||
int _countdown1;
|
||||
int _countdown2;
|
||||
void upWait();
|
||||
void upFocusKlaymen();
|
||||
void stJokeFinished();
|
||||
uint32 hmJoke(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene2401 : public Klaymen {
|
||||
public:
|
||||
KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
bool _canSpitPipe;
|
||||
bool _contSpitPipe;
|
||||
bool _readyToSpit;
|
||||
uint32 _spitPipeIndex;
|
||||
uint32 _spitDestPipeIndex;
|
||||
uint32 _spitContDestPipeIndex;
|
||||
|
||||
void spitIntoPipe();
|
||||
void stTrySpitIntoPipe();
|
||||
void stContSpitIntoPipe();
|
||||
uint32 hmSpit(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2402 : public Klaymen {
|
||||
public:
|
||||
KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2403 : public Klaymen {
|
||||
public:
|
||||
KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2406 : public Klaymen {
|
||||
public:
|
||||
KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2400_SPRITES_H */
|
||||
515
engines/neverhood/modules/module2500.cpp
Normal file
515
engines/neverhood/modules/module2500.cpp
Normal file
@@ -0,0 +1,515 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1600.h" // for Scene1608
|
||||
#include "neverhood/modules/module1600_sprites.h"
|
||||
#include "neverhood/modules/module2500.h"
|
||||
#include "neverhood/modules/module2500_sprites.h"
|
||||
#include "neverhood/modules/module2700.h" // for Scene2704
|
||||
#include "neverhood/modules/module2700_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kScene2505StaticSprites[] = {
|
||||
0x4000A226, 0
|
||||
};
|
||||
|
||||
static const NRect kScene2505ClipRect = { 0, 0, 564, 480 };
|
||||
|
||||
static const uint32 kScene2506StaticSprites[] = {
|
||||
0x4027AF02, 0
|
||||
};
|
||||
|
||||
static const NRect kScene2506ClipRect = { 0, 0, 640, 441 };
|
||||
|
||||
static const uint32 kScene2508StaticSprites1[] = {
|
||||
0x2F08E610, 0xD844E6A0, 0
|
||||
};
|
||||
|
||||
static const NRect kScene2508ClipRect1 = { 0, 0, 594, 448 };
|
||||
|
||||
static const uint32 kScene2508StaticSprites2[] = {
|
||||
0x2F08E610, 0
|
||||
};
|
||||
|
||||
static const NRect kScene2508ClipRect2 = { 0, 0, 594, 448 };
|
||||
|
||||
Module2500::Module2500(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule), _soundIndex(0) {
|
||||
|
||||
_vm->_soundMan->addMusic(0x29220120, 0x05343184);
|
||||
_vm->_soundMan->startMusic(0x05343184, 0, 0);
|
||||
SetMessageHandler(&Module2500::handleMessage);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, _vm->gameState().which);
|
||||
else
|
||||
createScene(0, 0);
|
||||
|
||||
loadSound(0, 0x00880CCC);
|
||||
loadSound(1, 0x00880CC0);
|
||||
loadSound(2, 0x00880CCC);
|
||||
loadSound(3, 0x00880CC0);
|
||||
|
||||
}
|
||||
|
||||
Module2500::~Module2500() {
|
||||
_vm->_soundMan->deleteMusicGroup(0x29220120);
|
||||
}
|
||||
|
||||
void Module2500::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module2500::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene2501(_vm, this, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_vm->gameState().which = which;
|
||||
createScene2704(which, 0x004B01B8, 220);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
_vm->gameState().which = which;
|
||||
if (getGlobalVar(V_WORLDS_JOINED))
|
||||
createScene2704(which, 0x004B01E0, 150);
|
||||
else
|
||||
createScene2704(which, 0x004B0208, 150);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
_childObject = new Scene2504(_vm, this, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_vm->gameState().which = which;
|
||||
createScene2704(which, 0x004B0230, 150, kScene2505StaticSprites, &kScene2505ClipRect);
|
||||
break;
|
||||
case 5:
|
||||
setGlobalVar(V_CAR_DELTA_X, 1);
|
||||
_vm->gameState().sceneNum = 5;
|
||||
_vm->gameState().which = which;
|
||||
createScene2704(which, 0x004B0268, 150, kScene2506StaticSprites, &kScene2506ClipRect);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
_vm->gameState().which = which;
|
||||
createScene2704(which, 0x004B02A0, 150);
|
||||
break;
|
||||
case 7:
|
||||
_vm->gameState().sceneNum = 7;
|
||||
_vm->gameState().which = which;
|
||||
if (getGlobalVar(V_ENTRANCE_OPEN))
|
||||
createScene2704(which, 0x004B02C8, 150, kScene2508StaticSprites1, &kScene2508ClipRect1);
|
||||
else
|
||||
createScene2704(which, 0x004B02C8, 150, kScene2508StaticSprites2, &kScene2508ClipRect2);
|
||||
break;
|
||||
case 8:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
_childObject = new Scene1608(_vm, this, which);
|
||||
break;
|
||||
case 9:
|
||||
_vm->gameState().sceneNum = 9;
|
||||
if (getGlobalVar(V_ENTRANCE_OPEN))
|
||||
createStaticScene(0xC62A0645, 0xA0641C6A);
|
||||
else
|
||||
createStaticScene(0x7A343546, 0x435427AB);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module2500::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module2500::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(2, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(1, 0);
|
||||
else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 1)
|
||||
createScene(3, -1);
|
||||
else
|
||||
createScene(0, 2);
|
||||
break;
|
||||
case 2:
|
||||
if (_moduleResult == 1)
|
||||
createScene(4, 0);
|
||||
else
|
||||
createScene(0, 1);
|
||||
break;
|
||||
case 3:
|
||||
createScene(1, 1);
|
||||
break;
|
||||
case 4:
|
||||
if (_moduleResult == 1)
|
||||
createScene(5, 0);
|
||||
else
|
||||
createScene(2, 1);
|
||||
break;
|
||||
case 5:
|
||||
if (_moduleResult == 1)
|
||||
createScene(6, 0);
|
||||
else
|
||||
createScene(4, 1);
|
||||
break;
|
||||
case 6:
|
||||
if (_moduleResult == 1)
|
||||
createScene(7, 0);
|
||||
else
|
||||
createScene(5, 1);
|
||||
break;
|
||||
case 7:
|
||||
if (_moduleResult == 1)
|
||||
createScene(8, 1);
|
||||
else
|
||||
createScene(6, 1);
|
||||
break;
|
||||
case 8:
|
||||
if (_moduleResult == 2)
|
||||
createScene(9, -1);
|
||||
else
|
||||
createScene(7, 1);
|
||||
break;
|
||||
case 9:
|
||||
createScene(8, 2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Module2500::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Module::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x200D:
|
||||
playSound(_soundIndex);
|
||||
_soundIndex++;
|
||||
if (_soundIndex >= 4)
|
||||
_soundIndex = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void Module2500::createScene2704(int which, uint32 sceneInfoId, int16 value, const uint32 *staticSprites, const NRect *clipRect) {
|
||||
_childObject = new Scene2704(_vm, this, which, sceneInfoId, value, staticSprites, clipRect);
|
||||
}
|
||||
|
||||
Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B2628));
|
||||
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B264C));
|
||||
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B2670));
|
||||
|
||||
setGlobalVar(V_CAR_DELTA_X, 1);
|
||||
SetUpdateHandler(&Scene2501::update);
|
||||
setBackground(0x1B8E8115);
|
||||
setPalette(0x1B8E8115);
|
||||
_palette->addPalette(0x00128842, 65, 31, 65);
|
||||
_palette->addPalette("paKlayRed", 0, 64, 0);
|
||||
insertScreenMouse(0xE81111B0);
|
||||
|
||||
_ssTrackShadowBackground = createSprite<SsCommonTrackShadowBackground>(0x99BE9015); // Don't add this to the sprite list
|
||||
addEntity(_ssTrackShadowBackground);
|
||||
_asCar = createSprite<AsCommonCar>(this, 211, 400); // Create but don't add to the sprite list yet
|
||||
_asIdleCarLower = insertSprite<AsCommonIdleCarLower>(211, 400);
|
||||
_asIdleCarFull = insertSprite<AsCommonIdleCarFull>(211, 400);
|
||||
insertStaticSprite(0xC42AC521, 1500);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene2501>(162, 393);
|
||||
_kmScene2501 = _klaymen;
|
||||
_klaymenInCar = false;
|
||||
setMessageList(0x004B2538);
|
||||
setRectList(0x004B2608);
|
||||
SetMessageHandler(&Scene2501::handleMessage);
|
||||
SetUpdateHandler(&Scene2501::update);
|
||||
sendMessage(_asCar, NM_CAR_ENTER, 0);
|
||||
_asCar->setVisible(false);
|
||||
_currTrackIndex = 0;
|
||||
} else if (which == 1 || which == 2) {
|
||||
// 1: Klaymen entering riding the car on the left track
|
||||
// 2: Klaymen entering riding the car on the bottom track
|
||||
addSprite(_asCar);
|
||||
_kmScene2501 = (Klaymen*)new KmScene2501(_vm, this, 275, 393);
|
||||
_klaymenInCar = true;
|
||||
sendMessage(_kmScene2501, 0x2000, 1);
|
||||
_kmScene2501->setDoDeltaX(1);
|
||||
SetMessageHandler(&Scene2501::hmRidingCar);
|
||||
SetUpdateHandler(&Scene2501::upRidingCar);
|
||||
_asIdleCarLower->setVisible(false);
|
||||
_asIdleCarFull->setVisible(false);
|
||||
_currTrackIndex = which;
|
||||
} else {
|
||||
// Klaymen entering the car
|
||||
insertKlaymen<KmScene2501>(162, 393);
|
||||
_kmScene2501 = _klaymen;
|
||||
_klaymenInCar = false;
|
||||
setMessageList(0x004B2538);
|
||||
setRectList(0x004B2608);
|
||||
SetMessageHandler(&Scene2501::handleMessage);
|
||||
SetUpdateHandler(&Scene2501::update);
|
||||
sendMessage(_asCar, NM_CAR_ENTER, 0);
|
||||
_asCar->setVisible(false);
|
||||
_currTrackIndex = 0;
|
||||
}
|
||||
|
||||
_asCarShadow = insertSprite<AsCommonCarShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4);
|
||||
_asCarTrackShadow = insertSprite<AsCommonCarTrackShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4);
|
||||
_asCarConnectorShadow = insertSprite<AsCommonCarConnectorShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4);
|
||||
insertSprite<AsCommonCarConnector>(_asCar);
|
||||
|
||||
_newTrackIndex = -1;
|
||||
_dataResource.load(calcHash("Ashooded"));
|
||||
|
||||
_trackPoints = _dataResource.getPointArray(_tracks[_currTrackIndex]->trackPointsName);
|
||||
_asCar->setPathPoints(_trackPoints);
|
||||
|
||||
if (which >= 0 && _tracks[_currTrackIndex]->which2 == which) {
|
||||
NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1];
|
||||
sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
|
||||
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
|
||||
sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
|
||||
} else {
|
||||
NPoint testPoint = (*_trackPoints)[0];
|
||||
sendMessage(_asCar, NM_POSITION_CHANGE, 0);
|
||||
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
|
||||
sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
|
||||
}
|
||||
|
||||
_carStatus = 0;
|
||||
|
||||
}
|
||||
|
||||
Scene2501::~Scene2501() {
|
||||
// Free sprites not currently in the sprite list
|
||||
if (_klaymenInCar)
|
||||
delete _kmScene2501;
|
||||
else
|
||||
delete _asCar;
|
||||
}
|
||||
|
||||
void Scene2501::update() {
|
||||
Scene::update();
|
||||
if (_carStatus == 1) {
|
||||
removeSprite(_klaymen);
|
||||
addSprite(_asCar);
|
||||
clearRectList();
|
||||
_klaymenInCar = true;
|
||||
SetMessageHandler(&Scene2501::hmCarAtHome);
|
||||
SetUpdateHandler(&Scene2501::upCarAtHome);
|
||||
_asIdleCarLower->setVisible(false);
|
||||
_asIdleCarFull->setVisible(false);
|
||||
_asCar->setVisible(true);
|
||||
sendMessage(_asCar, NM_CAR_ENTER, 0);
|
||||
_asCar->handleUpdate();
|
||||
_klaymen = nullptr;
|
||||
_carStatus = 0;
|
||||
}
|
||||
updateKlaymenClipRect();
|
||||
}
|
||||
|
||||
void Scene2501::upCarAtHome() {
|
||||
Scene::update();
|
||||
if (_mouseClicked) {
|
||||
if (_mouseClickPos.x <= 210 && _asCar->getX() == 211 && _asCar->getY() == 400) {
|
||||
sendMessage(_asCar, NM_CAR_LEAVE, 0);
|
||||
SetUpdateHandler(&Scene2501::upGettingOutOfCar);
|
||||
} else {
|
||||
moveCarToPoint(_mouseClickPos);
|
||||
SetMessageHandler(&Scene2501::hmRidingCar);
|
||||
SetUpdateHandler(&Scene2501::upRidingCar);
|
||||
}
|
||||
_mouseClicked = false;
|
||||
}
|
||||
updateKlaymenClipRect();
|
||||
}
|
||||
|
||||
void Scene2501::upGettingOutOfCar() {
|
||||
Scene::update();
|
||||
if (_carStatus == 2) {
|
||||
_klaymen = _kmScene2501;
|
||||
removeSprite(_asCar);
|
||||
addSprite(_klaymen);
|
||||
_klaymenInCar = false;
|
||||
SetMessageHandler(&Scene2501::handleMessage);
|
||||
SetUpdateHandler(&Scene2501::update);
|
||||
setRectList(0x004B2608);
|
||||
_asIdleCarLower->setVisible(true);
|
||||
_asIdleCarFull->setVisible(true);
|
||||
_asCar->setVisible(false);
|
||||
setMessageList(0x004B2570);
|
||||
processMessageList();
|
||||
_klaymen->handleUpdate();
|
||||
_carStatus = 0;
|
||||
}
|
||||
updateKlaymenClipRect();
|
||||
}
|
||||
|
||||
void Scene2501::upRidingCar() {
|
||||
Scene::update();
|
||||
if (_mouseClicked) {
|
||||
moveCarToPoint(_mouseClickPos);
|
||||
_mouseClicked = false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene2501::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x60842040)
|
||||
_carStatus = 1;
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 Scene2501::hmRidingCar(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_KLAYMEN_CLIMB_LADDER:
|
||||
if (_tracks[_currTrackIndex]->which1 < 0 && _newTrackIndex >= 0)
|
||||
changeTrack();
|
||||
else if (_tracks[_currTrackIndex]->which1 == 0) {
|
||||
SetMessageHandler(&Scene2501::hmCarAtHome);
|
||||
SetUpdateHandler(&Scene2501::upCarAtHome);
|
||||
sendMessage(_asCar, NM_CAR_AT_HOME, 1);
|
||||
} else if (_tracks[_currTrackIndex]->which1 > 0)
|
||||
leaveScene(_tracks[_currTrackIndex]->which1);
|
||||
break;
|
||||
case NM_KLAYMEN_STOP_CLIMBING:
|
||||
if (_tracks[_currTrackIndex]->which2 < 0 && _newTrackIndex >= 0)
|
||||
changeTrack();
|
||||
else if (_tracks[_currTrackIndex]->which2 == 0) {
|
||||
SetMessageHandler(&Scene2501::hmCarAtHome);
|
||||
SetUpdateHandler(&Scene2501::upCarAtHome);
|
||||
sendMessage(_asCar, NM_CAR_AT_HOME, 1);
|
||||
} else if (_tracks[_currTrackIndex]->which2 > 0)
|
||||
leaveScene(_tracks[_currTrackIndex]->which2);
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 Scene2501::hmCarAtHome(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_CAR_LEAVE:
|
||||
_carStatus = 2;
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void Scene2501::moveCarToPoint(NPoint &pt) {
|
||||
int minMatchTrackIndex, minMatchDistance;
|
||||
_tracks.findTrackPoint(pt, minMatchTrackIndex, minMatchDistance, _dataResource);
|
||||
if (minMatchTrackIndex >= 0 && minMatchTrackIndex != _currTrackIndex) {
|
||||
_newTrackIndex = minMatchTrackIndex;
|
||||
_clickPoint = pt;
|
||||
if (_currTrackIndex == 0)
|
||||
sendMessage(_asCar, 0x2003, _trackPoints->size() - 1);
|
||||
else
|
||||
sendMessage(_asCar, 0x2003, 0);
|
||||
} else {
|
||||
_newTrackIndex = -1;
|
||||
sendMessage(_asCar, 0x2004, pt);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene2501::changeTrack() {
|
||||
_currTrackIndex = _newTrackIndex;
|
||||
_trackPoints = _dataResource.getPointArray(_tracks[_currTrackIndex]->trackPointsName);
|
||||
_asCar->setPathPoints(_trackPoints);
|
||||
if (_currTrackIndex == 0)
|
||||
sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
|
||||
else
|
||||
sendMessage(_asCar, NM_POSITION_CHANGE, 0);
|
||||
sendPointMessage(_asCar, 0x2004, _clickPoint);
|
||||
_newTrackIndex = -1;
|
||||
}
|
||||
|
||||
void Scene2501::updateKlaymenClipRect() {
|
||||
if (_kmScene2501->getX() <= 211)
|
||||
_kmScene2501->setClipRect(0, 0, 640, 480);
|
||||
else
|
||||
_kmScene2501->setClipRect(0, 0, 640, 388);
|
||||
}
|
||||
|
||||
Scene2504::Scene2504(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
Sprite *ssButton;
|
||||
|
||||
setBackground(0x90791B80);
|
||||
setPalette(0x90791B80);
|
||||
ssButton = insertSprite<SsScene2504Button>();
|
||||
addCollisionSprite(ssButton);
|
||||
insertPuzzleMouse(0x91B8490F, 20, 620);
|
||||
SetMessageHandler(&Scene2504::handleMessage);
|
||||
SetUpdateHandler(&Scene::update);
|
||||
}
|
||||
|
||||
uint32 Scene2504::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
|
||||
leaveScene(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
88
engines/neverhood/modules/module2500.h
Normal file
88
engines/neverhood/modules/module2500.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2500_H
|
||||
#define NEVERHOOD_MODULES_MODULE2500_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/modules/module1600_sprites.h" // for Tracks
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module2500 : public Module {
|
||||
public:
|
||||
Module2500(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2500() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
int _soundIndex;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createScene2704(int which, uint32 sceneInfoId, int16 value, const uint32 *staticSprites = NULL, const NRect *clipRect = NULL);
|
||||
};
|
||||
|
||||
class AsCommonCar;
|
||||
|
||||
class Scene2501 : public Scene {
|
||||
public:
|
||||
Scene2501(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2501() override;
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_ssTrackShadowBackground;
|
||||
Sprite *_asCarShadow;
|
||||
Sprite *_asCarConnectorShadow;
|
||||
Sprite *_asCarTrackShadow;
|
||||
Sprite *_asIdleCarLower;
|
||||
Sprite *_asIdleCarFull;
|
||||
Klaymen *_kmScene2501;
|
||||
Tracks _tracks;
|
||||
NPointArray *_trackPoints;
|
||||
int _currTrackIndex;
|
||||
NPoint _clickPoint;
|
||||
int _newTrackIndex;
|
||||
int _carStatus;
|
||||
bool _klaymenInCar;
|
||||
void update();
|
||||
void upCarAtHome();
|
||||
void upGettingOutOfCar();
|
||||
void upRidingCar();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmRidingCar(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmCarAtHome(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void moveCarToPoint(NPoint &pt);
|
||||
void changeTrack();
|
||||
void updateKlaymenClipRect();
|
||||
};
|
||||
|
||||
class Scene2504 : public Scene {
|
||||
public:
|
||||
Scene2504(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2500_H */
|
||||
130
engines/neverhood/modules/module2500_sprites.cpp
Normal file
130
engines/neverhood/modules/module2500_sprites.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2500_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
SsScene2504Button::SsScene2504Button(NeverhoodEngine *vm)
|
||||
: StaticSprite(vm, 1400), _countdown(0), _isSoundPlaying(false) {
|
||||
|
||||
loadSprite(0x070220D9, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
|
||||
setVisible(false);
|
||||
loadSound(0, 0x4600204C);
|
||||
loadSound(1, 0x408C0034);
|
||||
loadSound(2, 0x44043000);
|
||||
loadSound(3, 0x44045000);
|
||||
SetMessageHandler(&SsScene2504Button::handleMessage);
|
||||
SetUpdateHandler(&SsScene2504Button::update);
|
||||
}
|
||||
|
||||
void SsScene2504Button::update() {
|
||||
updatePosition();
|
||||
if (_isSoundPlaying && !isSoundPlaying(0) && !isSoundPlaying(1)) {
|
||||
playSound(3);
|
||||
setVisible(false);
|
||||
_isSoundPlaying = false;
|
||||
}
|
||||
if (_countdown != 0 && (--_countdown) == 0) {
|
||||
if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
|
||||
playSound(0);
|
||||
else
|
||||
playSound(1);
|
||||
_isSoundPlaying = true;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene2504Button::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_countdown == 0 && !_isSoundPlaying) {
|
||||
setVisible(true);
|
||||
_countdown = 2;
|
||||
if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
|
||||
setSubVar(VA_LOCKS_DISABLED, 0x01180951, 0);
|
||||
else
|
||||
setSubVar(VA_LOCKS_DISABLED, 0x01180951, 1);
|
||||
playSound(2);
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene2501::KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2000, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
50
engines/neverhood/modules/module2500_sprites.h
Normal file
50
engines/neverhood/modules/module2500_sprites.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2500_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2500_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class SsScene2504Button : public StaticSprite {
|
||||
public:
|
||||
SsScene2504Button(NeverhoodEngine *vm);
|
||||
protected:
|
||||
int _countdown;
|
||||
bool _isSoundPlaying;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene2501 : public Klaymen {
|
||||
public:
|
||||
KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2500_SPRITES_H */
|
||||
266
engines/neverhood/modules/module2600.cpp
Normal file
266
engines/neverhood/modules/module2600.cpp
Normal file
@@ -0,0 +1,266 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2600.h"
|
||||
#include "neverhood/modules/module2600_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule2600SoundList[] = {
|
||||
0xB288D450,
|
||||
0x90804450,
|
||||
0x99801500,
|
||||
0xB288D455,
|
||||
0x93825040,
|
||||
0
|
||||
};
|
||||
|
||||
Module2600::Module2600(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 1)
|
||||
createScene(4, 1);
|
||||
else
|
||||
createScene(0, 1);
|
||||
|
||||
_vm->_soundMan->addSoundList(0x40271018, kModule2600SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule2600SoundList, true, 50, 600, 5, 150);
|
||||
_vm->_soundMan->playTwoSounds(0x40271018, 0x41861371, 0x43A2507F, 0);
|
||||
|
||||
}
|
||||
|
||||
Module2600::~Module2600() {
|
||||
_vm->_soundMan->deleteGroup(0x40271018);
|
||||
}
|
||||
|
||||
void Module2600::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module2600::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
createNavigationScene(0x004B8608, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
createNavigationScene(0x004B8638, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
createNavigationScene(0x004B86C8, which);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
if (getGlobalVar(V_CREATURE_ANGRY))
|
||||
createNavigationScene(0x004B8758, which);
|
||||
else
|
||||
createNavigationScene(0x004B86F8, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
createNavigationScene(0x004B87B8, which);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
createNavigationScene(0x004B8698, which);
|
||||
break;
|
||||
case 7:
|
||||
_vm->gameState().sceneNum = 7;
|
||||
_vm->_soundMan->deleteGroup(0x40271018);
|
||||
createSmackerScene(0x30090001, true, true, false);
|
||||
break;
|
||||
case 8:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
_childObject = new Scene2609(_vm, this, which);
|
||||
break;
|
||||
case 1002:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
if (getGlobalVar(V_FRUIT_COUNTING_INDEX) == 1)
|
||||
createSmackerScene(0x018C0404, true, true, false);
|
||||
else if (getGlobalVar(V_FRUIT_COUNTING_INDEX) == 2)
|
||||
createSmackerScene(0x018C0407, true, true, false);
|
||||
else
|
||||
createSmackerScene(0x818C0405, true, true, false);
|
||||
if (getGlobalVar(V_FRUIT_COUNTING_INDEX) >= 2)
|
||||
setGlobalVar(V_FRUIT_COUNTING_INDEX, 0);
|
||||
else
|
||||
incGlobalVar(V_FRUIT_COUNTING_INDEX, +1);
|
||||
break;
|
||||
case 1003:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
createSmackerScene(0x001C0007, true, true, false);
|
||||
break;
|
||||
case 1006:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
if (getGlobalVar(V_WATER_RUNNING))
|
||||
createSmackerScene(0x049A1181, true, true, false);
|
||||
else
|
||||
createSmackerScene(0x04981181, true, true, false);
|
||||
break;
|
||||
case 1008:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
if (getGlobalVar(V_WATER_RUNNING))
|
||||
createSmackerScene(0x42B80941, true, true, false);
|
||||
else
|
||||
createSmackerScene(0x42980941, true, true, false);
|
||||
break;
|
||||
case 9999:
|
||||
createDemoScene();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module2600::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module2600::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(1, 3);
|
||||
else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 0)
|
||||
createScene(6, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(0, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(2, 1);
|
||||
else if (_moduleResult == 3)
|
||||
createScene(3, 0);
|
||||
break;
|
||||
case 2:
|
||||
if (_moduleResult == 0)
|
||||
createScene(1, 0);
|
||||
else if (_moduleResult == 1) {
|
||||
if (_vm->isDemo())
|
||||
createScene(9999, -1);
|
||||
else
|
||||
createScene(1002, -1);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 0) {
|
||||
if (getGlobalVar(V_CREATURE_ANGRY))
|
||||
createScene(4, 0);
|
||||
else
|
||||
createScene(1003, -1);
|
||||
} else if (_moduleResult == 2)
|
||||
createScene(1, 1);
|
||||
else if (_moduleResult == 3) {
|
||||
if (getGlobalVar(V_CREATURE_ANGRY))
|
||||
createScene(4, 0);
|
||||
else {
|
||||
setGlobalVar(V_CREATURE_ANGRY, 1);
|
||||
createScene(7, -1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (_moduleResult == 0)
|
||||
leaveModule(1);
|
||||
else
|
||||
createScene(3, 1);
|
||||
break;
|
||||
case 6:
|
||||
if (_moduleResult == 0) {
|
||||
if (_vm->isDemo())
|
||||
createScene(9999, -1);
|
||||
else
|
||||
createScene(1006, -1);
|
||||
}
|
||||
else if (_moduleResult == 1)
|
||||
createScene(1, 2);
|
||||
break;
|
||||
case 7:
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 8:
|
||||
createScene(1008, -1);
|
||||
break;
|
||||
case 1002:
|
||||
createScene(2, 1);
|
||||
break;
|
||||
case 1003:
|
||||
createScene(3, 0);
|
||||
break;
|
||||
case 1006:
|
||||
createScene(8, -1);
|
||||
break;
|
||||
case 1008:
|
||||
createScene(6, 0);
|
||||
break;
|
||||
case 9999:
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene2609::Scene2609(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _isBusy(false) {
|
||||
|
||||
SetUpdateHandler(&Scene::update);
|
||||
SetMessageHandler(&Scene2609::handleMessage);
|
||||
|
||||
setBackground(0x51409A16);
|
||||
setPalette(0x51409A16);
|
||||
_asWater = insertSprite<AsScene2609Water>();
|
||||
_ssButton = insertSprite<SsScene2609Button>(this);
|
||||
addCollisionSprite(_ssButton);
|
||||
insertPuzzleMouse(0x09A1251C, 20, 620);
|
||||
insertStaticSprite(0x02138002, 1200);
|
||||
insertStaticSprite(0x825E2827, 1200);
|
||||
}
|
||||
|
||||
uint32 Scene2609::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !_isBusy)
|
||||
leaveScene(0);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isBusy = true;
|
||||
break;
|
||||
case 0x2001:
|
||||
_isBusy = false;
|
||||
sendMessage(_asWater, 0x2001, 0);
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
_isBusy = false;
|
||||
sendMessage(_asWater, NM_POSITION_CHANGE, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
55
engines/neverhood/modules/module2600.h
Normal file
55
engines/neverhood/modules/module2600.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2600_H
|
||||
#define NEVERHOOD_MODULES_MODULE2600_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module2600
|
||||
|
||||
class Module2600 : public Module {
|
||||
public:
|
||||
Module2600(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2600() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene2609 : public Scene {
|
||||
public:
|
||||
Scene2609(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
bool _isBusy;
|
||||
Sprite *_asWater;
|
||||
Sprite *_ssButton;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2600_H */
|
||||
118
engines/neverhood/modules/module2600_sprites.cpp
Normal file
118
engines/neverhood/modules/module2600_sprites.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2600_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
SsScene2609Button::SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
|
||||
|
||||
SetUpdateHandler(&SsScene2609Button::update);
|
||||
SetMessageHandler(&SsScene2609Button::handleMessage);
|
||||
|
||||
loadSprite(0x825A6923, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
|
||||
if (!getGlobalVar(V_WATER_RUNNING))
|
||||
setVisible(false);
|
||||
loadSound(0, 0x10267160);
|
||||
loadSound(1, 0x7027FD64);
|
||||
loadSound(2, 0x44043000);
|
||||
loadSound(3, 0x44045000);
|
||||
}
|
||||
|
||||
void SsScene2609Button::update() {
|
||||
updatePosition();
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
if (getGlobalVar(V_WATER_RUNNING)) {
|
||||
setGlobalVar(V_WATER_RUNNING, 0);
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
} else {
|
||||
setGlobalVar(V_WATER_RUNNING, 1);
|
||||
sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene2609Button::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_countdown == 0) {
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
if (getGlobalVar(V_WATER_RUNNING)) {
|
||||
setVisible(false);
|
||||
playSound(3);
|
||||
playSound(1);
|
||||
_countdown = 12;
|
||||
} else {
|
||||
setVisible(true);
|
||||
playSound(2);
|
||||
playSound(0);
|
||||
_countdown = 96;
|
||||
}
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene2609Water::AsScene2609Water(NeverhoodEngine *vm)
|
||||
: AnimatedSprite(vm, 1000) {
|
||||
|
||||
_x = 240;
|
||||
_y = 420;
|
||||
setDoDeltaX(1);
|
||||
createSurface1(0x9C210C90, 1200);
|
||||
setClipRect(260, 260, 400, 368);
|
||||
_vm->_soundMan->addSound(0x08526C36, 0xDC2769B0);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene2609Water::handleMessage);
|
||||
if (getGlobalVar(V_WATER_RUNNING))
|
||||
sendMessage(this, NM_POSITION_CHANGE, 0);
|
||||
}
|
||||
|
||||
AsScene2609Water::~AsScene2609Water() {
|
||||
_vm->_soundMan->deleteSoundGroup(0x08526C36);
|
||||
}
|
||||
|
||||
uint32 AsScene2609Water::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x2001:
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
_vm->_soundMan->stopSound(0xDC2769B0);
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
startAnimation(0x9C210C90, 0, -1);
|
||||
setVisible(true);
|
||||
_vm->_soundMan->playSoundLooping(0xDC2769B0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
53
engines/neverhood/modules/module2600_sprites.h
Normal file
53
engines/neverhood/modules/module2600_sprites.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2600_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2600_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module2600
|
||||
|
||||
class SsScene2609Button : public StaticSprite {
|
||||
public:
|
||||
SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2609Water : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2609Water(NeverhoodEngine *vm);
|
||||
~AsScene2609Water() override;
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2600_SPRITES_H */
|
||||
1155
engines/neverhood/modules/module2700.cpp
Normal file
1155
engines/neverhood/modules/module2700.cpp
Normal file
File diff suppressed because it is too large
Load Diff
150
engines/neverhood/modules/module2700.h
Normal file
150
engines/neverhood/modules/module2700.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2700_H
|
||||
#define NEVERHOOD_MODULES_MODULE2700_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/modules/module1600_sprites.h" // for Tracks
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module2700
|
||||
|
||||
class Module2700 : public Module {
|
||||
public:
|
||||
Module2700(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2700() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
int _soundIndex;
|
||||
bool _radioMusicInitialized;
|
||||
uint32 _scene2711StaticSprites[6];
|
||||
uint32 _musicFileHash;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createScene2703(int which, uint32 trackInfoId);
|
||||
void createScene2704(int which, uint32 trackInfoId, int16 value, const uint32 *staticSprites = NULL, const NRect *clipRect = NULL);
|
||||
};
|
||||
|
||||
class AsCommonCar;
|
||||
|
||||
class Scene2701 : public Scene {
|
||||
public:
|
||||
Scene2701(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_ssTrackShadowBackground;
|
||||
Sprite *_asCarShadow;
|
||||
Sprite *_asCarTrackShadow;
|
||||
Sprite *_asCarConnectorShadow;
|
||||
Sprite *_asCarConnector;
|
||||
int _which1, _which2;
|
||||
NPointArray *_trackPoints;
|
||||
uint32 hmRidingCar(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmCarAtHome(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2702 : public Scene {
|
||||
public:
|
||||
Scene2702(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_ssTrackShadowBackground;
|
||||
Sprite *_asCarShadow;
|
||||
Sprite *_asCarTrackShadow;
|
||||
Sprite *_asCarConnectorShadow;
|
||||
NPoint _newTrackDest;
|
||||
bool _isInLight;
|
||||
int _currTrackIndex, _newTrackIndex;
|
||||
bool _isUpperTrack;
|
||||
Tracks _tracks;
|
||||
NPointArray *_trackPoints;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void moveCarToPoint(NPoint pt);
|
||||
void changeTrack();
|
||||
};
|
||||
|
||||
class Scene2703 : public Scene {
|
||||
public:
|
||||
Scene2703(NeverhoodEngine *vm, Module *parentModule, int which, uint32 trackInfoId);
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_ssTrackShadowBackground;
|
||||
Sprite *_asCarShadow;
|
||||
Sprite *_asCarConnector;
|
||||
Sprite *_asCarTrackShadow;
|
||||
Sprite *_asCarConnectorShadow;
|
||||
int _palStatus;
|
||||
int _which1, _which2;
|
||||
NPointArray *_trackPoints;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2704 : public Scene {
|
||||
public:
|
||||
Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint32 trackInfoId, int16 value,
|
||||
const uint32 *staticSprites = NULL, const NRect *clipRect = NULL);
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_ssTrackShadowBackground;
|
||||
Sprite *_asCarShadow;
|
||||
Sprite *_asCarConnector;
|
||||
Sprite *_asCarTrackShadow;
|
||||
Sprite *_asCarConnectorShadow;
|
||||
int _which1, _which2;
|
||||
NPointArray *_trackPoints;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2706 : public Scene {
|
||||
public:
|
||||
Scene2706(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_ssTrackShadowBackground;
|
||||
Sprite *_asCarShadow;
|
||||
Sprite *_asCarConnector;
|
||||
Sprite *_asCarTrackShadow;
|
||||
Sprite *_asCarConnectorShadow;
|
||||
NPoint _newTrackDest;
|
||||
int _currTrackIndex, _newTrackIndex;
|
||||
Tracks _tracks;
|
||||
NPointArray *_trackPoints;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void moveCarToPoint(NPoint pt);
|
||||
void changeTrack();
|
||||
};
|
||||
|
||||
class Scene2732 : public Scene {
|
||||
public:
|
||||
Scene2732(NeverhoodEngine *vm, Module *parentModule);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2700_H */
|
||||
123
engines/neverhood/modules/module2700_sprites.cpp
Normal file
123
engines/neverhood/modules/module2700_sprites.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2700_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const NPoint kCarShadowOffsets[] = {
|
||||
{-63, 3}, {-48, 40}, {-33, 58},
|
||||
{ 0, 65}, { 40, 53}, { 56, 27},
|
||||
{ 63, 0}, {-30, 26}, { 0, 30},
|
||||
{ 26, 25}
|
||||
};
|
||||
|
||||
SsCommonTrackShadowBackground::SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash)
|
||||
: StaticSprite(vm, 0) {
|
||||
|
||||
loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition, 0);
|
||||
}
|
||||
|
||||
AsCommonCarShadow::AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, const Common::SharedPtr<BaseSurface> &shadowSurface, uint index)
|
||||
: AnimatedSprite(vm, 1100), _asCar(asCar), _index(index), _animFileHash(0) {
|
||||
|
||||
SetUpdateHandler(&AsCommonCarShadow::update);
|
||||
createShadowSurface(shadowSurface, 211, 147, 100);
|
||||
updateShadow();
|
||||
}
|
||||
|
||||
void AsCommonCarShadow::update() {
|
||||
updateShadow();
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
void AsCommonCarShadow::updateShadow() {
|
||||
if (_asCar->getFrameIndex() != _currFrameIndex || _asCar->getCurrAnimFileHash() != _animFileHash) {
|
||||
uint32 fileHash = _asCar->getCurrAnimFileHash();
|
||||
if (fileHash == 0x35698F78 || fileHash == 0x192ADD30 || fileHash == 0x9C220DA4 ||
|
||||
fileHash == 0x9966B138 || fileHash == 0xB579A77C || fileHash == 0xA86A9538 ||
|
||||
fileHash == 0xD4220027 || fileHash == 0xD00A1364 || fileHash == 0xD4AA03A4 ||
|
||||
fileHash == 0xF46A0324) {
|
||||
startAnimation(fileHash, _asCar->getFrameIndex(), -1);
|
||||
_newStickFrameIndex = _asCar->getFrameIndex();
|
||||
}
|
||||
_animFileHash = fileHash;
|
||||
}
|
||||
_x = _asCar->getX() + kCarShadowOffsets[_index].x;
|
||||
_y = _asCar->getY() + kCarShadowOffsets[_index].y;
|
||||
if (!_asCar->getVisible()) {
|
||||
startAnimation(0x1209E09F, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
setDoDeltaX(_asCar->isDoDeltaX() ? 1 : 0);
|
||||
}
|
||||
|
||||
AsCommonCarConnectorShadow::AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, const Common::SharedPtr<BaseSurface> &shadowSurface, uint index)
|
||||
: AnimatedSprite(vm, 1100), _asCar(asCar), _index(index) {
|
||||
|
||||
SetUpdateHandler(&AsCommonCarConnectorShadow::update);
|
||||
createShadowSurface1(shadowSurface, 0x60281C10, 150);
|
||||
startAnimation(0x60281C10, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
|
||||
void AsCommonCarConnectorShadow::update() {
|
||||
_x = _asCar->getX() + kCarShadowOffsets[_index].x;
|
||||
_y = _asCar->getY() + kCarShadowOffsets[_index].y;
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
AsCommonCarTrackShadow::AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, const Common::SharedPtr<BaseSurface> &shadowSurface, int16 frameIndex)
|
||||
: AnimatedSprite(vm, 1100), _asCar(asCar) {
|
||||
|
||||
SetUpdateHandler(&AsCommonCarTrackShadow::update);
|
||||
createShadowSurface1(shadowSurface, 0x0759129C, 100);
|
||||
startAnimation(0x0759129C, frameIndex, -1);
|
||||
_newStickFrameIndex = frameIndex;
|
||||
}
|
||||
|
||||
void AsCommonCarTrackShadow::update() {
|
||||
_x = _asCar->getX();
|
||||
_y = _asCar->getY();
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
KmScene2732::KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene2732::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4804:
|
||||
GotoState(&Klaymen::stPeekInside);
|
||||
break;
|
||||
case 0x483C:
|
||||
GotoState(&Klaymen::stPeekInsideReturn);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
73
engines/neverhood/modules/module2700_sprites.h
Normal file
73
engines/neverhood/modules/module2700_sprites.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2700_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2700_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class SsCommonTrackShadowBackground : public StaticSprite {
|
||||
public:
|
||||
SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash);
|
||||
};
|
||||
|
||||
class AsCommonCarShadow : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, const Common::SharedPtr<BaseSurface> &shadowSurface, uint index);
|
||||
protected:
|
||||
uint _index;
|
||||
AnimatedSprite *_asCar;
|
||||
uint32 _animFileHash;
|
||||
void update();
|
||||
void updateShadow();
|
||||
};
|
||||
|
||||
class AsCommonCarConnectorShadow : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, const Common::SharedPtr<BaseSurface> &shadowSurface, uint index);
|
||||
protected:
|
||||
uint _index;
|
||||
Sprite *_asCar;
|
||||
void update();
|
||||
};
|
||||
|
||||
class AsCommonCarTrackShadow : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, const Common::SharedPtr<BaseSurface> &shadowSurface, int16 frameIndex);
|
||||
protected:
|
||||
Sprite *_asCar;
|
||||
void update();
|
||||
};
|
||||
|
||||
class KmScene2732 : public Klaymen {
|
||||
public:
|
||||
KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2700_SPRITES_H */
|
||||
2174
engines/neverhood/modules/module2800.cpp
Normal file
2174
engines/neverhood/modules/module2800.cpp
Normal file
File diff suppressed because it is too large
Load Diff
278
engines/neverhood/modules/module2800.h
Normal file
278
engines/neverhood/modules/module2800.h
Normal file
@@ -0,0 +1,278 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2800_H
|
||||
#define NEVERHOOD_MODULES_MODULE2800_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module2800
|
||||
|
||||
class Module2800 : public Module {
|
||||
public:
|
||||
Module2800(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2800() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
uint32 _currentMusicFileHash;
|
||||
MusicResource *_musicResource;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
void updateMusic(bool halfVolume);
|
||||
};
|
||||
|
||||
class Scene2801 : public Scene {
|
||||
public:
|
||||
Scene2801(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2801() override;
|
||||
protected:
|
||||
Sprite *_asTape;
|
||||
uint32 _paletteHash;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2802 : public Scene {
|
||||
public:
|
||||
Scene2802(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2802() override;
|
||||
protected:
|
||||
SmackerPlayer *_smackerPlayer;
|
||||
uint _currRadioMusicIndex;
|
||||
int _currTuneStatus;
|
||||
int _countdown1;
|
||||
int _countdown2;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void incRadioMusicIndex(int delta);
|
||||
void changeTuneStatus(int prevTuneStatus, int newTuneStatus);
|
||||
};
|
||||
|
||||
class AsScene2803LightCord;
|
||||
|
||||
class Scene2803 : public Scene {
|
||||
public:
|
||||
Scene2803(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
StaticSprite *_asTestTubeOne;
|
||||
StaticSprite *_asTestTubeTwo;
|
||||
StaticSprite *_asTestTubeThree;
|
||||
Sprite *_asRope;
|
||||
AsScene2803LightCord *_asLightCord;
|
||||
StaticSprite *_sprite3;
|
||||
StaticSprite *_sprite4;
|
||||
StaticSprite *_sprite5;
|
||||
StaticSprite *_sprite6;
|
||||
StaticSprite *_sprite7;
|
||||
StaticSprite *_sprite8;
|
||||
StaticSprite *_sprite9;
|
||||
Sprite *_sprite10;
|
||||
NRect _clipRectsFloor[2];
|
||||
NRect _clipRectsStairs[3];
|
||||
int _paletteArea;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void upKlaymenStairs();
|
||||
void klaymenStairs();
|
||||
void klaymenFloor();
|
||||
void toggleBackground();
|
||||
void changeBackground();
|
||||
void setPaletteArea0();
|
||||
void setPaletteArea1();
|
||||
void updatePaletteArea();
|
||||
};
|
||||
|
||||
class Scene2803Small : public Scene {
|
||||
public:
|
||||
Scene2803Small(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
int _paletteArea;
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
Sprite *_sprite4;
|
||||
Sprite *_sprite5;
|
||||
Sprite *_sprite6;
|
||||
Sprite *_sprite7;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void upKlaymenSlope();
|
||||
void upKlaymenFloor();
|
||||
void klaymenSlope();
|
||||
void klaymenFloor();
|
||||
void setPaletteArea0();
|
||||
void setPaletteArea1();
|
||||
void setPaletteArea2();
|
||||
void setPaletteArea3();
|
||||
void updatePaletteArea(bool instantly);
|
||||
};
|
||||
|
||||
class SsScene2804Flash;
|
||||
class AsScene2804Crystal;
|
||||
|
||||
class Scene2804 : public Scene {
|
||||
public:
|
||||
Scene2804(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
bool isWorking() const { return _isWorking; }
|
||||
protected:
|
||||
int _countdown1;
|
||||
int _countdown2;
|
||||
int _countdown3;
|
||||
int _beamStatus;
|
||||
bool _isSolved;
|
||||
bool _isWorking;
|
||||
Sprite *_ssRedButton;
|
||||
Sprite *_asCoil;
|
||||
Sprite *_asTarget;
|
||||
SsScene2804Flash *_ssFlash;
|
||||
AsScene2804Crystal *_asCrystals[5];
|
||||
Sprite *_ssCrystalButtons[5];
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2805 : public Scene {
|
||||
public:
|
||||
Scene2805(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2806 : public Scene {
|
||||
public:
|
||||
Scene2806(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
NPointArray *_pointList;
|
||||
int _pointIndex;
|
||||
NRect _clipRects[4];
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
Sprite *_sprite4;
|
||||
Sprite *_asSpew;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void update();
|
||||
void findClosestPoint();
|
||||
};
|
||||
|
||||
class Scene2807 : public Scene {
|
||||
public:
|
||||
Scene2807(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2808Flow;
|
||||
class AsScene2808TestTube;
|
||||
|
||||
class Scene2808 : public Scene {
|
||||
public:
|
||||
Scene2808(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
int _countdown;
|
||||
int _testTubeSetNum;
|
||||
AsScene2808Flow *_asFlow;
|
||||
int _leaveResult;
|
||||
bool _isFlowing;
|
||||
AsScene2808TestTube *_asTestTubes[3];
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void update();
|
||||
bool isMixtureGood();
|
||||
bool isAnyTestTubeFilled();
|
||||
};
|
||||
|
||||
class Scene2809 : public Scene {
|
||||
public:
|
||||
Scene2809(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
NPointArray *_pointList;
|
||||
int _pointIndex;
|
||||
NRect _clipRects[4];
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
Sprite *_sprite4;
|
||||
Sprite *_asSpew;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void findClosestPoint();
|
||||
};
|
||||
|
||||
class Scene2810 : public Scene {
|
||||
public:
|
||||
Scene2810(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2810() override;
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
Sprite *_asRope;
|
||||
Sprite *_sprite4;
|
||||
Sprite *_asTape;
|
||||
Sprite *_sprite5;
|
||||
Sprite *_sprite6;
|
||||
bool _isRopingDown;
|
||||
NRect _clipRects[2];
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void insertKlaymenLadder();
|
||||
};
|
||||
|
||||
class Scene2812 : public Scene {
|
||||
public:
|
||||
Scene2812(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_asWinch;
|
||||
Sprite *_asTrapDoor;
|
||||
Sprite *_asRope;
|
||||
Sprite *_sprite3;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite4;
|
||||
Sprite *_ssTape;
|
||||
Sprite *_asKey;
|
||||
Sprite *_sprite1;
|
||||
bool _isRopingDown;
|
||||
int _paletteArea;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void setPaletteArea0(bool instantly);
|
||||
void setPaletteArea1(bool instantly);
|
||||
void setPaletteArea2(bool instantly);
|
||||
void updatePaletteArea(bool instantly);
|
||||
};
|
||||
|
||||
class Scene2822 : public Scene {
|
||||
public:
|
||||
Scene2822(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_ssButton;
|
||||
int _scrollIndex;
|
||||
int _countdown;
|
||||
int _countdownStatus;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2800_H */
|
||||
1681
engines/neverhood/modules/module2800_sprites.cpp
Normal file
1681
engines/neverhood/modules/module2800_sprites.cpp
Normal file
File diff suppressed because it is too large
Load Diff
336
engines/neverhood/modules/module2800_sprites.h
Normal file
336
engines/neverhood/modules/module2800_sprites.h
Normal file
@@ -0,0 +1,336 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2800_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2800_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class AsScene2803LightCord : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y);
|
||||
void stPulled();
|
||||
void stIdle();
|
||||
void setFileHashes(uint32 fileHash1, uint32 fileHash2);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 _fileHash1, _fileHash2;
|
||||
bool _isPulled, _isBusy;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmPulled(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2803TestTubeOne : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2);
|
||||
protected:
|
||||
uint32 _fileHash1, _fileHash2;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2803Rope : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmReleased(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stReleased();
|
||||
void stHide();
|
||||
};
|
||||
|
||||
class Scene2804;
|
||||
|
||||
class SsScene2804RedButton : public StaticSprite {
|
||||
public:
|
||||
SsScene2804RedButton(NeverhoodEngine *vm, Scene2804 *parentScene);
|
||||
protected:
|
||||
Scene2804 *_parentScene;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsScene2804LightCoil : public StaticSprite {
|
||||
public:
|
||||
SsScene2804LightCoil(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsScene2804BeamCoilBody : public StaticSprite {
|
||||
public:
|
||||
SsScene2804BeamCoilBody(NeverhoodEngine *vm);
|
||||
};
|
||||
|
||||
class SsScene2804LightTarget : public StaticSprite {
|
||||
public:
|
||||
SsScene2804LightTarget(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsScene2804Flash : public StaticSprite {
|
||||
public:
|
||||
SsScene2804Flash(NeverhoodEngine *vm);
|
||||
void show();
|
||||
};
|
||||
|
||||
class AsScene2804CrystalWaves : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2804CrystalWaves(NeverhoodEngine *vm, uint crystalIndex);
|
||||
void show();
|
||||
void hide();
|
||||
protected:
|
||||
uint _crystalIndex;
|
||||
};
|
||||
|
||||
class AsScene2804Crystal : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2804Crystal(NeverhoodEngine *vm, AsScene2804CrystalWaves *asCrystalWaves, uint crystalIndex);
|
||||
void show();
|
||||
void hide();
|
||||
void activate();
|
||||
int16 getColorNum() const { return _colorNum; }
|
||||
protected:
|
||||
AsScene2804CrystalWaves *_asCrystalWaves;
|
||||
uint _crystalIndex;
|
||||
int16 _colorNum;
|
||||
bool _isLightOn;
|
||||
bool _isShowing;
|
||||
};
|
||||
|
||||
class SsScene2804CrystalButton : public StaticSprite {
|
||||
public:
|
||||
SsScene2804CrystalButton(NeverhoodEngine *vm, Scene2804 *parentScene, AsScene2804Crystal *asCrystal, uint crystalIndex);
|
||||
protected:
|
||||
Scene2804 *_parentScene;
|
||||
AsScene2804Crystal *_asCrystal;
|
||||
uint _crystalIndex;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2804BeamCoil : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody);
|
||||
~AsScene2804BeamCoil() override;
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
SsScene2804BeamCoilBody *_ssBeamCoilBody;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void show();
|
||||
void hide();
|
||||
void stBeaming();
|
||||
uint32 hmBeaming(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2804BeamTarget : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2804BeamTarget(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2806Spew : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2806Spew(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsScene2808Dispenser : public StaticSprite {
|
||||
public:
|
||||
SsScene2808Dispenser(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum, int testTubeIndex);
|
||||
void startCountdown(int index);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _countdown;
|
||||
int _testTubeSetNum, _testTubeIndex;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2808TestTube : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum, int testTubeIndex, SsScene2808Dispenser *ssDispenser);
|
||||
void fill();
|
||||
void flush();
|
||||
uint32 getFillLevel() const { return _fillLevel; }
|
||||
protected:
|
||||
SsScene2808Dispenser *_ssDispenser;
|
||||
int _testTubeSetNum;
|
||||
uint32 _fillLevel;
|
||||
int _testTubeIndex;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2808Handle : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum);
|
||||
void activate();
|
||||
void stActivated();
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _testTubeSetNum;
|
||||
bool _isActivated;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmActivating(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2808Flow : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum);
|
||||
void start();
|
||||
void stKeepFlowing();
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _testTubeSetNum;
|
||||
uint32 hmFlowing(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2808LightEffect : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2808LightEffect(NeverhoodEngine *vm, int which);
|
||||
protected:
|
||||
int _countdown;
|
||||
void update();
|
||||
};
|
||||
|
||||
class AsScene2809Spew : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2809Spew(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2810Rope : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2812Winch : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2812Winch(NeverhoodEngine *vm);
|
||||
~AsScene2812Winch() override;
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2812Rope : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmRopingDown(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stRopingDown();
|
||||
};
|
||||
|
||||
class AsScene2812TrapDoor : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2812TrapDoor(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene2801 : public Klaymen {
|
||||
public:
|
||||
KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2803 : public Klaymen {
|
||||
public:
|
||||
KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2803Small : public Klaymen {
|
||||
public:
|
||||
KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void stShrink();
|
||||
uint32 hmShrink(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2805 : public Klaymen {
|
||||
public:
|
||||
KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2806 : public Klaymen {
|
||||
public:
|
||||
KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
|
||||
bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2809 : public Klaymen {
|
||||
public:
|
||||
KmScene2809(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
|
||||
bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2810Small : public Klaymen {
|
||||
public:
|
||||
KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2810 : public Klaymen {
|
||||
public:
|
||||
KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
|
||||
NRect *clipRects, uint clipRectsCount);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2812 : public Klaymen {
|
||||
public:
|
||||
KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2800_SPRITES_H */
|
||||
240
engines/neverhood/modules/module2900.cpp
Normal file
240
engines/neverhood/modules/module2900.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2900.h"
|
||||
#include "neverhood/modules/module2900_sprites.h"
|
||||
#include "neverhood/modules/module1100.h"
|
||||
#include "neverhood/modules/module1300.h"
|
||||
#include "neverhood/modules/module1700.h"
|
||||
#include "neverhood/modules/module2000.h"
|
||||
#include "neverhood/modules/module2100.h"
|
||||
#include "neverhood/modules/module2800.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module2900::Module2900(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
_teleporterModuleResult = -1;
|
||||
|
||||
if (which >= 0)
|
||||
setGlobalVar(V_TELEPORTER_WHICH, which);
|
||||
|
||||
createScene(0, 0);
|
||||
}
|
||||
|
||||
void Module2900::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module2900::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene2901(_vm, this, getGlobalVar(V_TELEPORTER_WHICH));
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene2805(_vm, this, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene2101(_vm, this, which);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene1306(_vm, this, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene1705(_vm, this, which);
|
||||
break;
|
||||
case 5:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene1109(_vm, this, which);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene2001(_vm, this, which);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module2900::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module2900::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == (uint32)-1) {
|
||||
leaveModule((uint32)-1);
|
||||
} else {
|
||||
_teleporterModuleResult = _moduleResult;
|
||||
switch (getGlobalVar(V_TELEPORTER_WHICH)) {
|
||||
case 0:
|
||||
createScene(3, 4);
|
||||
break;
|
||||
case 1:
|
||||
createScene(2, 2);
|
||||
break;
|
||||
case 2:
|
||||
createScene(5, 2);
|
||||
break;
|
||||
case 3:
|
||||
createScene(4, 2);
|
||||
break;
|
||||
case 4:
|
||||
createScene(6, 2);
|
||||
break;
|
||||
case 5:
|
||||
createScene(1, 2);
|
||||
break;
|
||||
default:
|
||||
leaveModule(_moduleResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
leaveModule(_teleporterModuleResult);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const uint32 kScene2901FileHashes1[] = {
|
||||
0x023023B4,
|
||||
0x36204507,
|
||||
0x046CF08E,
|
||||
0x9313A237,
|
||||
0xA651F246,
|
||||
0x02108034
|
||||
};
|
||||
|
||||
static const uint32 kScene2901FileHashes2[] = {
|
||||
0x023B002B,
|
||||
0x0450336A,
|
||||
0xCF08A04E,
|
||||
0x3A233939,
|
||||
0x1F242A6D,
|
||||
0x08030029
|
||||
};
|
||||
|
||||
Scene2901::Scene2901(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _currLocationButtonNum(which), _selectedButtonNum(which),
|
||||
_currWhirlButtonNum(0), _prevWhirlButtonNum(0), _countdown1(1), _skipCountdown(0), _blinkOn(0) {
|
||||
|
||||
_isButton2Broken = getGlobalVar(V_ENTRANCE_OPEN) != 0;
|
||||
|
||||
setSubVar(V_TELEPORTER_DEST_AVAILABLE, which, 1);
|
||||
setSubVar(V_TELEPORTER_DEST_AVAILABLE, 5, 1);
|
||||
setSubVar(V_TELEPORTER_DEST_AVAILABLE, 4, 1);
|
||||
|
||||
if (_currLocationButtonNum == 3)
|
||||
setSubVar(V_TELEPORTER_DEST_AVAILABLE, 2, 1);
|
||||
|
||||
setBackground(kScene2901FileHashes1[_currLocationButtonNum]);
|
||||
setPalette(kScene2901FileHashes1[_currLocationButtonNum]);
|
||||
|
||||
for (uint i = 0; i < 6; ++i) {
|
||||
if (i != 2 || !_isButton2Broken) {
|
||||
_ssLocationButtons[i] = insertSprite<SsScene2901LocationButton>(this, _currLocationButtonNum, i);
|
||||
addCollisionSprite(_ssLocationButtons[i]);
|
||||
_ssLocationButtonLights[i] = insertSprite<SsScene2901LocationButtonLight>(_currLocationButtonNum, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (_isButton2Broken)
|
||||
insertSprite<SsScene2901BrokenButton>(_currLocationButtonNum);
|
||||
|
||||
_ssBigButton = insertSprite<SsScene2901BigButton>(this, _currLocationButtonNum);
|
||||
addCollisionSprite(_ssBigButton);
|
||||
|
||||
insertPuzzleMouse(kScene2901FileHashes2[_currLocationButtonNum], 20, 620);
|
||||
|
||||
SetUpdateHandler(&Scene2901::update);
|
||||
SetMessageHandler(&Scene2901::handleMessage);
|
||||
|
||||
}
|
||||
|
||||
void Scene2901::update() {
|
||||
Scene::update();
|
||||
if (_countdown1 != 0 && (--_countdown1) == 0) {
|
||||
if (_currLocationButtonNum == _selectedButtonNum) {
|
||||
_ssLocationButtonLights[_currWhirlButtonNum]->hide();
|
||||
++_currWhirlButtonNum;
|
||||
while (!getSubVar(V_TELEPORTER_DEST_AVAILABLE, _currWhirlButtonNum) || (_currWhirlButtonNum == 2 && _isButton2Broken) || _currLocationButtonNum == _currWhirlButtonNum) {
|
||||
++_currWhirlButtonNum;
|
||||
if (_currWhirlButtonNum >= 6)
|
||||
_currWhirlButtonNum = 0;
|
||||
}
|
||||
if (_currWhirlButtonNum != _prevWhirlButtonNum || _skipCountdown == 0) {
|
||||
_ssLocationButtonLights[_currWhirlButtonNum]->show();
|
||||
_skipCountdown = 4;
|
||||
}
|
||||
_countdown1 = 2;
|
||||
--_skipCountdown;
|
||||
_prevWhirlButtonNum = _currWhirlButtonNum;
|
||||
} else if (_blinkOn) {
|
||||
_blinkOn = false;
|
||||
_ssLocationButtonLights[_selectedButtonNum]->hide();
|
||||
_countdown1 = 16;
|
||||
} else {
|
||||
_blinkOn = true;
|
||||
_ssLocationButtonLights[_selectedButtonNum]->show();
|
||||
_countdown1 = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene2901::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
|
||||
leaveScene((uint32)-1);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (_currLocationButtonNum != _selectedButtonNum)
|
||||
leaveScene(_selectedButtonNum);
|
||||
break;
|
||||
case 0x2001:
|
||||
if (_currLocationButtonNum == _selectedButtonNum)
|
||||
_selectedButtonNum = _currWhirlButtonNum;
|
||||
_ssLocationButtonLights[_selectedButtonNum]->hide();
|
||||
_selectedButtonNum = param.asInteger();
|
||||
if (!getSubVar(V_TELEPORTER_DEST_AVAILABLE, _selectedButtonNum))
|
||||
_selectedButtonNum = _currLocationButtonNum;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
67
engines/neverhood/modules/module2900.h
Normal file
67
engines/neverhood/modules/module2900.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2900_H
|
||||
#define NEVERHOOD_MODULES_MODULE2900_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module2900
|
||||
|
||||
class Module2900 : public Module {
|
||||
public:
|
||||
Module2900(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
int _sceneNum;
|
||||
int _teleporterModuleResult;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
void updateMusic(bool halfVolume);
|
||||
};
|
||||
|
||||
class SsScene2901LocationButtonLight;
|
||||
|
||||
class Scene2901 : public Scene {
|
||||
public:
|
||||
Scene2901(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_ssLocationButtons[6];
|
||||
SsScene2901LocationButtonLight *_ssLocationButtonLights[6];
|
||||
Sprite *_ssBigButton;
|
||||
int _currWhirlButtonNum;
|
||||
int _prevWhirlButtonNum;
|
||||
int _countdown1;
|
||||
int _currLocationButtonNum;
|
||||
int _selectedButtonNum;
|
||||
int _skipCountdown;
|
||||
int _blinkOn;
|
||||
bool _isButton2Broken;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2900_H */
|
||||
235
engines/neverhood/modules/module2900_sprites.cpp
Normal file
235
engines/neverhood/modules/module2900_sprites.cpp
Normal file
@@ -0,0 +1,235 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2900_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kSsScene2901LocationButtonFileHashes[] = {
|
||||
0x2311326A,
|
||||
0x212323AC,
|
||||
0x10098138,
|
||||
0x25213167,
|
||||
0x1119A363,
|
||||
0x94452612,
|
||||
0x39464212,
|
||||
0x01860450,
|
||||
0x53002104,
|
||||
0x58E68412,
|
||||
0x18600300,
|
||||
0xB650A890,
|
||||
0x2452A7C4,
|
||||
0xA0232748,
|
||||
0x08862B02,
|
||||
0x2491E648,
|
||||
0x0010EB46,
|
||||
0x214C8A11,
|
||||
0x16A31921,
|
||||
0x0AC33A00,
|
||||
0x238028AA,
|
||||
0x26737A21,
|
||||
0x063039A8,
|
||||
0x51286C60,
|
||||
0x464006B4,
|
||||
0x42242538,
|
||||
0x20716010,
|
||||
0x4A2000AE,
|
||||
0x225124A6,
|
||||
0x28E82E45,
|
||||
0x58652C04,
|
||||
0xC82210A4,
|
||||
0x62A84060,
|
||||
0xC0693CB4,
|
||||
0x22212C64,
|
||||
0x5034EA71
|
||||
};
|
||||
|
||||
static const NPoint kSsScene2901LocationButtonPoints[] = {
|
||||
{525, 120}, {576, 149}, {587, 205},
|
||||
{538, 232}, {484, 205}, {479, 153}
|
||||
};
|
||||
|
||||
static const uint32 kSsScene2901LocationButtonLightFileHashes1[] = {
|
||||
0x03136246,
|
||||
0x2106216E,
|
||||
0x4025A13A,
|
||||
0x21816927,
|
||||
0x110B2202,
|
||||
0xCC0522B2,
|
||||
0x3CC24258,
|
||||
0x59C600F0,
|
||||
0x534A2480,
|
||||
0x50E61019,
|
||||
0x34400150,
|
||||
0x225BA090,
|
||||
0xB059AFC4,
|
||||
0xE093A741,
|
||||
0x0086BF09,
|
||||
0x3281E760,
|
||||
0xA048AB42,
|
||||
0x20649C01,
|
||||
0x14611904,
|
||||
0x26E33850,
|
||||
0x23A52A68,
|
||||
0xA2733024,
|
||||
0x10203880,
|
||||
0x1B2DE860,
|
||||
0x0644A6EC,
|
||||
0x426E20BC,
|
||||
0x80292014,
|
||||
0x4360B02E,
|
||||
0x22742664,
|
||||
0x98682705,
|
||||
0x0925B82C,
|
||||
0x5C2918A4,
|
||||
0xD2284920,
|
||||
0x41083CA6,
|
||||
0x6824A864,
|
||||
0x50266B10
|
||||
};
|
||||
|
||||
static const uint32 kSsScene2901LocationButtonLightFileHashes2[] = {
|
||||
0x43C46D4C,
|
||||
0x43C4AD4C,
|
||||
0x43C52D4C,
|
||||
0x43C62D4C,
|
||||
0x43C02D4C,
|
||||
0x43CC2D4C
|
||||
};
|
||||
|
||||
static const uint32 kSsScene2901BrokenButtonFileHashes[] = {
|
||||
0x3081BD3A,
|
||||
0xD3443003,
|
||||
0x0786A320,
|
||||
0xE3A22029,
|
||||
0x61611814,
|
||||
0x425848E2
|
||||
};
|
||||
|
||||
static const uint32 kSsScene2901BigButtonFileHashes[] = {
|
||||
0x010D7748,
|
||||
0x9D02019A,
|
||||
0x351A2F43,
|
||||
0x448138E5,
|
||||
0x02788CF0,
|
||||
0x71718024
|
||||
};
|
||||
|
||||
SsScene2901LocationButton::SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index)
|
||||
: StaticSprite(vm, 900), _parentScene(parentScene), _index(index), _countdown1(0) {
|
||||
|
||||
const NPoint &pt = kSsScene2901LocationButtonPoints[_index];
|
||||
|
||||
loadSprite(kSsScene2901LocationButtonFileHashes[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 800);
|
||||
_collisionBounds.set(pt.x - 25, pt.y - 25, pt.x + 25, pt.y + 25);
|
||||
setVisible(false);
|
||||
loadSound(0, 0x440430C0);
|
||||
SetUpdateHandler(&SsScene2901LocationButton::update);
|
||||
SetMessageHandler(&SsScene2901LocationButton::handleMessage);
|
||||
}
|
||||
|
||||
void SsScene2901LocationButton::update() {
|
||||
updatePosition();
|
||||
if (_countdown1 != 0 && (--_countdown1) == 0) {
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene2901LocationButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_countdown1 == 0) {
|
||||
playSound(0);
|
||||
setVisible(true);
|
||||
_countdown1 = 4;
|
||||
sendMessage(_parentScene, 0x2001, _index);
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
SsScene2901LocationButtonLight::SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index)
|
||||
: StaticSprite(vm, 900), _index(index) {
|
||||
|
||||
loadSprite(kSsScene2901LocationButtonLightFileHashes1[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 900);
|
||||
setVisible(false);
|
||||
loadSound(0, kSsScene2901LocationButtonLightFileHashes2[_index]);
|
||||
}
|
||||
|
||||
void SsScene2901LocationButtonLight::show() {
|
||||
playSound(0);
|
||||
setVisible(true);
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
void SsScene2901LocationButtonLight::hide() {
|
||||
setVisible(false);
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
SsScene2901BrokenButton::SsScene2901BrokenButton(NeverhoodEngine *vm, int which)
|
||||
: StaticSprite(vm, 900) {
|
||||
|
||||
loadSprite(kSsScene2901BrokenButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 900);
|
||||
}
|
||||
|
||||
SsScene2901BigButton::SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which)
|
||||
: StaticSprite(vm, 900), _parentScene(parentScene), _which(which), _countdown1(0) {
|
||||
|
||||
loadSprite(kSsScene2901BigButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 400);
|
||||
_collisionBounds.set(62, 94, 322, 350);
|
||||
setVisible(false);
|
||||
loadSound(0, 0xF3D420C8);
|
||||
SetUpdateHandler(&SsScene2901BigButton::update);
|
||||
SetMessageHandler(&SsScene2901BigButton::handleMessage);
|
||||
}
|
||||
|
||||
void SsScene2901BigButton::update() {
|
||||
updatePosition();
|
||||
if (_countdown1 != 0 && (--_countdown1) == 0) {
|
||||
setVisible(false);
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene2901BigButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_countdown1 == 0) {
|
||||
playSound(0);
|
||||
setVisible(true);
|
||||
_countdown1 = 4;
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
71
engines/neverhood/modules/module2900_sprites.h
Normal file
71
engines/neverhood/modules/module2900_sprites.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2900_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2900_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module2900
|
||||
|
||||
class SsScene2901LocationButton : public StaticSprite {
|
||||
public:
|
||||
SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint _index;
|
||||
int _countdown1;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsScene2901LocationButtonLight : public StaticSprite {
|
||||
public:
|
||||
SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index);
|
||||
void show();
|
||||
void hide();
|
||||
protected:
|
||||
uint _index;
|
||||
};
|
||||
|
||||
class SsScene2901BrokenButton : public StaticSprite {
|
||||
public:
|
||||
SsScene2901BrokenButton(NeverhoodEngine *vm, int which);
|
||||
};
|
||||
|
||||
class SsScene2901BigButton : public StaticSprite {
|
||||
public:
|
||||
SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _which;
|
||||
int _countdown1;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2900_SPRITES_H */
|
||||
882
engines/neverhood/modules/module3000.cpp
Normal file
882
engines/neverhood/modules/module3000.cpp
Normal file
@@ -0,0 +1,882 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/gamemodule.h"
|
||||
#include "neverhood/navigationscene.h"
|
||||
#include "neverhood/modules/module3000.h"
|
||||
#include "neverhood/modules/module3000_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule3000SoundList[] = {
|
||||
0x92025040,
|
||||
0x90035066,
|
||||
0x90815450,
|
||||
0x99801500,
|
||||
0x90E14440,
|
||||
0x16805048,
|
||||
0x90F0D1C3,
|
||||
0
|
||||
};
|
||||
|
||||
Module3000::Module3000(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule), _waterfallSoundVolume(0) {
|
||||
|
||||
_vm->_soundMan->addSoundList(0x81293110, kModule3000SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule3000SoundList, true, 50, 600, 5, 150);
|
||||
_vm->_soundMan->setSoundParams(0x90F0D1C3, false, 20000, 30000, 20000, 30000);
|
||||
_vm->_soundMan->playTwoSounds(0x81293110, 0x48498E46, 0x50399F64, 0);
|
||||
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
|
||||
_vm->_soundMan->playTwoSounds(0x81293110, 0x41861371, 0x43A2507F, 0);
|
||||
|
||||
_isWaterfallRunning = getGlobalVar(V_WALL_BROKEN) != 1;
|
||||
|
||||
if (_isWaterfallRunning) {
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 0);
|
||||
_vm->_soundMan->playSoundLooping(0x90F0D1C3);
|
||||
}
|
||||
|
||||
if (which < 0) {
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
} else if (which == 0) {
|
||||
createScene(1, 0);
|
||||
} else if (which == 1) {
|
||||
createScene(4, 2);
|
||||
} else if (which == 2) {
|
||||
createScene(4, 1);
|
||||
} else if (which == 3) {
|
||||
createScene(5, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Module3000::~Module3000() {
|
||||
_vm->_soundMan->deleteGroup(0x81293110);
|
||||
}
|
||||
|
||||
void Module3000::createScene(int sceneNum, int which) {
|
||||
static const byte kNavigationTypes05[] = {2, 0};
|
||||
static const byte kNavigationTypes06[] = {5};
|
||||
debug(1, "Module3000::createScene(%d, %d)", sceneNum, which);
|
||||
_vm->gameState().sceneNum = sceneNum;
|
||||
switch (_vm->gameState().sceneNum) {
|
||||
case 1:
|
||||
if (!getGlobalVar(V_BOLT_DOOR_OPEN)) {
|
||||
createNavigationScene(0x004B7C80, which);
|
||||
} else if (getGlobalVar(V_WALL_BROKEN)) {
|
||||
createNavigationScene(0x004B7CE0, which);
|
||||
} else {
|
||||
createNavigationScene(0x004B7CB0, which);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
|
||||
if (_isWaterfallRunning) {
|
||||
_waterfallSoundVolume = 90;
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 90);
|
||||
}
|
||||
if (getGlobalVar(V_WALL_BROKEN)) {
|
||||
createNavigationScene(0x004B7D58, which);
|
||||
} else {
|
||||
createNavigationScene(0x004B7D10, which);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (getGlobalVar(V_STAIRS_DOWN))
|
||||
createNavigationScene(0x004B7E60, which);
|
||||
else if (getGlobalVar(V_WALL_BROKEN))
|
||||
createNavigationScene(0x004B7DA0, which);
|
||||
else
|
||||
createNavigationScene(0x004B7E00, which);
|
||||
break;
|
||||
case 4:
|
||||
if (getGlobalVar(V_STAIRS_DOWN))
|
||||
createNavigationScene(0x004B7F20, which);
|
||||
else
|
||||
createNavigationScene(0x004B7EC0, which);
|
||||
break;
|
||||
case 5:
|
||||
createNavigationScene(0x004B7F80, which, kNavigationTypes05);
|
||||
break;
|
||||
case 6:
|
||||
createNavigationScene(0x004B7FB0, which, kNavigationTypes06);
|
||||
break;
|
||||
case 7:
|
||||
_vm->_soundMan->setSoundListParams(kModule3000SoundList, false, 0, 0, 0, 0);
|
||||
if (!getSubVar(VA_IS_PUZZLE_INIT, 0x089809C2)) {
|
||||
setSubVar(VA_IS_PUZZLE_INIT, 0x089809C2, 1);
|
||||
createSmackerScene(0x90022001, true, true, false);
|
||||
} else
|
||||
createSmackerScene(0x98022001, true, true, false);
|
||||
break;
|
||||
case 8:
|
||||
_childObject = new Scene3009(_vm, this, which);
|
||||
break;
|
||||
case 9:
|
||||
_childObject = new Scene3010(_vm, this, 0);
|
||||
break;
|
||||
case 10:
|
||||
_childObject = new Scene3011(_vm, this, 0);
|
||||
break;
|
||||
case 11:
|
||||
_vm->_soundMan->setSoundListParams(kModule3000SoundList, false, 0, 0, 0, 0);
|
||||
if (!getSubVar(VA_IS_PUZZLE_INIT, 0x10130993)) {
|
||||
setSubVar(VA_IS_PUZZLE_INIT, 0x10130993, 1);
|
||||
createSmackerScene(0x31093019, true, true, false);
|
||||
} else
|
||||
createSmackerScene(0x20093019, true, true, false);
|
||||
break;
|
||||
case 12:
|
||||
_childObject = new Scene3010(_vm, this, 1);
|
||||
break;
|
||||
// NOTE: Newly introduced sceneNums
|
||||
case 1001:
|
||||
if (!getGlobalVar(V_BOLT_DOOR_OPEN))
|
||||
if (getGlobalVar(V_WALL_BROKEN))
|
||||
createSmackerScene(0x00940021, true, true, false);
|
||||
else
|
||||
createSmackerScene(0x01140021, true, true, false);
|
||||
else
|
||||
if (getGlobalVar(V_WALL_BROKEN))
|
||||
createSmackerScene(0x001011B1, true, true, false);
|
||||
else
|
||||
createSmackerScene(0x001021B1, true, true, false);
|
||||
setGlobalVar(V_BOLT_DOOR_OPEN, getGlobalVar(V_BOLT_DOOR_OPEN) ? 0 : 1);
|
||||
break;
|
||||
case 1006:
|
||||
createSmackerScene(0x080810C5, true, true, false);
|
||||
break;
|
||||
case 1008:
|
||||
createSmackerScene(getGlobalVar(V_CANNON_SMACKER_NAME), true, true, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module3000::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module3000::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_vm->gameState().sceneNum) {
|
||||
case 1:
|
||||
if (!getGlobalVar(V_BOLT_DOOR_OPEN)) {
|
||||
if (_moduleResult == 0)
|
||||
createScene(9, -1);
|
||||
else if (_moduleResult == 1)
|
||||
leaveModule(0);
|
||||
} else {
|
||||
if (_moduleResult == 0)
|
||||
if (_navigationAreaType == 2)
|
||||
createScene(2, 0);
|
||||
else
|
||||
createScene(1001, -1);
|
||||
else if (_moduleResult == 1)
|
||||
leaveModule(0);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
_vm->_soundMan->playTwoSounds(0x81293110, 0x41861371, 0x43A2507F, 0);
|
||||
if (_isWaterfallRunning) {
|
||||
_waterfallSoundVolume = 0;
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 0);
|
||||
}
|
||||
if (_moduleResult == 0) {
|
||||
createScene(3, 0);
|
||||
} else if (_moduleResult == 1) {
|
||||
setGlobalVar(V_BOLT_DOOR_OPEN, 0);
|
||||
createScene(1, 1);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 1)
|
||||
createScene(4, 0);
|
||||
else if (_moduleResult == 3)
|
||||
createScene(10, -1);
|
||||
else if (getGlobalVar(V_STAIRS_DOWN))
|
||||
createScene(5, 0);
|
||||
else
|
||||
createScene(2, 1);
|
||||
break;
|
||||
case 4:
|
||||
if (_moduleResult == 0)
|
||||
leaveModule(1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(7, -1);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(3, 3);
|
||||
break;
|
||||
case 5:
|
||||
if (_moduleResult == 0)
|
||||
createScene(6, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(3, 0);
|
||||
break;
|
||||
case 6:
|
||||
if (_navigationAreaType == 4)
|
||||
createScene(11, -1);
|
||||
else
|
||||
createScene(1006, -1);
|
||||
break;
|
||||
case 7:
|
||||
createScene(8, -1);
|
||||
break;
|
||||
case 8:
|
||||
_isWaterfallRunning = getGlobalVar(V_WALL_BROKEN) != 1;
|
||||
if (_moduleResult != 1) {
|
||||
_vm->_soundMan->setSoundListParams(kModule3000SoundList, true, 0, 0, 0, 0);
|
||||
createScene(4, 1);
|
||||
} else if (getGlobalVar(V_CANNON_SMACKER_NAME)) {
|
||||
createScene(1008, -1);
|
||||
} else {
|
||||
_vm->_soundMan->setSoundListParams(kModule3000SoundList, true, 0, 0, 0, 0);
|
||||
createScene(4, 1);
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (_moduleResult == 0 || _moduleResult == 2)
|
||||
createScene(1, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(1001, -1);
|
||||
break;
|
||||
case 10:
|
||||
createScene(3, 3);
|
||||
break;
|
||||
case 11:
|
||||
leaveModule(3);
|
||||
break;
|
||||
case 12:
|
||||
createScene(1, 0);
|
||||
break;
|
||||
case 1001:
|
||||
if (getGlobalVar(V_BOLT_DOOR_OPEN))
|
||||
createScene(1, 0);
|
||||
else
|
||||
createScene(12, -1);
|
||||
break;
|
||||
case 1006:
|
||||
createScene(5, 0);
|
||||
break;
|
||||
case 1008:
|
||||
createScene(8, -1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (_vm->gameState().sceneNum) {
|
||||
case 1:
|
||||
if (navigationScene()->isWalkingForward()) {
|
||||
uint32 frameNumber = navigationScene()->getFrameNumber();
|
||||
int navigationIndex = navigationScene()->getNavigationIndex();
|
||||
if (navigationIndex == 1) {
|
||||
if (frameNumber == 0) {
|
||||
_vm->_soundMan->playTwoSounds(0x81293110, 0x48498E46, 0x50399F64, 0);
|
||||
_vm->_soundMan->setSoundVolume(0x48498E46, 70);
|
||||
_vm->_soundMan->setSoundVolume(0x50399F64, 70);
|
||||
} else if (frameNumber == 100) {
|
||||
_vm->_soundMan->playTwoSounds(0x81293110, 0x41861371, 0x43A2507F, 0);
|
||||
}
|
||||
} else if (navigationIndex == 0) {
|
||||
if (frameNumber == 0) {
|
||||
_vm->_soundMan->playTwoSounds(0x81293110, 0x48498E46, 0x50399F64, 0);
|
||||
_vm->_soundMan->setSoundVolume(0x48498E46, 70);
|
||||
_vm->_soundMan->setSoundVolume(0x50399F64, 70);
|
||||
} else if (frameNumber == 10) {
|
||||
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
|
||||
}
|
||||
if (_isWaterfallRunning && _waterfallSoundVolume < 90 && frameNumber % 2) {
|
||||
if (frameNumber == 0)
|
||||
_waterfallSoundVolume = 40;
|
||||
else
|
||||
_waterfallSoundVolume++;
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (navigationScene()->isWalkingForward()) {
|
||||
uint32 frameNumber = navigationScene()->getFrameNumber();
|
||||
int navigationIndex = navigationScene()->getNavigationIndex();
|
||||
if (_isWaterfallRunning && _waterfallSoundVolume > 1 && frameNumber % 2) {
|
||||
_waterfallSoundVolume--;
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
|
||||
}
|
||||
if (navigationIndex == 0) {
|
||||
if (frameNumber == 35) {
|
||||
_vm->_soundMan->playTwoSounds(0x81293110, 0x41861371, 0x43A2507F, 0);
|
||||
}
|
||||
} else if (navigationIndex == 1) {
|
||||
if (frameNumber == 55) {
|
||||
_vm->_soundMan->playTwoSounds(0x81293110, 0x48498E46, 0x50399F64, 0);
|
||||
_vm->_soundMan->setSoundVolume(0x48498E46, 70);
|
||||
_vm->_soundMan->setSoundVolume(0x50399F64, 70);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (navigationScene()->isWalkingForward()) {
|
||||
uint32 frameNumber = navigationScene()->getFrameNumber();
|
||||
int navigationIndex = navigationScene()->getNavigationIndex();
|
||||
if (navigationIndex == 2) {
|
||||
if (frameNumber == 40) {
|
||||
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
|
||||
}
|
||||
if (_isWaterfallRunning && _waterfallSoundVolume < 90 && frameNumber % 2) {
|
||||
if (frameNumber == 0)
|
||||
_waterfallSoundVolume = 40;
|
||||
else
|
||||
_waterfallSoundVolume++;
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 0) {
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scene3009
|
||||
|
||||
enum {
|
||||
kCTSNull = 0,
|
||||
kCTSBreakWall = 1,
|
||||
kCTSWall = 2,
|
||||
kCTSEmptyness = 3,
|
||||
kCTSFireRobotNoTarget = 4,
|
||||
kCTSFireRobotIsTarget = 5,
|
||||
kCTSFireNoRobot = 6,
|
||||
kCTSRaiseCannon = 7,
|
||||
kCTSRightRobotNoTarget = 8,
|
||||
kCTSRightRobotIsTarget = 9,
|
||||
kCTSRightNoRobot = 10,
|
||||
kCTSLeftRobotNoTarget = 11,
|
||||
kCTSLeftRobotIsTarget = 12,
|
||||
kCTSLeftNoRobot = 13,
|
||||
kCTSLowerCannon = 14,
|
||||
kCTSCount = 14
|
||||
};
|
||||
|
||||
static const uint32 kScene3009CannonScopeVideos[] = {
|
||||
0x1010000D,
|
||||
0x340A0049,
|
||||
0x340A0049,
|
||||
0x0282081D,
|
||||
0x0082080D,
|
||||
0x0882080D,
|
||||
0x0882080D,
|
||||
0x0282081D,
|
||||
0x004B000B,
|
||||
0x014B000B,
|
||||
0x044B000B,
|
||||
0x0282081D,
|
||||
0x0282081D,
|
||||
0x0282081D,
|
||||
0x340A0049
|
||||
};
|
||||
|
||||
static const uint32 kScene3009CannonActionVideos[] = {
|
||||
0x00000000,
|
||||
0x8004001B, // 1 Fire cannon at wall, it breaks (lowered)
|
||||
0x0004001A, // 2 Fire cannon at wall, nothing happens (lowered)
|
||||
0x1048404B, // 3 Fire cannon at emptyness (raised)
|
||||
0x50200109, // 4 Fire cannon, robot missed (raised)
|
||||
0x12032109, // 5 Fire cannon, robot hit (raised)
|
||||
0x10201109, // 6 Fire cannon, no robot (raised)
|
||||
0x000A2030, // 7 Raise the cannon
|
||||
0x000A0028, // 8
|
||||
0x000A0028, // 9
|
||||
0x000A0028, // 10
|
||||
0x040A1069, // 11
|
||||
0x040A1069, // 12
|
||||
0x040A1069, // 13
|
||||
0x240A1101 // 14 Lower the cannon
|
||||
};
|
||||
|
||||
Scene3009::Scene3009(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _keepVideo(false), _moveCannonLeftFirst(false),
|
||||
_isTurning(false), _lockSymbolsPart1Countdown(1), _lockSymbolsPart2Countdown(1) {
|
||||
|
||||
_cannonTargetStatus = getGlobalVar(V_CANNON_TARGET_STATUS);
|
||||
|
||||
_vm->gameModule()->initCannonSymbolsPuzzle();
|
||||
|
||||
setGlobalVar(V_CANNON_SMACKER_NAME, 0);
|
||||
|
||||
_vm->_screen->clear();
|
||||
|
||||
setBackground(0xD000420C);
|
||||
setPalette(0xD000420C);
|
||||
insertPuzzleMouse(0x04208D08, 20, 620);
|
||||
|
||||
_ssFireCannonButton = insertSprite<SsScene3009FireCannonButton>(this);
|
||||
addCollisionSprite(_ssFireCannonButton);
|
||||
|
||||
_asVerticalIndicator = insertSprite<AsScene3009VerticalIndicator>(this, _cannonTargetStatus);
|
||||
addCollisionSprite(_asVerticalIndicator);
|
||||
|
||||
_asHorizontalIndicator = insertSprite<AsScene3009HorizontalIndicator>(this, _cannonTargetStatus);
|
||||
addCollisionSprite(_asHorizontalIndicator);
|
||||
|
||||
if (_cannonTargetStatus != kCTSNull && _cannonTargetStatus != kCTSRightRobotNoTarget && _cannonTargetStatus != kCTSRightRobotIsTarget && _cannonTargetStatus != kCTSRightNoRobot) {
|
||||
_keepVideo = true;
|
||||
} else {
|
||||
_keepVideo = false;
|
||||
if (_cannonTargetStatus != kCTSNull) {
|
||||
_asHorizontalIndicator->stMoveRight();
|
||||
_isTurning = true;
|
||||
}
|
||||
}
|
||||
|
||||
_cannonSmackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, kScene3009CannonScopeVideos[_cannonTargetStatus], false, _keepVideo));
|
||||
_cannonSmackerPlayer->setDrawPos(89, 37);
|
||||
_palette->usePalette(); // Use it again since the SmackerPlayer overrides the usage
|
||||
|
||||
insertStaticSprite(0x8540252C, 400);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
_ssSymbolEdges[i] = insertSprite<SsScene3009SymbolEdges>(i);
|
||||
_ssTargetLines[i] = insertSprite<SsScene3009TargetLine>(i);
|
||||
}
|
||||
|
||||
for (int symbolPosition = 0; symbolPosition < 6; symbolPosition++) {
|
||||
_asSymbols[symbolPosition] = insertSprite<AsScene3009Symbol>(this, symbolPosition);
|
||||
if (symbolPosition < 3)
|
||||
_correctSymbols[symbolPosition] = getSubVar(VA_GOOD_CANNON_SYMBOLS_1, symbolPosition);
|
||||
else
|
||||
_correctSymbols[symbolPosition] = getSubVar(VA_GOOD_CANNON_SYMBOLS_2, symbolPosition - 3);
|
||||
}
|
||||
|
||||
SetMessageHandler(&Scene3009::handleMessage);
|
||||
SetUpdateHandler(&Scene3009::update);
|
||||
}
|
||||
|
||||
Scene3009::~Scene3009() {
|
||||
}
|
||||
|
||||
void Scene3009::openSmacker(uint32 fileHash, bool keepLastFrame) {
|
||||
_cannonSmackerPlayer->open(fileHash, keepLastFrame);
|
||||
//_vm->_screen->setSmackerDecoder(_cannonSmackerPlayer->getSmackerDecoder());
|
||||
_palette->usePalette();
|
||||
}
|
||||
|
||||
void Scene3009::update() {
|
||||
Scene::update();
|
||||
|
||||
if (!_keepVideo && _cannonSmackerPlayer->isDone() && _cannonTargetStatus <= kCTSCount) {
|
||||
switch (_cannonTargetStatus) {
|
||||
case kCTSNull:
|
||||
case kCTSLowerCannon:
|
||||
openSmacker(0x340A0049, true);
|
||||
_keepVideo = true;
|
||||
break;
|
||||
case kCTSRightRobotNoTarget:
|
||||
openSmacker(0x0082080D, true);
|
||||
_keepVideo = true;
|
||||
_isTurning = false;
|
||||
break;
|
||||
case kCTSRightRobotIsTarget:
|
||||
openSmacker(0x0282080D, true);
|
||||
_keepVideo = true;
|
||||
_isTurning = false;
|
||||
break;
|
||||
case kCTSRightNoRobot:
|
||||
openSmacker(0x0882080D, true);
|
||||
_keepVideo = true;
|
||||
_isTurning = false;
|
||||
break;
|
||||
case kCTSLeftRobotNoTarget:
|
||||
case kCTSLeftRobotIsTarget:
|
||||
case kCTSLeftNoRobot:
|
||||
if (_moveCannonLeftFirst) {
|
||||
if (_cannonTargetStatus == kCTSLeftRobotNoTarget)
|
||||
openSmacker(0x110A000F, false);
|
||||
else if (_cannonTargetStatus == kCTSLeftRobotIsTarget)
|
||||
openSmacker(0x500B004F, false);
|
||||
else if (_cannonTargetStatus == kCTSLeftNoRobot)
|
||||
openSmacker(0x100B010E, false);
|
||||
_moveCannonLeftFirst = false;
|
||||
_asHorizontalIndicator->stMoveLeft();
|
||||
} else {
|
||||
playActionVideo();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_lockSymbolsPart1Countdown != 0 && (--_lockSymbolsPart1Countdown == 0) && isSymbolsPart1Solved()) {
|
||||
for (int i = 0; i < 3; i++)
|
||||
_asSymbols[i]->hide();
|
||||
if (!getGlobalVar(V_ROBOT_HIT) || getGlobalVar(V_CANNON_RAISED) || getGlobalVar(V_CANNON_TURNED)) {
|
||||
_ssSymbolEdges[0]->show();
|
||||
_ssTargetLines[0]->show();
|
||||
_asVerticalIndicator->show();
|
||||
}
|
||||
}
|
||||
|
||||
if (_lockSymbolsPart2Countdown != 0 && (--_lockSymbolsPart2Countdown == 0) && isSymbolsPart2Solved()) {
|
||||
for (int i = 3; i < 6; i++)
|
||||
_asSymbols[i]->hide();
|
||||
if (!getGlobalVar(V_ROBOT_HIT) || getGlobalVar(V_CANNON_RAISED) || getGlobalVar(V_CANNON_TURNED)) {
|
||||
_ssSymbolEdges[1]->show();
|
||||
_ssTargetLines[1]->show();
|
||||
_asHorizontalIndicator->show();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene3009::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !getGlobalVar(V_CANNON_RAISED)) {
|
||||
setGlobalVar(V_CANNON_TARGET_STATUS, 0);
|
||||
leaveScene(0);
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (!getGlobalVar(V_CANNON_RAISED)) {
|
||||
if (!getGlobalVar(V_WALL_BROKEN)) {
|
||||
_cannonTargetStatus = kCTSBreakWall;
|
||||
setGlobalVar(V_WALL_BROKEN, 1);
|
||||
} else {
|
||||
_cannonTargetStatus = kCTSWall;
|
||||
}
|
||||
} else if (!getGlobalVar(V_CANNON_TURNED)) {
|
||||
_cannonTargetStatus = kCTSEmptyness;
|
||||
} else if (!getGlobalVar(V_ROBOT_TARGET)) {
|
||||
_cannonTargetStatus = kCTSFireRobotNoTarget;
|
||||
} else if (!getGlobalVar(V_ROBOT_HIT)) {
|
||||
setGlobalVar(V_ROBOT_HIT, 1);
|
||||
_cannonTargetStatus = kCTSFireRobotIsTarget;
|
||||
} else {
|
||||
_cannonTargetStatus = kCTSFireNoRobot;
|
||||
}
|
||||
playActionVideo();
|
||||
break;
|
||||
case 0x2001:
|
||||
_lockSymbolsPart1Countdown = 24;
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
// Raise/lower the cannon
|
||||
if (!getGlobalVar(V_CANNON_TURNED) && !_isTurning) {
|
||||
if (getGlobalVar(V_CANNON_RAISED)) {
|
||||
_cannonTargetStatus = kCTSLowerCannon;
|
||||
setGlobalVar(V_CANNON_RAISED, 0);
|
||||
} else {
|
||||
_cannonTargetStatus = kCTSRaiseCannon;
|
||||
setGlobalVar(V_CANNON_RAISED, 1);
|
||||
}
|
||||
playActionVideo();
|
||||
}
|
||||
break;
|
||||
case 0x2003:
|
||||
_lockSymbolsPart2Countdown = 24;
|
||||
break;
|
||||
case 0x2004:
|
||||
// Turn the cannon if it's raised
|
||||
if (getGlobalVar(V_CANNON_RAISED)) {
|
||||
if (!getGlobalVar(V_CANNON_TURNED)) {
|
||||
// Cannon is at the left position
|
||||
if (!getGlobalVar(V_ROBOT_TARGET)) {
|
||||
_cannonTargetStatus = kCTSRightRobotNoTarget;
|
||||
} else if (!getGlobalVar(V_ROBOT_HIT)) {
|
||||
_cannonTargetStatus = kCTSRightRobotIsTarget;
|
||||
} else {
|
||||
_cannonTargetStatus = kCTSRightNoRobot;
|
||||
}
|
||||
setGlobalVar(V_CANNON_TURNED, 1);
|
||||
_isTurning = true;
|
||||
playActionVideo();
|
||||
} else {
|
||||
// Cannon is at the right position
|
||||
if (!getGlobalVar(V_ROBOT_TARGET)) {
|
||||
_cannonTargetStatus = kCTSLeftRobotNoTarget;
|
||||
openSmacker(0x108A000F, false);
|
||||
} else if (!getGlobalVar(V_ROBOT_HIT)) {
|
||||
_cannonTargetStatus = kCTSLeftRobotIsTarget;
|
||||
openSmacker(0x500B002F, false);
|
||||
} else {
|
||||
_cannonTargetStatus = kCTSLeftNoRobot;
|
||||
openSmacker(0x100B008E, false);
|
||||
}
|
||||
_moveCannonLeftFirst = true;
|
||||
_isTurning = true;
|
||||
_keepVideo = false;
|
||||
setGlobalVar(V_CANNON_TURNED, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Scene3009::playActionVideo() {
|
||||
setGlobalVar(V_CANNON_TARGET_STATUS, _cannonTargetStatus);
|
||||
setGlobalVar(V_CANNON_SMACKER_NAME, kScene3009CannonActionVideos[_cannonTargetStatus]);
|
||||
leaveScene(1);
|
||||
}
|
||||
|
||||
bool Scene3009::isSymbolsPart1Solved() {
|
||||
for (int i = 0; i < 3; i++)
|
||||
if (_correctSymbols[i] != getSubVar(VA_CURR_CANNON_SYMBOLS, i))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Scene3009::isSymbolsPart2Solved() {
|
||||
for (int i = 3; i < 6; i++)
|
||||
if (_correctSymbols[i] != getSubVar(VA_CURR_CANNON_SYMBOLS, i))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Scene3009::isTurning() {
|
||||
return _isTurning;
|
||||
}
|
||||
|
||||
// Scene3010
|
||||
|
||||
static const uint32 kScene3010ButtonNameHashes[] = {
|
||||
0x304008D2,
|
||||
0x40119852,
|
||||
0x01180951
|
||||
};
|
||||
|
||||
Scene3010::Scene3010(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _countdown(0), _doorUnlocked(false), _checkUnlocked(false) {
|
||||
|
||||
int initCountdown = 0;
|
||||
|
||||
setBackground(0x80802626);
|
||||
setPalette(0x80802626);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
_asDeadBolts[i] = insertSprite<AsScene3010DeadBolt>(this, i, which == 1);//CHECKME
|
||||
_ssDeadBoltButtons[i] = insertSprite<SsScene3010DeadBoltButton>(this, i, initCountdown, which == 1);//CHECKME
|
||||
addCollisionSprite(_ssDeadBoltButtons[i]);
|
||||
if (getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[i]))
|
||||
initCountdown++;
|
||||
_boltUnlocking[i] = false;
|
||||
_boltUnlocked[i] = false;
|
||||
}
|
||||
|
||||
if (which == 0) {
|
||||
insertPuzzleMouse(0x02622800, 20, 620);
|
||||
}
|
||||
|
||||
loadSound(0, 0x68E25540);
|
||||
|
||||
SetMessageHandler(&Scene3010::handleMessage);
|
||||
SetUpdateHandler(&Scene3010::update);
|
||||
|
||||
if (which == 1) {
|
||||
_checkUnlocked = true;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
_boltUnlocked[i] = true;
|
||||
_ssDeadBoltButtons[i]->setCountdown(i + 1);
|
||||
_asDeadBolts[i]->setCountdown(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Scene3010::update() {
|
||||
Scene::update();
|
||||
if (_checkUnlocked && !_boltUnlocked[0] && !_boltUnlocked[1] && !_boltUnlocked[2]) {
|
||||
_countdown = 24;
|
||||
_checkUnlocked = false;
|
||||
}
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
leaveScene(_doorUnlocked ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene3010::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && _countdown == 0 && !_checkUnlocked) {
|
||||
if (!_boltUnlocking[0] && !_boltUnlocking[1] && !_boltUnlocking[2]) {
|
||||
showMouse(false);
|
||||
if (!_boltUnlocked[0] && !_boltUnlocked[1] && !_boltUnlocked[2]) {
|
||||
_countdown = 1;
|
||||
} else {
|
||||
_checkUnlocked = true;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
_ssDeadBoltButtons[i]->setCountdown(i);
|
||||
if (_boltUnlocked[i]) {
|
||||
_asDeadBolts[i]->setCountdown(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (!_boltUnlocked[param.asInteger()] && !_checkUnlocked && _countdown == 0) {
|
||||
_asDeadBolts[param.asInteger()]->unlock(false);
|
||||
_boltUnlocking[param.asInteger()] = true;
|
||||
}
|
||||
break;
|
||||
case 0x2001:
|
||||
_boltUnlocked[param.asInteger()] = true;
|
||||
_boltUnlocking[param.asInteger()] = false;
|
||||
if (_boltUnlocked[0] && _boltUnlocked[1] && _boltUnlocked[2]) {
|
||||
if (!getGlobalVar(V_BOLT_DOOR_UNLOCKED)) {
|
||||
setGlobalVar(V_BOLT_DOOR_UNLOCKED, 1);
|
||||
playSound(0);
|
||||
_countdown = 60;
|
||||
} else {
|
||||
_countdown = 48;
|
||||
}
|
||||
_doorUnlocked = true;
|
||||
}
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
if (!_checkUnlocked && _countdown == 0) {
|
||||
_asDeadBolts[param.asInteger()]->lock();
|
||||
}
|
||||
break;
|
||||
case 0x2003:
|
||||
_boltUnlocked[param.asInteger()] = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Scene3011::Scene3011(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _updateStatus(0), _buttonClicked(false), _currentSymbolIndex(0), _countdown(0) {
|
||||
|
||||
_vm->gameModule()->initCodeSymbolsPuzzle();
|
||||
_noisySymbolIndex = getGlobalVar(V_NOISY_SYMBOL_INDEX);
|
||||
|
||||
SetMessageHandler(&Scene3011::handleMessage);
|
||||
SetUpdateHandler(&Scene3011::update);
|
||||
|
||||
setBackground(0x92124A04);
|
||||
setPalette(0xA4070114);
|
||||
addEntity(_palette);
|
||||
|
||||
insertPuzzleMouse(0x24A00929, 20, 620);
|
||||
|
||||
for (int symbolIndex = 0; symbolIndex < 12; symbolIndex++)
|
||||
_asSymbols[symbolIndex] = insertSprite<AsScene3011Symbol>(symbolIndex, true);
|
||||
|
||||
_ssButton = insertSprite<SsScene3011Button>(this, true);
|
||||
addCollisionSprite(_ssButton);
|
||||
|
||||
}
|
||||
|
||||
void Scene3011::update() {
|
||||
Scene::update();
|
||||
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
switch (_updateStatus) {
|
||||
case 0:
|
||||
if (_buttonClicked) {
|
||||
if (_noisySymbolIndex == _currentSymbolIndex) {
|
||||
do {
|
||||
_noisyRandomSymbolIndex = _vm->_rnd->getRandomNumber(12 - 1);
|
||||
} while (_noisySymbolIndex == _noisyRandomSymbolIndex);
|
||||
_asSymbols[getSubVar(VA_CODE_SYMBOLS, _noisyRandomSymbolIndex)]->show(true);
|
||||
} else {
|
||||
_asSymbols[getSubVar(VA_CODE_SYMBOLS, _currentSymbolIndex)]->show(false);
|
||||
}
|
||||
_updateStatus = 1;
|
||||
_countdown = 24;
|
||||
fadeIn();
|
||||
_buttonClicked = false;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
_updateStatus = 2;
|
||||
_countdown = 24;
|
||||
break;
|
||||
case 2:
|
||||
fadeOut();
|
||||
_updateStatus = 3;
|
||||
_countdown = 24;
|
||||
break;
|
||||
case 3:
|
||||
_updateStatus = 0;
|
||||
_countdown = 1;
|
||||
if (_noisySymbolIndex == _currentSymbolIndex) {
|
||||
_asSymbols[getSubVar(VA_CODE_SYMBOLS, _noisyRandomSymbolIndex)]->hide();
|
||||
} else {
|
||||
_asSymbols[getSubVar(VA_CODE_SYMBOLS, _currentSymbolIndex)]->hide();
|
||||
}
|
||||
_currentSymbolIndex++;
|
||||
if (_currentSymbolIndex >= 12)
|
||||
_currentSymbolIndex = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene3011::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
|
||||
leaveScene(0);
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_buttonClicked = true;
|
||||
if (_countdown == 0)
|
||||
_countdown = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Scene3011::fadeIn() {
|
||||
_palette->addBasePalette(0x92124A04, 0, 256, 0);
|
||||
_palette->startFadeToPalette(24);
|
||||
}
|
||||
|
||||
void Scene3011::fadeOut() {
|
||||
_palette->addBasePalette(0xA4070114, 0, 256, 0);
|
||||
_palette->startFadeToPalette(24);
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
116
engines/neverhood/modules/module3000.h
Normal file
116
engines/neverhood/modules/module3000.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE3000_H
|
||||
#define NEVERHOOD_MODULES_MODULE3000_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module3000 : public Module {
|
||||
public:
|
||||
Module3000(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module3000() override;
|
||||
protected:
|
||||
int _waterfallSoundVolume;
|
||||
bool _isWaterfallRunning;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class SsScene3009SymbolEdges;
|
||||
class SsScene3009TargetLine;
|
||||
class AsScene3009VerticalIndicator;
|
||||
class AsScene3009HorizontalIndicator;
|
||||
class AsScene3009Symbol;
|
||||
|
||||
class Scene3009 : public Scene {
|
||||
public:
|
||||
Scene3009(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene3009() override;
|
||||
bool isTurning();
|
||||
protected:
|
||||
int _lockSymbolsPart1Countdown;
|
||||
int _lockSymbolsPart2Countdown;
|
||||
SmackerPlayer *_cannonSmackerPlayer;
|
||||
Sprite *_ssFireCannonButton;
|
||||
SsScene3009SymbolEdges *_ssSymbolEdges[2];
|
||||
SsScene3009TargetLine *_ssTargetLines[2];
|
||||
AsScene3009VerticalIndicator *_asVerticalIndicator;
|
||||
AsScene3009HorizontalIndicator *_asHorizontalIndicator;
|
||||
AsScene3009Symbol *_asSymbols[6];
|
||||
uint32 _cannonTargetStatus;
|
||||
uint32 _correctSymbols[6];
|
||||
bool _keepVideo;
|
||||
bool _moveCannonLeftFirst;
|
||||
bool _isTurning;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void playActionVideo();
|
||||
bool isSymbolsPart1Solved();
|
||||
bool isSymbolsPart2Solved();
|
||||
void openSmacker(uint32 fileHash, bool keepLastFrame);
|
||||
};
|
||||
|
||||
class SsScene3010DeadBoltButton;
|
||||
class AsScene3010DeadBolt;
|
||||
|
||||
class Scene3010 : public Scene {
|
||||
public:
|
||||
Scene3010(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
int _countdown;
|
||||
bool _doorUnlocked;
|
||||
bool _checkUnlocked;
|
||||
SsScene3010DeadBoltButton *_ssDeadBoltButtons[3];
|
||||
AsScene3010DeadBolt *_asDeadBolts[3];
|
||||
bool _boltUnlocked[3];
|
||||
bool _boltUnlocking[3];
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene3011Symbol;
|
||||
|
||||
class Scene3011 : public Scene {
|
||||
public:
|
||||
Scene3011(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_ssButton;
|
||||
AsScene3011Symbol *_asSymbols[12];
|
||||
int _updateStatus;
|
||||
bool _buttonClicked;
|
||||
int _countdown;
|
||||
int _noisySymbolIndex;
|
||||
int _currentSymbolIndex;
|
||||
int _noisyRandomSymbolIndex;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void fadeIn();
|
||||
void fadeOut();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE3000_H */
|
||||
742
engines/neverhood/modules/module3000_sprites.cpp
Normal file
742
engines/neverhood/modules/module3000_sprites.cpp
Normal file
@@ -0,0 +1,742 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module3000.h"
|
||||
#include "neverhood/modules/module3000_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Scene3009
|
||||
|
||||
enum {
|
||||
kCTSNull = 0,
|
||||
kCTSBreakWall = 1,
|
||||
kCTSWall = 2,
|
||||
kCTSEmptyness = 3,
|
||||
kCTSFireRobotNoTarget = 4,
|
||||
kCTSFireRobotIsTarget = 5,
|
||||
kCTSFireNoRobot = 6,
|
||||
kCTSRaiseCannon = 7,
|
||||
kCTSRightRobotNoTarget = 8,
|
||||
kCTSRightRobotIsTarget = 9,
|
||||
kCTSRightNoRobot = 10,
|
||||
kCTSLeftRobotNoTarget = 11,
|
||||
kCTSLeftRobotIsTarget = 12,
|
||||
kCTSLeftNoRobot = 13,
|
||||
kCTSLowerCannon = 14,
|
||||
kCTSCount = 14
|
||||
};
|
||||
|
||||
static const uint32 kSsScene3009SymbolEdgesFileHashes[] = {
|
||||
0x618827A0,
|
||||
0xB1A92322
|
||||
};
|
||||
|
||||
static const uint32 kSsScene3009TargetLineFileHashes[] = {
|
||||
0x4011018C,
|
||||
0x15086623
|
||||
};
|
||||
|
||||
static const NPoint kAsScene3009SymbolPoints[] = {
|
||||
{289, 338},
|
||||
{285, 375},
|
||||
{284, 419},
|
||||
{456, 372},
|
||||
{498, 372},
|
||||
{541, 372}
|
||||
};
|
||||
|
||||
static const uint32 kAsScene3009SymbolFileHashes[] = {
|
||||
0x24542582,
|
||||
0x1CD61D96
|
||||
};
|
||||
|
||||
static const uint32 kSsScene3009SymbolArrowFileHashes1[] = {
|
||||
0x24016060,
|
||||
0x21216221,
|
||||
0x486160A0,
|
||||
0x42216422,
|
||||
0x90A16120,
|
||||
0x84216824,
|
||||
0x08017029,
|
||||
0x08217029,
|
||||
0x10014032,
|
||||
0x10214032,
|
||||
0x20012004,
|
||||
0x20212004
|
||||
};
|
||||
|
||||
static const uint32 kSsScene3009SymbolArrowFileHashes2[] = {
|
||||
0x40092024,
|
||||
0x01636002,
|
||||
0x8071E028,
|
||||
0x02A56064,
|
||||
0x00806031,
|
||||
0x052960A8,
|
||||
0x0A116130,
|
||||
0x0A316130,
|
||||
0x14216200,
|
||||
0x14016200,
|
||||
0x28416460,
|
||||
0x28616460
|
||||
};
|
||||
|
||||
SsScene3009FireCannonButton::SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene)
|
||||
: StaticSprite(vm, 1400), _parentScene(parentScene), _isClicked(false) {
|
||||
|
||||
loadSprite(0x120B24B0, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
|
||||
setVisible(false);
|
||||
SetUpdateHandler(&SsScene3009FireCannonButton::update);
|
||||
SetMessageHandler(&SsScene3009FireCannonButton::handleMessage);
|
||||
loadSound(0, 0x3901B44F);
|
||||
}
|
||||
|
||||
void SsScene3009FireCannonButton::update() {
|
||||
updatePosition();
|
||||
if (_isClicked && !isSoundPlaying(0)) {
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene3009FireCannonButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (!_isClicked && !_parentScene->isTurning()) {
|
||||
_isClicked = true;
|
||||
setVisible(true);
|
||||
playSound(0);
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
SsScene3009SymbolEdges::SsScene3009SymbolEdges(NeverhoodEngine *vm, int index)
|
||||
: StaticSprite(vm, 1400), _blinkCountdown(0) {
|
||||
|
||||
loadSprite(kSsScene3009SymbolEdgesFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
|
||||
if (getGlobalVar(V_ROBOT_HIT))
|
||||
hide();
|
||||
else
|
||||
startBlinking();
|
||||
SetUpdateHandler(&SsScene3009SymbolEdges::update);
|
||||
}
|
||||
|
||||
void SsScene3009SymbolEdges::update() {
|
||||
if (_blinkCountdown != 0 && (--_blinkCountdown == 0)) {
|
||||
if (_blinkToggle) {
|
||||
setVisible(true);
|
||||
} else {
|
||||
setVisible(false);
|
||||
}
|
||||
updatePosition();
|
||||
_blinkCountdown = 3;
|
||||
_blinkToggle = !_blinkToggle;
|
||||
}
|
||||
}
|
||||
|
||||
void SsScene3009SymbolEdges::show() {
|
||||
setVisible(true);
|
||||
updatePosition();
|
||||
_blinkCountdown = 0;
|
||||
}
|
||||
|
||||
void SsScene3009SymbolEdges::hide() {
|
||||
setVisible(false);
|
||||
updatePosition();
|
||||
_blinkCountdown = 0;
|
||||
}
|
||||
|
||||
void SsScene3009SymbolEdges::startBlinking() {
|
||||
setVisible(true);
|
||||
updatePosition();
|
||||
_blinkCountdown = 3;
|
||||
_blinkToggle = true;
|
||||
}
|
||||
|
||||
SsScene3009TargetLine::SsScene3009TargetLine(NeverhoodEngine *vm, int index)
|
||||
: StaticSprite(vm, 1400) {
|
||||
|
||||
loadSprite(kSsScene3009TargetLineFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
void SsScene3009TargetLine::show() {
|
||||
setVisible(true);
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
SsScene3009SymbolArrow::SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index)
|
||||
: StaticSprite(vm, 1400), _asSymbol(asSymbol), _index(index), _enabled(true), _countdown(0) {
|
||||
|
||||
_incrDecr = _index % 2;
|
||||
|
||||
createSurface(1200, 33, 31);
|
||||
loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefPosition);
|
||||
_drawOffset.set(0, 0, 33, 31);
|
||||
_collisionBoundsOffset = _drawOffset;
|
||||
updateBounds();
|
||||
_needRefresh = true;
|
||||
|
||||
SetUpdateHandler(&SsScene3009SymbolArrow::update);
|
||||
SetMessageHandler(&SsScene3009SymbolArrow::handleMessage);
|
||||
loadSound(0, 0x2C852206);
|
||||
}
|
||||
|
||||
void SsScene3009SymbolArrow::hide() {
|
||||
_enabled = false;
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
void SsScene3009SymbolArrow::update() {
|
||||
updatePosition();
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefDrawOffset);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene3009SymbolArrow::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_enabled && _countdown == 0) {
|
||||
_countdown = 2;
|
||||
loadSprite(kSsScene3009SymbolArrowFileHashes1[_index], kSLFDefDrawOffset);
|
||||
playSound(0);
|
||||
sendMessage(_asSymbol, NM_KLAYMEN_CLIMB_LADDER, _incrDecr);
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene3009VerticalIndicator::AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index)
|
||||
: AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
|
||||
|
||||
_x = 300;
|
||||
_y = getGlobalVar(V_CANNON_RAISED) ? 52 : 266;
|
||||
createSurface1(0xC2463913, 1200);
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
setVisible(false);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene3009VerticalIndicator::handleMessage);
|
||||
}
|
||||
|
||||
void AsScene3009VerticalIndicator::show() {
|
||||
startAnimation(0xC2463913, 0, -1);
|
||||
setVisible(true);
|
||||
updatePosition();
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
uint32 AsScene3009VerticalIndicator::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_enabled) {
|
||||
sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene3009HorizontalIndicator::AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus)
|
||||
: AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
|
||||
|
||||
_x = getGlobalVar(V_CANNON_TURNED) ? 533 : 92;
|
||||
_y = 150;
|
||||
createSurface1(0xC0C12954, 1200);
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
setVisible(false);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene3009HorizontalIndicator::handleMessage);
|
||||
if (cannonTargetStatus == kCTSRightRobotNoTarget || cannonTargetStatus == kCTSRightRobotIsTarget || cannonTargetStatus == kCTSRightNoRobot) {
|
||||
SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
|
||||
_x = 280;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 AsScene3009HorizontalIndicator::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_enabled) {
|
||||
sendMessage(_parentScene, 0x2004, 0);
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene3009HorizontalIndicator::suMoveLeft() {
|
||||
_x -= 6;
|
||||
if (_x < 92) {
|
||||
SetSpriteUpdate(nullptr);
|
||||
_x = 92;
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene3009HorizontalIndicator::suMoveRight() {
|
||||
_x += 6;
|
||||
if (_x > 533) {
|
||||
SetSpriteUpdate(nullptr);
|
||||
_x = 533;
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene3009HorizontalIndicator::show() {
|
||||
startAnimation(0xC0C12954, 0, -1);
|
||||
setVisible(true);
|
||||
updatePosition();
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
void AsScene3009HorizontalIndicator::stMoveLeft() {
|
||||
_x = 533;
|
||||
SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveLeft);
|
||||
}
|
||||
|
||||
void AsScene3009HorizontalIndicator::stMoveRight() {
|
||||
_x = 330;
|
||||
SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
|
||||
}
|
||||
|
||||
AsScene3009Symbol::AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _symbolPosition(symbolPosition) {
|
||||
|
||||
_symbolIndex = getSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition);
|
||||
|
||||
_x = kAsScene3009SymbolPoints[_symbolPosition].x;
|
||||
_y = kAsScene3009SymbolPoints[_symbolPosition].y;
|
||||
createSurface1(kAsScene3009SymbolFileHashes[_symbolPosition / 3], 1200);
|
||||
startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
|
||||
_newStickFrameIndex = _symbolIndex;
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene3009Symbol::handleMessage);
|
||||
_ssArrowPrev = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 0);
|
||||
_parentScene->addCollisionSprite(_ssArrowPrev);
|
||||
_ssArrowNext = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 1);
|
||||
_parentScene->addCollisionSprite(_ssArrowNext);
|
||||
}
|
||||
|
||||
uint32 AsScene3009Symbol::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_KLAYMEN_CLIMB_LADDER:
|
||||
if (param.asInteger()) {
|
||||
if (_symbolIndex == 11)
|
||||
_symbolIndex = 0;
|
||||
else
|
||||
_symbolIndex++;
|
||||
} else {
|
||||
if (_symbolIndex == 0)
|
||||
_symbolIndex = 11;
|
||||
else
|
||||
_symbolIndex--;
|
||||
}
|
||||
startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
|
||||
_newStickFrameIndex = _symbolIndex;
|
||||
setSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition, _symbolIndex);
|
||||
if (_symbolPosition / 3 == 0) {
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
} else {
|
||||
sendMessage(_parentScene, 0x2003, 0);
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene3009Symbol::hide() {
|
||||
_ssArrowPrev->hide();
|
||||
_ssArrowNext->hide();
|
||||
}
|
||||
|
||||
// Scene3010
|
||||
|
||||
static const uint32 kScene3010ButtonNameHashes[] = {
|
||||
0x304008D2,
|
||||
0x40119852,
|
||||
0x01180951
|
||||
};
|
||||
|
||||
static const uint32 kScene3010DeadBoltButtonFileHashes1[] = {
|
||||
0x301024C2,
|
||||
0x20280580,
|
||||
0x30200452
|
||||
};
|
||||
|
||||
static const uint32 kScene3010DeadBoltButtonFileHashes2[] = {
|
||||
0x50C025A8,
|
||||
0x1020A0A0,
|
||||
0x5000A7E8
|
||||
};
|
||||
|
||||
static const NPoint kAsScene3010DeadBoltPoints[] = {
|
||||
{550, 307},
|
||||
{564, 415},
|
||||
{560, 514}
|
||||
};
|
||||
|
||||
static const uint32 kAsScene3010DeadBoltFileHashes2[] = {
|
||||
0x181A0042,
|
||||
0x580A08F2,
|
||||
0x18420076
|
||||
};
|
||||
|
||||
static const uint32 kAsScene3010DeadBoltFileHashes1[] = {
|
||||
0x300E105A,
|
||||
0x804E0052,
|
||||
0x040E485A
|
||||
};
|
||||
|
||||
SsScene3010DeadBoltButton::SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled)
|
||||
: StaticSprite(vm, 900), _parentScene(parentScene), _buttonLocked(false), _countdown1(0), _countdown2(0), _buttonIndex(buttonIndex) {
|
||||
|
||||
_buttonEnabled = getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_buttonIndex]) != 0;
|
||||
createSurface(400, 88, 95);
|
||||
setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
|
||||
if (initDisabled)
|
||||
disableButton();
|
||||
else if (_buttonEnabled)
|
||||
_countdown1 = initCountdown * 12 + 1;
|
||||
loadSound(0, 0xF4217243);
|
||||
loadSound(1, 0x44049000);
|
||||
loadSound(2, 0x6408107E);
|
||||
SetUpdateHandler(&SsScene3010DeadBoltButton::update);
|
||||
SetMessageHandler(&SsScene3010DeadBoltButton::handleMessage);
|
||||
}
|
||||
|
||||
void SsScene3010DeadBoltButton::update() {
|
||||
|
||||
if (_countdown1 != 0 && (--_countdown1 == 0)) {
|
||||
playSound(0);
|
||||
setVisible(false);
|
||||
setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
|
||||
}
|
||||
|
||||
if (_countdown2 != 0 && (--_countdown2 == 0)) {
|
||||
setVisible(true);
|
||||
setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32 SsScene3010DeadBoltButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (!_buttonLocked && _countdown1 == 0) {
|
||||
if (_buttonEnabled) {
|
||||
playSound(1);
|
||||
playSound(2);
|
||||
setVisible(true);
|
||||
_buttonLocked = true;
|
||||
sendMessage(_parentScene, 0x2000, _buttonIndex);
|
||||
} else {
|
||||
sendMessage(_parentScene, NM_POSITION_CHANGE, _buttonIndex);
|
||||
}
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void SsScene3010DeadBoltButton::disableButton() {
|
||||
_buttonLocked = true;
|
||||
setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
void SsScene3010DeadBoltButton::setSprite(uint32 fileHash) {
|
||||
loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset);
|
||||
}
|
||||
|
||||
void SsScene3010DeadBoltButton::setCountdown(int count) {
|
||||
_countdown2 = count * 18 + 1;
|
||||
}
|
||||
|
||||
AsScene3010DeadBolt::AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _boltIndex(boltIndex), _soundToggle(true),
|
||||
_unlocked(false), _locked(false), _countdown(0) {
|
||||
|
||||
_x = kAsScene3010DeadBoltPoints[_boltIndex].x;
|
||||
_y = kAsScene3010DeadBoltPoints[_boltIndex].y;
|
||||
|
||||
if (getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_boltIndex])) {
|
||||
createSurface1(kAsScene3010DeadBoltFileHashes1[_boltIndex], 1200);
|
||||
startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
|
||||
loadSound(0, 0x46005BC4);
|
||||
} else {
|
||||
createSurface1(kAsScene3010DeadBoltFileHashes2[_boltIndex], 1200);
|
||||
startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
|
||||
loadSound(0, 0x420073DC);
|
||||
loadSound(1, 0x420073DC);
|
||||
}
|
||||
|
||||
setVisible(false);
|
||||
stIdle();
|
||||
if (initUnlocked)
|
||||
unlock(true);
|
||||
|
||||
_needRefresh = true;
|
||||
AnimatedSprite::updatePosition();
|
||||
|
||||
}
|
||||
|
||||
void AsScene3010DeadBolt::update() {
|
||||
updateAnim();
|
||||
updatePosition();
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
stDisabled();
|
||||
}
|
||||
}
|
||||
|
||||
uint32 AsScene3010DeadBolt::hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene3010DeadBolt::stIdle() {
|
||||
stopAnimation();
|
||||
SetUpdateHandler(&AsScene3010DeadBolt::update);
|
||||
SetMessageHandler(&Sprite::handleMessage);
|
||||
_locked = false;
|
||||
}
|
||||
|
||||
void AsScene3010DeadBolt::unlock(bool skipAnim) {
|
||||
if (!_unlocked) {
|
||||
setVisible(true);
|
||||
if (skipAnim) {
|
||||
startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], -1, 0);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
} else {
|
||||
startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
|
||||
SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
|
||||
FinalizeState(&AsScene3010DeadBolt::stIdleMessage);
|
||||
NextState(&AsScene3010DeadBolt::stIdle);
|
||||
playSound(0);
|
||||
}
|
||||
_unlocked = true;
|
||||
loadSound(2, 0x4010C345);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene3010DeadBolt::stIdleMessage() {
|
||||
stopAnimation();
|
||||
SetMessageHandler(&Sprite::handleMessage);
|
||||
sendMessage(_parentScene, 0x2001, _boltIndex);
|
||||
}
|
||||
|
||||
void AsScene3010DeadBolt::lock() {
|
||||
if (!_locked) {
|
||||
_locked = true;
|
||||
setVisible(true);
|
||||
startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
|
||||
SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
|
||||
FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
|
||||
NextState(&AsScene3010DeadBolt::stIdle);
|
||||
if (_soundToggle) {
|
||||
playSound(0);
|
||||
} else {
|
||||
playSound(1);
|
||||
}
|
||||
_soundToggle = !_soundToggle;
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene3010DeadBolt::setCountdown(int count) {
|
||||
_countdown = count * 18 + 1;
|
||||
}
|
||||
|
||||
void AsScene3010DeadBolt::stDisabled() {
|
||||
setVisible(true);
|
||||
startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
|
||||
SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
|
||||
FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
|
||||
NextState(&AsScene3010DeadBolt::stIdle);
|
||||
_playBackwards = true;
|
||||
playSound(2);
|
||||
}
|
||||
|
||||
void AsScene3010DeadBolt::stDisabledMessage() {
|
||||
setVisible(false);
|
||||
sendMessage(_parentScene, 0x2003, _boltIndex);
|
||||
}
|
||||
|
||||
// Scene3011
|
||||
|
||||
static const uint32 kAsScene3011SymbolFileHashes[] = {
|
||||
0x00C88050,
|
||||
0x01488050,
|
||||
0x02488050,
|
||||
0x04488050,
|
||||
0x08488050,
|
||||
0x10488050,
|
||||
0x20488050,
|
||||
0x40488050,
|
||||
0x80488050,
|
||||
0x00488051,
|
||||
0x00488052,
|
||||
0x00488054,
|
||||
0x008B0000,
|
||||
0x008D0000,
|
||||
0x00810000,
|
||||
0x00990000,
|
||||
0x00A90000,
|
||||
0x00C90000,
|
||||
0x00090000,
|
||||
0x01890000,
|
||||
0x02890000,
|
||||
0x04890000,
|
||||
0x08890000,
|
||||
0x10890000
|
||||
};
|
||||
|
||||
SsScene3011Button::SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag)
|
||||
: StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
|
||||
|
||||
loadSprite(flag ? 0x11282020 : 0x994D0433, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
|
||||
setVisible(false);
|
||||
loadSound(0, 0x44061000);
|
||||
SetUpdateHandler(&SsScene3011Button::update);
|
||||
SetMessageHandler(&SsScene3011Button::handleMessage);
|
||||
}
|
||||
|
||||
void SsScene3011Button::update() {
|
||||
updatePosition();
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene3011Button::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
StaticSprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_countdown == 0) {
|
||||
setVisible(true);
|
||||
_countdown = 4;
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
playSound(0);
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene3011Symbol::AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol)
|
||||
: AnimatedSprite(vm, 1000), _symbolIndex(symbolIndex), _largeSymbol(largeSymbol), _isNoisy(false) {
|
||||
|
||||
if (_largeSymbol) {
|
||||
_x = 310;
|
||||
_y = 200;
|
||||
createSurface1(kAsScene3011SymbolFileHashes[_symbolIndex], 1200);
|
||||
loadSound(0, 0x6052C60F);
|
||||
loadSound(1, 0x6890433B);
|
||||
} else {
|
||||
_symbolIndex = 12;
|
||||
_x = symbolIndex * 39 + 96;
|
||||
_y = 225;
|
||||
createSurface(1200, 41, 48);
|
||||
loadSound(0, 0x64428609);
|
||||
loadSound(1, 0x7080023B);
|
||||
}
|
||||
setVisible(false);
|
||||
_needRefresh = true;
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
}
|
||||
|
||||
void AsScene3011Symbol::show(bool isNoisy) {
|
||||
_isNoisy = isNoisy;
|
||||
startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
|
||||
setVisible(true);
|
||||
if (_isNoisy) {
|
||||
playSound(1);
|
||||
} else {
|
||||
playSound(0);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene3011Symbol::hide() {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
void AsScene3011Symbol::stopSymbolSound() {
|
||||
if (_isNoisy) {
|
||||
stopSound(1);
|
||||
} else {
|
||||
stopSound(0);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene3011Symbol::change(int symbolIndex, bool isNoisy) {
|
||||
_symbolIndex = symbolIndex;
|
||||
_isNoisy = isNoisy;
|
||||
startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
|
||||
setVisible(true);
|
||||
if (_isNoisy) {
|
||||
playSound(1);
|
||||
} else {
|
||||
playSound(0);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
184
engines/neverhood/modules/module3000_sprites.h
Normal file
184
engines/neverhood/modules/module3000_sprites.h
Normal file
@@ -0,0 +1,184 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE3000_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE3000_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/modules/module1200.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Scene3009
|
||||
|
||||
class Scene3009;
|
||||
|
||||
class SsScene3009FireCannonButton : public StaticSprite {
|
||||
public:
|
||||
SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene);
|
||||
protected:
|
||||
Scene3009 *_parentScene;
|
||||
bool _isClicked;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsScene3009SymbolEdges : public StaticSprite {
|
||||
public:
|
||||
SsScene3009SymbolEdges(NeverhoodEngine *vm, int index);
|
||||
void show();
|
||||
void hide();
|
||||
void startBlinking();
|
||||
protected:
|
||||
int _blinkCountdown;
|
||||
bool _blinkToggle;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsScene3009TargetLine : public StaticSprite {
|
||||
public:
|
||||
SsScene3009TargetLine(NeverhoodEngine *vm, int index);
|
||||
void show();
|
||||
};
|
||||
|
||||
class SsScene3009SymbolArrow : public StaticSprite {
|
||||
public:
|
||||
SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index);
|
||||
void hide();
|
||||
protected:
|
||||
Sprite *_asSymbol;
|
||||
int _index;
|
||||
int _incrDecr;
|
||||
bool _enabled;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene3009VerticalIndicator : public AnimatedSprite {
|
||||
public:
|
||||
AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index);
|
||||
void show();
|
||||
protected:
|
||||
Scene3009 *_parentScene;
|
||||
bool _enabled;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene3009HorizontalIndicator : public AnimatedSprite {
|
||||
public:
|
||||
AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus);
|
||||
void show();
|
||||
void stMoveLeft();
|
||||
void stMoveRight();
|
||||
protected:
|
||||
Scene3009 *_parentScene;
|
||||
bool _enabled;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suMoveLeft();
|
||||
void suMoveRight();
|
||||
};
|
||||
|
||||
class AsScene3009Symbol : public AnimatedSprite {
|
||||
public:
|
||||
AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition);
|
||||
void hide();
|
||||
protected:
|
||||
Scene3009 *_parentScene;
|
||||
int _symbolPosition;
|
||||
uint32 _symbolIndex;
|
||||
SsScene3009SymbolArrow *_ssArrowPrev;
|
||||
SsScene3009SymbolArrow *_ssArrowNext;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
// Scene3010
|
||||
|
||||
class SsScene3010DeadBoltButton : public StaticSprite {
|
||||
public:
|
||||
SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled);
|
||||
void setCountdown(int count);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _buttonIndex;
|
||||
bool _buttonEnabled;
|
||||
bool _buttonLocked;
|
||||
int _countdown1;
|
||||
int _countdown2;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void disableButton();
|
||||
void setSprite(uint32 fileHash);
|
||||
};
|
||||
|
||||
class AsScene3010DeadBolt : public AnimatedSprite {
|
||||
public:
|
||||
AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked);
|
||||
void setCountdown(int count);
|
||||
void lock();
|
||||
void unlock(bool skipAnim);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _boltIndex;
|
||||
int _countdown;
|
||||
bool _soundToggle;
|
||||
bool _unlocked;
|
||||
bool _locked;
|
||||
void update();
|
||||
uint32 hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stIdle();
|
||||
void stIdleMessage();
|
||||
void stDisabled();
|
||||
void stDisabledMessage();
|
||||
};
|
||||
|
||||
// Scene3011
|
||||
|
||||
class SsScene3011Button : public StaticSprite {
|
||||
public:
|
||||
SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene3011Symbol : public AnimatedSprite {
|
||||
public:
|
||||
AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol);
|
||||
void show(bool isNoisy);
|
||||
void hide();
|
||||
void stopSymbolSound();
|
||||
void change(int symbolIndex, bool isNoisy);
|
||||
int getSymbolIndex() { return _largeSymbol ? _symbolIndex : _symbolIndex - 12; }
|
||||
protected:
|
||||
bool _largeSymbol;
|
||||
bool _isNoisy;
|
||||
int _symbolIndex;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE3000_SPRITES_H */
|
||||
Reference in New Issue
Block a user