Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene01_fixEntrance() {
GameVar *var = g_nmi->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME");
if (var->getSubVarAsInt("Entrance") == TrubaLeft)
var->setSubVarAsInt("Entrance", TrubaRight);
}
void scene01_initScene(Scene *sc, int entrance) {
g_vars->scene01_picSc01Osk = sc->getPictureObjectById(PIC_SC1_OSK, 0);
g_vars->scene01_picSc01Osk->_flags &= 0xFFFB;
g_vars->scene01_picSc01Osk2 = sc->getPictureObjectById(PIC_SC1_OSK2, 0);
g_vars->scene01_picSc01Osk2->_flags &= 0xFFFB;
if (g_nmi->getObjectState(sO_EggCracker) == g_nmi->getObjectEnumState(sO_EggCracker, sO_DidNotCrackEgg)) {
PictureObject *pic = sc->getPictureObjectById(PIC_SC1_KUCHKA, 0);
if (pic)
pic->_flags &= 0xFFFB;
}
if (entrance != TrubaLeft) {
StaticANIObject *bootAnim = sc->getStaticANIObject1ById(ANI_BOOT_1, -1);
if (bootAnim)
bootAnim->_flags &= ~0x04;
}
g_nmi->lift_setButton(sO_Level2, ST_LBN_2N);
}
int sceneHandler01(ExCommand *cmd) {
int res = 0;
if (cmd->_messageKind != 17)
return 0;
if (cmd->_messageNum > MSG_SC1_SHOWOSK) {
if (cmd->_messageNum == MSG_SC1_UTRUBACLICK)
handleObjectInteraction(g_nmi->_aniMan, g_nmi->_currentScene->getPictureObjectById(PIC_SC1_LADDER, 0), 0);
return 0;
}
if (cmd->_messageNum == MSG_SC1_SHOWOSK) {
g_vars->scene01_picSc01Osk->_flags |= 4;
g_vars->scene01_picSc01Osk->_priority = 20;
g_vars->scene01_picSc01Osk2->_priority = 21;
return 0;
}
if (cmd->_messageNum != 0x21) {
if (cmd->_messageNum == MSG_SC1_SHOWOSK2) {
g_vars->scene01_picSc01Osk2->_flags |= 4;
g_vars->scene01_picSc01Osk2->_priority = 20;
g_vars->scene01_picSc01Osk->_priority = 21;
return 0;
}
return 0;
}
if (g_nmi->_aniMan2) {
if (g_nmi->_aniMan2->_ox < g_nmi->_sceneRect.left + 200) {
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.left - 300;
}
if (g_nmi->_aniMan2->_ox > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.right + 300;
res = 1;
}
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
return res;
}
} // End of namespace NGI

View File

@@ -0,0 +1,141 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
#include "ngi/floaters.h"
namespace NGI {
void scene02_initScene(Scene *sc) {
g_vars->scene02_guvTheDrawer = sc->getStaticANIObject1ById(ANI_DADAYASHIK, -1);
if (g_nmi->getObjectState(sO_GuvTheDrawer) == g_nmi->getObjectEnumState(sO_GuvTheDrawer, sO_IsSleeping)) {
Scene *s = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
g_vars->scene02_guvTheDrawer->changeStatics2(ST_DYAS_LIES);
g_nmi->_currentScene = s;
}
g_vars->scene02_boxDelay = 0;
StaticANIObject *box = sc->getStaticANIObject1ById(ANI_SC2_BOX, -1);
if (box && box->_flags & 4) {
g_vars->scene02_boxOpen = false;
} else {
g_vars->scene02_boxOpen = true;
g_vars->scene02_boxDelay = 100 * g_nmi->_rnd.getRandomNumber(32767) + 150;
}
g_nmi->_floaters->init(g_nmi->_gameLoader->_gameVar->getSubVarByName("SC_2"));
}
void sceneHandler02_ladderClick() {
handleObjectInteraction(g_nmi->_aniMan2, g_nmi->_currentScene->getPictureObjectById(PIC_SC2_DTRUBA, 0), 0);
}
void sceneHandler02_showLadder() {
g_nmi->_currentScene->getPictureObjectById(PIC_SC2_LADDER, 0)->_flags |= 4;
}
void sceneHandler02_hideLadder() {
g_nmi->_currentScene->getPictureObjectById(PIC_SC2_LADDER, 0)->_flags &= 0xfffb;
g_nmi->_aniMan2->_priority = 25;
}
int sceneHandler02(ExCommand *ex) {
int res = 0;
if (ex->_messageKind != 17)
return 0;
switch(ex->_messageNum) {
case MSG_SC2_LADDERCLICK:
sceneHandler02_ladderClick();
break;
case MSG_SC2_SHOWLADDER:
sceneHandler02_showLadder();
break;
case MSG_SC2_PUTMANUP:
g_nmi->_aniMan2->_priority = 0;
break;
case MSG_SC2_HIDELADDER:
sceneHandler02_hideLadder();
break;
case 33:
if (g_nmi->_aniMan2) {
if (g_nmi->_aniMan2->_ox < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.left - 300;
if (g_nmi->_aniMan2->_ox > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.right + 300;
res = 1;
}
if (g_vars->scene02_boxOpen) {
if (g_vars->scene02_boxDelay >= 1) {
--g_vars->scene02_boxDelay;
} else if (g_nmi->_floaters->_array2.size() >= 1) {
if (g_nmi->_floaters->_array2[0].val5 == -50) {
g_nmi->_floaters->stopAll();
g_vars->scene02_boxOpen = false;
g_vars->scene02_boxDelay = 100 * g_nmi->_rnd.getRandomNumber(32767) + 150;
} else {
g_nmi->_floaters->_array2[0].val3 = -50;
}
} else {
g_nmi->_floaters->genFlies(g_nmi->_currentScene, g_nmi->_rnd.getRandomNumber(700) + 100, -50, 0, 0);
g_vars->scene02_boxDelay = 500 * g_nmi->_rnd.getRandomNumber(32767) + 1000;
}
}
g_nmi->_floaters->update();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
return res;
}
} // End of namespace NGI

View File

@@ -0,0 +1,332 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void NGIEngine::setSwallowedEggsState() {
GameVar *v = _gameLoader->_gameVar->getSubVarByName("OBJSTATES")->getSubVarByName(sO_GulpedEggs);
g_vars->swallowedEgg1 = v->getSubVarByName(sO_Egg1);
g_vars->swallowedEgg2 = v->getSubVarByName(sO_Egg2);
g_vars->swallowedEgg3 = v->getSubVarByName(sO_Egg3);
g_vars->swallowedEgg1->_value.intValue = 0;
g_vars->swallowedEgg2->_value.intValue = 0;
g_vars->swallowedEgg3->_value.intValue = 0;
}
void scene03_initScene(Scene *sc) {
debugC(1, kDebugSceneLogic, "scene03_initScene()");
#if 0
Inventory2 *inv = getGameLoaderInventory();
inv->addItem(ANI_INV_EGGAPL, 1);
inv->addItem(ANI_INV_EGGDOM, 1);
inv->addItem(ANI_INV_EGGCOIN, 1);
inv->addItem(ANI_INV_EGGBOOT, 1);
inv->addItem(ANI_INV_EGGGLS, 1);
inv->rebuildItemRects();
#endif
g_vars->scene03_eggeater = sc->getStaticANIObject1ById(ANI_EGGEATER, -1);
g_vars->scene03_domino = sc->getStaticANIObject1ById(ANI_DOMINO_3, -1);
GameVar *v = g_nmi->_gameLoader->_gameVar->getSubVarByName("OBJSTATES")->getSubVarByName(sO_GulpedEggs);
g_vars->swallowedEgg1 = v->getSubVarByName(sO_Egg1);
g_vars->swallowedEgg2 = v->getSubVarByName(sO_Egg2);
g_vars->swallowedEgg3 = v->getSubVarByName(sO_Egg3);
g_nmi->lift_setButton(sO_Level2, ST_LBN_2N);
g_nmi->lift_init(sc, QU_SC3_ENTERLIFT, QU_SC3_EXITLIFT);
debugC(2, kDebugSceneLogic, "scene03: egg1: %d egg2: %d egg3: %d", g_vars->swallowedEgg1->_value.intValue,
g_vars->swallowedEgg2->_value.intValue, g_vars->swallowedEgg3->_value.intValue);
}
void scene03_setEaterState() {
if (g_nmi->getObjectState(sO_EggGulperGaveCoin) == g_nmi->getObjectEnumState(sO_EggGulperGaveCoin, sO_Yes)) {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene03_eggeater, ST_EGTR_SLIM, QU_EGTR_SLIMSHOW, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene03_eggeater, ST_EGTR_MID1, QU_EGTR_MD1_SHOW, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene03_eggeater, ST_EGTR_MID2, QU_EGTR_MD2_SHOW, 0);
}
}
int scene03_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_cursorId == PIC_CSR_DEFAULT && g_nmi->_objectIdAtCursor == PIC_SC3_DOMIN && g_vars->scene03_domino) {
if (g_vars->scene03_domino->_flags & 4)
g_nmi->_cursorId = PIC_CSR_ITN;
}
return g_nmi->_cursorId;
}
void sceneHandler03_eaterFat() {
debugC(2, kDebugSceneLogic, "scene03: eaterFat");
g_vars->scene03_eggeater->_flags &= 0xFF7F;
g_vars->scene03_eggeater->startAnim(MV_EGTR_FATASK, 0, -1);
}
void sceneHandler03_swallowEgg(int item) {
debugC(2, kDebugSceneLogic, "scene03: swallowEgg");
if (!g_vars->swallowedEgg1->_value.intValue) {
g_vars->swallowedEgg1->_value.intValue = item;
debugC(2, kDebugSceneLogic, "scene03: setting egg1: %d", g_vars->swallowedEgg1->_value.intValue);
} else if (!g_vars->swallowedEgg2->_value.intValue) {
g_vars->swallowedEgg2->_value.intValue = item;
debugC(2, kDebugSceneLogic, "scene03: setting egg2: %d", g_vars->swallowedEgg2->_value.intValue);
} else if (!g_vars->swallowedEgg3->_value.intValue) {
g_vars->swallowedEgg3->_value.intValue = item;
debugC(2, kDebugSceneLogic, "scene03: setting egg3: %d", g_vars->swallowedEgg3->_value.intValue);
g_nmi->setObjectState(sO_EggGulperGaveCoin, g_nmi->getObjectEnumState(sO_EggGulperGaveCoin, sO_Yes));
scene03_setEaterState();
}
}
void sceneHandler03_giveItem(ExCommand *ex) {
debugC(2, kDebugSceneLogic, "scene03: giveItem");
if (ex->_parentId == ANI_INV_EGGAPL || ex->_parentId == ANI_INV_EGGDOM ||
ex->_parentId == ANI_INV_EGGCOIN || ex->_parentId == ANI_INV_EGGBOOT ||
ex->_parentId == ANI_INV_EGGGLS)
sceneHandler03_swallowEgg(ex->_parentId);
}
int sceneHandler03_swallowedEgg1State() {
return g_vars->swallowedEgg1->_value.intValue;
}
void sceneHandler03_giveCoin(ExCommand *ex) {
debugC(2, kDebugSceneLogic, "scene03: giveCoin");
MessageQueue *mq = g_nmi->_globalMessageQueueList->getMessageQueueById(ex->_parId);
if (mq && mq->getCount() > 0) {
ExCommand *ex0 = mq->getExCommandByIndex(0);
ExCommand *ex1 = mq->getExCommandByIndex(1);
if (sceneHandler03_swallowedEgg1State()) {
ex0->_messageKind = 1;
ex1->_messageKind = 1;
getGameLoaderInventory()->removeItem(ANI_INV_COIN, 1);
} else {
ex0->_messageKind = 0;
ex0->_excFlags |= 1;
ex1->_messageKind = 0;
ex1->_excFlags |= 1;
g_vars->scene03_eggeater->_flags &= 0xFF7Fu;
}
}
}
void sceneHandler03_goLadder() {
handleObjectInteraction(g_nmi->_aniMan, g_nmi->_currentScene->getPictureObjectById(PIC_SC3_LADDER, 0), 0);
}
void sceneHandler03_pushEggStack() {
debugC(2, kDebugSceneLogic, "scene03: pushEggStack");
g_vars->swallowedEgg1->_value.intValue = g_vars->swallowedEgg2->_value.intValue;
g_vars->swallowedEgg2->_value.intValue = g_vars->swallowedEgg3->_value.intValue;
g_vars->swallowedEgg3->_value.intValue = 0;
if (g_vars->swallowedEgg2->_value.intValue == ANI_INV_EGGBOOT
&& g_vars->swallowedEgg1->_value.intValue == ANI_INV_EGGAPL) {
g_vars->swallowedEgg1->_value.intValue = ANI_INV_EGGBOOT;
g_vars->swallowedEgg2->_value.intValue = ANI_INV_EGGAPL;
}
}
void sceneHandler03_releaseEgg() {
debugC(2, kDebugSceneLogic, "scene03: releaseEgg");
g_vars->scene03_eggeater->_flags &= 0xFF7F;
g_vars->scene03_eggeater->show1(-1, -1, -1, 0);
}
void sceneHandler03_takeEgg(ExCommand *ex) {
debugC(2, kDebugSceneLogic, "scene03: taking egg");
MessageQueue *mq = g_nmi->_globalMessageQueueList->getMessageQueueById(ex->_parId);
if (mq && mq->getCount() > 0) {
ExCommand *ex0 = mq->getExCommandByIndex(0);
ExCommand *ex1 = mq->getExCommandByIndex(1);
int egg1 = sceneHandler03_swallowedEgg1State();
if (egg1 && ex0) {
ex0->_parentId = egg1;
sceneHandler03_pushEggStack();
}
if ( g_vars->swallowedEgg1->_value.intValue == ANI_INV_EGGAPL
&& !g_vars->swallowedEgg2->_value.intValue
&& !g_vars->swallowedEgg3->_value.intValue
&& ex1) {
if (ex1->_objtype == kObjTypeObjstateCommand) {
ObjstateCommand *com = static_cast<ObjstateCommand *>(ex1);
com->_value = g_nmi->getObjectEnumState(sO_EggGulper, sO_WantsNothing);
}
}
}
}
int sceneHandler03(ExCommand *ex) {
if (ex->_messageKind != 17 && ex->_messageNum != 33)
debugC(3, kDebugSceneLogic, "scene03: got message: kind %d, num: %d", ex->_messageKind, ex->_messageNum);
if (ex->_messageKind != 17) {
if (ex->_messageKind == 57)
sceneHandler03_giveItem(ex);
return 0;
}
switch (ex->_messageNum) {
case MSG_LIFT_EXITLIFT:
g_nmi->lift_exitSeq(ex);
break;
case MSG_LIFT_CLOSEDOOR:
g_nmi->lift_closedoorSeq();
break;
case MSG_SC3_ONTAKECOIN:
sceneHandler03_eaterFat();
break;
case MSG_LIFT_STARTEXITQUEUE:
g_nmi->lift_startExitQueue();
break;
case MSG_SC3_RELEASEEGG:
sceneHandler03_releaseEgg();
break;
case MSG_LIFT_CLICKBUTTON:
g_nmi->lift_clickButton();
break;
case MSG_SC3_HIDEDOMINO:
g_vars->scene03_domino->_flags &= 0xFFFB;
break;
case MSG_SC3_TAKEEGG:
sceneHandler03_takeEgg(ex);
break;
case MSG_LIFT_GO:
g_nmi->lift_goAnimation();
break;
case MSG_SC3_UTRUBACLICK:
sceneHandler03_goLadder();
break;
case MSG_SC3_TESTFAT:
sceneHandler03_giveCoin(ex);
break;
case 64:
g_nmi->lift_hoverButton(ex);
break;
case 29:
{
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(ex->_sceneClickX, ex->_sceneClickY);
if (ani && ani->_id == ANI_LIFTBUTTON) {
g_nmi->lift_animateButton(ani);
ex->_messageKind = 0;
return 0;
}
if (g_nmi->_currentScene->getPictureObjectIdAtPos(ex->_sceneClickX, ex->_sceneClickY) == PIC_SC3_DOMIN) {
if (g_vars->scene03_domino)
if (g_vars->scene03_domino->_flags & 4)
if (g_nmi->_aniMan->isIdle())
if (!(g_nmi->_aniMan->_flags & 0x100) && g_nmi->_msgObjectId2 != g_vars->scene03_domino->_id) {
handleObjectInteraction(g_nmi->_aniMan, g_vars->scene03_domino, ex->_param);
ex->_messageKind = 0;
return 0;
}
}
}
break;
case 33:
{
int res = 0;
if (g_nmi->_aniMan2) {
if (g_nmi->_aniMan2->_ox < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.left - 300;
if (g_nmi->_aniMan2->_ox > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.right + 300;
res = 1;
}
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
return res;
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,409 @@
/* 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 "ngi/ngi.h"
#include "ngi/gameloader.h"
#include "ngi/objects.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/statics.h"
#include "ngi/scene.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/messages.h"
#include "ngi/floaters.h"
#include "ngi/behavior.h"
namespace NGI {
void scene05_initScene(Scene *sc) {
debugC(1, kDebugSceneLogic, "scene05_initScene()");
#if 0
Inventory2 *inv = getGameLoaderInventory();
inv->addItem(ANI_INV_BOX, 1);
inv->rebuildItemRects();
#endif
g_vars->scene05_handle = sc->getStaticANIObject1ById(ANI_HANDLE, -1);
g_vars->scene05_wacko = sc->getStaticANIObject1ById(ANI_OTMOROZ, -1);
g_vars->scene05_bigHatch = sc->getStaticANIObject1ById(ANI_BIGLUK, -1);
g_vars->scene05_wackoTicker = 0;
g_vars->scene05_handleFlipper = 1;
g_vars->scene05_floatersTicker = 1000;
Scene *oldscene = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
debugC(2, kDebugSceneLogic, "scene05: Weird Wacko state: %d", g_nmi->getObjectState(sO_WeirdWacko));
if (g_nmi->getObjectState(sO_WeirdWacko) == g_nmi->getObjectEnumState(sO_WeirdWacko, sO_InGlasses)) {
debugC(2, kDebugSceneLogic, "scene05: In glasses");
g_vars->scene05_wacko->changeStatics2(ST_OTM_GLS_LEFT);
g_vars->scene05_bigHatch->changeStatics2(ST_BLK_CLOSED);
g_vars->scene05_handle->changeStatics2(ST_HDL_UP);
g_vars->scene05_handle->_flags |= 4;
} else if (g_nmi->getObjectState(sO_WeirdWacko) == g_nmi->getObjectEnumState(sO_WeirdWacko, sO_WithDrawer)) {
debugC(2, kDebugSceneLogic, "scene05: With Drawer");
g_vars->scene05_wacko->changeStatics2(ST_OTM_BOX_LEFT);
g_vars->scene05_bigHatch->changeStatics2(ST_BLK_CLOSED);
g_vars->scene05_handle->changeStatics2(ST_HDL_UP);
g_vars->scene05_handle->_flags |= 4;
} else {
if (g_nmi->getObjectState(sO_WeirdWacko) != g_nmi->getObjectEnumState(sO_WeirdWacko, sO_WithPlunger)) {
debugC(2, kDebugSceneLogic, "scene05: Without plunger");
g_vars->scene05_handle->changeStatics2(ST_HDL_BROKEN);
g_vars->scene05_bigHatch->changeStatics2(ST_BLK_CLOSED);
} else {
debugC(2, kDebugSceneLogic, "scene05: With plunger");
}
g_vars->scene05_wacko->changeStatics2(ST_OTM_VNT_LEFT);
}
g_nmi->_currentScene = oldscene;
}
void sceneHandler05_makeManFlight() {
int qid;
if (!g_vars->scene05_bigHatch->_statics || g_vars->scene05_bigHatch->_statics->_staticsId != ST_BLK_OPEN)
qid = QU_SC5_MANBUMP;
else
qid = QU_SC5_MANFLY;
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(qid), 0, 0);
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
}
void sceneHandler05_makeWackoFeedback() {
int staticsId1;
int staticsId2;
if (g_nmi->getObjectState(sO_WeirdWacko) == g_nmi->getObjectEnumState(sO_WeirdWacko, sO_InGlasses)) {
staticsId1 = ST_OTM_GLS_LEFT;
staticsId2 = (g_vars->scene05_handle->_statics->_staticsId == ST_HDL_DOWN) ? MV_OTM_HANDLEUP : MV_OTM_HANDLEDOWN;
} else if (g_nmi->getObjectState(sO_WeirdWacko) != g_nmi->getObjectEnumState(sO_WeirdWacko, sO_WithDrawer)) {
return;
} else {
staticsId1 = ST_OTM_BOX_LEFT;
staticsId2 = (g_vars->scene05_handle->_statics->_staticsId == ST_HDL_DOWN) ? MV_OTM_BOXHANDLEUP : MV_OTM_BOXHANDLEDOWN;
}
if (g_vars->scene05_wacko->_movement)
g_vars->scene05_wacko->changeStatics2(g_vars->scene05_wacko->_movement->_staticsObj2->_staticsId);
if (staticsId1 == g_vars->scene05_wacko->_statics->_staticsId) {
g_vars->scene05_wacko->startAnim(staticsId2, 0, -1);
} else {
MessageQueue *mq = g_vars->scene05_wacko->changeStatics1(staticsId1);
if (mq) {
mq->setFlags(mq->getFlags() | 1);
ExCommand *ex = new ExCommand(0, 17, MSG_SC5_MAKEOTMFEEDBACK, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
mq->_isFinished = 0;
}
}
}
void sceneHandler05_resetTicks() {
if (g_nmi->_aniMan->_movement && (g_nmi->_aniMan->_movement->_id == MV_MANHDL_HANDLEUP
|| g_nmi->_aniMan->_movement->_id == MV_MANHDL_HANDLEDOWN))
g_vars->scene05_wackoTicker = g_nmi->_updateTicks;
else
g_vars->scene05_wackoTicker = 0;
}
void sceneHandler05_genFlies() {
if (g_vars->scene05_floatersTicker <= 1000)
return;
if (g_nmi->_rnd.getRandomNumber(1)) {
int numFlies = g_nmi->_rnd.getRandomNumber(3) + 1;
for (int i = 0; i < numFlies; i++) {
int x = g_nmi->_rnd.getRandomNumber(55) + 538;
int y = g_nmi->_rnd.getRandomNumber(60) + i * 30 + 520;
g_nmi->_floaters->genFlies(g_nmi->_currentScene, x, y, 5, 1);
g_nmi->_floaters->_array2.back().val2 = 585;
g_nmi->_floaters->_array2.back().val3 = -70;
g_nmi->_floaters->_array2.back().val11 = 8.0;
}
}
g_vars->scene05_floatersTicker = 0;
}
void sceneHandler05_showHandle() {
g_nmi->_currentScene->getStaticANIObject1ById(ANI_HANDLE, -1)->show1(-1, -1, -1, 0);
}
void sceneHandler05_handleDown() {
StaticANIObject *hatch = g_nmi->_currentScene->getStaticANIObject1ById(ANI_BIGLUK, -1);
hatch->changeStatics2(ST_BLK_CLOSED);
hatch->startAnim(MV_BLK_OPEN, 0, -1);
sceneHandler05_resetTicks();
sceneHandler05_genFlies();
}
void sceneHandler05_hideHandle() {
g_nmi->_currentScene->getStaticANIObject1ById(ANI_HANDLE, -1)->hide();
}
void sceneHandler05_handleUp() {
StaticANIObject *hatch = g_nmi->_currentScene->getStaticANIObject1ById(ANI_BIGLUK, -1);
hatch->changeStatics2(ST_BLK_OPEN);
hatch->startAnim(MV_BLK_CLOSE, 0, -1);
sceneHandler05_resetTicks();
}
void sceneHandler05_testHatch(ExCommand *inex) {
ExCommand *ex;
if (g_nmi->_currentScene->getStaticANIObject1ById(ANI_BIGLUK, -1)->_statics->_staticsId == ST_BLK_CLOSED) {
ex = new ExCommand(SC_5, 17, 61, 0, 0, 0, 1, 0, 0, 0);
ex->_param = TrubaLeft;
ex->_excFlags |= 2;
ex->postMessage();
return;
}
StaticANIObject *wacko = g_nmi->_currentScene->getStaticANIObject1ById(ANI_OTMOROZ, -1);
if (wacko->_movement)
wacko->changeStatics2(wacko->_movement->_staticsObj2->_staticsId);
if (g_nmi->getObjectState(sO_WeirdWacko) == g_nmi->getObjectEnumState(sO_WeirdWacko, sO_InGlasses)) {
MessageQueue *mq = g_nmi->_globalMessageQueueList->getMessageQueueById(inex->_parId);
if (mq)
mq->deleteExCommandByIndex(mq->getCount() - 1, 1);
if (wacko->_statics->_staticsId != ST_OTM_GLS_LEFT) {
mq = wacko->changeStatics1(ST_OTM_GLS_LEFT);
if (!mq) {
wacko->changeStatics2(ST_OTM_GLS_LEFT);
mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
}
mq->setFlags(mq->getFlags() | 1);
ex = new ExCommand(ANI_OTMOROZ, 1, MV_OTM_HANDLEUP, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2u;
mq->addExCommandToEnd(ex);
ex = new ExCommand(SC_5, 17, 61, 0, 0, 0, 1, 0, 0, 0);
ex->_param = TrubaLeft;
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
mq->_isFinished = 0;
return;
}
mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
mq->setFlags(mq->getFlags() | 1);
ex = new ExCommand(ANI_OTMOROZ, 1, MV_OTM_HANDLEUP, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
ex = new ExCommand(SC_5, 17, 61, 0, 0, 0, 1, 0, 0, 0);
ex->_param = TrubaLeft;
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
if (!mq->chain(wacko))
delete mq;
} else if (g_nmi->getObjectState(sO_WeirdWacko) == g_nmi->getObjectEnumState(sO_WeirdWacko, sO_WithDrawer)) {
MessageQueue *mq = g_nmi->_globalMessageQueueList->getMessageQueueById(inex->_parId);
if (mq)
mq->deleteExCommandByIndex(mq->getCount() - 1, 1);
if (wacko->_statics->_staticsId != ST_OTM_BOX_LEFT) {
mq = wacko->changeStatics1(ST_OTM_BOX_LEFT);
if (!mq) {
wacko->changeStatics2(ST_OTM_BOX_LEFT);
mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
}
mq->setFlags(mq->getFlags() | 1);
ex = new ExCommand(ANI_OTMOROZ, 1, MV_OTM_BOXHANDLEUP, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
ex = new ExCommand(SC_5, 17, 61, 0, 0, 0, 1, 0, 0, 0);
ex->_param = TrubaLeft;
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
mq->_isFinished = 0;
if (!mq->chain(wacko))
delete mq;
return;
}
mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
mq->setFlags(mq->getFlags() | 1);
ex = new ExCommand(ANI_OTMOROZ, 1, MV_OTM_BOXHANDLEUP, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
ex = new ExCommand(SC_5, 17, 61, 0, 0, 0, 1, 0, 0, 0);
ex->_param = TrubaLeft;
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
if (!mq->chain(wacko))
delete mq;
return;
} else {
ex = new ExCommand(SC_5, 17, 61, 0, 0, 0, 1, 0, 0, 0);
ex->_param = TrubaLeft;
ex->_excFlags |= 2;
ex->postMessage();
return;
}
}
int sceneHandler05(ExCommand *ex) {
if (ex->_messageKind != 17)
return 0;
switch (ex->_messageNum) {
case MSG_SC5_BGRSOUNDOFF:
g_nmi->stopAllSoundInstances(SND_5_026);
break;
case MSG_SC5_BGRSOUNDON:
g_nmi->playSound(SND_5_026, 1);
break;
case MSG_SC5_MAKEMANFLIGHT:
sceneHandler05_makeManFlight();
break;
case MSG_SC5_MAKEOTMFEEDBACK:
if (!g_nmi->_aniMan->_movement || (g_nmi->_aniMan->_movement->_id != MV_MANHDL_HANDLEUP
&& g_nmi->_aniMan->_movement->_id != MV_MANHDL_HANDLEDOWN)) {
sceneHandler05_makeWackoFeedback();
g_vars->scene05_wackoTicker = 0;
}
break;
case MSG_SC5_SHOWHANDLE:
sceneHandler05_showHandle();
break;
case MSG_SC5_HANDLEDOWN:
g_vars->scene05_handle->changeStatics2(ST_HDL_DOWN);
sceneHandler05_handleDown();
break;
case MSG_SC5_HIDEHANDLE:
sceneHandler05_hideHandle();
break;
case MSG_SC5_HANDLEUP:
g_vars->scene05_handle->changeStatics2(ST_HDL_UP);
sceneHandler05_handleUp();
break;
case MSG_SC5_TESTLUK:
sceneHandler05_testHatch(ex);
break;
case 33:
{
int res = 0;
if (g_nmi->_aniMan2) {
if (g_nmi->_aniMan2->_ox < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.left - 300;
if (g_nmi->_aniMan2->_ox > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.right + 300;
res = 1;
}
if (g_vars->scene05_wackoTicker) {
if ((g_nmi->_updateTicks - g_vars->scene05_wackoTicker) > 62) {
if (!g_nmi->_aniMan->_movement || (g_nmi->_aniMan->_movement->_id != MV_MANHDL_HANDLEUP
&& g_nmi->_aniMan->_movement->_id != MV_MANHDL_HANDLEDOWN)) {
if (g_vars->scene05_handleFlipper % 2)
sceneHandler05_makeWackoFeedback();
g_vars->scene05_wackoTicker = 0;
++g_vars->scene05_handleFlipper;
}
}
}
++g_vars->scene05_floatersTicker;
g_nmi->_floaters->update();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
return res;
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View 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 "ngi/ngi.h"
#include "ngi/objects.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gfx.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/scene.h"
#include "ngi/messages.h"
#include "ngi/gameloader.h"
#include "ngi/behavior.h"
#include "ngi/interaction.h"
namespace NGI {
void scene06_initMumsy() {
g_vars->scene06_mumsyJumpFw = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(g_vars->scene06_mumsy, ST_MOM_STANDS, QU_MOM_JUMPFW);
g_vars->scene06_mumsyJumpBk = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(g_vars->scene06_mumsy, ST_MOM_STANDS, QU_MOM_JUMPBK);
g_vars->scene06_mumsyJumpFwPercent = g_vars->scene06_mumsyJumpFw->_percent;
g_vars->scene06_mumsyJumpBkPercent = g_vars->scene06_mumsyJumpBk->_percent;
}
int scene06_updateCursor() {
g_nmi->updateCursorCommon();
if (g_vars->scene06_arcadeEnabled) {
if (g_vars->scene06_aimingBall) {
g_nmi->_cursorId = PIC_CSR_ARCADE2_D;
return PIC_CSR_ARCADE2_D;
}
if (g_nmi->_aniMan == g_nmi->_objectAtCursor) {
if (g_nmi->_aniMan->_statics->_staticsId == ST_MAN6_BALL && g_nmi->_cursorId == PIC_CSR_DEFAULT) {
g_nmi->_cursorId = PIC_CSR_ITN;
return PIC_CSR_ITN;
}
} else if (g_nmi->_objectAtCursor && g_nmi->_objectAtCursor == g_vars->scene06_currentBall
&& g_nmi->_cursorId == PIC_CSR_DEFAULT) {
g_nmi->_cursorId = PIC_CSR_ITN;
}
}
return g_nmi->_cursorId;
}
void sceneHandler06_setExits(Scene *sc) {
MotionController *mc = getSc2MctlCompoundBySceneId(sc->_sceneId);
mc->enableLinks(sO_CloseThing, (g_nmi->getObjectState(sO_BigMumsy) != g_nmi->getObjectEnumState(sO_BigMumsy, sO_IsGone)));
mc->enableLinks(sO_CloseThing2, g_vars->scene06_arcadeEnabled);
}
void sceneHandler06_winArcade() {
g_nmi->setObjectState(sO_BigMumsy, g_nmi->getObjectEnumState(sO_BigMumsy, sO_IsGone));
if (g_nmi->getObjectState(sO_ClockAxis) == g_nmi->getObjectEnumState(sO_ClockAxis, sO_IsNotAvailable))
g_nmi->setObjectState(sO_ClockAxis, g_nmi->getObjectEnumState(sO_ClockAxis, sO_WithoutHandle));
if (g_vars->scene06_arcadeEnabled) {
g_nmi->_aniMan->_callback2 = nullptr; // Really NULL
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
if (g_vars->scene06_someBall) {
g_vars->scene06_someBall->_flags &= 0xFFFB;
g_vars->scene06_balls.push_back(g_vars->scene06_someBall);
g_vars->scene06_someBall = nullptr;
}
if (g_vars->scene06_flyingBall) {
g_vars->scene06_flyingBall->_flags &= 0xFFFB;
g_vars->scene06_balls.push_back(g_vars->scene06_flyingBall);
g_vars->scene06_flyingBall = nullptr;
}
if (g_vars->scene06_ballInHands) {
g_vars->scene06_ballInHands->_flags &= 0xFFFB;
g_vars->scene06_balls.push_back(g_vars->scene06_ballInHands);
g_vars->scene06_ballInHands = nullptr;
}
g_vars->scene06_arcadeEnabled = false;
g_vars->scene06_aimingBall = false;
}
g_vars->scene06_mumsy->_flags &= 0xFFFB;
sceneHandler06_setExits(g_nmi->_currentScene);
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
}
void sceneHandler06_enableDrops() {
chainQueue(QU_SC6_DROPS, 0);
g_vars->scene06_mumsy->changeStatics2(ST_MOM_SITS);
g_nmi->setObjectState(sO_BigMumsy, g_nmi->getObjectEnumState(sO_BigMumsy, sO_IsPlaying));
chainQueue(QU_MOM_STANDUP, 1);
g_vars->scene06_arcadeEnabled = true;
g_vars->scene06_numBallsGiven = 0;
g_vars->scene06_mumsyPos = 0;
g_vars->scene06_mumsyNumBalls = 0;
g_vars->scene06_mumsyGotBall = false;
sceneHandler06_setExits(g_nmi->_currentScene);
}
void sceneHandler06_mumsyBallTake() {
int momAni = 0;
switch (g_vars->scene06_mumsyNumBalls) {
case 1:
momAni = MV_MOM_TAKE1;
break;
case 2:
momAni = MV_MOM_TAKE2;
break;
case 3:
momAni = MV_MOM_TAKE3;
break;
case 4:
momAni = MV_MOM_TAKE4;
break;
case 5:
momAni = MV_MOM_TAKE5;
break;
default:
break;
}
MessageQueue *mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
ExCommand *ex = new ExCommand(ANI_MAMASHA, 2, 50, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags = 2u;
mq->addExCommandToEnd(ex);
if (g_vars->scene06_mumsyNumBalls >= 5) {
g_nmi->setObjectState(sO_BigMumsy, g_nmi->getObjectEnumState(sO_BigMumsy, sO_IsGone));
if (g_nmi->getObjectState(sO_ClockAxis) == g_nmi->getObjectEnumState(sO_ClockAxis, sO_IsNotAvailable))
g_nmi->setObjectState(sO_ClockAxis, g_nmi->getObjectEnumState(sO_ClockAxis, sO_WithoutHandle));
ex = new ExCommand(ANI_MAMASHA, 1, momAni, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
if (g_vars->scene06_mumsyPos + 3 >= 0) {
ex = new ExCommand(ANI_MAMASHA, 1, MV_MOM_STARTBK, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2u;
mq->addExCommandToEnd(ex);
for (int i = 0; i < g_vars->scene06_mumsyPos + 3; i++) {
ex = new ExCommand(ANI_MAMASHA, 1, MV_MOM_CYCLEBK, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
}
ex = new ExCommand(ANI_MAMASHA, 1, MV_MOM_STOPBK, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
}
ex = new ExCommand(0, 18, QU_MOM_TOLIFT, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 3;
mq->addExCommandToEnd(ex);
} else {
if (momAni) {
ex = new ExCommand(ANI_MAMASHA, 1, momAni, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
}
if (g_vars->scene06_mumsyPos < 0) {
for (int i = 0; i > g_vars->scene06_mumsyPos; i--) {
ex = new ExCommand(ANI_MAMASHA, 1, MV_MOM_JUMPFW, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
}
} else if (g_vars->scene06_mumsyPos > 0) {
for (int i = 0; i < g_vars->scene06_mumsyPos; i++) {
ex = new ExCommand(ANI_MAMASHA, 1, MV_MOM_JUMPBK, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
}
}
ex = new ExCommand(0, 18, QU_MOM_SITDOWN, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 3u;
mq->addExCommandToEnd(ex);
}
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
g_vars->scene06_mumsyNumBalls = 0;
g_vars->scene06_arcadeEnabled = false;
g_nmi->_aniMan2 = nullptr;
}
void sceneHandler06_spinHandle() {
int tummy = g_nmi->getObjectState(sO_TummyTrampie);
if (tummy == g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsEating))
g_nmi->setObjectState(sO_TummyTrampie, g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsSleeping));
else if (tummy == g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsSleeping))
g_nmi->setObjectState(sO_TummyTrampie, g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsDrinking));
else if (tummy == g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsDrinking))
g_nmi->setObjectState(sO_TummyTrampie, g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsScratchingBelly));
else if (tummy == g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsScratchingBelly))
g_nmi->setObjectState(sO_TummyTrampie, g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsEating));
}
void sceneHandler06_uPipeClick() {
if (getGameLoaderInteractionController()->_flag24)
handleObjectInteraction(g_nmi->_aniMan2, g_nmi->_currentScene->getPictureObjectById(PIC_SC6_LADDER, 0), 0);
}
void sceneHandler06_buttonPush() {
g_vars->scene06_invHandle = g_nmi->_currentScene->getStaticANIObject1ById(ANI_INV_HANDLE, -1);
if (g_vars->scene06_invHandle)
if (g_vars->scene06_invHandle->_flags & 4)
if (g_vars->scene06_invHandle->_statics)
if (g_vars->scene06_invHandle->_statics->_staticsId == ST_HDL_PLUGGED)
chainQueue(QU_SC6_FALLHANDLE, 1);
}
void sceneHandler06_showNextBall() {
if (g_vars->scene06_balls.size()) {
g_vars->scene06_currentBall = g_vars->scene06_balls.remove_at(0);
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC6_SHOWNEXTBALL), 0, 1);
mq->setParamInt(-1, g_vars->scene06_currentBall->_odelay);
mq->chain(nullptr);
++g_vars->scene06_numBallsGiven;
}
}
void sceneHandler06_installHandle() {
chainQueue(QU_SC6_SHOWHANDLE, 0);
}
int sceneHandler06_updateScreenCallback() {
int res;
res = g_nmi->drawArcadeOverlay(g_vars->scene06_arcadeEnabled);
if (!res)
g_nmi->_updateScreenCallback = nullptr;
return res;
}
void sceneHandler06_startAiming() {
if (g_vars->scene06_currentBall) {
g_vars->scene06_currentBall->hide();
g_nmi->_aniMan->startAnim(MV_MAN6_TAKEBALL, 0, -1);
g_vars->scene06_ballInHands = g_vars->scene06_currentBall;
g_vars->scene06_currentBall = nullptr;
if (getCurrSceneSc2MotionController()->_isEnabled)
g_nmi->_updateScreenCallback = sceneHandler06_updateScreenCallback;
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
g_vars->scene06_ballDrop->queueMessageQueue(nullptr);
}
}
void sceneHandler06_takeBall() {
if (g_vars->scene06_currentBall && !g_vars->scene06_currentBall->_movement && g_vars->scene06_currentBall->_statics->_staticsId == ST_NBL_NORM) {
if (abs(1158 - g_nmi->_aniMan->_ox) > 1
|| abs(452 - g_nmi->_aniMan->_oy) > 1
|| g_nmi->_aniMan->_movement
|| g_nmi->_aniMan->_statics->_staticsId != (0x4000 | ST_MAN_RIGHT)) {
MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, 1158, 452, 1, (0x4000 | ST_MAN_RIGHT));
if (mq) {
ExCommand *ex = new ExCommand(0, 17, MSG_SC6_TAKEBALL, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 3;
mq->addExCommandToEnd(ex);
postExCommand(g_nmi->_aniMan->_id, 2, 1158, 452, 0, -1);
}
} else {
sceneHandler06_startAiming();
}
}
}
void sceneHandler06_aiming() {
if (g_vars->scene06_ballInHands) {
g_vars->scene06_ballDeltaX = 4 * g_nmi->_aniMan->_movement->_currDynamicPhaseIndex + 16;
g_vars->scene06_ballDeltaY = 5 * (g_nmi->_aniMan->_movement->_currDynamicPhaseIndex + 4);
if (g_nmi->_aniMan->_movement->_currDynamicPhaseIndex < 4) {
g_nmi->_aniMan->_movement->setDynamicPhaseIndex(11);
g_vars->scene06_aimingBall = false;
return;
}
g_nmi->_aniMan->_movement->setDynamicPhaseIndex(9);
}
g_vars->scene06_aimingBall = false;
}
void sceneHandler06_ballStartFly() {
if (g_vars->scene06_ballInHands) {
g_vars->scene06_flyingBall = g_vars->scene06_ballInHands;
g_vars->scene06_ballInHands = nullptr;
g_vars->scene06_flyingBall->show1(g_nmi->_aniMan->_ox - 60, g_nmi->_aniMan->_oy - 60, -1, 0);
g_vars->scene06_flyingBall->_priority = 27;
}
}
void sceneHandler06_throwCallback(int *arg) {
if (g_vars->scene06_aimingBall) {
int dist = (g_nmi->_mouseVirtY - g_vars->scene06_sceneClickY)
* (g_nmi->_mouseVirtY - g_vars->scene06_sceneClickY)
+ (g_nmi->_mouseVirtX - g_vars->scene06_sceneClickX)
* (g_nmi->_mouseVirtX - g_vars->scene06_sceneClickX);
*arg = (int)(sqrt((double)dist) * 0.1);
if (*arg > 8)
*arg = 8;
} else {
*arg = *arg + 1;
if (*arg == 12)
sceneHandler06_ballStartFly();
}
}
void sceneHandler06_throwBall() {
g_nmi->_aniMan->_callback2 = sceneHandler06_throwCallback;
g_nmi->_aniMan->startAnim(MV_MAN6_THROWBALL, 0, -1);
g_vars->scene06_aimingBall = true;
}
void sceneHandler06_eggieWalk() {
if (15 - g_vars->scene06_numBallsGiven >= 4 && !g_nmi->_rnd.getRandomNumber(9)) {
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_EGGIE, -1);
if (!ani || !(ani->_flags & 4)) {
if (g_vars->scene06_eggieDirection)
chainQueue(QU_EGG6_GOR, 0);
else
chainQueue(QU_EGG6_GOL, 0);
g_vars->scene06_eggieTimeout = 0;
g_vars->scene06_eggieDirection = !g_vars->scene06_eggieDirection;
}
}
}
void sceneHandler06_dropBall() {
if (g_vars->scene06_numBallsGiven >= 15 || g_vars->scene06_mumsyNumBalls >= 5)
g_vars->scene06_ballDrop->hide();
else
chainQueue(QU_SC6_DROPS3, 0);
}
void sceneHandler06_fallBall() {
g_vars->scene06_ballY = 475;
g_vars->scene06_flyingBall->setOXY(g_vars->scene06_ballX, g_vars->scene06_ballY);
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC6_FALLBALL), 0, 1);
mq->setParamInt(-1, g_vars->scene06_flyingBall->_odelay);
mq->chain(nullptr);
g_vars->scene06_balls.push_back(g_vars->scene06_flyingBall);
g_vars->scene06_flyingBall = nullptr;
sceneHandler06_dropBall();
sceneHandler06_eggieWalk();
}
void sceneHandler06_catchBall() {
if (g_vars->scene06_flyingBall) {
g_vars->scene06_flyingBall->hide();
g_vars->scene06_balls.push_back(g_vars->scene06_flyingBall);
g_vars->scene06_flyingBall = nullptr;
g_vars->scene06_mumsyNumBalls++;
if (g_vars->scene06_mumsy->_movement) {
Common::Point point;
if (g_vars->scene06_mumsy->_movement->_id == MV_MOM_JUMPFW) {
if (g_vars->scene06_mumsy->_movement->_currDynamicPhaseIndex <= 5) {
point = g_vars->scene06_mumsy->_movement->calcSomeXY(0, g_vars->scene06_mumsy->_movement->_currDynamicPhaseIndex);
point.x = -point.x;
point.y = -point.y;
} else {
point = g_vars->scene06_mumsy->_movement->calcSomeXY(1, -1);
g_vars->scene06_mumsyPos++;
}
} else if (g_vars->scene06_mumsy->_movement->_id == MV_MOM_JUMPBK) {
if (g_vars->scene06_mumsy->_movement->_currDynamicPhaseIndex <= 4) {
point = g_vars->scene06_mumsy->_movement->calcSomeXY(0, g_vars->scene06_mumsy->_movement->_currDynamicPhaseIndex);
point.x = -point.x;
point.y = -point.y;
} else {
point = g_vars->scene06_mumsy->_movement->calcSomeXY(1, -1);
g_vars->scene06_mumsyPos--;
}
}
g_vars->scene06_mumsy->changeStatics2(ST_MOM_STANDS);
g_vars->scene06_mumsy->setOXY(point.x + g_vars->scene06_mumsy->_ox,
point.y + g_vars->scene06_mumsy->_oy);
} else {
g_vars->scene06_mumsy->changeStatics2(ST_MOM_STANDS);
}
chainQueue(QU_MOM_PUTBALL, 1);
g_vars->scene06_mumsyGotBall = true;
sceneHandler06_dropBall();
}
}
void sceneHandler06_checkBallTarget(int par) {
if (g_vars->scene06_ballY <= 475) {
if (g_vars->scene06_mumsy->isPixelHitAtPos(g_vars->scene06_ballX, g_vars->scene06_ballY)) {
chainObjQueue(g_vars->scene06_mumsy, QU_MOM_JUMPBK, 0);
sceneHandler06_catchBall();
}
} else {
sceneHandler06_fallBall();
}
}
void scene06_initScene(Scene *sc) {
g_vars->scene06_mumsy = sc->getStaticANIObject1ById(ANI_MAMASHA, -1);
g_vars->scene06_someBall = nullptr;
g_vars->scene06_invHandle = sc->getStaticANIObject1ById(ANI_INV_HANDLE, -1);
g_vars->scene06_liftButton = sc->getStaticANIObject1ById(ANI_BUTTON_6, -1);
g_vars->scene06_ballDrop = sc->getStaticANIObject1ById(ANI_BALLDROP, -1);
g_vars->scene06_arcadeEnabled = false;
g_vars->scene06_aimingBall = false;
g_vars->scene06_currentBall = nullptr;
g_vars->scene06_ballInHands = nullptr;
g_vars->scene06_flyingBall = nullptr;
g_vars->scene06_balls.clear();
g_vars->scene06_numBallsGiven = 0;
g_vars->scene06_mumsyNumBalls = 0;
g_vars->scene06_eggieTimeout = 0;
g_vars->scene06_eggieDirection = true;
StaticANIObject *ball = sc->getStaticANIObject1ById(ANI_NEWBALL, -1);
ball->hide();
ball->_statics = ball->getStaticsById(ST_NBL_NORM);
g_vars->scene06_balls.push_back(ball);
for (int i = 0; i < 3; i++) {
StaticANIObject *ball2 = new StaticANIObject(ball);
ball2->hide();
ball2->_statics = ball2->getStaticsById(ST_NBL_NORM);
sc->addStaticANIObject(ball2, 1);
g_vars->scene06_balls.push_back(ball2);
}
if (g_nmi->getObjectState(sO_BigMumsy) == g_nmi->getObjectEnumState(sO_BigMumsy, sO_IsPlaying))
g_nmi->setObjectState(sO_BigMumsy, g_nmi->getObjectEnumState(sO_BigMumsy, sO_IsSleeping));
if (g_nmi->getObjectState(sO_BigMumsy) != g_nmi->getObjectEnumState(sO_BigMumsy, sO_IsSleeping))
g_vars->scene06_mumsy->hide();
g_nmi->lift_setButton(sO_Level3, ST_LBN_3N);
g_nmi->lift_init(sc, QU_SC6_ENTERLIFT, QU_SC6_EXITLIFT);
g_nmi->initArcadeKeys("SC_6");
sceneHandler06_setExits(sc);
g_nmi->setArcadeOverlay(PIC_CSR_ARCADE2);
}
int sceneHandler06(ExCommand *ex) {
if (ex->_messageKind != 17)
return 0;
switch(ex->_messageNum) {
case MSG_LIFT_CLOSEDOOR:
g_nmi->lift_closedoorSeq();
break;
case MSG_LIFT_EXITLIFT:
g_nmi->lift_exitSeq(ex);
break;
case MSG_CMN_WINARCADE:
sceneHandler06_winArcade();
break;
case MSG_LIFT_STARTEXITQUEUE:
g_nmi->lift_startExitQueue();
break;
case MSG_SC6_RESTORESCROLL:
g_nmi->_aniMan2 = g_nmi->_aniMan;
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
sceneHandler06_setExits(g_nmi->_currentScene);
break;
case MSG_SC6_STARTDROPS:
if (g_nmi->getObjectState(sO_BigMumsy) == g_nmi->getObjectEnumState(sO_BigMumsy, sO_IsSleeping))
sceneHandler06_enableDrops();
break;
case MSG_SC6_TESTNUMBALLS:
g_vars->scene06_mumsyGotBall = false;
if (g_vars->scene06_mumsyNumBalls < 5 || !g_vars->scene06_arcadeEnabled)
return 0;
sceneHandler06_mumsyBallTake();
break;
case MSG_SC6_JUMPFW:
++g_vars->scene06_mumsyPos;
break;
case MSG_SC6_JUMPBK:
--g_vars->scene06_mumsyPos;
break;
case MSG_LIFT_CLICKBUTTON:
g_nmi->lift_clickButton();
break;
case MSG_SPINHANDLE:
sceneHandler06_spinHandle();
break;
case MSG_LIFT_GO:
g_nmi->lift_goAnimation();
break;
case MSG_SC6_UTRUBACLICK:
sceneHandler06_uPipeClick();
break;
case MSG_SC6_BTNPUSH:
sceneHandler06_buttonPush();
break;
case MSG_SC6_SHOWNEXTBALL:
sceneHandler06_showNextBall();
break;
case MSG_SC6_INSTHANDLE:
sceneHandler06_installHandle();
break;
case MSG_SC6_ENABLEDROPS:
sceneHandler06_enableDrops();
break;
case 64:
g_nmi->lift_hoverButton(ex);
break;
case MSG_SC6_TAKEBALL:
sceneHandler06_takeBall();
break;
case 30:
if (g_vars->scene06_aimingBall) {
sceneHandler06_aiming();
break;
}
if (!g_vars->scene06_arcadeEnabled) {
// Do nothing
break;
}
break;
case 29:
{
StaticANIObject *st = g_nmi->_currentScene->getStaticANIObjectAtPos(ex->_sceneClickX, ex->_sceneClickY);
if (st) {
if (!g_vars->scene06_arcadeEnabled && st->_id == ANI_LIFTBUTTON) {
g_nmi->lift_animateButton(st);
ex->_messageKind = 0;
return 0;
}
if (g_vars->scene06_currentBall == st) {
if (g_vars->scene06_numBallsGiven == 1)
sceneHandler06_takeBall();
ex->_messageKind = 0;
} else if (g_vars->scene06_ballInHands && g_nmi->_aniMan == st && !g_nmi->_aniMan->_movement && g_nmi->_aniMan->_statics->_staticsId == ST_MAN6_BALL) {
g_vars->scene06_sceneClickX = ex->_sceneClickX;
g_vars->scene06_sceneClickY = ex->_sceneClickY;
sceneHandler06_throwBall();
}
}
if (!st || !canInteractAny(g_nmi->_aniMan, st, ex->_param)) {
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(ex->_sceneClickX, ex->_sceneClickY);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picId, 0);
if (!pic || !canInteractAny(g_nmi->_aniMan, pic, ex->_param)) {
if ((g_nmi->_sceneRect.right - ex->_sceneClickX < 47
&& g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1)
|| (ex->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0)) {
g_nmi->processArcade(ex);
return 0;
}
}
}
}
break;
case 33:
{
int res = 0;
if (g_nmi->_aniMan2) {
int ox = g_nmi->_aniMan2->_ox;
int oy = g_nmi->_aniMan2->_oy;
g_vars->scene06_manX = ox;
g_vars->scene06_manY = oy;
if (g_vars->scene06_arcadeEnabled && oy <= 470 && ox >= 1088) {
if (ox < g_nmi->_sceneRect.left + 600) {
g_nmi->_currentScene->_x = ox - g_nmi->_sceneRect.left - 700;
ox = g_vars->scene06_manX;
}
if (ox > g_nmi->_sceneRect.right - 50)
g_nmi->_currentScene->_x = ox - g_nmi->_sceneRect.right + 70;
} else {
if (ox < g_nmi->_sceneRect.left + 200) {
g_nmi->_currentScene->_x = ox - g_nmi->_sceneRect.left - 300;
ox = g_vars->scene06_manX;
}
if (ox > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = ox - g_nmi->_sceneRect.right + 300;
}
res = 1;
g_nmi->sceneAutoScrolling();
}
if (g_vars->scene06_arcadeEnabled) {
if (g_vars->scene06_mumsyPos > -3)
g_vars->scene06_mumsyJumpBk->_percent = g_vars->scene06_mumsyJumpBkPercent;
else
g_vars->scene06_mumsyJumpBk->_percent = 0;
if (g_vars->scene06_mumsyPos < 4)
g_vars->scene06_mumsyJumpFw->_percent = g_vars->scene06_mumsyJumpFwPercent;
else
g_vars->scene06_mumsyJumpFw->_percent = 0;
if (g_vars->scene06_aimingBall) {
g_vars->scene06_eggieTimeout++;
if (g_vars->scene06_eggieTimeout >= 600)
sceneHandler06_eggieWalk();
}
} else {
g_vars->scene06_mumsyJumpFw->_percent = 0;
g_vars->scene06_mumsyJumpBk->_percent = 0;
}
if (g_vars->scene06_flyingBall) {
g_vars->scene06_ballX = g_vars->scene06_flyingBall->_ox - g_vars->scene06_ballDeltaX;
g_vars->scene06_ballY = g_vars->scene06_flyingBall->_oy - g_vars->scene06_ballDeltaY;
g_vars->scene06_flyingBall->setOXY(g_vars->scene06_ballX, g_vars->scene06_ballY);
if (g_vars->scene06_ballDeltaX >= 2)
g_vars->scene06_ballDeltaX -= 2;
g_vars->scene06_ballDeltaY -= 5;
sceneHandler06_checkBallTarget(g_vars->scene06_ballDeltaX);
}
if (g_vars->scene06_arcadeEnabled
&& !g_vars->scene06_currentBall
&& !g_vars->scene06_ballInHands
&& !g_vars->scene06_flyingBall
&& g_vars->scene06_numBallsGiven >= 15
&& !g_vars->scene06_ballDrop->_movement
&& !g_vars->scene06_mumsy->_movement
&& !g_vars->scene06_mumsyGotBall)
sceneHandler06_mumsyBallTake();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
return res;
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,178 @@
/* 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 "ngi/ngi.h"
#include "ngi/objects.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/scene.h"
#include "ngi/statics.h"
#include "ngi/messages.h"
#include "ngi/behavior.h"
namespace NGI {
void scene07_initScene(Scene *sc) {
g_vars->scene07_lukeAnim = nullptr;
g_vars->scene07_lukePercent = 0;
g_vars->scene07_plusMinus = sc->getStaticANIObject1ById(ANI_PLUSMINUS, -1);
if (g_nmi->getObjectState(sO_Guard_1) == g_nmi->getObjectEnumState(sO_Guard_1, sO_Off))
g_vars->scene07_plusMinus->_statics = g_vars->scene07_plusMinus->getStaticsById(ST_PMS_MINUS);
else
g_vars->scene07_plusMinus->_statics = g_vars->scene07_plusMinus->getStaticsById(ST_PMS_PLUS);
if (g_nmi->getObjectState(sO_HareTheNooksiter) == g_nmi->getObjectEnumState(sO_HareTheNooksiter, sO_WithoutHandle)) {
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
sc->getStaticANIObject1ById(ANI_CORNERSITTER, -1)->changeStatics2(ST_CST_HANDLELESS);
g_nmi->_currentScene = oldsc;
}
}
void sceneHandler07_openLuke() {
StaticANIObject *luke = g_nmi->_currentScene->getStaticANIObject1ById(ANI_LUKE, -1);
luke->changeStatics2(ST_LUK_OPEN);
luke->show1(-1, -1, -1, 0);
if (g_vars->scene07_lukeAnim) {
g_vars->scene07_lukeAnim->_percent = g_vars->scene07_lukePercent;
} else {
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_CORNERSITTER, -1);
g_vars->scene07_lukeAnim = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(ani, ST_CST_HANDLELESS, QU_CST_CLOSELUKE);
g_vars->scene07_lukeAnim->_percent = g_vars->scene07_lukePercent;
}
}
void sceneHandler07_closeLuke() {
g_nmi->_currentScene->getStaticANIObject1ById(ANI_LUKE, -1)->changeStatics2(ST_LUK_CLOSED);
if (!g_vars->scene07_lukeAnim) {
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_CORNERSITTER, -1);
g_vars->scene07_lukeAnim = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(ani, ST_CST_HANDLELESS, QU_CST_CLOSELUKE);
}
g_vars->scene07_lukePercent = g_vars->scene07_lukeAnim->_percent;
g_vars->scene07_lukeAnim->_percent = 0;
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_HOOLIGAN, -1);
ani->changeStatics2(ST_HGN_LUKE);
ani->show1(-1, -1, -1, 0);
}
void sceneHandler07_hideLuke() {
g_nmi->_currentScene->getStaticANIObject1ById(ANI_LUKE, -1)->hide();
Movement *mov = g_nmi->_currentScene->getStaticANIObject1ById(ANI_CORNERSITTER, -1)->_movement;
if (mov) {
if (mov->_id == MV_CST_CLOSELUKE) {
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_HOOLIGAN, -1);
ani->changeStatics2(ST_HGN_LOOK);
ani->_flags &= 0xFFFB;
}
}
}
void sceneHandler07_showBox() {
StaticANIObject *box = g_nmi->_currentScene->getStaticANIObject1ById(ANI_SC7_BOX, -1);
box->show1(492, 474, MV_SC7_BOX_default, 0);
box->_priority = 25;
}
void sceneHandler07_hideBox() {
g_nmi->_currentScene->getStaticANIObject1ById(ANI_SC7_BOX, -1)->hide();
}
int sceneHandler07(ExCommand *ex) {
if (ex->_messageKind != 17)
return 0;
switch(ex->_messageNum) {
case MSG_SC7_OPENLUKE:
sceneHandler07_openLuke();
break;
case MSG_SC7_PULL:
if (g_vars->scene07_plusMinus->_statics->_staticsId == ST_PMS_MINUS) {
g_vars->scene07_plusMinus->_statics = g_vars->scene07_plusMinus->getStaticsById(ST_PMS_PLUS);
} else {
g_vars->scene07_plusMinus->_statics = g_vars->scene07_plusMinus->getStaticsById(ST_PMS_MINUS);
}
break;
case MSG_SC7_CLOSELUKE:
sceneHandler07_closeLuke();
break;
case MSG_SC7_HIDELUKE:
sceneHandler07_hideLuke();
break;
case MSG_SC7_SHOWBOX:
sceneHandler07_showBox();
break;
case MSG_SC7_HIDEBOX:
sceneHandler07_hideBox();
break;
case 33:
{
int res = 0;
if (g_nmi->_aniMan2) {
if (g_nmi->_aniMan2->_ox < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.left - 300;
if (g_nmi->_aniMan2->_ox > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.right + 300;
res = 1;
}
g_nmi->_behaviorManager->updateBehaviors();
return res;
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,558 @@
/* 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 "ngi/ngi.h"
#include "ngi/objects.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/scene.h"
#include "ngi/statics.h"
#include "ngi/floaters.h"
#include "ngi/gameloader.h"
#include "ngi/behavior.h"
#include "ngi/interaction.h"
#include "ngi/modal.h"
namespace NGI {
void scene08_clockCallback(int *phase) {
// do nothing
}
void scene08_initScene(Scene *sc) {
g_vars->scene08_inArcade = false;
g_vars->scene08_inAir = false;
g_vars->scene08_flyingUp = false;
g_vars->scene08_onBelly = false;
g_vars->scene08_batuta = sc->getStaticANIObject1ById(ANI_BATUTA, -1);
g_vars->scene08_vmyats = sc->getStaticANIObject1ById(ANI_VMYATS, -1);
g_vars->scene08_clock = sc->getStaticANIObject1ById(ANI_CLOCK_8, -1);
g_vars->scene08_stairsOffset = -37;
g_vars->scene08_snoringCountdown = -1;
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
int batuta = g_nmi->getObjectState(sO_TummyTrampie);
MovGraphLink *lock = getSc2MctlCompoundBySceneId(sc->_sceneId)->getLinkByName(sO_CloseThing);
if (lock)
lock->_flags &= 0xDFFFFFFF;
if (batuta == g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsEating)) {
g_vars->scene08_batuta->changeStatics2(ST_BTT_SPOON);
} else if (batuta == g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsDrinking)) {
g_vars->scene08_batuta->changeStatics2(ST_BTT_NOSPOON);
g_vars->scene08_clock->startAnim(MV_CLK8_GO, 0, -1);
g_vars->scene08_clock->_movement->setDynamicPhaseIndex(3);
} else if (batuta== g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsScratchingBelly)) {
g_vars->scene08_batuta->changeStatics2(ST_BTT_CHESHET);
g_vars->scene08_clock->startAnim(MV_CLK8_GO, 0, -1);
g_vars->scene08_clock->_movement->setDynamicPhaseIndex(8);
} else if (batuta == g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsSleeping)) {
g_vars->scene08_batuta->changeStatics2(ST_BTT_SLEEPS);
g_vars->scene08_clock->startAnim(MV_CLK8_GO, 0, -1);
g_vars->scene08_clock->_movement->setDynamicPhaseIndex(2);
if (lock)
lock->_flags |= 0x20000000;
g_vars->scene08_snoringCountdown = 71;
}
g_vars->scene08_clock->_callback2 = scene08_clockCallback;
if (g_nmi->getObjectState(sO_StairsUp_8) == g_nmi->getObjectEnumState(sO_StairsUp_8, sO_Broken)) {
g_vars->scene08_stairsVisible = false;
sc->getPictureObjectById(PIC_SC8_LADDER, 0)->_flags &= 0xFFFB;
g_vars->scene08_stairsOffset = -39;
} else {
g_vars->scene08_stairsVisible = true;
}
sc->getPictureObjectById(PIC_SC8_ARCADENOW, 0)->_flags &= 0xFFFB;
g_nmi->_currentScene = oldsc;
g_nmi->_floaters->init(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_8"));
g_nmi->_floaters->genFlies(sc, 100, 100, 0, 0);
g_nmi->setArcadeOverlay(PIC_CSR_ARCADE3);
}
void scene08_setupMusic() {
if (g_nmi->getObjectState(sO_TummyTrampie) == g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsSleeping))
g_nmi->playTrack(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_8"), "MUSIC_ARCADE", 1);
}
int scene08_updateCursor() {
g_nmi->updateCursorCommon();
if (g_vars->scene08_inArcade) {
if (g_vars->scene08_onBelly) {
if (g_nmi->_objectIdAtCursor == PIC_SC8_LADDERD && g_nmi->_cursorId == PIC_CSR_ITN)
g_nmi->_cursorId = PIC_CSR_GOU;
} else {
g_nmi->_cursorId = -1;
}
} else {
if (g_nmi->_objectIdAtCursor == PIC_SC8_LADDERD && g_nmi->_cursorId == PIC_CSR_ITN) {
if (g_nmi->_aniMan2->_oy >= 520) {
if (g_nmi->_aniMan2->_oy <= 750)
g_nmi->_cursorId = PIC_CSR_GOU;
} else {
g_nmi->_cursorId = PIC_CSR_GOD;
}
}
}
return g_nmi->_cursorId;
}
void sceneHandler08_enterUp() {
g_nmi->_currentScene->getPictureObjectById(PIC_SC8_LADDER, 0)->_flags &= 0xFFFB;
g_nmi->_aniMan->changeStatics2(ST_MAN8_HANDSUP);
g_nmi->_aniMan->setOXY(386, 236);
g_nmi->_aniMan->_priority = 10;
g_nmi->_aniMan->_flags = 4;
chainObjQueue(g_nmi->_aniMan, QU_SC8_FINISH, 1);
g_vars->scene08_inAir = false;
}
void sceneHandler08_winArcade() {
if (g_vars->scene08_inArcade) {
g_vars->scene08_inArcade = false;
g_nmi->_sceneRect.top = 0;
g_nmi->_sceneRect.bottom = 600;
sceneHandler08_enterUp();
}
}
void sceneHandler08_hideLadder() {
g_nmi->_currentScene->getPictureObjectById(PIC_SC8_LADDER_D, 0)->_flags &= 0xFFFB;
}
void sceneHandler08_arcadeNow() {
MovGraphLink *lnk = getCurrSceneSc2MotionController()->getLinkByName(sO_Stairway);
g_nmi->setObjectState(sO_TummyTrampie, g_nmi->getObjectEnumState(sO_TummyTrampie, sO_IsSleeping));
g_vars->scene08_batuta->changeStatics2(ST_BTT_SLEEPS);
if (lnk)
lnk->_flags |= 0x20000000;
}
void sceneHandler08_resumeFlight() {
g_vars->scene08_manOffsetY = 3;
g_vars->scene08_stairsOffset = -39;
g_vars->scene08_inAir = true;
g_vars->scene08_stairsVisible = false;
}
int sceneHandler08_calcOffset(int off, int flag) {
if (off > 0) {
if (flag)
return off * 31 / 10; // off * 3.1
else
return 5 * off;
} else {
return 5 * off;
}
}
void sceneHandler08_pushCallback(int *par) {
int y = g_nmi->_aniMan->_oy + g_nmi->_aniMan->getSomeXY().y;
if (g_nmi->_aniMan->_statics && g_nmi->_aniMan->_statics->_staticsId == ST_MAN8_FLYDOWN)
y -= 25;
*par = (y - 703) / 10;
if (*par > 11) {
*par = 11;
g_vars->scene08_manOffsetY = 0;
}
if (*par >= 0)
g_vars->scene08_manOffsetY -= sceneHandler08_calcOffset(*par, g_vars->scene08_manOffsetY < 0);
else
*par = 0;
}
int sceneHandler08_updateScreenCallback() {
int res;
res = g_nmi->drawArcadeOverlay(g_vars->scene08_inArcade);
if (!res)
g_nmi->_updateScreenCallback = nullptr;
return res;
}
void sceneHandler08_startArcade() {
g_vars->scene08_inArcade = true;
g_vars->scene08_inAir = true;
g_vars->scene08_flyingUp = false;
g_vars->scene08_onBelly = false;
getGameLoaderInteractionController()->disableFlag24();
getCurrSceneSc2MotionController()->deactivate();
g_vars->scene08_batuta->stopAnim_maybe();
g_vars->scene08_vmyats->_statics = g_vars->scene08_vmyats->getStaticsById(ST_VMT_MIN);
g_vars->scene08_vmyats->setOXY(382, 703);
g_vars->scene08_vmyats->_priority = 29;
g_vars->scene08_vmyats->_callback2 = sceneHandler08_pushCallback;
g_nmi->_aniMan = g_nmi->_currentScene->getStaticANIObject1ById(ANI_MAN, -1);
g_vars->scene08_manOffsetY = 15;
g_nmi->_currentScene->_y = 0;
g_nmi->_updateScreenCallback = sceneHandler08_updateScreenCallback;
}
void sceneHandler08_airMoves() {
if (g_nmi->_aniMan->isIdle() && !(g_nmi->_aniMan->_flags & 0x100)) {
int x = g_nmi->_aniMan->_ox;
int y = g_nmi->_aniMan->_oy;
if (703 - g_nmi->_aniMan->getSomeXY().y - y < 150) {
if (g_nmi->_aniMan->_statics) {
if (g_nmi->_aniMan->_statics->_staticsId == ST_MAN8_FLYDOWN) {
y -= 25;
g_nmi->_aniMan->setOXY(x, y);
}
}
g_nmi->_aniMan->changeStatics2(ST_MAN8_STAND);
g_nmi->_aniMan->setOXY(380, y);
g_nmi->_aniMan->startAnim(MV_MAN8_JUMP, 0, -1);
} else if (g_nmi->_aniMan->_statics) {
if (g_nmi->_aniMan->_statics->_staticsId == ST_MAN8_FLYUP) {
g_nmi->_aniMan->startAnim(MV_MAN8_DRYGUP, 0, -1);
} else if (g_nmi->_aniMan->_statics->_staticsId == ST_MAN8_FLYDOWN) {
g_nmi->_aniMan->startAnim(MV_MAN8_DRYGDOWN, 0, -1);
}
}
}
}
void sceneHandler08_finishArcade() {
g_vars->scene08_inArcade = false;
getGameLoaderInteractionController()->enableFlag24();
getCurrSceneSc2MotionController()->activate();
}
void sceneHandler08_jumpOff(ExCommand *cmd) {
MessageQueue *mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
mq->addExCommandToEnd(cmd->createClone());
mq->setFlags(mq->getFlags() | 1);
g_nmi->_globalMessageQueueList->addMessageQueue(mq);
g_nmi->_aniMan->startAnim(MV_MAN8_JUMPOFF, mq->_id, -1);
sceneHandler08_finishArcade();
}
void sceneHandler08_standUp() {
chainQueue(QU_SC8_STANDUP, 1);
g_vars->scene08_onBelly = false;
}
void sceneHandler08_jumpLogic(ExCommand *cmd) {
if (g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY) == PIC_SC8_LADDERD) {
sceneHandler08_jumpOff(cmd);
cmd->_messageKind = 0;
} else {
sceneHandler08_standUp();
}
}
void sceneHandler08_badLuck() {
g_nmi->_currentScene->getPictureObjectById(PIC_SC8_LADDER, 0)->_flags &= 0xFFFB;
g_nmi->_aniMan->changeStatics2(ST_MAN8_HANDSUP);
g_nmi->_aniMan->setOXY(376, 280);
g_nmi->_aniMan->_priority = 10;
MessageQueue *mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
ExCommand *ex = new ExCommand(g_nmi->_aniMan->_id, 1, MV_MAN8_BADLUCK, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
ex->_param = g_nmi->_aniMan->_odelay;
mq->addExCommandToEnd(ex);
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
g_nmi->setObjectState(sO_StairsUp_8, g_nmi->getObjectEnumState(sO_StairsUp_8, sO_NotBroken));
g_vars->scene08_inAir = false;
}
void sceneHandler08_sitDown() {
g_nmi->_aniMan->setOXY(380, g_nmi->_aniMan->_oy);
g_nmi->_aniMan->changeStatics2(ST_MAN8_FLYDOWN);
g_nmi->_aniMan->startAnim(MV_MAN8_SITDOWN, 0, -1);
g_vars->scene08_vmyats->changeStatics2(ST_VMT_MIN);
g_vars->scene08_vmyats->hide();
g_vars->scene08_inAir = false;
g_vars->scene08_onBelly = true;
}
void sceneHandler08_calcFlight() {
int y = g_vars->scene08_manOffsetY + g_nmi->_aniMan->_oy;
g_nmi->_aniMan->setOXY(g_nmi->_aniMan->_ox, y);
g_vars->scene08_manOffsetY += 2;
if (g_vars->scene08_manOffsetY < g_vars->scene08_stairsOffset)
g_vars->scene08_manOffsetY = g_vars->scene08_stairsOffset;
y = y + g_nmi->_aniMan->getSomeXY().y;
if (g_nmi->_aniMan->_statics && g_nmi->_aniMan->_statics->_staticsId == ST_MAN8_FLYDOWN)
y -= 25;
if (y <= g_vars->scene08_vmyats->_oy) {
g_vars->scene08_vmyats->hide();
} else {
g_vars->scene08_vmyats->show1(-1, -1, -1, 0);
if (!g_vars->scene08_vmyats->_movement)
g_vars->scene08_vmyats->startAnim(MV_VMT_DEF, 0, -1);
}
if (g_nmi->_aniMan->_oy <= 280 && g_vars->scene08_stairsVisible
&& g_nmi->_aniMan->_statics && g_nmi->_aniMan->_statics->_staticsId == ST_MAN8_HANDSUP) {
sceneHandler08_badLuck();
} else if (g_nmi->_aniMan->_oy > 236 || g_vars->scene08_stairsVisible
|| !g_nmi->_aniMan->_statics || g_nmi->_aniMan->_statics->_staticsId != ST_MAN8_HANDSUP) {
if (g_nmi->_aniMan->_movement || g_nmi->_aniMan->_oy < 660
|| (g_vars->scene08_vmyats->_movement && g_vars->scene08_vmyats->_movement->_currDynamicPhaseIndex > 0)
|| abs(g_vars->scene08_manOffsetY) > 2) {
if (g_vars->scene08_manOffsetY >= 0 && !g_nmi->_aniMan->_movement) {
if (g_nmi->_aniMan->_statics->_staticsId == ST_MAN8_HANDSUP)
g_nmi->_aniMan->startAnim(MV_MAN8_HANDSDOWN, 0, -1);
else
g_nmi->_aniMan->changeStatics2(ST_MAN8_FLYDOWN);
}
if (g_nmi->_aniMan->_oy < 500 && !g_nmi->_aniMan->_movement && g_nmi->_aniMan->_statics->_staticsId == ST_MAN8_FLYUP && g_vars->scene08_manOffsetY < 0)
g_nmi->_aniMan->startAnim(MV_MAN8_HANDSUP, 0, -1);
} else {
sceneHandler08_sitDown();
}
} else {
sceneHandler08_enterUp();
}
}
void sceneHandler08_checkEndArcade() {
if (g_vars->scene08_flyingUp) {
int x = g_nmi->_aniMan->_ox;
int y = g_vars->scene08_manOffsetY + g_nmi->_aniMan->_oy;
if (!((g_vars->scene08_manOffsetY + g_nmi->_aniMan->_oy) % 3))
g_vars->scene08_manOffsetY--;
g_nmi->_aniMan->setOXY(x, y);
if (y < 80) {
sceneHandler08_finishArcade();
if (g_nmi->isDemo() && g_nmi->getLanguage() == Common::DE_DEU) {
ModalDemo *demo = new ModalDemo;
demo->launch();
g_nmi->_modalObject = demo;
return;
}
ExCommand *ex = new ExCommand(SC_8, 17, 0, 0, 0, 0, 1, 0, 0, 0);
ex->_messageNum = 61;
ex->_excFlags |= 2;
ex->_param = TrubaUp;
ex->postMessage();
}
}
}
int sceneHandler08(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_CMN_WINARCADE:
sceneHandler08_winArcade();
break;
case MSG_SC8_ENTERUP:
sceneHandler08_enterUp();
break;
case MSG_SC8_HIDELADDER_D:
sceneHandler08_hideLadder();
break;
case MSG_SC8_STANDUP:
g_vars->scene08_manOffsetY = -10;
g_vars->scene08_vmyats->changeStatics2(ST_VMT_MIN);
g_vars->scene08_vmyats->setOXY(382, 703);
g_vars->scene08_vmyats->_priority = 29;
g_vars->scene08_vmyats->_callback2 = sceneHandler08_pushCallback;
g_vars->scene08_inAir = true;
break;
case MSG_SC8_ARCADENOW:
sceneHandler08_arcadeNow();
break;
case MSG_SC8_RESUMEFLIGHT:
sceneHandler08_resumeFlight();
break;
case MSG_SC8_GETHIMUP:
g_vars->scene08_manOffsetY = 0;
g_vars->scene08_flyingUp = true;
break;
case MSG_STARTARCADE:
sceneHandler08_startArcade();
break;
case 29:
if (g_vars->scene08_inArcade) {
if (g_vars->scene08_inAir) {
sceneHandler08_airMoves();
break;
}
if (g_vars->scene08_onBelly) {
sceneHandler08_jumpLogic(cmd);
break;
}
}
break;
case 33:
{
int res = 0;
if (g_nmi->_aniMan2) {
if (g_vars->scene08_inArcade) {
int scHeight = g_nmi->_sceneRect.bottom - g_nmi->_sceneRect.top;
if (g_nmi->_aniMan2->_oy < g_nmi->_sceneRect.top + 200) {
g_nmi->_sceneRect.top = g_nmi->_aniMan2->_oy - 200;
if (g_nmi->_sceneRect.top < 0)
g_nmi->_sceneRect.top = 0;
g_nmi->_sceneRect.bottom = scHeight + g_nmi->_sceneRect.top;
}
if (g_nmi->_aniMan2->_oy > g_nmi->_sceneRect.bottom - 350) {
g_nmi->_sceneRect.bottom = g_nmi->_aniMan2->_oy + 350;
g_nmi->_sceneRect.top = g_nmi->_aniMan2->_oy + 350 - scHeight;
}
} else {
if (g_nmi->_aniMan2->_ox < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.left - 300;
if (g_nmi->_aniMan2->_ox > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.right + 300;
res = 1;
}
}
g_nmi->_floaters->update();
if (g_vars->scene08_inArcade) {
if (g_vars->scene08_inAir)
sceneHandler08_calcFlight();
} else {
Movement *mov = g_nmi->_aniMan->_movement;
if (mov) {
if (mov->_id == MV_MAN_TOLADDERD && mov->_currDynamicPhaseIndex == 8)
g_nmi->_aniMan->_priority = 2;
if (mov && mov->_id == MV_MAN_FROMLADDERUP && mov->_currDynamicPhaseIndex == 13)
g_nmi->_aniMan->_priority = 20;
}
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
}
if (g_vars->scene08_flyingUp)
sceneHandler08_checkEndArcade();
if (g_vars->scene08_snoringCountdown > 0) {
g_vars->scene08_snoringCountdown--;
if (!g_vars->scene08_snoringCountdown) {
g_nmi->playSound(SND_8_014, 0);
g_vars->scene08_snoringCountdown = 71;
}
}
return res;
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,589 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
struct Hanger {
StaticANIObject *ani;
int field_4;
int field_8;
int phase;
};
void scene09_setupGrit(Scene *sc) {
if (g_vars->scene09_grit->_statics->_staticsId == ST_GRT9_GRIT) {
if (!getGameLoaderInventory()->getCountItemsWithId(ANI_INV_COIN)) {
if (g_nmi->getObjectState(sO_CoinSlot_1) == g_nmi->getObjectEnumState(sO_CoinSlot_1, sO_Empty)
&& (g_vars->swallowedEgg1->_value.intValue == ANI_INV_EGGBOOT || g_vars->swallowedEgg2->_value.intValue == ANI_INV_EGGBOOT || g_vars->swallowedEgg3->_value.intValue == ANI_INV_EGGBOOT)) {
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
g_vars->scene09_grit->changeStatics2(ST_GRT9_NORM);
g_nmi->_currentScene = oldsc;
}
}
}
}
void scene09_initScene(Scene *sc) {
g_vars->scene09_flyingBall = nullptr;
g_vars->scene09_numSwallenBalls = 0;
g_vars->scene09_gulper = sc->getStaticANIObject1ById(ANI_GLOTATEL, -1);
g_vars->scene09_spitter = sc->getStaticANIObject1ById(ANI_PLEVATEL, -1);
g_vars->scene09_grit = sc->getStaticANIObject1ById(ANI_GRIT_9, -1);
g_vars->scene09_gulperIsPresent = true;
g_vars->scene09_dudeIsOnLadder = false;
g_vars->scene09_interactingHanger = -1;
g_vars->scene09_intHangerPhase = -1;
g_vars->scene09_intHangerMaxPhase = -1000;
g_vars->scene09_flyingBalls.clear();
for (uint i = 0; i < g_vars->scene09_hangers.size(); i++)
delete g_vars->scene09_hangers[i];
g_vars->scene09_hangers.clear();
g_vars->scene09_numMovingHangers = 4;
StaticANIObject *hanger = sc->getStaticANIObject1ById(ANI_VISUNCHIK, -1);
Hanger *hng = new Hanger;
hng->ani = hanger;
hng->phase = 0;
hng->field_4 = 0;
hng->field_8 = 0;
g_vars->scene09_hangers.push_back(hng);
for (int x = 75; x < 300; x += 75) {
StaticANIObject *ani = new StaticANIObject(hanger);
ani->show1(x + hanger->_ox, hanger->_oy, MV_VSN_CYCLE2, 0);
sc->addStaticANIObject(ani, 1);
hng = new Hanger;
hng->ani = ani;
hng->phase = 0;
hng->field_4 = 0;
hng->field_8 = 0;
g_vars->scene09_hangers.push_back(hng);
}
g_vars->scene09_sceneBalls.clear();
StaticANIObject *newball1 = new StaticANIObject(sc->getStaticANIObject1ById(ANI_BALL9, -1));
newball1->setAlpha(0xc8);
for (int i = 0; i < 4; i++) {
StaticANIObject *newball = new StaticANIObject(newball1);
newball->setAlpha(0xc8);
g_vars->scene09_sceneBalls.push_back(newball);
sc->addStaticANIObject(newball, 1);
}
delete newball1;
g_nmi->setObjectState(sO_RightStairs_9, g_nmi->getObjectEnumState(sO_RightStairs_9, sO_IsClosed));
GameVar *eggvar = g_nmi->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName(sO_GulpedEggs);
g_vars->swallowedEgg1 = eggvar->getSubVarByName(sO_Egg1);
g_vars->swallowedEgg2 = eggvar->getSubVarByName(sO_Egg2);
g_vars->swallowedEgg3 = eggvar->getSubVarByName(sO_Egg3);
scene09_setupGrit(sc);
g_nmi->initArcadeKeys("SC_9");
g_nmi->lift_setButton(sO_Level1, ST_LBN_1N);
g_nmi->setArcadeOverlay(PIC_CSR_ARCADE4);
}
int sceneHandler09_updateScreenCallback() {
int res = g_nmi->drawArcadeOverlay(g_nmi->_objectIdAtCursor == ANI_VISUNCHIK || g_vars->scene09_interactingHanger >= 0);
if (!res)
g_nmi->_updateScreenCallback = nullptr;
return res;
}
int scene09_updateCursor() {
g_nmi->updateCursorCommon();
if (g_vars->scene09_interactingHanger < 0) {
if (g_nmi->_objectIdAtCursor == ANI_VISUNCHIK) {
if (g_nmi->_cursorId == PIC_CSR_ITN)
g_nmi->_updateScreenCallback = sceneHandler09_updateScreenCallback;
} else {
if (g_nmi->_objectIdAtCursor == PIC_SC9_LADDER_R && g_nmi->_cursorId == PIC_CSR_ITN)
g_nmi->_cursorId = (g_vars->scene09_dudeY < 350) ? PIC_CSR_GOD : PIC_CSR_GOU;
}
} else {
g_nmi->_cursorId = PIC_CSR_ITN;
}
return g_nmi->_cursorId;
}
void sceneHandler09_winArcade() {
if (g_vars->scene09_gulper->_flags & 4) {
g_vars->scene09_gulper->changeStatics2(ST_GLT_SIT);
g_vars->scene09_gulper->startAnim(MV_GLT_FLYAWAY, 0, -1);
g_nmi->setObjectState(sO_Jug, g_nmi->getObjectEnumState(sO_Jug, sO_Unblocked));
g_nmi->setObjectState(sO_RightStairs_9, g_nmi->getObjectEnumState(sO_RightStairs_9, sO_IsOpened));
g_vars->scene09_gulperIsPresent = false;
}
}
void sceneHandler09_startAuntie() {
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_TTA9_GOL), 0, 1);
mq->getExCommandByIndex(0)->_x = g_nmi->_sceneRect.right + 30;
mq->chain(nullptr);
}
void sceneHandler09_spitterClick() {
debugC(2, kDebugSceneLogic, "scene09: spitterClick");
if (g_vars->scene09_spitter->_flags & 4) {
PicAniInfo info;
g_vars->scene09_spitter->getPicAniInfo(info);
g_vars->scene09_spitter->_messageQueueId = 0;
g_vars->scene09_spitter->changeStatics2(ST_PLV_SIT);
int x = g_vars->scene09_spitter->_ox - 10;
int y = g_vars->scene09_spitter->_oy + 145;
g_vars->scene09_spitter->setPicAniInfo(info);
if (ABS(x - g_nmi->_aniMan->_ox) > 1 || ABS(y - g_nmi->_aniMan->_oy) > 1) {
MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, x, y, 1, ST_MAN_UP);
if (mq) {
ExCommand *ex = new ExCommand(0, 17, MSG_SC9_PLVCLICK, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags = 2;
mq->addExCommandToEnd(ex);
postExCommand(g_nmi->_aniMan->_id, 2, x, y, 0, -1);
}
} else {
if (!g_nmi->_aniMan->_movement) {
g_vars->scene09_spitter->changeStatics2(ST_PLV_SIT);
g_vars->scene09_spitter->hide();
g_nmi->_aniMan->startAnim(MV_MAN9_SHOOT, 0, -1);
g_nmi->stopAllSoundInstances(SND_9_006);
}
g_nmi->_aniMan2 = nullptr;
if (g_nmi->_sceneRect.left < 800)
g_nmi->_currentScene->_x = 800 - g_nmi->_sceneRect.left;
}
}
}
void sceneHandler09_eatBall() {
debugC(2, kDebugSceneLogic, "scene09: eatBall");
if (g_vars->scene09_flyingBall) {
g_vars->scene09_flyingBall->hide();
g_vars->scene09_flyingBalls.pop_back();
//g_vars->scene09_sceneBalls.pop_back();
g_vars->scene09_flyingBall = nullptr;
g_vars->scene09_numSwallenBalls++;
if (g_vars->scene09_numSwallenBalls >= 3) {
MessageQueue *mq = g_vars->scene09_gulper->getMessageQueue();
if (mq) {
ExCommand *ex = new ExCommand(ANI_GLOTATEL, 1, MV_GLT_FLYAWAY, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
}
g_nmi->setObjectState(sO_Jug, g_nmi->getObjectEnumState(sO_Jug, sO_Unblocked));
g_nmi->setObjectState(sO_RightStairs_9, g_nmi->getObjectEnumState(sO_RightStairs_9, sO_IsOpened));
g_vars->scene09_gulperIsPresent = false;
}
}
}
void sceneHandler09_showBall() {
debugC(2, kDebugSceneLogic, "scene09: showBall");
if (g_vars->scene09_sceneBalls.size()) {
StaticANIObject *ani = g_vars->scene09_sceneBalls.front();
g_vars->scene09_sceneBalls.push_back(ani);
g_vars->scene09_sceneBalls.remove_at(0);
g_vars->scene09_flyingBalls.insert_at(0, ani);
ani->show1(g_nmi->_aniMan->_ox + 94, g_nmi->_aniMan->_oy - 162, MV_BALL9_EXPLODE, 0);
}
}
void sceneHandler09_cycleHangers() {
for (int i = 0; i < g_vars->scene09_numMovingHangers; i++) {
Movement *mov = g_vars->scene09_hangers[i]->ani->_movement;
if (mov && mov->_id == MV_VSN_CYCLE2) {
int idx;
if (g_vars->scene09_hangers[i]->phase >= 0)
idx = 18 - g_vars->scene09_hangers[i]->phase / 5;
else
idx = 18 - g_vars->scene09_hangers[i]->phase * 10 / 43;
if (idx > 38)
idx = 38;
if (idx < 1)
idx = 1;
mov->setDynamicPhaseIndex(idx);
}
}
}
void sceneHandler09_limitHangerPhase() {
for (int i = 0; i < g_vars->scene09_numMovingHangers; i++) {
if (i != g_vars->scene09_interactingHanger) {
g_vars->scene09_hangers[i]->phase += g_vars->scene09_hangers[i]->field_8;
if (g_vars->scene09_hangers[i]->phase > 85)
g_vars->scene09_hangers[i]->phase = 85;
if (g_vars->scene09_hangers[i]->phase < -85)
g_vars->scene09_hangers[i]->phase = -85;
if (g_vars->scene09_hangers[i]->phase < 0)
g_vars->scene09_hangers[i]->field_8++;
if (g_vars->scene09_hangers[i]->phase > 0)
g_vars->scene09_hangers[i]->field_8--;
}
}
}
void sceneHandler09_collideBall(uint num) {
debugC(2, kDebugSceneLogic, "scene09: collideBall");
if (g_vars->scene09_gulperIsPresent) {
g_vars->scene09_flyingBall = g_vars->scene09_flyingBalls[num];
if (g_vars->scene09_gulper) {
g_vars->scene09_gulper->changeStatics2(ST_GLT_SIT);
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC9_EATBALL), 0, 0);
mq->setFlags(mq->getFlags() | 1);
if (!mq->chain(g_vars->scene09_gulper))
delete mq;
}
}
}
void sceneHandler09_ballExplode(uint num) {
debugC(2, kDebugSceneLogic, "scene09: ballExplode(%d) of %d", num, g_vars->scene09_flyingBalls.size());
StaticANIObject *ball = g_vars->scene09_flyingBalls[num];
g_vars->scene09_flyingBalls.remove_at(num);
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC9_BALLEXPLODE), 0, 1);
mq->setParamInt(-1, ball->_odelay);
if (!mq->chain(ball))
delete mq;
}
void sceneHandler09_checkHangerCollide() {
for (uint b = 0; b < g_vars->scene09_flyingBalls.size(); b++) {
StaticANIObject *ball = g_vars->scene09_flyingBalls[b];
int newx = ball->_ox + 5;
ball->setOXY(newx, ball->_oy);
if (newx <= 1398 || g_vars->scene09_flyingBall) {
if (g_vars->scene09_gulperIsPresent)
goto LABEL_11;
} else if (g_vars->scene09_gulperIsPresent) {
sceneHandler09_collideBall(b);
continue;
}
if (newx > 1600) {
sceneHandler09_ballExplode(b);
continue;
}
LABEL_11:
bool hit;
for (int i = 0; i < g_vars->scene09_numMovingHangers; i++) {
for (int j = 0; j < 4; j++) {
int x1 = newx + g_vars->scene09_hangerOffsets[j].x;
int y1 = ball->_oy + g_vars->scene09_hangerOffsets[j].y;
// Check 2 pixels to compensate cord width
hit = g_vars->scene09_hangers[i]->ani->isPixelHitAtPos(x1, y1)
&& g_vars->scene09_hangers[i]->ani->isPixelHitAtPos(x1 + 10, y1);
if (hit) {
sceneHandler09_ballExplode(b);
break;
}
}
if (hit)
break;
}
}
}
void sceneHandler09_hangerStartCycle() {
StaticANIObject *ani = g_vars->scene09_hangers[g_vars->scene09_interactingHanger]->ani;
if (ani->_movement) {
ani->startAnim(MV_VSN_CYCLE2, 0, -1);
g_vars->scene09_hangers[g_vars->scene09_interactingHanger]->field_8 = 0;
g_vars->scene09_hangers[g_vars->scene09_interactingHanger]->phase = g_vars->scene09_intHangerPhase + (g_nmi->_mouseScreenPos.y - g_vars->scene09_clickY) / 2;
if (g_vars->scene09_intHangerMaxPhase != -1000 && g_vars->scene09_hangers[g_vars->scene09_interactingHanger]->phase != g_vars->scene09_intHangerMaxPhase) {
ExCommand *ex = new ExCommand(0, 35, SND_9_019, 0, 0, 0, 1, 0, 0, 0);
ex->_z = 1;
ex->_excFlags |= 2;
ex->postMessage();
g_vars->scene09_intHangerMaxPhase = -1000;
}
} else {
g_vars->scene09_interactingHanger = -1;
}
}
void scene09_visCallback(int *phase) {
// do nothing
}
int sceneHandler09(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_CMN_WINARCADE:
sceneHandler09_winArcade();
break;
case MSG_SC9_STARTTIOTIA:
sceneHandler09_startAuntie();
break;
case MSG_SC9_FROMLADDER:
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
g_vars->scene09_dudeIsOnLadder = false;
break;
case MSG_SC9_TOLADDER:
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
g_vars->scene09_dudeIsOnLadder = true;
break;
case MSG_SC9_PLVCLICK:
sceneHandler09_spitterClick();
break;
case MSG_SC9_FLOWN:
g_vars->scene09_gulperIsPresent = false;
break;
case MSG_SC9_EATBALL:
sceneHandler09_eatBall();
break;
case MSG_SC9_SHOWBALL:
sceneHandler09_showBall();
break;
case 367:
if (g_nmi->isDemo() && g_nmi->getLanguage() == Common::RU_RUS) {
g_nmi->_needRestart = true;
return 0;
}
break;
case 33:
{
int res = 0;
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
g_vars->scene09_dudeY = g_nmi->_aniMan2->_oy;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - g_nmi->_sceneRect.left - 300;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x - g_nmi->_sceneRect.right + 300;
res = 1;
g_nmi->sceneAutoScrolling();
} else {
if (g_nmi->_aniMan->_movement && g_nmi->_aniMan->_movement->_id != MV_MAN9_SHOOT)
g_nmi->_aniMan2 = g_nmi->_aniMan;
}
sceneHandler09_cycleHangers();
sceneHandler09_limitHangerPhase();
sceneHandler09_checkHangerCollide();
if (g_vars->scene09_interactingHanger >= 0)
sceneHandler09_hangerStartCycle();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
return res;
}
break;
case 30:
if (g_vars->scene09_interactingHanger >= 0) {
if (ABS(g_vars->scene09_hangers[g_vars->scene09_interactingHanger]->phase) < 15) {
g_vars->scene09_hangers[g_vars->scene09_interactingHanger]->ani->_callback2 = nullptr; // Really NULL
g_vars->scene09_hangers[g_vars->scene09_interactingHanger]->ani->changeStatics2(ST_VSN_NORMAL);
}
}
g_vars->scene09_interactingHanger = -1;
break;
case 29:
{
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(g_nmi->_sceneRect.left + cmd->_x, g_nmi->_sceneRect.top + cmd->_y);
if (ani) {
if (ani->_id == ANI_PLEVATEL) {
sceneHandler09_spitterClick();
break;
}
if (ani->_id == ANI_VISUNCHIK) {
debugC(2, kDebugSceneLogic, "scene09: VISUNCHIK");
if (g_vars->scene09_numMovingHangers > 0) {
int hng = 0;
while (g_vars->scene09_hangers[hng]->ani != ani) {
++hng;
if (hng >= g_vars->scene09_numMovingHangers)
break;
}
g_vars->scene09_interactingHanger = hng;
g_vars->scene09_intHangerPhase = g_vars->scene09_hangers[hng]->phase;
g_vars->scene09_intHangerMaxPhase = g_vars->scene09_hangers[hng]->phase;
g_vars->scene09_clickY = cmd->_y;
if (!g_vars->scene09_hangers[hng]->ani->_movement || g_vars->scene09_hangers[hng]->ani->_movement->_id != MV_VSN_CYCLE2) {
g_vars->scene09_hangers[hng]->ani->changeStatics2(ST_VSN_NORMAL);
g_vars->scene09_hangers[hng]->ani->startAnim(MV_VSN_CYCLE2, 0, -1);
g_vars->scene09_hangers[hng]->ani->_callback2 = scene09_visCallback;
}
ExCommand *ex = new ExCommand(0, 35, SND_9_018, 0, 0, 0, 1, 0, 0, 0);
ex->_z = 1;
ex->_excFlags |= 2;
ex->postMessage();
}
break;
}
}
if (g_vars->scene09_dudeIsOnLadder && g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY) == PIC_SC9_LADDER_R
&& !cmd->_param && !g_nmi->_aniMan->_movement) {
handleObjectInteraction(g_nmi->_aniMan, g_nmi->_currentScene->getPictureObjectById(PIC_SC9_LADDER_R, 0), 0);
}
if (!ani || !canInteractAny(g_nmi->_aniMan, ani, cmd->_param)) {
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picId, 0);
if (!pic || !canInteractAny(g_nmi->_aniMan, pic, cmd->_param)) {
if ((g_nmi->_sceneRect.right - cmd->_sceneClickX < 47 && g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1) || (cmd->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0))
g_nmi->processArcade(cmd);
}
}
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/behavior.h"
#include "ngi/interaction.h"
namespace NGI {
void scene10_initScene(Scene *sc) {
g_vars->scene10_gum = sc->getStaticANIObject1ById(ANI_GUM, -1);
g_vars->scene10_packet = sc->getStaticANIObject1ById(ANI_PACHKA, -1);
g_vars->scene10_packet2 = sc->getStaticANIObject1ById(ANI_PACHKA2, -1);
g_vars->scene10_inflater = sc->getStaticANIObject1ById(ANI_NADUVATEL, -1);
g_vars->scene10_ladder = sc->getPictureObjectById(PIC_SC10_LADDER, 0);
g_nmi->lift_setButton(sO_Level1, ST_LBN_1N);
g_nmi->lift_init(sc, QU_SC10_ENTERLIFT, QU_SC10_EXITLIFT);
if (g_nmi->getObjectState(sO_Inflater) == g_nmi->getObjectEnumState(sO_Inflater, sO_WithGum)) {
g_vars->scene10_hasGum = 1;
} else {
g_vars->scene10_hasGum = 0;
g_vars->scene10_gum->hide();
}
}
bool sceneHandler10_inflaterIsBlind() {
return g_vars->scene10_inflater->_movement
&& g_vars->scene10_inflater->_movement->_id == MV_NDV_BLOW2
&& g_vars->scene10_inflater->_movement->_currDynamicPhaseIndex < 42;
}
int scene10_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_objectIdAtCursor == ANI_PACHKA || g_nmi->_objectIdAtCursor == ANI_GUM) {
if (g_nmi->_cursorId == PIC_CSR_ITN) {
if (g_vars->scene10_hasGum)
g_nmi->_cursorId = (sceneHandler10_inflaterIsBlind() != 0) ? PIC_CSR_ITN_GREEN : PIC_CSR_ITN_RED;
else
g_nmi->_cursorId = PIC_CSR_DEFAULT;
}
}
return g_nmi->_cursorId;
}
void sceneHandler10_clickGum() {
if (g_vars->scene10_hasGum) {
if (sceneHandler10_inflaterIsBlind()) {
if (g_vars->scene10_hasGum) {
int x = g_vars->scene10_gum->_ox - 139;
int y = g_vars->scene10_gum->_oy - 48;
if (abs(x - g_nmi->_aniMan->_ox) > 1 || abs(y - g_nmi->_aniMan->_oy) > 1) {
MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, x, y, 1, ST_MAN_RIGHT);
if (mq) {
ExCommand *ex = new ExCommand(0, 17, MSG_SC10_CLICKGUM, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags = 2;
mq->addExCommandToEnd(ex);
postExCommand(g_nmi->_aniMan->_id, 2, x, y, 0, -1);
}
} else {
g_vars->scene10_hasGum = 0;
chainQueue(QU_SC10_TAKEGUM, 1);
}
}
} else {
g_vars->scene10_inflater->changeStatics2(ST_NDV_SIT);
if (g_nmi->getObjectState(sO_Inflater) == g_nmi->getObjectEnumState(sO_Inflater, sO_WithGum))
g_vars->scene10_inflater->startAnim(MV_NDV_DENIES, 0, -1);
else
g_vars->scene10_inflater->startAnim(MV_NDV_DENY_NOGUM, 0, -1);
}
}
}
void sceneHandler10_hideGum() {
g_vars->scene10_gum->hide();
g_vars->scene10_packet->hide();
g_vars->scene10_packet2->hide();
}
void sceneHandler10_showGum() {
if (g_vars->scene10_hasGum)
g_vars->scene10_gum->show1(-1, -1, -1, 0);
g_vars->scene10_packet->show1(-1, -1, -1, 0);
g_vars->scene10_packet2->show1(-1, -1, -1, 0);
}
int sceneHandler10(ExCommand *ex) {
if (ex->_messageKind != 17)
return 0;
switch(ex->_messageNum) {
case MSG_LIFT_CLOSEDOOR:
g_nmi->lift_closedoorSeq();
break;
case MSG_LIFT_EXITLIFT:
g_nmi->lift_exitSeq(ex);
break;
case MSG_LIFT_STARTEXITQUEUE:
g_nmi->lift_startExitQueue();
break;
case MSG_LIFT_CLICKBUTTON:
g_nmi->lift_clickButton();
break;
case MSG_SC10_LADDERTOBACK:
g_vars->scene10_ladder->_priority = 49;
break;
case MSG_SC10_LADDERTOFORE:
g_vars->scene10_ladder->_priority = 0;
break;
case MSG_LIFT_GO:
g_nmi->lift_goAnimation();
break;
case MSG_SC10_CLICKGUM:
sceneHandler10_clickGum();
ex->_messageKind = 0;
break;
case MSG_SC10_HIDEGUM:
sceneHandler10_hideGum();
break;
case MSG_SC10_SHOWGUM:
sceneHandler10_showGum();
break;
case 64:
g_nmi->lift_hoverButton(ex);
break;
case 29:
{
if (g_nmi->_currentScene->getPictureObjectIdAtPos(ex->_sceneClickX, ex->_sceneClickY) == PIC_SC10_LADDER) {
handleObjectInteraction(g_nmi->_aniMan, g_nmi->_currentScene->getPictureObjectById(PIC_SC10_DTRUBA, 0), ex->_param);
ex->_messageKind = 0;
return 0;
}
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(ex->_sceneClickX, ex->_sceneClickY);
if (ani && ani->_id == ANI_LIFTBUTTON) {
g_nmi->lift_animateButton(ani);
ex->_messageKind = 0;
return 0;
}
}
break;
case 33:
{
int res = 0;
if (g_nmi->_aniMan2) {
if (g_nmi->_aniMan2->_ox < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.left - 300;
if (g_nmi->_aniMan2->_ox > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.right + 300;
res = 1;
}
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
return res;
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,776 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene11_dudeSwingCallback(int *arg) {
int oldarg = *arg;
*arg = 45 - (int)(g_vars->scene11_swingAngle * -29.66666666666666);
if (*arg < 1)
*arg = 1;
if (*arg > 90)
*arg = 90;
g_vars->scene11_swingAngleDiff = (g_vars->scene11_swingAngle - g_vars->scene11_swingOldAngle) * -490.0000000000001;
g_vars->scene11_swingSpeed = g_vars->scene11_swingAngleDiff * 0.0042 + g_vars->scene11_swingSpeed - g_vars->scene11_swingInertia * (g_vars->scene11_swingAngleDiff * 0.0042 + g_vars->scene11_swingSpeed);
g_vars->scene11_swingAngle = g_vars->scene11_swingSpeed * 0.0042 + g_vars->scene11_swingAngle;
if (g_vars->scene11_swingAngle < -1.5) {
g_vars->scene11_swingAngle = -1.5; //1.0004882812500000;
g_vars->scene11_swingSpeed = 0.0;
g_vars->scene11_swingAngleDiff = 0.0;
}
if (g_vars->scene11_swingAngle > 1.5) {
g_vars->scene11_swingAngle = 1.5; //1.9990234375;
g_vars->scene11_swingSpeed = 0.0;
g_vars->scene11_swingAngleDiff = 0.0;
}
if (g_vars->scene11_swingMaxAngle == *arg && 0.0 != g_vars->scene11_swingSpeed && fabs(g_vars->scene11_swingSpeed) < 2.5) {
g_vars->scene11_swingSpeed = 0.0;
g_vars->scene11_swingAngleDiff = 0.0;
g_vars->scene11_swingAngle = g_vars->scene11_swingOldAngle;
}
g_vars->scene11_swingCounter++;
if (g_vars->scene11_arcadeIsOn) {
if (g_vars->scene11_hintCounter <= 720) {
g_vars->scene11_hintCounter++;
if (g_vars->scene11_hintCounter == 720)
g_vars->scene11_hint->_flags |= 4;
}
}
if ((oldarg >= 45) != (*arg >= 45) && g_vars->scene11_arcadeIsOn) {
if (oldarg >= *arg)
g_nmi->playSound(SND_11_031, 0);
else
g_nmi->playSound(SND_11_020, 0);
}
}
void scene11_setupMusic() {
if (g_nmi->getObjectState(sO_DudeHasJumped) == g_nmi->getObjectEnumState(sO_DudeHasJumped, sO_Yes))
g_nmi->playTrack(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_11"), "MUSIC2", 1);
}
void scene11_initScene(Scene *sc) {
g_vars->scene11_swingie = sc->getStaticANIObject1ById(ANI_SWINGER, -1);
g_vars->scene11_boots = sc->getStaticANIObject1ById(ANI_BOOTS_11, -1);
g_vars->scene11_aniHandler.detachAllObjects();
g_vars->scene11_dudeOnSwing = sc->getStaticANIObject1ById(ANI_MAN11, -1);
g_vars->scene11_dudeOnSwing->_callback2 = scene11_dudeSwingCallback;
g_vars->scene11_dudeOnSwing = sc->getStaticANIObject1ById(ANI_KACHELI, -1);
g_vars->scene11_dudeOnSwing->_callback2 = scene11_dudeSwingCallback;
g_vars->scene11_hint = sc->getPictureObjectById(PIC_SC11_HINT, 0);
g_vars->scene11_hint->_flags &= 0xFFFB;
g_vars->scene11_arcadeIsOn = false;
g_vars->scene11_scrollIsEnabled = false;
g_vars->scene11_scrollIsMaximized = false;
g_vars->scene11_hintCounter = 0;
g_vars->scene11_swingieScreenEdge = 0;
g_vars->scene11_crySound = 0;
g_vars->scene11_swingAngle = 0.0;
g_vars->scene11_swingOldAngle = 0.0;
g_vars->scene11_swingSpeed = 0.0;
g_vars->scene11_swingAngleDiff = 0.0;
g_vars->scene11_swingInertia = 0.01; //1.9849218750000000;
g_vars->scene11_swingCounter = 0;
g_vars->scene11_swingCounterPrevTurn = 0;
g_vars->scene11_swingDirection = 0;
g_vars->scene11_swingDirectionPrevTurn = 0;
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
int swingie = g_nmi->getObjectState(sO_Swingie);
if (swingie == g_nmi->getObjectEnumState(sO_Swingie, sO_IsSwinging)
|| swingie == g_nmi->getObjectEnumState(sO_Swingie, sO_IsSwingingWithBoot)) {
g_vars->scene11_swingIsSwinging = true;
g_vars->scene11_swingieStands = false;
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 1);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 1);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 0);
getCurrSceneSc2MotionController()->replaceNodeX(805, 905);
getSc2MctlCompoundBySceneId(sc->_sceneId)->replaceNodeX(303, 353);
} else if (swingie == g_nmi->getObjectEnumState(sO_Swingie, sO_IsStandingInBoots)
|| swingie == g_nmi->getObjectEnumState(sO_Swingie, sO_IsStandingInCorner)) {
g_vars->scene11_swingIsSwinging = false;
g_vars->scene11_swingieStands = true;
g_vars->scene11_swingie->changeStatics2(ST_SWR_STAND3);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 0);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 1);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 0);
getCurrSceneSc2MotionController()->replaceNodeX(905, 805);
} else {
g_vars->scene11_swingIsSwinging = false;
g_vars->scene11_swingieStands = false;
if (swingie == g_nmi->getObjectEnumState(sO_Swingie, sO_IsSitting)) {
g_vars->scene11_swingie->_movement = nullptr;
g_vars->scene11_swingie->_statics = g_vars->scene11_swingie->getStaticsById(ST_SWR_SIT);
g_vars->scene11_swingie->setOXY(144, 389);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 0);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 0);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 1);
} else {
g_vars->scene11_swingie->_movement = nullptr;
g_vars->scene11_swingie->_statics = g_vars->scene11_swingie->getStaticsById(ST_SWR_SITBALD);
g_vars->scene11_swingie->setOXY(144, 415);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 0);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 0);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 1);
}
}
if (!g_vars->scene11_swingIsSwinging) {
g_vars->scene11_dudeOnSwing->changeStatics2(ST_KCH_STATIC);
g_vars->scene11_dudeOnSwing->setOXY(691, 371);
g_vars->scene11_dudeOnSwing->_priority = 20;
g_vars->scene11_dudeOnSwing->_flags |= 4;
}
g_nmi->_currentScene = oldsc;
g_nmi->initArcadeKeys("SC_11");
g_nmi->setArcadeOverlay(PIC_CSR_ARCADE5);
}
void sceneHandler11_restartMan() {
chainObjQueue(nullptr, QU_SC11_RESTARTMAN, 1);
getGameLoaderInteractionController()->enableFlag24();
getCurrSceneSc2MotionController()->activate();
g_vars->scene11_scrollIsEnabled = false;
}
void sceneHandler11_hitMan() {
if (g_nmi->_aniMan->_ox > 345 && g_nmi->_aniMan->_ox < 355) {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT);
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC11_MANFALL), 0, 0);
mq->setFlags(mq->getFlags() | 1);
if (!mq->chain(g_nmi->_aniMan))
delete mq;
getCurrSceneSc2MotionController()->replaceNodeX(353, 303);
}
}
int scene11_updateCursor() {
g_nmi->updateCursorCommon();
if (g_vars->scene11_arcadeIsOn) {
if (g_nmi->_cursorId != PIC_CSR_DEFAULT_INV && g_nmi->_cursorId != PIC_CSR_ITN_INV)
g_nmi->_cursorId = -1;
} else if (g_vars->scene11_swingie == g_nmi->_objectAtCursor && g_nmi->_inventory->getSelectedItemId() == ANI_INV_BOOT)
g_nmi->_cursorId = PIC_CSR_ITN_INV;
return g_nmi->_cursorId;
}
int sceneHandler11_updateScreenCallback() {
int res = g_nmi->drawArcadeOverlay(g_vars->scene11_arcadeIsOn);
if (!res)
g_nmi->_updateScreenCallback = nullptr;
return res;
}
void sceneHandler11_manToSwing() {
debugC(1, kDebugSceneLogic, "sceneHandler11_manToSwing()");
g_vars->scene11_arcadeIsOn = true;
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
g_nmi->_aniMan2->hide();
g_vars->scene11_swingCounter = 0;
g_vars->scene11_swingInertia = 0.01; //1.9849218;
g_vars->scene11_dudeOnSwing->_flags &= 0xFFFB;
g_vars->scene11_dudeOnSwing = g_nmi->_currentScene->getStaticANIObject1ById(ANI_MAN11, -1);
g_vars->scene11_dudeOnSwing->_statics = g_vars->scene11_dudeOnSwing->getStaticsById(ST_MAN11_EMPTY);
g_vars->scene11_dudeOnSwing->_movement = nullptr;
g_vars->scene11_dudeOnSwing->show1(690, 215, MV_MAN11_SWING_0, 0);
g_vars->scene11_dudeOnSwing->_priority = 20;
g_vars->scene11_dudeOnSwing->startAnim(MV_MAN11_SWING_0, 0, -1);
g_vars->scene11_dudeOnSwing->_movement->setDynamicPhaseIndex(45);
g_vars->scene11_aniHandler.attachObject(g_nmi->_aniMan->_id);
g_nmi->_currentScene->_x = 1400 - g_nmi->_sceneRect.right;
g_vars->scene11_scrollIsEnabled = true;
g_nmi->_updateScreenCallback = sceneHandler11_updateScreenCallback;
}
void sceneHandler11_putABoot() {
if (g_vars->scene11_boots->_flags & 4) {
if (g_vars->scene11_boots->_statics->_staticsId == ST_BTS11_ONE)
chainObjQueue(nullptr, QU_SC11_PUTBOOT2, 1);
} else {
chainObjQueue(nullptr, QU_SC11_PUTBOOT1, 1);
}
}
void sceneHandler11_putBoot() {
if (abs(353 - g_nmi->_aniMan->_ox) > 1 || abs(498 - g_nmi->_aniMan->_oy) > 1
|| g_nmi->_aniMan->_movement || g_nmi->_aniMan->_statics->_staticsId != ST_MAN_RIGHT) {
MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, 353, 498, 1, ST_MAN_RIGHT);
if (mq) {
ExCommand *ex = new ExCommand(0, 17, MSG_SC11_PUTBOOT, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 3;
mq->addExCommandToEnd(ex);
postExCommand(g_nmi->_aniMan->_id, 2, 353, 498, 0, -1);
}
} else {
sceneHandler11_putABoot();
}
}
void sceneHandler11_showSwing() {
g_vars->scene11_dudeOnSwing = g_nmi->_currentScene->getStaticANIObject1ById(ANI_KACHELI, -1);
g_vars->scene11_dudeOnSwing->_statics = g_vars->scene11_dudeOnSwing->getStaticsById(ST_KCH_0);
g_vars->scene11_dudeOnSwing->_movement = nullptr;
g_vars->scene11_dudeOnSwing->show1(691, 371, MV_KCH_START, 0);
g_vars->scene11_dudeOnSwing->_priority = 20;
}
void sceneHandler11_jumpFromSwing() {
g_vars->scene11_arcadeIsOn = false;
g_vars->scene11_hint->_flags &= 0xFFFB;
g_vars->scene11_scrollIsEnabled = false;
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
g_vars->scene11_swingOldAngle = 0.0;
g_vars->scene11_swingAngleDiff = 0.0;
g_vars->scene11_swingSpeed = 0.0;
g_vars->scene11_swingAngle = 0.0;
g_vars->scene11_dudeOnSwing = g_nmi->_currentScene->getStaticANIObject1ById(ANI_MAN11, -1);
g_vars->scene11_dudeOnSwing->_flags &= 0xFFFB;
g_vars->scene11_dudeOnSwing = g_nmi->_currentScene->getStaticANIObject1ById(ANI_KACHELI, -1);
g_vars->scene11_dudeOnSwing->changeStatics2(ST_KCH_STATIC);
g_vars->scene11_dudeOnSwing->setOXY(691, 371);
g_vars->scene11_dudeOnSwing->_priority = 20;
g_vars->scene11_dudeOnSwing->_flags |= 4;
MessageQueue *mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
ExCommand *ex = new ExCommand(g_nmi->_aniMan->_id, 34, 256, 0, 0, 0, 1, 0, 0, 0);
ex->_z = 256;
ex->_messageNum = 0;
ex->_excFlags |= 3;
mq->addExCommandToEnd(ex);
mq->setFlags(mq->getFlags() | 1);
g_nmi->_globalMessageQueueList->addMessageQueue(mq);
g_nmi->_aniMan->_flags |= 0x104;
g_nmi->_aniMan->changeStatics2(ST_MAN11_SWING);
g_nmi->_aniMan->setOXY(685, 373);
g_nmi->_aniMan->startAnim(MV_MAN11_JUMPFROMSWING, mq->_id, -1);
g_nmi->_aniMan2 = g_nmi->_aniMan;
}
void sceneHandler11_swing0() {
debugC(1, kDebugSceneLogic, "sceneHandler11_swing0()");
int phase = g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex;
g_vars->scene11_dudeOnSwing->_statics = g_vars->scene11_dudeOnSwing->getStaticsById(ST_MAN11_EMPTY);
g_vars->scene11_dudeOnSwing->_movement = nullptr;
g_vars->scene11_dudeOnSwing->show1(690, 215, MV_MAN11_SWING_0, 0);
g_vars->scene11_dudeOnSwing->startAnim(MV_MAN11_SWING_0, 0, -1);
g_vars->scene11_dudeOnSwing->_movement->setDynamicPhaseIndex(phase);
g_vars->scene11_swingDirection = 0;
g_vars->scene11_swingMaxAngle = 45;
g_vars->scene11_swingOldAngle = 0.0;
}
void sceneHandler11_swing1() {
debugC(1, kDebugSceneLogic, "sceneHandler11_swing1()");
int phase = g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex;
g_vars->scene11_dudeOnSwing->_statics = g_vars->scene11_dudeOnSwing->getStaticsById(ST_MAN11_EMPTY);
g_vars->scene11_dudeOnSwing->_movement = nullptr;
g_vars->scene11_dudeOnSwing->show1(690, 215, MV_MAN11_SWING_1, 0);
g_vars->scene11_dudeOnSwing->startAnim(MV_MAN11_SWING_1, 0, -1);
g_vars->scene11_dudeOnSwing->_movement->setDynamicPhaseIndex(phase);
g_vars->scene11_swingDirection = 1;
g_vars->scene11_swingMaxAngle = 42;
g_vars->scene11_swingOldAngle = -(fabs(g_vars->scene11_swingAngle) * 0.075 + 0.12);
}
void sceneHandler11_swing2() {
debugC(1, kDebugSceneLogic, "sceneHandler11_swing2()");
int phase = g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex;
g_vars->scene11_dudeOnSwing->_statics = g_vars->scene11_dudeOnSwing->getStaticsById(ST_MAN11_EMPTY);
g_vars->scene11_dudeOnSwing->_movement = nullptr;
g_vars->scene11_dudeOnSwing->show1(690, 215, MV_MAN11_SWING_2, 0);
g_vars->scene11_dudeOnSwing->startAnim(MV_MAN11_SWING_2, 0, -1);
g_vars->scene11_dudeOnSwing->_movement->setDynamicPhaseIndex(phase);
g_vars->scene11_swingDirection = 2;
g_vars->scene11_swingMaxAngle = 48;
g_vars->scene11_swingOldAngle = fabs(g_vars->scene11_swingAngle) * 0.075 + 0.12;
}
void sceneHandler11_emptySwing() {
int phase = g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex;
if (g_vars->scene11_swingDirection)
sceneHandler11_swing0();
g_vars->scene11_dudeOnSwing->stopAnim_maybe();
g_vars->scene11_dudeOnSwing->hide();
g_vars->scene11_dudeOnSwing = g_nmi->_currentScene->getStaticANIObject1ById(ANI_KACHELI, -1);
g_vars->scene11_dudeOnSwing->show1(-1, -1, -1, 0);
g_vars->scene11_dudeOnSwing->changeStatics2(ST_KCH_EMPTY);
g_vars->scene11_dudeOnSwing->startAnim(MV_KCH_MOVE2, 0, -1);
g_vars->scene11_dudeOnSwing->_movement->setDynamicPhaseIndex(phase);
g_vars->scene11_swingInertia = 0.03; //1.9881250;
}
void sceneHandler11_jumpHitAndWin() {
MakeQueueStruct mkQueue;
sceneHandler11_emptySwing();
g_nmi->_aniMan->show1(690 - (int)(sin(g_vars->scene11_swingAngle) * -267.0), 215 - (int)(cos(g_vars->scene11_swingAngle) * -267.0),
MV_MAN11_JUMPHIT, 0);
g_nmi->_aniMan->_priority = 10;
mkQueue.field_1C = 10;
mkQueue.ani = g_nmi->_aniMan;
mkQueue.staticsId2 = ST_MAN_1PIX;
mkQueue.x1 = 1400;
mkQueue.y1 = 0;
mkQueue.field_10 = 1;
mkQueue.flags = 66;
mkQueue.movementId = MV_MAN11_JUMPHIT;
MessageQueue *mq = g_vars->scene11_aniHandler.makeRunQueue(&mkQueue);
if (mq) {
g_vars->scene11_crySound = SND_11_024;
ExCommand *ex = new ExCommand(ANI_MAN, 2, 36, 0, 0, 0, 1, 0, 0, 0);
ex->_param = -1;
ex->_excFlags = 2;
mq->addExCommandToEnd(ex);
ex = new ExCommand(SC_11, 17, 61, 0, 0, 0, 1, 0, 0, 0);
ex->_param = TrubaRight;
ex->_excFlags = 3;
mq->addExCommandToEnd(ex);
if (!mq->chain(g_nmi->_aniMan))
delete mq;
if (g_nmi->getObjectState(sO_Swingie) == g_nmi->getObjectEnumState(sO_Swingie, sO_IsStandingInCorner))
g_nmi->setObjectState(sO_Swingie, g_nmi->getObjectEnumState(sO_Swingie, sO_IsSitting));
g_nmi->setObjectState(sO_DudeHasJumped, g_nmi->getObjectEnumState(sO_DudeHasJumped, sO_Yes));
}
}
void sceneHandler11_jumpOver(double angle) {
MakeQueueStruct mkQueue;
sceneHandler11_emptySwing();
g_nmi->_aniMan->show1(690 - (int)(sin(g_vars->scene11_swingAngle) * -267.0), 215 - (int)(cos(g_vars->scene11_swingAngle) * -267.0),
MV_MAN11_JUMPOVER, 0);
g_nmi->_aniMan->_priority = 0;
mkQueue.staticsId2 = ST_MAN_1PIX;
mkQueue.ani = g_nmi->_aniMan;
mkQueue.x1 = 1163;
mkQueue.y1 = 837 - (int)(angle * 153.0);
mkQueue.field_1C = 0;
mkQueue.field_10 = 1;
mkQueue.flags = 78;
mkQueue.movementId = MV_MAN11_JUMPOVER;
MessageQueue *mq = g_vars->scene11_aniHandler.makeRunQueue(&mkQueue);
if (mq) {
g_vars->scene11_crySound = SND_11_022;
ExCommand *ex = new ExCommand(0, 17, MSG_SC11_RESTARTMAN, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags = 2;
mq->addExCommandToEnd(ex);
if (!mq->chain(g_nmi->_aniMan))
delete mq;
}
}
void sceneHandler11_jumpHit(double angle) {
MakeQueueStruct mkQueue;
sceneHandler11_emptySwing();
if (angle >= 0.0) {
if (angle > 1.0)
angle = 1.0;
} else {
angle = 0.0;
}
g_nmi->_aniMan->show1(690 - (int)(sin(g_vars->scene11_swingAngle) * -267.0), 215 - (int)(cos(g_vars->scene11_swingAngle) * -267.0),
MV_MAN11_JUMPOVER, 0);
g_nmi->_aniMan->_priority = 0;
mkQueue.staticsId2 = ST_MAN_1PIX;
mkQueue.ani = g_nmi->_aniMan;
mkQueue.x1 = 1017 - (int)(angle * -214.0);
mkQueue.y1 = 700;
mkQueue.field_1C = 0;
mkQueue.field_10 = 1;
mkQueue.flags = 78;
mkQueue.movementId = MV_MAN11_JUMPHIT;
MessageQueue *mq = g_vars->scene11_aniHandler.makeRunQueue(&mkQueue);
if (mq) {
g_vars->scene11_crySound = SND_11_022;
ExCommand *ex = new ExCommand(0, 17, MSG_SC11_RESTARTMAN, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags = 2;
mq->addExCommandToEnd(ex);
if (!mq->chain(g_nmi->_aniMan))
delete mq;
}
}
void sceneHandler11_swingLogic() {
if (g_vars->scene11_dudeOnSwing->_movement) {
int ph = g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex;
if (ph > 53 && ph < 90) {
if (ph < 70 && g_vars->scene11_swingSpeed >= 22.0) {
sceneHandler11_jumpOver((double)ph * 0.01428571428571429); // = 1 / 70
} else if (ph <= 80 && g_vars->scene11_swingSpeed >= 22.0) {
sceneHandler11_jumpHitAndWin();
} else {
sceneHandler11_jumpHit((double)ph * g_vars->scene11_swingSpeed * 0.0006493506493506494); // = 1/1540
}
g_vars->scene11_arcadeIsOn = false;
g_vars->scene11_hint->_flags &= 0xFFFB;
return;
}
if (ph > 38 && ph < 53 && fabs(g_vars->scene11_swingSpeed) <= 5.0)
sceneHandler11_jumpFromSwing();
}
}
void sceneHandler11_setSwingDirection() {
if (g_vars->scene11_swingDirection == 2)
g_vars->scene11_swingDirectionPrevTurn = 1;
else if (g_vars->scene11_swingDirection == 1)
g_vars->scene11_swingDirectionPrevTurn = 2;
else
g_vars->scene11_swingDirectionPrevTurn = (g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex <= 45 ? 1 : 0) + 1;
}
void sceneHandler11_swingieSit() {
if (g_nmi->getObjectState(sO_Swingie) == g_nmi->getObjectEnumState(sO_Swingie, sO_IsStandingInBoots)) {
g_vars->scene11_swingIsSwinging = false;
g_vars->scene11_swingieStands = false;
g_vars->scene11_swingie->changeStatics2(ST_SWR_SIT);
g_vars->scene11_swingie->setOXY(144, 389);
g_nmi->setObjectState(sO_Swingie, g_nmi->getObjectEnumState(sO_Swingie, sO_IsSitting));
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 0);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 0);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 1);
}
}
void sceneHandler11_swingieJumpDown() {
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SWR_JUMPDOWN), 0, 0);
mq->setFlags(mq->getFlags() | 1);
if (!mq->chain(g_vars->scene11_swingie))
delete mq;
g_vars->scene11_swingIsSwinging = false;
g_vars->scene11_swingieStands = true;
g_vars->scene11_swingieScreenEdge = g_nmi->_sceneRect.left;
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 0);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 1);
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 0);
getCurrSceneSc2MotionController()->replaceNodeX(905, 805);
}
void sceneHandler11_winArcade() {
if (g_vars->scene11_arcadeIsOn) {
g_vars->scene11_arcadeIsOn = false;
sceneHandler11_emptySwing();
g_nmi->_gameLoader->preloadScene(SC_11, TrubaRight);
}
}
int sceneHandler11(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_CMN_WINARCADE:
sceneHandler11_winArcade();
break;
case MSG_SC11_SITSWINGER:
if (g_nmi->getObjectState(sO_Swingie) == g_nmi->getObjectEnumState(sO_Swingie, sO_IsStandingInBoots)
|| g_nmi->getObjectState(sO_Swingie) == g_nmi->getObjectEnumState(sO_Swingie, sO_IsStandingInCorner)) {
g_nmi->setObjectState(sO_Swingie, g_nmi->getObjectEnumState(sO_Swingie, sO_IsSitting));
}
break;
case MSG_SC11_MANCRY:
g_nmi->playSound(g_vars->scene11_crySound, 0);
g_vars->scene11_crySound = 0;
break;
case MSG_SC11_RESTARTMAN:
sceneHandler11_restartMan();
break;
case MSG_SC11_HITMAN:
sceneHandler11_hitMan();
break;
case MSG_SC11_MANTOSWING:
sceneHandler11_manToSwing();
break;
case MSG_SC11_PUTBOOT:
sceneHandler11_putBoot();
break;
case MSG_SC11_SHOWSWING:
sceneHandler11_showSwing();
break;
case 107:
if (g_vars->scene11_arcadeIsOn) {
sceneHandler11_swingLogic();
}
break;
case 33:
{
int res = 0;
if (g_nmi->_aniMan2) {
int x, y;
x = g_nmi->_aniMan2->_ox;
y = g_nmi->_aniMan2->_oy;
g_vars->scene11_dudeX = x;
g_vars->scene11_dudeY = y;
if (g_vars->scene11_scrollIsEnabled) {
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x - g_nmi->_sceneRect.right + 200;
} else if (g_vars->scene11_scrollIsMaximized) {
g_nmi->_currentScene->_x = g_nmi->_sceneWidth - x;
if (g_vars->scene11_dudeX < 910)
g_vars->scene11_scrollIsMaximized = false;
} else {
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - g_nmi->_sceneRect.left - 300;
else if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x - g_nmi->_sceneRect.right + 300;
if (y < g_nmi->_sceneRect.top + 200)
g_nmi->_currentScene->_y = y - g_nmi->_sceneRect.top - 300;
if (y > g_nmi->_sceneRect.bottom - 300)
g_nmi->_currentScene->_y = y - g_nmi->_sceneRect.bottom + 300;
if (x >= 940)
g_vars->scene11_scrollIsMaximized = true;
g_nmi->sceneAutoScrolling();
}
res = 1;
}
if (g_vars->scene11_swingieStands) {
if (g_nmi->_sceneRect.left >= 534 && g_vars->scene11_swingieScreenEdge < 534)
sceneHandler11_swingieSit();
g_vars->scene11_swingieScreenEdge = g_nmi->_sceneRect.left;
}
if (g_vars->scene11_arcadeIsOn) {
if (g_vars->scene11_swingCounterPrevTurn > 0 && g_vars->scene11_swingCounter - g_vars->scene11_swingCounterPrevTurn > 72) {
sceneHandler11_swing0();
g_vars->scene11_swingDirectionPrevTurn = 0;
g_vars->scene11_swingCounterPrevTurn = 0;
}
}
if (g_vars->scene11_arcadeIsOn) {
if (g_vars->scene11_swingDirection != g_vars->scene11_swingDirectionPrevTurn
&& g_vars->scene11_swingCounterPrevTurn > 0 && g_vars->scene11_swingCounter - g_vars->scene11_swingCounterPrevTurn > 2) {
if (g_vars->scene11_swingDirectionPrevTurn == 1) {
if (g_vars->scene11_swingDirection == 0)
sceneHandler11_swing1();
else
sceneHandler11_swing0();
} else if (g_vars->scene11_swingDirectionPrevTurn == 2) {
if (g_vars->scene11_swingDirection == 0)
sceneHandler11_swing2();
else
sceneHandler11_swing0();
}
g_vars->scene11_swingCounterPrevTurn = g_vars->scene11_swingCounter;
}
}
if (!g_vars->scene11_arcadeIsOn && !g_vars->scene11_swingIsSwinging) {
if (g_vars->scene11_swingSpeed == 0.0
&& g_vars->scene11_dudeOnSwing->_movement && g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex == 45) {
g_vars->scene11_dudeOnSwing->changeStatics2(ST_KCH_STATIC);
}
}
if (!g_vars->scene11_arcadeIsOn && g_vars->scene11_swingIsSwinging) {
if (!g_vars->scene11_swingie->_movement) {
if ((g_vars->scene11_boots->_flags & 4) && g_vars->scene11_boots->_statics->_staticsId == ST_BTS11_2)
sceneHandler11_swingieJumpDown();
else
g_vars->scene11_swingie->startAnim(MV_SWR_SWING, 0, -1);
}
}
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
return res;
}
break;
case 29:
if (g_vars->scene11_swingIsSwinging) {
if (g_nmi->_currentScene->getStaticANIObjectAtPos(g_nmi->_sceneRect.left + cmd->_x, g_nmi->_sceneRect.top + cmd->_y) == g_vars->scene11_swingie
&& cmd->_param == ANI_INV_BOOT)
sceneHandler11_putBoot();
} else {
if (!g_vars->scene11_arcadeIsOn)
goto LABEL_69;
sceneHandler11_setSwingDirection();
g_vars->scene11_swingCounterPrevTurn = g_vars->scene11_swingCounter;
}
if (!g_vars->scene11_arcadeIsOn) {
LABEL_69:
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (!ani || !canInteractAny(g_nmi->_aniMan, ani, cmd->_param)) {
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picId, 0);
if (!pic || !canInteractAny(g_nmi->_aniMan, pic, cmd->_param)) {
if ((g_nmi->_sceneRect.right - cmd->_sceneClickX < 47 && g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1)
|| (cmd->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0)) {
g_nmi->processArcade(cmd);
break;
}
}
}
break;
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View 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/>.
*
*/
#include "ngi/ngi.h"
#include "ngi/objects.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/scene.h"
#include "ngi/floaters.h"
#include "ngi/messages.h"
#include "ngi/statics.h"
#include "ngi/behavior.h"
namespace NGI {
void scene12_initScene(Scene *sc) {
GameVar *var = g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_12");
g_nmi->_floaters->init(var);
g_vars->scene12_fly = g_nmi->getObjectState(sO_Fly_12);
if (g_vars->scene12_fly)
g_vars->scene12_flyCountdown = g_nmi->_rnd.getRandomNumber(600) + 600;
g_nmi->setObjectState(sO_Fly_12, g_nmi->_rnd.getRandomNumber(1));
}
void sceneHandler12_updateFloaters() {
g_nmi->_floaters->genFlies(g_nmi->_currentScene, 397, -50, 100, 6);
g_nmi->_floaters->_array2[0].countdown = g_nmi->_rnd.getRandomNumber(6) + 4;
g_nmi->_floaters->_array2[0].val6 = 397;
g_nmi->_floaters->_array2[0].val7 = -50;
}
int sceneHandler12(ExCommand *cmd) {
int res = 0;
if (cmd->_messageKind == 17 && cmd->_messageNum == 33) {
if (g_nmi->_aniMan2) {
if (g_nmi->_aniMan2->_ox < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.left - 300;
if (g_nmi->_aniMan2->_ox > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = g_nmi->_aniMan2->_ox - g_nmi->_sceneRect.right + 300;
res = 1;
}
g_vars->scene12_flyCountdown--;
if (!g_vars->scene12_flyCountdown)
sceneHandler12_updateFloaters();
g_nmi->_floaters->update();
g_nmi->_behaviorManager->updateBehaviors();
}
return res;
}
} // End of namespace NGI

View File

@@ -0,0 +1,393 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene13_whirlgigCallback(int *phase) {
// Do nothing
}
void scene13_initScene(Scene *sc) {
g_vars->scene13_whirlgig = sc->getStaticANIObject1ById(ANI_WHIRLGIG_13, -1);
g_vars->scene13_guard = sc->getStaticANIObject1ById(ANI_STOROZH, -1);
g_vars->scene13_handleR = sc->getStaticANIObject1ById(ANI_HANDLE_R, -1);
g_vars->scene13_handleL = sc->getStaticANIObject1ById(ANI_HANDLE_L, -1);
g_vars->scene13_bridge = sc->getStaticANIObject1ById(ANI_BRIDGE, -1);
g_vars->scene13_guardDirection = true;
MovGraphLink *lnk = getSc2MctlCompoundBySceneId(sc->_sceneId)->getLinkByName(sO_Bridge);
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
if (g_nmi->getObjectState(sO_Bridge) == g_nmi->getObjectEnumState(sO_Bridge, sO_Convoluted)) {
g_vars->scene13_bridge->changeStatics2(ST_BDG_CLOSED);
lnk->_flags |= 0x20000000u;
g_nmi->playSound(SND_13_018, 1);
g_vars->scene13_whirlgig->_callback2 = nullptr; // Really NULL
} else {
g_vars->scene13_bridge->changeStatics2(ST_BDG_OPEN2);
lnk->_flags &= 0xDFFFFFFF;
g_vars->scene13_whirlgig->stopAnim_maybe();
g_vars->scene13_whirlgig->_callback2 = scene13_whirlgigCallback;
g_vars->scene13_whirlgig->startAnim(MV_WHR13_SPIN, 0, -1);
if (g_vars->scene13_whirlgig->_movement)
g_vars->scene13_whirlgig->_movement->setDynamicPhaseIndex(30);
g_nmi->playSound(SND_13_037, 1);
}
g_vars->scene13_bridge->_flags &= 0xFFFD;
g_nmi->_currentScene = oldsc;
g_nmi->initArcadeKeys("SC_13");
}
void sceneHandler13_openBridge() {
Movement *mov = g_vars->scene13_bridge->_movement;
g_nmi->setObjectState(sO_Bridge, g_nmi->getObjectEnumState(sO_Bridge, sO_IsFree));
if (mov && mov->_id == MV_BDG_CLOSE) {
int sz;
if (mov->_currMovement)
sz = mov->_currMovement->_dynamicPhases.size();
else
sz = mov->_dynamicPhases.size();
g_vars->scene13_bridge->changeStatics2(ST_BDG_CLOSED);
g_vars->scene13_bridge->startAnim(MV_BDG_OPEN, 0, -1);
mov->setDynamicPhaseIndex(sz - mov->_currDynamicPhaseIndex);
} else {
g_vars->scene13_bridge->changeStatics2(ST_BDG_CLOSED);
g_vars->scene13_bridge->startAnim(MV_BDG_OPEN, 0, -1);
}
}
void sceneHandler13_testClose() {
int id = g_vars->scene13_handleL->_statics->_staticsId;
if (id == ST_HDLL_UP)
chainQueue(QU_SC13_CLOSEFAIL, 1);
else if (id == ST_HDLL_FIRECAN || id == ST_HDLL_HAMMER)
chainQueue(QU_SC13_CLOSESUCCESS, 1);
}
void sceneHandler13_testOpen() {
switch (g_vars->scene13_handleR->_statics->_staticsId) {
case ST_HDLR_DOWN:
chainQueue(QU_SC13_OPENFAIL, 1);
break;
case ST_HDLR_DOWN_GUM:
chainQueue(QU_SC13_OPENSUCCESS, 1);
break;
case ST_HDLR_GUM:
g_vars->scene13_handleR->changeStatics2(ST_HDLR_DOWN_GUM);
chainQueue(QU_SC13_OPENSUCCESS, 1);
break;
default:
break;
}
}
void sceneHandler13_closeBridge() {
Movement *mov = g_vars->scene13_bridge->_movement;
if (mov && mov->_id == MV_BDG_OPEN) {
int sz;
if (mov->_currMovement)
sz = mov->_currMovement->_dynamicPhases.size();
else
sz = mov->_dynamicPhases.size();
g_vars->scene13_bridge->changeStatics2(ST_BDG_OPEN2);
g_vars->scene13_bridge->startAnim(MV_BDG_CLOSE, 0, -1);
mov->setDynamicPhaseIndex(sz - mov->_currDynamicPhaseIndex);
} else {
g_vars->scene13_bridge->changeStatics2(ST_BDG_OPEN2);
g_vars->scene13_bridge->startAnim(MV_BDG_CLOSE, 0, -1);
}
}
void sceneHandler13_closeFast() {
g_vars->scene13_bridge->changeStatics2(ST_BDG_OPEN2);
g_vars->scene13_bridge->startAnim(MV_BDG_CLOSE, 0, -1);
g_vars->scene13_bridge->_movement->setDynamicPhaseIndex(21);
}
void sceneHandler13_stopWhirlgig() {
g_vars->scene13_whirlgig->_callback2 = scene13_whirlgigCallback;
g_nmi->stopAllSoundInstances(SND_13_018);
g_nmi->playSound(SND_13_033, 0);
g_nmi->playSound(SND_13_037, 1);
}
void sceneHandler13_startWhirlgig() {
g_vars->scene13_whirlgig->_callback2 = nullptr; // Really NULL
g_nmi->playSound(SND_13_018, 1);
g_nmi->playSound(SND_13_034, 0);
g_nmi->stopAllSoundInstances(SND_13_037);
}
void sceneHandler13_openFast() {
g_vars->scene13_bridge->changeStatics2(ST_BDG_CLOSED);
g_vars->scene13_bridge->startAnim(MV_BDG_OPEN, 0, -1);
g_vars->scene13_bridge->_movement->setDynamicPhaseIndex(15);
}
void sceneHandler13_uneatGum() {
BehaviorMove *beh = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(g_vars->scene13_guard, ST_STR_RIGHT, QU_STR_CHEW);
if (beh) {
beh->_percent = 0;
beh->_delay = 36;
}
beh = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(g_vars->scene13_guard, ST_STR_RIGHT, QU_STR_PLUU);
if (beh) {
beh->_percent = 0;
beh->_delay = 36;
}
}
void sceneHandler13_eatGum() {
BehaviorMove *beh = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(g_vars->scene13_guard, ST_STR_RIGHT, QU_STR_CHEW);
if (beh) {
beh->_percent = 10922;
beh->_delay = 0;
}
}
void sceneHandler13_updateBridge() {
MovGraphLink *lnk = getCurrSceneSc2MotionController()->getLinkByName(sO_Bridge);
if (lnk) {
if (g_nmi->getObjectState(sO_Bridge) == g_nmi->getObjectEnumState(sO_Bridge, sO_Convoluted))
lnk->_flags |= 0x20000000;
else
lnk->_flags &= 0xDFFFFFFF;
}
}
void sceneHandler13_showGum() {
chainQueue(QU_SC13_SHOWGUM, 0);
}
void sceneHandler13_setBehFlag(BehaviorMove *beh, bool flag) {
if (!flag) {
beh->_percent = 327;
beh->_flags |= 1;
beh->_delay = 36;
} else {
beh->_percent = 0x7FFF;
beh->_flags &= 0xFFFFFFFE;
beh->_delay = 0;
}
}
void sceneHandler13_walkForward(bool flag) {
BehaviorMove *beh = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(g_vars->scene13_guard, ST_STR_RIGHT, QU_STR_RTOL);
sceneHandler13_setBehFlag(beh, flag);
beh = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(g_vars->scene13_guard, ST_STR_LEFT, QU_STR_TURNR);
sceneHandler13_setBehFlag(beh, flag);
beh->_flags &= 0xFE;
}
void sceneHandler13_walkBackward(bool flag) {
BehaviorMove *beh = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(g_vars->scene13_guard, ST_STR_RIGHT|0x4000, QU_STR_LTOR);
sceneHandler13_setBehFlag(beh, flag);
beh = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(g_vars->scene13_guard, ST_STR_LEFT|0x4000, QU_STR_TURNR_L);
sceneHandler13_setBehFlag(beh, flag);
beh->_flags &= 0xFE;
}
int sceneHandler13(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch(cmd->_messageNum) {
case MSG_SC13_OPENBRIDGE:
sceneHandler13_openBridge();
break;
case MSG_SC13_TESTCLOSE:
sceneHandler13_testClose();
break;
case MSG_SC13_TESTOPEN:
sceneHandler13_testOpen();
break;
case MSG_SC13_CLOSEBRIDGE:
sceneHandler13_closeBridge();
break;
case MSG_SC13_CLOSEFAST:
sceneHandler13_closeFast();
break;
case MSG_SC13_STOPWHIRLGIG:
sceneHandler13_stopWhirlgig();
break;
case MSG_SC13_STARTWHIRLGIG:
sceneHandler13_startWhirlgig();
break;
case MSG_SC13_OPENFAST:
sceneHandler13_openFast();
break;
case MSG_SC13_UNEATGUM:
sceneHandler13_uneatGum();
break;
case MSG_SC13_EATGUM:
sceneHandler13_eatGum();
break;
case MSG_SC13_CHEW:
g_vars->scene13_guard->_flags &= 0xFF7Fu;
break;
case MSG_SC13_UPDATEBRIDGE:
sceneHandler13_updateBridge();
break;
case MSG_SC13_SHOWGUM:
sceneHandler13_showGum();
break;
case 29:
{
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (!ani || !canInteractAny(g_nmi->_aniMan, ani, cmd->_param)) {
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picId, 0);
if (!pic || !canInteractAny(g_nmi->_aniMan, pic, cmd->_param)) {
if ((g_nmi->_sceneRect.right - cmd->_sceneClickX < 47
&& g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1)
|| (cmd->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0)) {
g_nmi->processArcade(cmd);
}
}
}
}
break;
case 33:
{
int res = 0;
int x;
if (g_nmi->_aniMan2) {
x = g_nmi->_aniMan2->_ox;
g_vars->scene13_dudeX = x;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - g_nmi->_sceneRect.left - 300;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x - g_nmi->_sceneRect.right + 300;
res = 1;
g_nmi->sceneAutoScrolling();
} else {
x = g_vars->scene13_dudeX;
}
if (g_vars->scene13_guardDirection) {
if (x < 1022) {
sceneHandler13_walkForward(1);
sceneHandler13_walkBackward(0);
g_vars->scene13_guardDirection = false;
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
return res;
}
} else if (x > 1022) {
sceneHandler13_walkForward(0);
sceneHandler13_walkBackward(1);
g_vars->scene13_guardDirection = true;
}
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
return res;
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,849 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
#include "ngi/input.h"
namespace NGI {
void scene14_initScene(Scene *sc) {
g_vars->scene14_grandma = sc->getStaticANIObject1ById(ANI_GRANDMA, -1);
g_vars->scene14_sceneDeltaX = 200;
g_vars->scene14_sceneDeltaY = 200;
g_vars->scene14_arcadeIsOn = false;
g_vars->scene14_dudeIsKicking = false;
g_vars->scene14_ballIsFlying = false;
g_vars->scene14_dudeCanKick = false;
g_vars->scene14_sceneDiffX = 300;
g_vars->scene14_sceneDiffY = 300;
g_vars->scene14_pink = nullptr;
g_vars->scene14_flyingBall = nullptr;
g_vars->scene14_balls.clear();
if (g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_In_14)) {
g_vars->scene14_grandmaIsHere = true;
StaticANIObject *ball = sc->getStaticANIObject1ById(ANI_BALL14, -1);
ball->_flags &= 0xFFFB;
g_vars->scene14_balls.push_back(ball);
for (uint i = 0; i < 3; i++) {
ball = new StaticANIObject(ball); // create a copy
ball->_flags &= 0xFFFB;
g_vars->scene14_balls.push_back(ball);
sc->addStaticANIObject(ball, 1);
}
} else {
g_vars->scene14_grandmaIsHere = false;
g_vars->scene14_grandma->hide();
}
g_nmi->lift_setButton(sO_Level4, ST_LBN_4N);
g_nmi->lift_init(sc, QU_SC14_ENTERLIFT, QU_SC14_EXITLIFT);
g_nmi->initArcadeKeys("SC_14");
g_nmi->setArcadeOverlay(PIC_CSR_ARCADE6);
}
void scene14_setupMusic() {
if (!g_vars->scene14_grandmaIsHere)
g_nmi->playTrack(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_14"), "MUSIC2", 0);
}
int scene14_updateCursor() {
g_nmi->updateCursorCommon();
if (g_vars->scene14_arcadeIsOn) {
if (g_vars->scene14_dudeIsKicking) {
g_nmi->_cursorId = PIC_CSR_ARCADE2_D;
} else {
if (g_nmi->_aniMan != g_nmi->_objectAtCursor || g_nmi->_aniMan->_movement || g_nmi->_cursorId != PIC_CSR_DEFAULT) {
if (g_nmi->_cursorId != PIC_CSR_DEFAULT_INV && g_nmi->_cursorId != PIC_CSR_ITN_INV) {
g_nmi->_cursorId = PIC_CSR_DEFAULT;
}
} else {
g_nmi->_cursorId = PIC_CSR_ITN;
}
}
}
return g_nmi->_cursorId;
}
int sceneHandler14_updateScreenCallback() {
int res;
res = g_nmi->drawArcadeOverlay(g_vars->scene14_arcadeIsOn);
if (!res)
g_nmi->_updateScreenCallback = nullptr;
return res;
}
void sceneHandler14_showBallGrandmaHit2() {
if (g_vars->scene14_flyingBall) {
g_vars->scene14_flyingBall->show1(g_vars->scene14_grandmaX + 223, g_vars->scene14_grandmaY + 35, MV_BAL14_SPIN, 0);
g_vars->scene14_flyingBall->_priority = 27;
g_vars->scene14_pink = g_vars->scene14_flyingBall;
g_vars->scene14_flyingBall = nullptr;
}
}
void sceneHandler14_showBallGrandmaDive() {
if (g_vars->scene14_flyingBall) {
g_vars->scene14_flyingBall->show1(g_vars->scene14_grandmaX + 506, g_vars->scene14_grandmaY - 29, -1, 0);
g_vars->scene14_balls.push_back(g_vars->scene14_flyingBall);
g_vars->scene14_flyingBall = nullptr;
}
g_nmi->_aniMan2 = g_nmi->_aniMan;
}
void sceneHandler14_showBallGrandmaHit() {
if (g_vars->scene14_flyingBall) {
g_vars->scene14_flyingBall->show1(g_vars->scene14_grandmaX + 190, g_vars->scene14_grandmaY + 56, MV_BAL14_TOGMA, 0);
g_vars->scene14_flyingBall->_priority = 27;
MessageQueue *mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
ExCommand *ex = new ExCommand(ANI_BALL14, 1, MV_BAL14_TOGMA, 0, 0, 0, 1, 0, 0, 0);
ex->_param = g_vars->scene14_flyingBall->_odelay;
ex->_excFlags |= 2;
ex->_field_24 = 1;
mq->addExCommandToEnd(ex);
ex = new ExCommand(ANI_BALL14, 6, 0, 0, 0, 0, 1, 0, 0, 0);
ex->_param = g_vars->scene14_flyingBall->_odelay;
ex->_excFlags |= 3;
mq->addExCommandToEnd(ex);
mq->chain(nullptr);
g_vars->scene14_balls.push_back(g_vars->scene14_flyingBall);
g_vars->scene14_flyingBall = nullptr;
}
}
void sceneHandler14_exitScene() {
g_vars->scene14_arcadeIsOn = false;
if (g_nmi->_aniMan->_movement)
g_nmi->_aniMan->_movement->gotoLastFrame();
g_nmi->_aniMan->stopAnim_maybe();
handleObjectInteraction(g_nmi->_aniMan, g_nmi->_currentScene->getPictureObjectById(PIC_SC14_RTRUBA, 0), 0);
g_vars->scene14_grandma->changeStatics2(ST_GMA_SIT);
chainQueue(QU_SC14_ENDARCADE, 0);
getGameLoaderInteractionController()->disableFlag24();
getCurrSceneSc2MotionController()->deactivate();
}
void sceneHandler14_showBallMan() {
if (g_vars->scene14_flyingBall) {
g_vars->scene14_flyingBall->show1(g_vars->scene14_dudeX - 166, g_vars->scene14_dudeY + 40, MV_BAL14_TOGMA, 0);
g_vars->scene14_flyingBall->_priority = 27;
MessageQueue *mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
ExCommand *ex = new ExCommand(ANI_BALL14, 1, MV_BAL14_TOGMA, 0, 0, 0, 1, 0, 0, 0);
ex->_param = g_vars->scene14_flyingBall->_odelay;
ex->_excFlags |= 2;
ex->_field_24 = 1;
mq->addExCommandToEnd(ex);
ex = new ExCommand(ANI_BALL14, 6, 0, 0, 0, 0, 1, 0, 0, 0);
ex->_param = g_vars->scene14_flyingBall->_odelay;
ex->_excFlags |= 3;
mq->addExCommandToEnd(ex);
mq->chain(nullptr);
g_vars->scene14_flyingBall->startAnim(MV_BAL14_TOGMA, 0, -1);
g_vars->scene14_balls.push_back(g_vars->scene14_flyingBall);
g_vars->scene14_flyingBall = nullptr;
if (g_vars->scene14_dudeX >= 1300)
sceneHandler14_exitScene();
}
}
void sceneHandler14_manKickBall() {
int val = (g_vars->scene14_grandmaX + 65 - (g_vars->scene14_dudeX - 85)) / -32;
int den = val;
g_vars->scene14_ballX = g_vars->scene14_dudeX - 85;
g_vars->scene14_ballY = g_vars->scene14_dudeY - 76;
g_vars->scene14_ballDeltaX = -32;
if (!val)
den = 1;
g_vars->scene14_ballDeltaY = (g_vars->scene14_grandmaY - 102 - val * val / 2 - (g_vars->scene14_dudeY - 76)) / den;
g_vars->scene14_flyingBall->show1(g_vars->scene14_dudeX - 85, g_vars->scene14_dudeY - 76, -1, 0);
g_vars->scene14_flyingBall->startAnim(MV_BAL14_SPIN, 0, -1);
g_vars->scene14_flyingBall->_priority = 5;
g_vars->scene14_ballIsFlying = true;
}
void sceneHandler14_showBallFly() {
if (g_vars->scene14_balls.size()) {
g_vars->scene14_flyingBall = g_vars->scene14_balls.front();
g_vars->scene14_balls.pop_front();
}
int x, y;
if (g_vars->scene14_grandma->_movement) {
x = g_vars->scene14_grandma->_movement->_ox;
g_vars->scene14_ballX = x;
y = g_vars->scene14_grandma->_movement->_oy;
} else {
x = g_vars->scene14_grandmaX;
y = g_vars->scene14_grandmaY;
}
x = x + 38;
y = y - 77;
g_vars->scene14_ballDeltaX = 32;
int dist = (g_vars->scene14_dudeX - 16 - x) / 32;
int den = dist;
if (!dist)
den = 1;
g_vars->scene14_ballX = x + 32;
g_vars->scene14_ballDeltaY = (g_vars->scene14_dudeY - 40 - dist * dist / 2 - y) / den;
g_vars->scene14_ballY = g_vars->scene14_ballDeltaY + y;
g_vars->scene14_flyingBall->show1(x + 32, g_vars->scene14_ballDeltaY + y, MV_BAL14_SPIN, 0);
g_vars->scene14_flyingBall->_priority = 5;
g_vars->scene14_flyingBall->startAnim(MV_BAL14_SPIN, 0, -1);
g_vars->scene14_ballIsFlying = true;
}
void sceneHandler14_grandmaJump() {
BehaviorMove *beh1 = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(g_vars->scene14_grandma, ST_GMA_SIT, QU_GMA_JUMPFW);
BehaviorMove *beh2 = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(g_vars->scene14_grandma, ST_GMA_SIT, QU_GMA_JUMPBK);
if (beh1) {
if (beh2) {
int p = beh1->_percent;
beh1->_percent = beh2->_percent;
beh2->_percent = p;
}
}
}
void sceneHandler14_endArcade() {
g_vars->scene14_arcadeIsOn = false;
setInputDisabled(0);
getGameLoaderInteractionController()->enableFlag24();
getCurrSceneSc2MotionController()->activate();
BehaviorMove *beh = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(g_vars->scene14_grandma, ST_GMA_SIT, QU_GMA_BLINK);
if (beh)
beh->_percent = 327;
beh = g_nmi->_behaviorManager->getBehaviorMoveByMessageQueueDataId(g_vars->scene14_grandma, ST_GMA_SIT, QU_GMA_THROW);
if (beh)
beh->_percent = 0;
g_vars->scene14_sceneDeltaX = 200;
g_vars->scene14_sceneDeltaY = 200;
g_nmi->_aniMan2 = g_nmi->_aniMan;
g_vars->scene14_sceneDiffX = 300;
g_vars->scene14_sceneDiffY = 300;
}
void sceneHandler14_winArcade() {
if (g_vars->scene14_arcadeIsOn) {
if (g_vars->scene14_dudeIsKicking) {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
g_vars->scene14_dudeIsKicking = false;
}
if (g_vars->scene14_flyingBall) {
g_vars->scene14_balls.push_back(g_vars->scene14_flyingBall);
g_vars->scene14_flyingBall->_flags &= 0xFFFB;
g_vars->scene14_flyingBall = nullptr;
}
g_vars->scene14_ballIsFlying = false;
sceneHandler14_endArcade();
g_vars->scene14_grandmaIsHere = false;
if (g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_In_14)) {
g_nmi->setObjectState(sO_Grandma, g_nmi->getObjectEnumState(sO_Grandma, sO_In_15));
g_vars->scene14_grandma->changeStatics2(ST_GMA_SIT);
g_vars->scene14_grandma->_flags &= 0xFFFB;
}
if (g_nmi->_currentScene->_messageQueueId) {
MessageQueue *mq = g_nmi->_globalMessageQueueList->getMessageQueueById(g_nmi->_currentScene->_messageQueueId);
if (mq)
delete mq;
g_nmi->_currentScene->_messageQueueId = 0;
}
}
}
void sceneHandler14_showBallLast() {
if (g_vars->scene14_pink) {
g_vars->scene14_pink->show1(693, 491, MV_BAL14_SPIN, 0);
g_vars->scene14_pink->_priority = 27;
}
}
void sceneHandler14_hideBallLast() {
if (g_vars->scene14_pink) {
g_vars->scene14_pink->hide();
g_vars->scene14_balls.push_back(g_vars->scene14_pink);
g_vars->scene14_pink = nullptr;
}
}
void sceneHandler14_startArcade() {
g_vars->scene14_arcadeIsOn = true;
g_vars->scene14_dudeCanKick = true;
if (g_nmi->_aniMan->_movement) {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
g_nmi->_aniMan->setOXY(1237, 451);
g_nmi->_aniMan->_priority = 25;
}
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
g_nmi->_aniMan2 = nullptr;
g_vars->scene14_sceneDeltaX = 50;
g_vars->scene14_sceneDiffX = 100;
g_vars->scene14_hitsLeft = 4;
g_vars->scene14_pink = nullptr;
chainQueue(QU_SC14_STARTARCADE, 0);
g_nmi->_updateScreenCallback = sceneHandler14_updateScreenCallback;
}
void sceneHandler14_clearCallback() {
g_nmi->_aniMan->_callback2 = nullptr; // Really NULL
g_vars->scene14_dudeIsKicking = false;
}
void sceneHandler14_kickAnimation() {
if (g_nmi->_aniMan->_movement) {
sceneHandler14_clearCallback();
if (g_vars->scene14_flyingBall && g_vars->scene14_dudeX - g_vars->scene14_flyingBall->_ox < 180) {
g_nmi->_aniMan->changeStatics2(g_nmi->_aniMan->_movement->_staticsObj2->_staticsId);
g_nmi->_aniMan->startAnim(MV_MAN14_KICK, 0, -1);
g_vars->scene14_ballIsFlying = false;
g_vars->scene14_flyingBall->stopAnim_maybe();
g_vars->scene14_flyingBall->hide();
} else {
g_nmi->_aniMan->changeStatics2(g_nmi->_aniMan->_movement->_staticsObj2->_staticsId);
g_nmi->_aniMan->startAnim(MV_MAN14_KICKAIR, 0, -1);
}
}
}
void sceneHandler14_declineCallback(int *arg) {
if (g_vars->scene14_dudeIsKicking) {
*arg = (int)(sqrt((double)(g_nmi->_mouseVirtY - g_vars->scene14_mouseCursorPos.y)
* (g_nmi->_mouseVirtY - g_vars->scene14_mouseCursorPos.y)
+ (g_nmi->_mouseVirtX - g_vars->scene14_mouseCursorPos.x)
* (g_nmi->_mouseVirtX - g_vars->scene14_mouseCursorPos.x)) * 0.1);
if (*arg > 11)
*arg = 11;
} else {
++*arg;
}
}
void sceneHandler14_dudeDecline() {
g_vars->scene14_mouseCursorPos.x = g_nmi->_mouseVirtX;
g_vars->scene14_mouseCursorPos.y = g_nmi->_mouseVirtY;
g_nmi->_aniMan->_callback2 = sceneHandler14_declineCallback;
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
g_nmi->_aniMan->startAnim(MV_MAN14_DECLINE, 0, -1);
g_vars->scene14_dudeIsKicking = true;
}
bool sceneHandler14_arcadeProcessClick(ExCommand *cmd) {
if (!getCurrSceneSc2MotionController()->_isEnabled)
return 0;
if (!g_vars->scene14_grandmaIsHere) {
if (!cmd->_param) {
if (g_vars->scene14_pink) {
if (g_vars->scene14_pink->_flags & 4) {
if (cmd->_sceneClickX < g_vars->scene14_pink->_ox + 40) {
handleObjectInteraction(g_nmi->_aniMan, g_vars->scene14_pink, 0);
cmd->_messageKind = 0;
return true;
}
}
}
}
return false;
}
if (getCurrSceneSc2MotionController()->_objtype != kObjTypeMctlCompound)
return false;
if (!getCurrSceneSc2MotionController()->_motionControllers[0]->_movGraphReactObj->pointInRegion(cmd->_sceneClickX, cmd->_sceneClickY))
return false;
if (cmd->_sceneClickX > 1237)
return false;
MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, 1237, 451, 1, 0);
if (!mq)
return false;
ExCommand *ex = new ExCommand(0, 17, MSG_SC14_STARTARCADE, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 3;
mq->addExCommandToEnd(ex);
mq->setFlags(mq->getFlags() | 1);
postExCommand(g_nmi->_aniMan->_id, 2, 1237, 451, 0, -1);
cmd->_messageKind = 0;
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
return true;
}
void sceneHandler14_grandmaThrow() {
g_vars->scene14_grandma->changeStatics2(ST_GMA_SIT);
MessageQueue *mq = new MessageQueue(0);
ExCommand *ex = new ExCommand(ANI_GRANDMA, 2, 30, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_THROW, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
mq->chain(nullptr);
}
void sceneHandler14_passToGrandma() {
g_vars->scene14_flyingBall->stopAnim_maybe();
g_vars->scene14_flyingBall->_priority = 27;
MessageQueue *mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
ExCommand *ex = new ExCommand(ANI_BALL14, 1, MV_BAL14_FALL, 0, 0, 0, 1, 0, 0, 0);
ex->_param = g_vars->scene14_flyingBall->_odelay;
ex->_excFlags |= 2;
ex->_field_24 = 1;
mq->addExCommandToEnd(ex);
ex = new ExCommand(ANI_BALL14, 6, 0, 0, 0, 0, 1, 0, 0, 0);
ex->_param = g_vars->scene14_flyingBall->_odelay;
ex->_excFlags |= 3;
mq->addExCommandToEnd(ex);
mq->chain(nullptr);
g_vars->scene14_balls.push_back(g_vars->scene14_flyingBall);
g_vars->scene14_flyingBall = nullptr;
sceneHandler14_grandmaThrow();
}
void sceneHandler14_grandmaJumpThrow() {
g_vars->scene14_grandma->changeStatics2(ST_GMA_SIT);
MessageQueue *mq = new MessageQueue(0);
ExCommand *ex = new ExCommand(ANI_GRANDMA, 2, 30, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_JUMPFW, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_THROW, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
mq->chain(nullptr);
g_vars->scene14_dude2X += 71;
g_nmi->_currentScene->_x = 71;
g_nmi->_aniMan2 = g_nmi->_aniMan;
}
void sceneHandler14_dudeFall() {
if (!g_nmi->_aniMan->_movement || g_nmi->_aniMan->_movement->_id != MV_MAN14_FALL) {
sceneHandler14_clearCallback();
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
g_nmi->_aniMan->startAnim(MV_MAN14_FALL, 0, -1);
g_vars->scene14_flyingBall->stopAnim_maybe();
g_vars->scene14_flyingBall->hide();
sceneHandler14_grandmaJumpThrow();
}
++g_vars->scene14_hitsLeft;
}
void sceneHandler14_grandmaStepForward() {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
g_nmi->_aniMan->startAnim(MV_MAN14_STEPFW, 0, -1);
g_vars->scene14_dude2X -= 71;
g_nmi->_currentScene->_x = -71;
g_nmi->_aniMan2 = g_vars->scene14_grandma;
}
void sceneHandler14_arcadeLogic() {
g_vars->scene14_flyingBall->stopAnim_maybe();
g_vars->scene14_flyingBall->hide();
if (g_vars->scene14_dudeIsKicking)
sceneHandler14_clearCallback();
if (g_vars->scene14_hitsLeft <= 1) {
setInputDisabled(1);
sceneHandler14_clearCallback();
g_vars->scene14_dudeCanKick = false;
g_nmi->_aniMan2 = nullptr;
chainQueue(QU_SC14_WINARCADE, 1);
--g_vars->scene14_hitsLeft;
} else {
ExCommand *ex;
g_vars->scene14_grandma->changeStatics2(ST_GMA_SIT);
if (g_vars->scene14_hitsLeft != 3 || g_vars->scene14_pink) {
MessageQueue *mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_BACKOFF, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_THROW, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
mq->chain(nullptr);
} else {
MessageQueue *mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_BACKOFF2, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_THROW, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
mq->chain(nullptr);
}
sceneHandler14_grandmaStepForward();
--g_vars->scene14_hitsLeft;
}
}
void sceneHandler14_animateBall() {
g_vars->scene14_ballX += g_vars->scene14_ballDeltaX;
g_vars->scene14_ballY += g_vars->scene14_ballDeltaY;
int x = g_vars->scene14_ballX;
int y = g_vars->scene14_ballY;
g_vars->scene14_ballDeltaY++;
if (g_vars->scene14_ballY <= 517) {
if (x <= g_vars->scene14_dudeX - 16) {
if (g_vars->scene14_ballDeltaX >= 0 || x >= g_vars->scene14_grandmaX + 65
|| x <= g_vars->scene14_grandmaX - 135 || y <= g_vars->scene14_grandmaY - 102) {
if (g_vars->scene14_flyingBall->_movement)
g_vars->scene14_flyingBall->_movement->setOXY(x, y);
else
g_vars->scene14_flyingBall->setOXY(x, y);
} else {
sceneHandler14_arcadeLogic();
g_vars->scene14_ballIsFlying = false;
}
} else {
sceneHandler14_dudeFall();
g_vars->scene14_ballIsFlying = false;
}
} else {
sceneHandler14_passToGrandma();
g_vars->scene14_ballIsFlying = false;
}
}
int sceneHandler14(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch(cmd->_messageNum) {
case MSG_SC14_SHOWBALLGMAHIT2:
sceneHandler14_showBallGrandmaHit2();
break;
case MSG_SC14_SHOWBALLGMADIVE:
sceneHandler14_showBallGrandmaDive();
break;
case MSG_LIFT_CLICKBUTTON:
g_nmi->lift_clickButton();
break;
case MSG_SC14_SHOWBALLGMAHIT:
sceneHandler14_showBallGrandmaHit();
break;
case MSG_SC14_SHOWBALLMAN:
sceneHandler14_showBallMan();
break;
case MSG_SC14_MANKICKBALL:
sceneHandler14_manKickBall();
break;
case MSG_SC14_SHOWBALLFLY:
sceneHandler14_showBallFly();
break;
case MSG_LIFT_GO:
g_nmi->lift_goAnimation();
break;
case MSG_SC14_GMAJUMP:
sceneHandler14_grandmaJump();
break;
case MSG_LIFT_CLOSEDOOR:
g_nmi->lift_closedoorSeq();
break;
case MSG_LIFT_EXITLIFT:
g_nmi->lift_exitSeq(cmd);
break;
case MSG_LIFT_STARTEXITQUEUE:
g_nmi->lift_startExitQueue();
break;
case MSG_SC14_RESTORESCROLL:
g_nmi->_aniMan2 = g_nmi->_aniMan;
g_nmi->_scrollSpeed = 8;
break;
case MSG_CMN_WINARCADE:
sceneHandler14_winArcade();
break;
case MSG_SC14_SCROLLLEFT:
g_nmi->_aniMan2 = nullptr;
g_nmi->_currentScene->_x = -g_nmi->_sceneRect.left;
g_nmi->_scrollSpeed = 24;
break;
case MSG_SC14_SHOWBALLLAST:
sceneHandler14_showBallLast();
break;
case MSG_SC14_HIDEBALLLAST:
sceneHandler14_hideBallLast();
break;
case MSG_SC14_HIDEPINK:
if (g_vars->scene14_pink) {
g_vars->scene14_pink->hide();
}
break;
case MSG_SC14_GMATOTRUBA:
g_nmi->_currentScene->_x = -g_nmi->_sceneRect.left;
break;
case MSG_SC14_STARTARCADE:
sceneHandler14_startArcade();
break;
case MSG_SC14_ENDARCADE:
sceneHandler14_endArcade();
g_vars->scene14_grandmaIsHere = false;
break;
case 64:
g_nmi->lift_hoverButton(cmd);
break;
case 33:
{
Movement *mov = g_nmi->_aniMan->_movement;
if (mov) {
g_vars->scene14_dudeX = mov->_ox;
g_vars->scene14_dudeY = mov->_oy;
if (mov->_id == MV_MAN14_KICK)
g_vars->scene14_dudeX = mov->_ox + 2 * g_nmi->_aniMan->_movement->_currDynamicPhaseIndex;
} else {
g_vars->scene14_dudeX = g_nmi->_aniMan->_ox;
g_vars->scene14_dudeY = g_nmi->_aniMan->_oy;
}
mov = g_vars->scene14_grandma->_movement;
if (mov) {
g_vars->scene14_grandmaX = mov->_ox;
g_vars->scene14_grandmaY = mov->_oy;
} else {
g_vars->scene14_grandmaX = g_vars->scene14_grandma->_ox;
g_vars->scene14_grandmaY = g_vars->scene14_grandma->_oy;
}
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
g_vars->scene14_dude2X = x;
if (x < g_nmi->_sceneRect.left + g_vars->scene14_sceneDeltaX) {
g_nmi->_currentScene->_x = x - g_vars->scene14_sceneDiffX - g_nmi->_sceneRect.left;
x = g_vars->scene14_dude2X;
}
if (x > g_nmi->_sceneRect.right - g_vars->scene14_sceneDeltaX)
g_nmi->_currentScene->_x = x + g_vars->scene14_sceneDiffX - g_nmi->_sceneRect.right;
g_nmi->sceneAutoScrolling();
}
if (g_vars->scene14_ballIsFlying)
sceneHandler14_animateBall();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
}
break;
case 30:
if (g_vars->scene14_dudeIsKicking) {
sceneHandler14_kickAnimation();
break;
}
if (!g_vars->scene14_arcadeIsOn) {
break;
}
break;
case 29:
if (g_vars->scene14_arcadeIsOn) {
if (g_vars->scene14_dudeCanKick && g_nmi->_aniMan->isPixelHitAtPos(cmd->_sceneClickX, cmd->_sceneClickY) && !g_nmi->_aniMan->_movement) {
sceneHandler14_dudeDecline();
break;
}
} else {
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (ani && ani->_id == ANI_LIFTBUTTON) {
g_nmi->lift_animateButton(ani);
cmd->_messageKind = 0;
break;
}
if (!sceneHandler14_arcadeProcessClick(cmd) && (!ani || !canInteractAny(g_nmi->_aniMan, ani, cmd->_param))) {
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picId, 0);
if (!pic || !canInteractAny(g_nmi->_aniMan, pic, cmd->_param)) {
if ((g_nmi->_sceneRect.right - cmd->_sceneClickX < 47 && g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1)
|| (cmd->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0)) {
g_nmi->processArcade(cmd);
sceneHandler14_arcadeProcessClick(cmd);
break;
}
}
}
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,212 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene15_initScene(Scene *sc) {
g_vars->scene15_chantingCountdown = 0;
StaticANIObject *grandma = sc->getStaticANIObject1ById(ANI_GRANDMA_ASS, -1);
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
int grandmaState = g_nmi->getObjectState(sO_Grandma);
if (grandmaState == g_nmi->getObjectEnumState(sO_Grandma, sO_In_15)) {
grandma->changeStatics2(ST_GMS_BOOT);
grandma->setOXY(97, 399);
g_nmi->setObjectState(sO_LeftPipe_15, g_nmi->getObjectEnumState(sO_LeftPipe_15, sO_IsClosed));
} else if (grandmaState == g_nmi->getObjectEnumState(sO_Grandma, sO_In_15_1)) {
grandma->changeStatics2(ST_GMS_BOOT);
grandma->setOXY(86, 399);
g_nmi->setObjectState(sO_LeftPipe_15, g_nmi->getObjectEnumState(sO_LeftPipe_15, sO_IsClosed));
} else if (grandmaState == g_nmi->getObjectEnumState(sO_Grandma, sO_In_15_2)) {
grandma->changeStatics2(ST_GMS_BOOT);
grandma->setOXY(71, 399);
g_nmi->setObjectState(sO_LeftPipe_15, g_nmi->getObjectEnumState(sO_LeftPipe_15, sO_IsClosed));
} else if (grandmaState == g_nmi->getObjectEnumState(sO_Grandma, sO_In_15_3)) {
grandma->changeStatics2(ST_GMS_BOOT);
grandma->setOXY(49, 399);
g_nmi->setObjectState(sO_LeftPipe_15, g_nmi->getObjectEnumState(sO_LeftPipe_15, sO_IsClosed));
} else if (grandmaState == g_nmi->getObjectEnumState(sO_Grandma, sO_WithoutBoot)) {
grandma->changeStatics2(ST_GMS_BOOT);
grandma->setOXY(97, 399);
grandma->changeStatics2(ST_GMS_BOOTLESS2);
g_nmi->setObjectState(sO_LeftPipe_15, g_nmi->getObjectEnumState(sO_LeftPipe_15, sO_IsClosed));
} else {
grandma->hide();
g_nmi->setObjectState(sO_LeftPipe_15, g_nmi->getObjectEnumState(sO_LeftPipe_15, sO_IsOpened));
}
g_vars->scene15_plusminus = sc->getStaticANIObject1ById(ANI_PLUSMINUS, -1);
if (g_nmi->getObjectState(sO_Guard_2) == g_nmi->getObjectEnumState(sO_Guard_2, sO_Off))
g_vars->scene15_plusminus->_statics = g_vars->scene15_plusminus->getStaticsById(ST_PMS_MINUS);
else
g_vars->scene15_plusminus->_statics = g_vars->scene15_plusminus->getStaticsById(ST_PMS_PLUS);
g_vars->scene15_ladder = sc->getPictureObjectById(PIC_SC15_LADDER, 0);
g_vars->scene15_boot = sc->getStaticANIObject1ById(ANI_BOOT_15, -1);
if (g_nmi->getObjectState(sO_Boot_15) != g_nmi->getObjectEnumState(sO_Boot_15, sO_IsPresent))
g_vars->scene15_boot->_flags &= 0xFFFB;
g_nmi->_currentScene = oldsc;
g_nmi->lift_setButton(sO_Level5, ST_LBN_5N);
g_nmi->lift_init(sc, QU_SC15_ENTERLIFT, QU_SC15_EXITLIFT);
}
int scene15_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_cursorId == PIC_CSR_ITN && g_nmi->_objectIdAtCursor == PIC_SC15_LTRUBA)
g_nmi->_cursorId = PIC_CSR_GOL;
return g_nmi->_cursorId;
}
int sceneHandler15(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch(cmd->_messageNum) {
case MSG_LIFT_CLOSEDOOR:
g_nmi->lift_closedoorSeq();
break;
case MSG_LIFT_EXITLIFT:
g_nmi->lift_exitSeq(cmd);
break;
case MSG_LIFT_STARTEXITQUEUE:
g_nmi->lift_startExitQueue();
break;
case MSG_SC4_HIDEBOOT:
g_vars->scene15_boot->_flags &= 0xFFFB;
break;
case MSG_SC15_STOPCHANTING:
g_nmi->stopAllSoundInstances(SND_15_001);
g_vars->scene15_chantingCountdown = 120;
break;
case MSG_SC15_ASSDRYG:
if (g_nmi->_rnd.getRandomNumber(1)) {
g_nmi->playSound(SND_15_011, 0);
} else {
g_nmi->playSound(SND_15_006, 0);
}
break;
case MSG_SC15_LADDERTOBACK:
g_vars->scene15_ladder->_priority = 60;
break;
case MSG_LIFT_GO:
g_nmi->lift_goAnimation();
break;
case MSG_LIFT_CLICKBUTTON:
g_nmi->lift_clickButton();
break;
case MSG_SC15_PULL:
if (g_vars->scene15_plusminus->_statics->_staticsId == ST_PMS_MINUS) {
g_vars->scene15_plusminus->_statics = g_vars->scene15_plusminus->getStaticsById(ST_PMS_PLUS);
} else {
g_vars->scene15_plusminus->_statics = g_vars->scene15_plusminus->getStaticsById(ST_PMS_MINUS);
}
break;
case 64:
g_nmi->lift_hoverButton(cmd);
break;
case 29:
{
if (g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY) == PIC_SC15_LADDER) {
handleObjectInteraction(g_nmi->_aniMan, g_nmi->_currentScene->getPictureObjectById(PIC_SC15_DTRUBA, 0), cmd->_param);
cmd->_messageKind = 0;
return 0;
}
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (ani && ani->_id == ANI_LIFTBUTTON) {
g_nmi->lift_animateButton(ani);
cmd->_messageKind = 0;
}
}
break;
case 30:
// nop
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
}
if (g_vars->scene15_chantingCountdown > 0) {
g_vars->scene15_chantingCountdown--;
if (!g_vars->scene15_chantingCountdown)
g_nmi->playSound(SND_15_001, 1);
}
g_nmi->_behaviorManager->updateBehaviors();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,488 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene16_initScene(Scene *sc) {
g_vars->scene16_figures.clear();
g_vars->scene16_walkingBoy = nullptr;
g_vars->scene16_walkingGirl = nullptr;
g_vars->scene16_walkingCount = 200;
g_vars->scene16_wire = sc->getStaticANIObject1ById(ANI_WIRE16, -1);
g_vars->scene16_mug = sc->getStaticANIObject1ById(ANI_MUG, -1);
g_vars->scene16_jettie = sc->getStaticANIObject1ById(ANI_JETTIE, -1);
g_vars->scene16_boot = sc->getStaticANIObject1ById(ANI_BOOT_16, -1);
g_vars->scene16_girlIsLaughing = false;
g_vars->scene16_sound = SND_16_034;
if (g_nmi->getObjectState(sO_Bridge) == g_nmi->getObjectEnumState(sO_Bridge, sO_Convoluted)) {
g_vars->scene16_placeIsOccupied = true;
StaticANIObject *boy[2];
boy[0] = sc->getStaticANIObject1ById(ANI_BOY, -1);
boy[0]->loadMovementsPixelData();
boy[1] = new StaticANIObject(boy[0]);
sc->addStaticANIObject(boy[1], 1);
int idx = 0;
for (int i = 0; i < 3; i++) {
g_vars->scene16_figures.push_back(boy[idx]);
idx++;
if (idx > 1)
idx = 0;
}
g_vars->scene16_figures.push_back(sc->getStaticANIObject1ById(ANI_GIRL, -1));
for (int i = 0; i < 4; i++) {
g_vars->scene16_figures.push_back(boy[idx]);
idx++;
if (idx > 1)
idx = 0;
}
} else {
g_nmi->setObjectState(sO_Girl, g_nmi->getObjectEnumState(sO_Girl, sO_IsSwinging));
g_vars->scene16_placeIsOccupied = false;
StaticANIObject *ani = new StaticANIObject(g_nmi->accessScene(SC_COMMON)->getStaticANIObject1ById(ANI_BEARDED_CMN, -1));
ani->_movement = nullptr;
ani->_statics = ani->_staticsList[0];
sc->addStaticANIObject(ani, 1);
}
if (g_nmi->getObjectState(sO_Girl) == g_nmi->getObjectEnumState(sO_Girl, sO_IsLaughing)) {
StaticANIObject *girl = sc->getStaticANIObject1ById(ANI_GIRL, -1);
girl->show1(554, 432, MV_GRL_LAUGH_POPA, 0);
girl->_priority = 20;
}
if (g_nmi->getObjectState(sO_Cup) == g_nmi->getObjectEnumState(sO_Cup, sO_In_16)) {
g_vars->scene16_mug->_statics = g_vars->scene16_mug->getStaticsById(ST_MUG_EMPTY);
g_vars->scene16_mug->_movement = nullptr;
g_vars->scene16_mug->setOXY(409, 459);
g_vars->scene16_mug->_priority = 5;
g_vars->scene16_mug->_flags |= 4;
}
}
int scene16_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_objectIdAtCursor == PIC_SC16_TUMBA) {
if (g_nmi->_cursorId == PIC_CSR_DEFAULT)
g_nmi->_cursorId = PIC_CSR_ITN;
} else {
if (g_nmi->_objectIdAtCursor == ANI_MUG && g_nmi->_cursorId == PIC_CSR_ITN && g_vars->scene16_mug->_statics->_staticsId == ST_MUG_FULL)
g_nmi->_cursorId = PIC_CSR_ITN_GREEN;
}
return g_nmi->_cursorId;
}
void sceneHandler16_laughSound() {
int snd = SND_16_035;
switch (g_vars->scene16_sound) {
case SND_16_034:
default:
snd = SND_16_035;
break;
case SND_16_035:
snd = SND_16_037;
break;
case SND_16_037:
snd = SND_16_034;
break;
}
g_vars->scene16_sound = snd;
g_nmi->playSound(snd, 0);
}
void sceneHandler16_showBearded() {
if (g_nmi->getObjectState(sO_Bridge) == g_nmi->getObjectEnumState(sO_Bridge, sO_Unconvoluted)) {
StaticANIObject *brd = g_nmi->_currentScene->getStaticANIObject1ById(ANI_BEARDED_CMN, -1);
if (!brd || !(brd->_flags & 4))
chainQueue(QU_BRD16_STARTBEARDED, 0);
}
}
void sceneHandler16_showMugFull() {
g_vars->scene16_mug->changeStatics2(ST_MUG_FULL);
}
void sceneHandler16_fillMug() {
if (g_vars->scene16_mug->_flags & 4) {
g_vars->scene16_jettie->_priority = 2;
g_vars->scene16_jettie->startAnim(MV_JTI_FLOWIN, 0, -1);
if (g_nmi->_aniMan->_movement) {
if (g_nmi->_aniMan->_movement->_id == MV_MAN16_TAKEMUG) {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT);
g_vars->scene16_mug->show1(-1, -1, -1, 0);
g_nmi->setObjectState(sO_Cup, g_nmi->getObjectEnumState(sO_Cup, sO_DudeHas));
}
}
return;
}
MessageQueue *mq;
if (!(g_vars->scene16_boot->_flags & 4)) {
g_vars->scene16_jettie->_priority = 15;
g_vars->scene16_jettie->startAnim(MV_JTI_FLOWBY, 0, -1);
if (g_vars->scene16_walkingBoy) {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC16_BOYOUT), 0, 1);
mq->setParamInt(-1, g_vars->scene16_walkingBoy->_odelay);
if (mq->chain(g_vars->scene16_walkingBoy))
return;
} else {
if (!g_vars->scene16_walkingGirl)
return;
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC16_GIRLOUT), 0, 1);
mq->setParamInt(-1, g_vars->scene16_walkingGirl->_odelay);
if (mq->chain(g_vars->scene16_walkingGirl))
return;
}
delete mq;
return;
}
g_vars->scene16_jettie->_priority = 15;
g_vars->scene16_boot->startAnim(MV_BT16_FILL, 0, -1);
StaticANIObject *ani;
if (g_vars->scene16_walkingBoy) {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC16_BOYOUT), 0, 1);
mq->setParamInt(-1, g_vars->scene16_walkingBoy->_odelay);
ani = g_vars->scene16_walkingBoy;
} else {
if (!g_vars->scene16_walkingGirl)
return;
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC16_GIRLOUT), 0, 1);
mq->setParamInt(-1, g_vars->scene16_walkingGirl->_odelay);
ani = g_vars->scene16_walkingGirl;
}
if (!mq->chain(ani))
delete mq;
}
void sceneHandler16_startLaugh() {
StaticANIObject *girl = g_nmi->_currentScene->getStaticANIObject1ById(ANI_GIRL, -1);
girl->changeStatics2(ST_GRL_STAND);
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC16_GIRLLAUGH), 0, 1);
mq->setParamInt(-1, girl->_odelay);
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
g_nmi->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->setSubVarAsInt(sO_DudeSwinged, 0);
g_vars->scene16_girlIsLaughing = true;
}
void sceneHandler16_drink() {
if (g_vars->scene16_mug->_flags & 4) {
if (!g_vars->scene16_jettie->_movement) {
if (!g_vars->scene16_walkingBoy || !g_vars->scene16_walkingBoy->_movement || g_vars->scene16_walkingBoy->_movement->_id != MV_BOY_DRINK) {
if (!g_vars->scene16_walkingGirl || !g_vars->scene16_walkingGirl->_movement || g_vars->scene16_walkingGirl->_movement->_id != MV_GRL_DRINK) {
if (g_vars->scene16_mug->_statics->_staticsId == ST_MUG_FULL) {
MessageQueue *mq;
ExCommand *ex;
if (g_vars->scene16_walkingBoy) {
g_nmi->_aniMan->_flags |= 0x180;
g_vars->scene16_walkingBoy->changeStatics2(ST_BOY_STAND);
g_vars->scene16_walkingBoy->queueMessageQueue(nullptr);
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC16_BOYKICK), 0, 1);
mq->setParamInt(-1, g_vars->scene16_walkingBoy->_odelay);
ex = new ExCommand(ANI_MAN, 34, 384, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 3u;
ex->_z = 384;
ex->_messageNum = 0;
mq->insertExCommandAt(2, ex);
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
} else {
g_nmi->_aniMan->_flags |= 0x100;
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC16_MANDRINK), 0, 1);
ex = new ExCommand(ANI_MAN, 34, 256, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 3u;
ex->_z = 256;
ex->_messageNum = 0;
mq->addExCommandToEnd(ex);
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
g_nmi->_currentScene->getStaticANIObject1ById(ANI_GIRL, -1)->changeStatics2(ST_GRL_STAND);
}
g_nmi->_currentScene->getStaticANIObject1ById(ANI_WIRE16, -1)->show1(-1, -1, -1, 0);
} else {
chainObjQueue(g_nmi->_aniMan, QU_SC16_TAKEMUG, 1);
}
}
}
}
}
}
void sceneHandler16_mugClick() {
if (abs(310 - g_nmi->_aniMan->_ox) >= 1 || abs(449 - g_nmi->_aniMan->_oy) >= 1
|| g_nmi->_aniMan->_movement || g_nmi->_aniMan->_statics->_staticsId != ST_MAN_RIGHT) {
MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, 310, 449, 1, ST_MAN_RIGHT);
if (mq) {
ExCommand *ex = new ExCommand(0, 17, MSG_SC16_MUGCLICK, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags = 2;
mq->addExCommandToEnd(ex);
postExCommand(g_nmi->_aniMan->_id, 2, 310, 449, 0, -1);
}
} else {
sceneHandler16_drink();
}
}
void sceneHandler16_showMan() {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT);
g_nmi->_aniMan->show1(-1, -1, -1, 0);
g_vars->scene16_mug->show1(-1, -1, -1, 0);
}
void sceneHandler16_showMug() {
chainQueue(QU_SC16_SHOWMUG, 0);
}
void sceneHandler16_hideMan() {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT);
g_nmi->_aniMan->hide();
g_vars->scene16_mug->hide();
}
void sceneHandler16_hideMug() {
g_vars->scene16_mug->hide();
}
void sceneHandler16_hideWire() {
g_vars->scene16_wire->hide();
}
void sceneHandler16_showWire() {
g_vars->scene16_wire->show1(-1, -1, -1, 0);
}
void sceneHandler16_putOnWheel() {
StaticANIObject *ani = g_vars->scene16_walkingBoy;
if (!ani)
ani = g_vars->scene16_walkingGirl;
if (ani)
g_vars->scene16_figures.push_back(ani);
ani = g_vars->scene16_figures.front();
g_vars->scene16_figures.pop_front();
if (ani) {
MessageQueue *mq;
if (ani->_id == ANI_BOY) {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC16_GOBOY), 0, 1);
mq->setParamInt(-1, ani->_odelay);
mq->chain(nullptr);
g_vars->scene16_walkingBoy = ani;
g_vars->scene16_walkingGirl = nullptr;
} else if (ani->_id == ANI_GIRL) {
if (g_nmi->getObjectState(sO_Girl) == g_nmi->getObjectEnumState(sO_Girl, sO_IsSwinging)) {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC16_GOGIRL), 0, 1);
mq->setParamInt(-1, ani->_odelay);
mq->chain(nullptr);
g_vars->scene16_walkingBoy = nullptr;
g_vars->scene16_walkingGirl = ani;
}
}
}
}
void sceneHandler16_girlROTFL() {
StaticANIObject *girl = g_nmi->_currentScene->getStaticANIObject1ById(ANI_GIRL, -1);
girl->changeStatics2(ST_GRL_LAUGH);
girl->startAnim(MV_GRL_FALL, 0, -1);
g_vars->scene16_girlIsLaughing = false;
}
int sceneHandler16(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch(cmd->_messageNum) {
case MSG_SC16_LAUGHSOUND:
sceneHandler16_laughSound();
break;
case MSG_SC16_SHOWBEARDED:
sceneHandler16_showBearded();
break;
case MSG_SC16_SHOWMUGFULL:
sceneHandler16_showMugFull();
break;
case MSG_SC16_FILLMUG:
sceneHandler16_fillMug();
break;
case MSG_SC16_STARTLAUGH:
sceneHandler16_startLaugh();
break;
case MSG_SC16_MUGCLICK:
if (!g_nmi->_aniMan->isIdle() || g_nmi->_aniMan->_flags & 0x100) {
cmd->_messageKind = 0;
} else {
sceneHandler16_mugClick();
}
break;
case MSG_SC16_SHOWMAN:
sceneHandler16_showMan();
break;
case MSG_SC16_SHOWMUG:
sceneHandler16_showMug();
break;
case MSG_SC16_HIDEMAN:
sceneHandler16_hideMan();
break;
case MSG_SC16_HIDEMUG:
sceneHandler16_hideMug();
break;
case MSG_SC16_HIDEWIRE:
sceneHandler16_hideWire();
break;
case MSG_SC16_SHOWWIRE:
sceneHandler16_showWire();
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
}
if (g_vars->scene16_placeIsOccupied) {
g_vars->scene16_walkingCount++;
if (g_vars->scene16_walkingCount >= 280) {
sceneHandler16_putOnWheel();
g_vars->scene16_walkingCount = 0;
}
}
if (g_vars->scene16_girlIsLaughing) {
if (g_nmi->_aniMan->_movement)
if (g_nmi->_aniMan->_movement->_id == MV_MAN_TURN_RL)
sceneHandler16_girlROTFL();
}
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,286 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
#include "ngi/floaters.h"
namespace NGI {
void scene17_initScene(Scene *sc) {
g_vars->scene17_flyState = 1;
g_vars->scene17_sugarIsShown = false;
g_vars->scene17_sceneOldEdgeX = 0;
g_vars->scene17_flyCountdown = 0;
g_vars->scene17_hand = sc->getStaticANIObject1ById(ANI_HAND17, -1);
}
void scene17_restoreState() {
if (g_nmi->getObjectState(sO_UsherHand) == g_nmi->getObjectEnumState(sO_UsherHand, sO_WithCoin)) {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_ASK, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_TOCYCLE, 0);
g_vars->scene17_handPhase = false;
} else {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_ASK, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_TOCYCLE, 1);
g_vars->scene17_handPhase = true;
}
g_nmi->_floaters->init(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_17"));
g_vars->scene17_flyState = g_nmi->getObjectState(sO_Fly_17);
if (g_vars->scene17_flyState <= 0 ) {
g_vars->scene17_flyCountdown = g_nmi->_rnd.getRandomNumber(600) + 600;
g_vars->scene17_flyState = g_nmi->_rnd.getRandomNumber(4) + 1;
}
g_nmi->setObjectState(sO_Fly_17, g_vars->scene17_flyState - 1);
}
int scene17_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_objectIdAtCursor != PIC_SC17_RTRUBA2 && g_nmi->_objectIdAtCursor != PIC_SC17_RTRUBA)
return g_nmi->_cursorId;
if (!g_vars->scene17_handPhase)
return g_nmi->_cursorId;
int item = g_nmi->_inventory->getSelectedItemId();
if ((g_nmi->_cursorId != PIC_CSR_DEFAULT_INV || item != ANI_INV_COIN) && item != ANI_INV_BOOT && item != ANI_INV_HAMMER)
; // empty
else
g_nmi->_cursorId = PIC_CSR_ITN_INV;
return g_nmi->_cursorId;
}
void sceneHandler17_drop() {
StaticANIObject *mug = g_nmi->_currentScene->getStaticANIObject1ById(ANI_MUG_17, -1);
StaticANIObject *jet = g_nmi->_currentScene->getStaticANIObject1ById(ANI_JET_17, -1);
if (mug && mug->_flags & 4) {
mug->changeStatics2(ST_MUG17_EMPTY);
chainQueue(QU_SC17_FILLMUG_DROP, 0);
} else if (jet) {
jet->queueMessageQueue(nullptr);
chainQueue(QU_JET17_DROP, 0);
}
}
void sceneHandler17_fillBottle() {
StaticANIObject *bottle = g_nmi->_currentScene->getStaticANIObject1ById(ANI_INV_BOTTLE, -1);
StaticANIObject *mug = g_nmi->_currentScene->getStaticANIObject1ById(ANI_MUG_17, -1);
StaticANIObject *boot = g_nmi->_currentScene->getStaticANIObject1ById(ANI_BOOT_17, -1);
if (bottle && (bottle->_flags & 4))
chainQueue(QU_SC17_FILLBOTTLE, 1);
else if (mug && (mug->_flags & 4) && mug->_statics->_staticsId == ST_MUG17_EMPTY)
chainQueue(QU_SC17_FILLMUG, 1);
else if (boot && (boot->_flags & 4))
chainQueue(QU_SC17_FILLBOOT, 1);
else
chainQueue(QU_JET17_FLOW, 1);
}
void sceneHandler17_testTruba() {
if (g_vars->scene17_hand->isIdle()) {
if (!g_vars->scene17_hand->_movement || g_vars->scene17_hand->_movement->_id != MV_HND17_FIGA) {
g_vars->scene17_hand->changeStatics2(ST_HND17_EMPTY);
g_vars->scene17_hand->startAnim(MV_HND17_FIGA, 0, -1);
}
}
}
void sceneHandler17_showBottle() {
chainQueue(QU_SC17_SHOWBOTTLE, 0);
}
void sceneHandler17_hideSugar() {
StaticANIObject *sugar = g_nmi->_currentScene->getStaticANIObject1ById(ANI_INV_SUGAR, -1);
if (sugar)
sugar->hide();
}
void sceneHandler17_showSugar() {
chainQueue(QU_SC17_SHOWSUGAR, 0);
g_vars->scene17_sugarIsShown = true;
}
void sceneHandler17_moonshineFill() {
StaticANIObject *moonshiner = g_nmi->_currentScene->getStaticANIObject1ById(ANI_SAMOGONSHCHIK, -1);
if (!(moonshiner->_flags & 0x80)) {
moonshiner->changeStatics2(ST_SMG_SIT);
chainObjQueue(moonshiner, QU_SMG_FILLBOTTLE, 1);
g_vars->scene17_sugarIsShown = false;
}
}
void sceneHandler17_updateFlies() {
g_nmi->_floaters->genFlies(g_nmi->_currentScene, 239, -50, 20, 4);
g_nmi->_floaters->_array2[0].countdown = g_nmi->_rnd.getRandomNumber(5) + 6;
g_nmi->_floaters->_array2[0].val6 = 239;
g_nmi->_floaters->_array2[0].val7 = -50;
}
int sceneHandler17(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_SC17_DROP:
sceneHandler17_drop();
break;
case MSG_SC17_UPDATEHAND:
if (g_nmi->getObjectState(sO_UsherHand) == g_nmi->getObjectEnumState(sO_UsherHand, sO_WithCoin)) {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_ASK, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_TOCYCLE, 0);
g_vars->scene17_handPhase = false;
} else {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_ASK, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_TOCYCLE, 1);
g_vars->scene17_handPhase = true;
}
break;
case MSG_SC17_FILLBOTTLE:
sceneHandler17_fillBottle();
break;
case MSG_SC17_TESTTRUBA:
sceneHandler17_testTruba();
break;
case MSG_SC17_SHOWBOTTLE:
sceneHandler17_showBottle();
break;
case MSG_SC17_HIDESUGAR:
sceneHandler17_hideSugar();
break;
case MSG_SC17_SHOWSUGAR:
sceneHandler17_showSugar();
break;
case 29:
{
int pic = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (pic == PIC_SC17_RTRUBA2 || pic == PIC_SC17_RTRUBA) {
if (cmd->_param == ANI_INV_COIN || cmd->_param == ANI_INV_BOOT || cmd->_param == ANI_INV_HAMMER) {
if (g_vars->scene17_handPhase) {
if (g_nmi->_aniMan->isIdle()) {
if (!(g_nmi->_aniMan->_flags & 0x100)) {
handleObjectInteraction(g_nmi->_aniMan, g_vars->scene17_hand, cmd->_param);
break;
}
}
}
}
}
}
break;
case 33:
{
int x = g_vars->scene17_sceneEdgeX;
g_vars->scene17_sceneOldEdgeX = g_vars->scene17_sceneEdgeX;
if (g_nmi->_aniMan2) {
x = g_nmi->_aniMan2->_ox;
g_vars->scene17_sceneEdgeX = x;
if (x < g_nmi->_sceneRect.left + 200) {
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
x = g_vars->scene17_sceneEdgeX;
}
if (x > g_nmi->_sceneRect.right - 200) {
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
x = g_vars->scene17_sceneEdgeX;
}
}
if (g_vars->scene17_sugarIsShown) {
sceneHandler17_moonshineFill();
x = g_vars->scene17_sceneEdgeX;
}
if (g_vars->scene17_handPhase) {
if (g_vars->scene17_sceneOldEdgeX < 410 && x >= 410) {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_TOCYCLE, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_ATTRACT, QU_HND17_ATTRACT, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_ASK, 1);
} else if (g_vars->scene17_sceneOldEdgeX > 410 && x <= 410) {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_TOCYCLE, 1);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_ATTRACT, QU_HND17_ATTRACT, 1);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_ASK, 0);
}
}
--g_vars->scene17_flyCountdown;
if (!g_vars->scene17_flyCountdown)
sceneHandler17_updateFlies();
g_nmi->_floaters->update();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,937 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
#include "math/utils.h"
namespace NGI {
struct Swinger {
StaticANIObject *ani;
int sfield_4;
double angle;
int sx;
int sy;
int ix;
int iy;
int sflags;
int sfield_24;
};
void scene18_preload() {
g_nmi->_scene3 = nullptr;
for (SceneTagList::iterator s = g_nmi->_gameProject->_sceneTagList->begin(); s != g_nmi->_gameProject->_sceneTagList->end(); ++s) {
if (s->_sceneId == SC_18) {
g_nmi->_scene3 = s->_scene;
s->_scene = nullptr;
g_nmi->_scene3->getStaticANIObject1ById(ANI_WHIRLIGIG_18, -1)->freeMovementsPixelData();
break;
}
}
}
void scene18_setupEntrance() {
GameVar *var = g_nmi->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME");
if (var->getSubVarAsInt("Entrance") == TrubaRight)
var->setSubVarAsInt("Entrance", TrubaLeft);
}
void scene19_setSugarState(Scene *sc) {
if (g_nmi->getObjectState(sO_Sugar) != g_nmi->getObjectEnumState(sO_Sugar, sO_Present)) {
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
sc->getStaticANIObject1ById(ANI_CORDIE, -1)->changeStatics2(ST_CDI_EMPTY2);
g_nmi->_currentScene = oldsc;
}
}
void scene19_setMovements(Scene *sc, int entranceId) {
if (entranceId == TrubaRight) {
g_vars->scene18_enteredTrubaRight = true;
} else {
g_vars->scene18_enteredTrubaRight = false;
g_vars->scene19_enteredTruba3 = (entranceId == PIC_SC19_RTRUBA3);
}
for (uint i = 0; i < g_vars->scene18_swingers.size(); i++) {
if (!g_vars->scene18_enteredTrubaRight && (g_vars->scene18_swingers[i]->sflags & 0x20)) {
Scene *oldsc = g_nmi->_currentScene;
g_vars->scene18_swingers[i]->sflags = 1;
g_nmi->_currentScene = sc;
g_vars->scene18_swingers[i]->ani->changeStatics2(ST_KSL_NORM);
g_vars->scene18_swingers[i]->ani->_priority = 30;
g_nmi->_currentScene = oldsc;
}
sc->deleteStaticANIObject(g_vars->scene18_swingers[i]->ani);
}
if (g_vars->scene18_whirlgig->_movement) {
g_vars->scene18_whirlgigMovMum = g_vars->scene18_whirlgig->_movement->_currDynamicPhaseIndex + 1;
int mx;
if (g_vars->scene18_whirlgig->_movement->_currMovement)
mx = g_vars->scene18_whirlgig->_movement->_currMovement->_dynamicPhases.size();
else
mx = g_vars->scene18_whirlgig->_movement->_dynamicPhases.size();
if (g_vars->scene18_whirlgigMovMum > mx - 1)
g_vars->scene18_whirlgigMovMum = -1;
} else {
g_vars->scene18_whirlgigMovMum = 0;
}
sc->deleteStaticANIObject(g_vars->scene18_boy);
sc->deleteStaticANIObject(g_vars->scene18_girl);
sc->stopAllSounds();
}
void scene19_preload() {
for (SceneTagList::iterator s = g_nmi->_gameProject->_sceneTagList->begin(); s != g_nmi->_gameProject->_sceneTagList->end(); ++s) {
if (s->_sceneId == SC_18) {
delete s->_scene;
s->_scene = g_nmi->_scene3;
break;
}
}
}
void scene18_setupSwingers(StaticANIObject *ani, Scene *sc) {
Swinger *swinger;
g_vars->scene18_swingers.clear();
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
for (int i = 0; i < 8; i++) {
swinger = new Swinger;
swinger->angle = (double)i * Math::deg2rad<double>(45.0);
swinger->sx = g_vars->scene18_wheelCenterX - (int)(cos(swinger->angle) * -575.0);
swinger->sy = g_vars->scene18_wheelCenterY - (int)(sin(swinger->angle) * -575.0) + 87;
swinger->ix = swinger->sx;
swinger->iy = swinger->sy;
if (i) {
StaticANIObject *newani = new StaticANIObject(ani);
ani = newani;
swinger->ani = newani;
swinger->sflags = 2;
sc->addStaticANIObject(newani, 1);
} else {
swinger->ani = ani;
swinger->sflags = g_vars->scene18_girlIsSwinging ? 4 : 1;
}
ani->_statics = ani->getStaticsById(ST_KSL_NORM);
//ani->_movement = 0;
ani->setOXY(swinger->sx, swinger->sy);
ani->_priority = 30;
ani->_flags |= 4;
if (swinger->sflags & 2)
ani->startAnim(MV_KSL_SWINGBOY, 0, -1);
else if (swinger->sflags & 4)
ani->startAnim(MV_KSL_SWINGGIRL, 0, -1);
else
ani->startAnim(MV_KSL_SWING, 0, -1);
ani->_movement->setDynamicPhaseIndex(g_nmi->_rnd.getRandomNumber(17));
g_vars->scene18_swingers.push_back(swinger);
}
g_nmi->_currentScene = oldsc;
}
void scene18_initScene1(Scene *sc) {
PicAniInfo info;
int oldx = g_vars->scene18_wheelCenterX;
int oldy = g_vars->scene18_wheelCenterY;
g_vars->scene18_girlIsSwinging = (g_nmi->getObjectState(sO_Girl) == g_nmi->getObjectEnumState(sO_Girl, sO_IsSwinging));
if (sc->_sceneId == SC_18) {
g_vars->scene18_whirlgig = sc->getStaticANIObject1ById(ANI_WHIRLIGIG_18, -1);
g_vars->scene18_wheelCenterX = 1032;
g_vars->scene18_wheelCenterY = -318;
} else {
g_vars->scene18_whirlgig = sc->getStaticANIObject1ById(ANI_WHIRLGIG_19, -1);
g_vars->scene18_wheelCenterX = 1024;
g_vars->scene18_wheelCenterY = 242;
}
int newx = g_vars->scene18_wheelCenterX - oldx;
int newy = g_vars->scene18_wheelCenterY - oldy;
g_vars->scene18_boyJumpX += newx;
g_vars->scene18_boyJumpY += newy;
g_vars->scene18_girlJumpX += newx;
g_vars->scene18_girlJumpY += newy;
for (uint i = 0; i < g_vars->scene18_swingers.size(); i++) {
g_vars->scene18_swingers[i]->ani->getPicAniInfo(info);
sc->addStaticANIObject(g_vars->scene18_swingers[i]->ani, 1);
g_vars->scene18_swingers[i]->ani->setPicAniInfo(info);
g_vars->scene18_swingers[i]->sx += newx;
g_vars->scene18_swingers[i]->sy += newy;
g_vars->scene18_swingers[i]->ix += newx;
g_vars->scene18_swingers[i]->iy += newy;
GameObject *go;
if (g_vars->scene18_swingers[i]->ani->_movement)
go = g_vars->scene18_swingers[i]->ani->_movement;
else
go = g_vars->scene18_swingers[i]->ani;
go->setOXY(newx + go->_ox, newy + go->_oy);
}
if (g_vars->scene18_bridgeIsConvoluted && g_vars->scene18_whirlgigMovMum != -1) {
g_vars->scene18_whirlgig->startAnim(sc->_sceneId != SC_18 ? MV_WHR19_SPIN : MV_WHR18_SPIN, 0, -1);
g_vars->scene18_whirlgig->_movement->setDynamicPhaseIndex(g_vars->scene18_whirlgigMovMum);
}
int sndid;
if (sc->_sceneId == SC_19) {
if (g_vars->scene18_bridgeIsConvoluted)
sndid = SND_19_015;
else
sndid = SND_19_016;
} else {
if (g_vars->scene18_bridgeIsConvoluted)
sndid = SND_18_006;
else
sndid = SND_18_010;
}
g_nmi->playSound(sndid, 1);
g_vars->scene18_boy->getPicAniInfo(info);
sc->addStaticANIObject(g_vars->scene18_boy, 1);
g_vars->scene18_boy->setPicAniInfo(info);
int x, y;
if (g_vars->scene18_boy->_movement) {
x = g_vars->scene18_boy->_movement->_ox;
y = g_vars->scene18_boy->_movement->_oy;
} else {
x = g_vars->scene18_boy->_ox;
y = g_vars->scene18_boy->_oy;
}
g_vars->scene18_boy->setOXY(newx + x, newy + y);
g_vars->scene18_girl->getPicAniInfo(info);
sc->addStaticANIObject(g_vars->scene18_girl, 1);
g_vars->scene18_girl->setPicAniInfo(info);
if (g_vars->scene18_girl->_movement) {
x = g_vars->scene18_girl->_movement->_ox;
y = g_vars->scene18_girl->_movement->_oy;
} else {
x = g_vars->scene18_girl->_ox;
y = g_vars->scene18_girl->_oy;
}
g_vars->scene18_girl->setOXY(newx + x, newy + y);
g_vars->scene18_wheelFlipper = false;
g_vars->scene18_jumpDistance = -1;
g_vars->scene18_jumpAngle = -1;
if (g_vars->scene18_enteredTrubaRight) {
if (sc->_sceneId == SC_19)
g_nmi->_aniMan2 = nullptr;
else
g_nmi->_aniMan2 = g_vars->scene18_swingers[g_vars->scene18_manWheelPosTo]->ani;
} else {
g_nmi->_aniMan2 = g_nmi->_aniMan;
}
}
void scene18_initScene2(Scene *sc) {
g_vars->scene18_whirlgig = sc->getStaticANIObject1ById(ANI_WHIRLIGIG_18, -1);
g_vars->scene18_wheelCenterX = 1032;
g_vars->scene18_wheelCenterY = -318;
StaticANIObject *armchair = sc->getStaticANIObject1ById(ANI_KRESLO, -1);
armchair->loadMovementsPixelData();
g_vars->scene18_girlIsSwinging = (g_nmi->getObjectState(sO_Girl) == g_nmi->getObjectEnumState(sO_Girl, sO_IsSwinging));
if (g_nmi->getObjectState(sO_Bridge) == g_nmi->getObjectEnumState(sO_Bridge, sO_Convoluted)) {
g_vars->scene18_bridgeIsConvoluted = true;
g_nmi->playSound(SND_18_006, 1);
} else {
g_vars->scene18_bridgeIsConvoluted = false;
g_nmi->playSound(SND_18_010, 1);
}
scene18_setupSwingers(armchair, sc);
g_vars->scene18_rotationCounter = 0;
g_vars->scene18_wheelFlipper = false;
g_vars->scene18_wheelIsTurning = true;
g_vars->scene18_kidIsOnWheel = -1;
g_vars->scene18_boyIsOnWheel = 0;
g_vars->scene18_girlIsOnWheel = 0;
g_vars->scene18_boyJumpedOff = true;
g_vars->scene18_manWheelPosTo = -1;
g_vars->scene18_jumpDistance = -1;
g_vars->scene18_jumpAngle = -1;
g_vars->scene18_manIsReady = false;
g_vars->scene18_enteredTrubaRight = 0;
g_vars->scene18_boy = sc->getStaticANIObject1ById(ANI_BOY18, -1);
g_vars->scene18_girl = sc->getStaticANIObject1ById(ANI_GIRL18, -1);
g_vars->scene18_domino = sc->getStaticANIObject1ById(ANI_DOMINO_18, -1);
g_vars->scene18_boyJumpX = 290;
g_vars->scene18_boyJumpY = -363;
g_vars->scene18_girlJumpX = 283;
g_vars->scene18_girlJumpY = -350;
g_nmi->initArcadeKeys("SC_18");
}
void scene19_initScene2() {
g_nmi->_aniMan2 = nullptr;
}
int scene18_updateCursor() {
if (g_vars->scene18_enteredTrubaRight) {
g_nmi->_cursorId = PIC_CSR_DEFAULT;
} else {
g_nmi->updateCursorCommon();
if (g_nmi->_cursorId == PIC_CSR_ITN) {
if (g_nmi->_objectIdAtCursor == PIC_SC18_LADDER1) {
g_nmi->_cursorId = (g_vars->scene18_manY <= 250) ? PIC_CSR_GOD : PIC_CSR_GOU;
} else if (g_nmi->_objectIdAtCursor == PIC_SC18_LADDER2 || g_nmi->_objectIdAtCursor == PIC_SC18_LADDER3) {
g_nmi->_cursorId = PIC_CSR_GOU;
}
} else if (g_nmi->_cursorId == PIC_CSR_DEFAULT && g_nmi->_objectIdAtCursor == PIC_SC18_DOMIN && g_vars->scene18_domino && (g_vars->scene18_domino->_flags & 4)) {
g_nmi->_cursorId = PIC_CSR_ITN;
}
}
return g_nmi->_cursorId;
}
int scene19_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_objectIdAtCursor == PIC_SC19_RTRUBA31)
g_nmi->_cursorId = g_vars->scene19_enteredTruba3 ? PIC_CSR_GOR : PIC_CSR_DEFAULT;
return g_nmi->_cursorId;
}
void sceneHandler18_clickBoard() {
if (ABS(967 - g_nmi->_aniMan->_ox) > 1 || ABS(379 - g_nmi->_aniMan->_oy) > 1 || g_nmi->_aniMan->_statics->_staticsId != ST_MAN_RIGHT) {
MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, 967, 379, 1, ST_MAN_RIGHT);
ExCommand *ex = new ExCommand(0, 17, MSG_SC18_MANREADY, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags = 2;
mq->addExCommandToEnd(ex);
postExCommand(g_nmi->_aniMan->_id, 2, 967, 379, 0, -1);
} else {
g_vars->scene18_manIsReady = true;
}
}
void sceneHandler18_showManJumpTo() {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT);
g_nmi->_aniMan->_flags &= 0xFFFB;
g_nmi->_aniMan->_flags &= 0xFEFF;
g_vars->scene18_swingers[g_vars->scene18_manWheelPosTo]->sflags = 0x20;
g_vars->scene18_swingers[g_vars->scene18_manWheelPosTo]->ani->changeStatics2(ST_KSL_JUMPMAN);
g_vars->scene18_swingers[g_vars->scene18_manWheelPosTo]->ani->startAnim(MV_KSL_INMAN, 0, -1);
g_vars->scene18_swingers[g_vars->scene18_manWheelPosTo]->ani->_priority = 20;
g_vars->scene18_manIsReady = false;
g_vars->scene18_enteredTrubaRight = true;
g_nmi->_aniMan2 = g_vars->scene18_swingers[g_vars->scene18_manWheelPosTo]->ani;
}
void sceneHandler18and19_showManJump() {
int x, y;
if (g_vars->scene18_swingers[g_vars->scene18_manWheelPos]->ani->_movement) {
x = g_vars->scene18_swingers[g_vars->scene18_manWheelPos]->ani->_movement->_ox;
y = g_vars->scene18_swingers[g_vars->scene18_manWheelPos]->ani->_movement->_oy;
} else {
x = g_vars->scene18_swingers[g_vars->scene18_manWheelPos]->ani->_ox;
y = g_vars->scene18_swingers[g_vars->scene18_manWheelPos]->ani->_oy;
}
g_nmi->_aniMan->show1(x + 62, y + 5, MV_MAN18_JUMPTOTRUBA, 0);
g_nmi->_aniMan->_priority = 35;
int mqid = 0;
if (g_vars->scene18_jumpDistance == 1) {
mqid = QU_SC19_MANJUMP1;
} else if (g_vars->scene18_jumpDistance == 2) {
mqid = QU_SC19_MANJUMP2;
} else if (g_vars->scene18_jumpDistance == 3) {
mqid = QU_SC19_MANJUMP3;
}
if (mqid) {
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(mqid), 0, 0);
g_nmi->_aniMan2 = g_nmi->_aniMan;
g_vars->scene18_enteredTrubaRight = false;
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
}
g_vars->scene18_swingers[g_vars->scene18_manWheelPos]->sflags = 1;
g_vars->scene18_swingers[g_vars->scene18_manWheelPos]->ani->changeStatics2(ST_KSL_NORM);
g_vars->scene18_swingers[g_vars->scene18_manWheelPos]->ani->_priority = 30;
}
void sceneHandler18and19_showGirlJumpTo() {
g_vars->scene18_girl->stopAnim_maybe();
g_vars->scene18_girl->hide();
g_vars->scene18_swingers[g_vars->scene18_kidWheelPosTo]->sflags = 4;
g_vars->scene18_swingers[g_vars->scene18_kidWheelPosTo]->ani->changeStatics2(ST_KSL_JUMPGIRL);
g_vars->scene18_swingers[g_vars->scene18_kidWheelPosTo]->ani->startAnim(MV_KSL_INGIRL, 0, -1);
g_vars->scene18_kidIsOnWheel--;
g_vars->scene18_girlIsOnWheel--;
}
void sceneHandler18and19_showGirlJump() {
StaticANIObject *ani = g_vars->scene18_swingers[g_vars->scene18_kidWheelPos]->ani;
int x, y;
if (ani->_movement) {
x = ani->_movement->_ox;
y = ani->_movement->_oy;
} else {
x = ani->_ox;
y = ani->_oy;
}
g_vars->scene18_girl->show1(x - 62, y - 10, MV_GRL18_JUMPFROM, 0);
g_vars->scene18_girl->_priority = 50;
g_vars->scene18_girl->startAnim(MV_GRL18_JUMPFROM, 0, -1);
g_vars->scene18_swingers[g_vars->scene18_kidWheelPos]->sflags = 1;
g_vars->scene18_swingers[g_vars->scene18_kidWheelPos]->ani->changeStatics2(ST_KSL_REACT);
g_vars->scene18_swingers[g_vars->scene18_kidWheelPos]->ani->startAnim(MV_KSL_CALMDOWN, 0, -1);
g_vars->scene18_kidIsOnWheel = 1;
g_vars->scene18_girlIsOnWheel++;
}
void sceneHandler18and19_showBoyJumpTo() {
g_vars->scene18_boy->stopAnim_maybe();
g_vars->scene18_boy->hide();
g_vars->scene18_swingers[g_vars->scene18_kidWheelPosTo]->sflags = 2;
g_vars->scene18_swingers[g_vars->scene18_kidWheelPosTo]->ani->changeStatics2(ST_KSL_JUMPBOY);
g_vars->scene18_swingers[g_vars->scene18_kidWheelPosTo]->ani->startAnim(MV_KSL_INBOY, 0, -1);
g_vars->scene18_kidIsOnWheel--;
g_vars->scene18_boyIsOnWheel--;
}
void sceneHandler18and19_showBoyJump() {
StaticANIObject *ani = g_vars->scene18_swingers[g_vars->scene18_kidWheelPos]->ani;
int x, y;
if (ani->_movement) {
x = ani->_movement->_ox;
y = ani->_movement->_oy;
} else {
x = ani->_ox;
y = ani->_oy;
}
g_vars->scene18_boy->show1(x - 48, y + 8, MV_BOY18_JUMPFROM, 0);
g_vars->scene18_boy->_priority = 50;
g_vars->scene18_boy->startAnim(MV_BOY18_JUMPFROM, 0, -1);
g_vars->scene18_swingers[g_vars->scene18_kidWheelPos]->sflags = 1;
g_vars->scene18_swingers[g_vars->scene18_kidWheelPos]->ani->changeStatics2(ST_KSL_REACT);
g_vars->scene18_swingers[g_vars->scene18_kidWheelPos]->ani->startAnim(MV_KSL_CALMDOWN, 0, -1);
g_vars->scene18_boyJumpedOff = true;
}
void sceneHandler18and19_boyJumpTo() {
g_vars->scene18_boy->stopAnim_maybe();
g_vars->scene18_boy->show1(g_vars->scene18_boyJumpX, g_vars->scene18_boyJumpY, MV_BOY18_JUMPTO, 0);
g_vars->scene18_boy->_priority = 50;
g_vars->scene18_boy->startAnim(MV_BOY18_JUMPTO, 0, -1);
}
void sceneHandler18and19_girlJumpTo() {
g_vars->scene18_girl->stopAnim_maybe();
g_vars->scene18_girl->show1(g_vars->scene18_girlJumpX, g_vars->scene18_girlJumpY, MV_GRL18_JUMPTO, 0);
g_vars->scene18_girl->_priority = 50;
g_vars->scene18_girl->startAnim(MV_GRL18_JUMPTO, 0, -1);
}
void sceneHandler18and19_manStandArmchair() {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT);
g_nmi->_aniMan->_flags |= 0x100;
g_nmi->_aniMan->_priority = 35;
g_nmi->_aniMan->startAnim(MV_MAN18_STANDKRESLO, 0, -1);
}
void sceneHandler18and19_drawRiders() {
g_vars->scene18_rotationCounter++;
if (g_vars->scene18_rotationCounter >= 359)
g_vars->scene18_rotationCounter = 0;
for (uint i = 0; i < g_vars->scene18_swingers.size(); i++) {
Swinger *swinger = g_vars->scene18_swingers[i];
double oldangle = swinger->angle;
swinger->angle += Math::deg2rad<double>(1.0);
if (swinger->angle > Math::deg2rad<double>(360.0)) {
swinger->angle -= Math::deg2rad<double>(360.0);
oldangle -= Math::deg2rad<double>(360.0);
}
int ix = g_vars->scene18_wheelCenterX - (int)(cos(swinger->angle) * -575.0);
int iy = g_vars->scene18_wheelCenterY - (int)(sin(swinger->angle) * -575.0) + 87;
if (!g_vars->scene18_rotationCounter) {
ix = swinger->sx;
iy = swinger->sy;
swinger->angle = (double)i * Math::deg2rad<double>(45.0);
}
if (swinger->ani->_movement)
swinger->ani->setOXY(ix - swinger->ix + swinger->ani->_movement->_ox, iy - swinger->iy + swinger->ani->_movement->_oy);
else
swinger->ani->setOXY(ix - swinger->ix + swinger->ani->_ox, iy - swinger->iy + swinger->ani->_oy);
swinger->ix = ix;
swinger->iy = iy;
if (!swinger->ani->_movement) {
int mv = 0;
if (swinger->sflags & 2) {
mv = MV_KSL_SWINGBOY;
} else if (swinger->sflags & 4) {
mv = MV_KSL_SWINGGIRL;
} else if (swinger->sflags & 0x20) {
mv = MV_KSL_SWINGMAN;
} else if (swinger->sflags & 1) {
mv = MV_KSL_SWING;
}
if (mv)
swinger->ani->startAnim(mv, 0, -1);
if (swinger->ani->_movement)
swinger->ani->_movement->_counter = 0;
}
if (g_vars->scene18_wheelIsTurning) {
if ((swinger->sflags & 2) && swinger->angle >= Math::deg2rad<double>(160.0) && oldangle < Math::deg2rad<double>(160.0)) {
swinger->sflags = 8;
swinger->ani->changeStatics2(ST_KSL_BOY);
swinger->ani->startAnim(MV_KSL_JUMPBOY, 0, -1);
g_vars->scene18_kidWheelPos = i;
} else if ((swinger->sflags & 4) && swinger->angle >= Math::deg2rad<double>(162.0) && oldangle < Math::deg2rad<double>(162.0)) {
swinger->sflags = 16;
swinger->ani->changeStatics2(ST_KSL_GIRL);
swinger->ani->startAnim(MV_KSL_JUMPGIRL, 0, -1);
g_vars->scene18_kidWheelPos = i;
} else if (g_vars->scene18_kidIsOnWheel) {
if (g_vars->scene18_boyIsOnWheel > 0 && (swinger->sflags & 1) && swinger->angle >= Math::deg2rad<double>(185.0) && oldangle < Math::deg2rad<double>(185.0)) {
g_vars->scene18_kidWheelPosTo = i;
sceneHandler18and19_boyJumpTo();
}
} else if (g_vars->scene18_girlIsOnWheel > 0 && (swinger->sflags & 1) && swinger->angle >= Math::deg2rad<double>(187.0) && oldangle < Math::deg2rad<double>(187.0)) {
g_vars->scene18_kidWheelPosTo = i;
sceneHandler18and19_girlJumpTo();
}
if (swinger->angle >= Math::deg2rad<double>(200.0) && oldangle < Math::deg2rad<double>(200.0)) {
if (g_vars->scene18_boyJumpedOff)
g_vars->scene18_boyIsOnWheel++;
g_vars->scene18_boyJumpedOff = false;
}
}
if (g_vars->scene18_manIsReady && (swinger->sflags & 1) && swinger->angle >= Math::deg2rad<double>(83.0) && oldangle < Math::deg2rad<double>(83.0)) {
g_vars->scene18_manWheelPosTo = i;
sceneHandler18and19_manStandArmchair();
}
if (!g_vars->scene18_enteredTrubaRight)
continue;
if ((int)i == g_vars->scene18_manWheelPosTo) {
if (swinger->angle >= Math::deg2rad<double>(170.0) && oldangle < Math::deg2rad<double>(170.0)) {
g_nmi->_gameLoader->preloadScene(SC_18, TrubaRight);
} else if (swinger->angle >= Math::deg2rad<double>(25.0) && oldangle < Math::deg2rad<double>(25.0)) {
g_nmi->_gameLoader->preloadScene(SC_19, TrubaRight);
} else if (swinger->angle >= Math::deg2rad<double>(270.0) && oldangle < Math::deg2rad<double>(270.0)) {
g_nmi->_sceneRect.translate(1200, 0);
}
}
if (g_vars->scene18_jumpDistance > 0) {
if (swinger->sflags & 0x20) {
double newa = (double)g_vars->scene18_jumpAngle * Math::deg2rad<double>(1.0);
if (newa <= swinger->angle && oldangle < newa) {
swinger->ani->changeStatics2(ST_KSL_MAN);
swinger->ani->startAnim(MV_KSL_JUMPMAN, 0, -1);
swinger->ani->_priority = 35;
g_vars->scene18_manWheelPos = i;
}
}
}
}
}
void sceneHandler18and19_animateRiders() {
for (uint i = 0; i < g_vars->scene18_swingers.size(); i++) {
Swinger *swinger = g_vars->scene18_swingers[i];
if (!swinger->ani->_movement) {
int mv = 0;
if (swinger->sflags & 2)
mv = MV_KSL_SWINGBOY;
else if (swinger->sflags & 4)
mv = MV_KSL_SWINGGIRL;
else if (swinger->sflags & 0x20)
mv = MV_KSL_SWINGMAN;
if (mv)
swinger->ani->startAnim(mv, 0, -1);
if (swinger->ani->_movement)
swinger->ani->_movement->_counter = 0;
}
}
}
int sceneHandler18(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_SC18_CLICKBOARD:
sceneHandler18_clickBoard();
break;
case MSG_SC3_HIDEDOMINO:
g_vars->scene18_domino->_flags &= 0xFFFB;
break;
case MSG_SC18_SHOWMANJUMP:
sceneHandler18and19_showManJump();
break;
case MSG_SC18_MANREADY:
g_vars->scene18_manIsReady = true;
break;
case MSG_SC18_SHOWMANJUMPTO:
sceneHandler18_showManJumpTo();
break;
case MSG_SC18_SHOWGIRLJUMPTO:
sceneHandler18and19_showGirlJumpTo();
break;
case MSG_SC18_SHOWGIRLJUMP:
sceneHandler18and19_showGirlJump();
break;
case MSG_SC18_SHOWBOYJUMPTO:
sceneHandler18and19_showBoyJumpTo();
break;
case MSG_SC18_SHOWBOYJUMP:
sceneHandler18and19_showBoyJump();
break;
case 29:
{
if (g_vars->scene18_enteredTrubaRight) {
cmd->_messageKind = 0;
break;
}
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (!ani || !canInteractAny(g_nmi->_aniMan, ani, cmd->_param)) {
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picId, 0);
if (pic && pic->_id == PIC_SC18_DOMIN && g_vars->scene18_domino
&& (g_vars->scene18_domino->_flags & 4) && g_nmi->_aniMan->isIdle()) {
if (!(g_nmi->_aniMan->_flags & 0x100) && g_nmi->_msgObjectId2 != g_vars->scene18_domino->_id) {
handleObjectInteraction(g_nmi->_aniMan, g_vars->scene18_domino, cmd->_param);
cmd->_messageKind = 0;
break;
}
}
if (!pic || !canInteractAny(g_nmi->_aniMan, pic, cmd->_param)) {
if ((g_nmi->_sceneRect.right - cmd->_sceneClickX < 47 && g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1)
|| (cmd->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0)) {
g_nmi->processArcade(cmd);
g_vars->scene18_manIsReady = false;
break;
}
}
}
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
g_vars->scene18_manY = g_nmi->_aniMan2->_oy;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
g_nmi->sceneAutoScrolling();
}
if (g_vars->scene18_manIsReady && g_nmi->_aniMan->_movement)
g_vars->scene18_manIsReady = false;
if (g_vars->scene18_bridgeIsConvoluted) {
if (!g_vars->scene18_wheelFlipper)
sceneHandler18and19_drawRiders();
g_vars->scene18_wheelFlipper = !g_vars->scene18_wheelFlipper;
if (!g_vars->scene18_whirlgig->_movement) {
g_vars->scene18_whirlgig->startAnim(MV_WHR18_SPIN, 0, -1);
g_nmi->_behaviorManager->updateBehaviors();
break;
}
} else {
sceneHandler18and19_animateRiders();
}
g_nmi->_behaviorManager->updateBehaviors();
break;
default:
break;
}
return 0;
}
void sceneHandler19_updateNumRides() {
int numRides = g_nmi->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarAsInt(sO_DudeSwinged) + 1;
if (numRides > 1) {
g_nmi->setObjectState(sO_Girl, g_nmi->getObjectEnumState(sO_Girl, sO_IsSwinging));
g_vars->scene18_kidIsOnWheel = 1;
g_vars->scene18_girlIsOnWheel++;
numRides = 0;
}
g_nmi->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->setSubVarAsInt(sO_DudeSwinged, numRides);
}
int sceneHandler19(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_SC18_SHOWMANJUMP:
sceneHandler18and19_showManJump();
break;
case MSG_SC19_UPDATENUMRIDES:
sceneHandler19_updateNumRides();
break;
case MSG_SC18_SHOWGIRLJUMPTO:
sceneHandler18and19_showGirlJumpTo();
break;
case MSG_SC18_SHOWBOYJUMPTO:
sceneHandler18and19_showBoyJumpTo();
break;
case MSG_SC18_SHOWGIRLJUMP:
sceneHandler18and19_showGirlJump();
break;
case MSG_SC18_SHOWBOYJUMP:
sceneHandler18and19_showBoyJump();
break;
case 29:
if (g_vars->scene18_enteredTrubaRight) {
switch (g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY)) {
case PIC_SC19_RTRUBA1:
g_vars->scene18_jumpDistance = 1;
g_vars->scene18_jumpAngle = 331;
cmd->_messageKind = 0;
break;
case PIC_SC19_RTRUBA2:
g_vars->scene18_jumpDistance = 2;
g_vars->scene18_jumpAngle = 350;
cmd->_messageKind = 0;
break;
case PIC_SC19_RTRUBA3:
g_vars->scene18_jumpDistance = 3;
g_vars->scene18_jumpAngle = 9;
cmd->_messageKind = 0;
break;
default:
g_vars->scene18_jumpDistance = -1;
g_vars->scene18_jumpAngle = -1;
cmd->_messageKind = 0;
break;
}
} else {
if (g_vars->scene19_enteredTruba3) {
if (g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY) == PIC_SC19_RTRUBA3) {
if (g_nmi->_aniMan->isIdle()) {
if (!(g_nmi->_aniMan->_flags & 0x100)) {
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(PIC_SC19_RTRUBA31, 0);
handleObjectInteraction(g_nmi->_aniMan, pic, cmd->_param);
break;
}
}
}
}
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
g_vars->scene18_manY = g_nmi->_aniMan2->_oy;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
}
if (g_vars->scene18_bridgeIsConvoluted) {
if (!g_vars->scene18_wheelFlipper)
sceneHandler18and19_drawRiders();
g_vars->scene18_wheelFlipper = !g_vars->scene18_wheelFlipper;
if (!g_vars->scene18_whirlgig->_movement) {
g_vars->scene18_whirlgig->startAnim(MV_WHR19_SPIN, 0, -1);
g_nmi->_behaviorManager->updateBehaviors();
break;
}
} else {
sceneHandler18and19_animateRiders();
}
g_nmi->_behaviorManager->updateBehaviors();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,157 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
#include "ngi/floaters.h"
namespace NGI {
void scene20_setExits(Scene *sc) {
int thingpar;
if (g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_OnStool)
|| g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_OnTheFloor))
thingpar = 1;
else if (g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_NearPipe)
|| g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_NearPipeWithStool)) {
getSc2MctlCompoundBySceneId(sc->_sceneId)->enableLinks(sO_CloseThing, true);
getSc2MctlCompoundBySceneId(sc->_sceneId)->enableLinks(sO_CloseThing2, true);
getSc2MctlCompoundBySceneId(sc->_sceneId)->enableLinks(sO_CloseThing3, false);
return;
} else {
thingpar = 0;
}
getSc2MctlCompoundBySceneId(sc->_sceneId)->enableLinks(sO_CloseThing, thingpar);
getSc2MctlCompoundBySceneId(sc->_sceneId)->enableLinks(sO_CloseThing2, false);
getSc2MctlCompoundBySceneId(sc->_sceneId)->enableLinks(sO_CloseThing3, true);
}
void scene20_initScene(Scene *sc) {
Scene *oldsc = g_nmi->_currentScene;
g_vars->scene20_grandma = sc->getStaticANIObject1ById(ANI_GRANDMA_20, -1);
g_nmi->_currentScene = sc;
if (g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_OnTheFloor))
g_nmi->setObjectState(sO_Grandma, g_nmi->getObjectEnumState(sO_Grandma, sO_NearPipe));
if (g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_OnStool)) {
g_vars->scene20_grandma->changeStatics2(ST_GMA20_STOOL);
} else if (g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_OnTheFloor)) {
g_vars->scene20_grandma->changeStatics2(ST_GMA20_FLOOR);
} else if (g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_NearPipe)
|| g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_NearPipeWithStool)) {
g_vars->scene20_grandma->changeStatics2(ST_GMA20_STAND);
} else {
g_vars->scene20_grandma->hide();
}
scene20_setExits(sc);
g_nmi->_floaters->init(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_20"));
for (int i = 0; i < 3; i++) {
g_nmi->_floaters->genFlies(sc, g_nmi->_rnd.getRandomNumber(101) + 70, g_nmi->_rnd.getRandomNumber(51) + 175, 100, 0);
g_nmi->_floaters->_array2[g_nmi->_floaters->_array2.size() - 1].val13 = g_nmi->_rnd.getRandomNumber(9);
}
g_nmi->_currentScene = oldsc;
g_vars->scene20_fliesCountdown = g_nmi->_rnd.getRandomNumber(200) + 400;
}
void sceneHandler20_updateFlies() {
int sz = g_nmi->_floaters->_array2.size();
if (sz < 3) {
g_nmi->_floaters->genFlies(g_nmi->_currentScene, 253, 650, 200, 0);
g_nmi->_floaters->_array2[sz - 1].val2 = 250;
g_nmi->_floaters->_array2[sz - 1].val3 = 200;
} else {
int idx = g_nmi->_rnd.getRandomNumber(sz);
g_nmi->_floaters->_array2[idx].countdown = 0;
g_nmi->_floaters->_array2[idx].fflags |= 4u;
g_nmi->_floaters->_array2[idx].val2 = 250;
g_nmi->_floaters->_array2[idx].val3 = 200;
g_nmi->_floaters->_array2[idx].val6 = 253;
g_nmi->_floaters->_array2[idx].val7 = 650;
g_nmi->_floaters->_array2[idx].ani->_priority = 200;
}
g_vars->scene20_fliesCountdown = g_nmi->_rnd.getRandomNumber(200) + 400;
}
int sceneHandler20(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_SC20_UPDATELOCKABLE:
scene20_setExits(g_nmi->_currentScene);
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
}
--g_vars->scene20_fliesCountdown;
if (g_vars->scene20_fliesCountdown <= 0)
sceneHandler20_updateFlies();
g_nmi->_floaters->update();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,151 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene21_initScene(Scene *sc) {
Scene *oldsc = g_nmi->_currentScene;
g_vars->scene21_giraffeBottom = sc->getStaticANIObject1ById(ANI_GIRAFFE_BOTTOM, -1);
g_nmi->_currentScene = sc;
if (g_nmi->getObjectState(sO_LowerPipe_21) == g_nmi->getObjectEnumState(sO_LowerPipe_21, sO_IsOpened)) {
g_vars->scene21_giraffeBottom->changeStatics2(ST_GRFB_HANG);
g_vars->scene21_pipeIsOpen = true;
g_vars->scene21_wigglePos = 0.0;
g_vars->scene21_giraffeBottomX = g_vars->scene21_giraffeBottom->_ox;
g_vars->scene21_giraffeBottomY = g_vars->scene21_giraffeBottom->_oy;
g_vars->scene21_wiggleTrigger = false;
} else {
g_vars->scene21_pipeIsOpen = false;
}
g_nmi->_currentScene = oldsc;
g_nmi->initArcadeKeys("SC_21");
}
int scene21_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_cursorId == PIC_CSR_ITN && g_nmi->_objectIdAtCursor == PIC_SC21_DTRUBA)
g_nmi->_cursorId = PIC_CSR_GOD;
return g_nmi->_cursorId;
}
void sceneHandler21_doWiggle() {
g_vars->scene21_giraffeBottom->setOXY((int)(cos(g_vars->scene21_wigglePos) * 4.0) + g_vars->scene21_giraffeBottom->_ox,
g_vars->scene21_giraffeBottom->_oy);
g_vars->scene21_wigglePos += 0.19635;
if (g_vars->scene21_wigglePos > 6.2831853) {
g_vars->scene21_wigglePos = 0;
if (!g_vars->scene21_giraffeBottom->_movement)
g_vars->scene21_giraffeBottom->setOXY(g_vars->scene21_giraffeBottomX, g_vars->scene21_giraffeBottomY);
}
}
int sceneHandler21(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_SC21_UPDATEASS:
if (g_nmi->getObjectState(sO_LowerPipe_21) == g_nmi->getObjectEnumState(sO_LowerPipe_21, sO_IsOpened)) {
g_vars->scene21_giraffeBottom->changeStatics2(ST_GRFB_HANG);
g_vars->scene21_giraffeBottom->setOXY(g_vars->scene21_giraffeBottomX, g_vars->scene21_giraffeBottomY);
g_vars->scene21_giraffeBottom->changeStatics2(ST_GRFB_SIT);
g_vars->scene21_pipeIsOpen = false;
g_nmi->setObjectState(sO_LowerPipe_21, g_nmi->getObjectEnumState(sO_LowerPipe_21, sO_IsClosed));
}
break;
case 29:
{
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (!ani || !canInteractAny(g_nmi->_aniMan, ani, cmd->_param)) {
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picId, 0);
if (!pic || !canInteractAny(g_nmi->_aniMan, pic, cmd->_param) ) {
if ((g_nmi->_sceneRect.right - cmd->_sceneClickX < 47 && g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1)
|| (cmd->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0))
g_nmi->processArcade(cmd);
}
}
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x <= g_nmi->_sceneWidth - 460) {
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
} else {
g_nmi->_currentScene->_x = g_nmi->_sceneWidth - x;
}
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
g_nmi->sceneAutoScrolling();
}
if (g_vars->scene21_pipeIsOpen && !g_vars->scene21_wiggleTrigger)
sceneHandler21_doWiggle();
g_vars->scene21_wiggleTrigger = !g_vars->scene21_wiggleTrigger;
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,399 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene22_initScene(Scene *sc) {
g_vars->scene22_bag = sc->getStaticANIObject1ById(ANI_MESHOK, -1);
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
g_vars->scene22_giraffeMiddle = sc->getStaticANIObject1ById(ANI_GIRAFFE_MIDDLE, -1);
g_vars->scene22_dudeIsOnStool = false;
g_vars->scene22_interactionIsDisabled = false;
g_vars->scene22_craneIsOut = true;
if (g_nmi->getObjectState(sO_Bag_22) == g_nmi->getObjectEnumState(sO_Bag_22, sO_NotFallen))
g_vars->scene22_numBagFalls = 0;
else if (g_nmi->getObjectState(sO_Bag_22) == g_nmi->getObjectEnumState(sO_Bag_22, sO_FallenOnce))
g_vars->scene22_numBagFalls = 1;
else if ( g_nmi->getObjectState(sO_Bag_22) == g_nmi->getObjectEnumState(sO_Bag_22, sO_FallenTwice))
g_vars->scene22_numBagFalls = 2;
else {
g_vars->scene22_numBagFalls = 3;
g_vars->scene22_craneIsOut = false;
}
if ( g_nmi->getObjectState(sO_LowerPipe_21) == g_nmi->getObjectEnumState(sO_LowerPipe_21, sO_IsOpened))
g_vars->scene22_giraffeMiddle->changeStatics2(ST_GRFM_AFTER);
else
g_vars->scene22_giraffeMiddle->changeStatics2(ST_GRFM_NORM);
g_nmi->_currentScene = oldsc;
g_nmi->initArcadeKeys("SC_22");
}
int scene22_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_objectIdAtCursor != ANI_HANDLE_L)
return g_nmi->_cursorId;
int sel = g_nmi->_inventory->getSelectedItemId();
if (!sel) {
g_nmi->_cursorId = PIC_CSR_ITN;
return g_nmi->_cursorId;
}
if (g_vars->scene22_dudeIsOnStool || (sel != ANI_INV_STOOL && sel != ANI_INV_BOX))
; //empty
else
g_nmi->_cursorId = PIC_CSR_ITN_INV;
return g_nmi->_cursorId;
}
void scene22_setBagState() {
if (g_vars->scene22_craneIsOut) {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene22_bag, ST_MSH_SIT, QU_MSH_CRANEOUT, 1);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene22_bag, ST_MSH_SIT, QU_MSH_MOVE, 0);
} else {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene22_bag, ST_MSH_SIT, QU_MSH_CRANEOUT, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene22_bag, ST_MSH_SIT, QU_MSH_MOVE, 1);
}
}
void sceneHandler22_showStool() {
chainQueue(QU_SC22_SHOWSTOOL, 0);
}
void sceneHandler22_hideStool() {
g_nmi->_currentScene->getStaticANIObject1ById(ANI_TABURETTE, -1)->hide();
}
void sceneHandler22_handleDown() {
if (g_vars->scene22_bag->_statics->_staticsId == ST_MSH_SIT) {
chainQueue(QU_MSH_CRANEOUT, 1);
g_vars->scene22_interactionIsDisabled = false;
} else {
++g_vars->scene22_numBagFalls;
int qid;
if (g_vars->scene22_numBagFalls == 3) {
chainQueue(QU_SC22_FALLSACK_GMA, 1);
qid = QU_SC22_FALLBROOM;
} else {
qid = QU_SC22_FALLSACK;
}
chainQueue(qid, 1);
int state;
if (g_vars->scene22_numBagFalls) {
if (g_vars->scene22_numBagFalls == 1) {
state = g_nmi->getObjectEnumState(sO_Bag_22, sO_FallenOnce);
} else if (g_vars->scene22_numBagFalls == 2) {
state = g_nmi->getObjectEnumState(sO_Bag_22, sO_FallenTwice);
} else {
state = g_nmi->getObjectEnumState(sO_Bag_22, sO_BrushHasFallen);
}
} else {
state = g_nmi->getObjectEnumState(sO_Bag_22, sO_NotFallen);
}
g_nmi->setObjectState(sO_Bag_22, state);
}
g_vars->scene22_craneIsOut = true;
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene22_bag, ST_MSH_SIT, QU_MSH_CRANEOUT, 1);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene22_bag, ST_MSH_SIT, QU_MSH_MOVE, 0);
}
void sceneHandler22_fromStool(ExCommand *cmd) {
if (g_nmi->_aniMan->isIdle() && !(g_nmi->_aniMan->_flags & 0x100)) {
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC22_FROMSTOOL), 0, 0);
mq->addExCommandToEnd(cmd->createClone());
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
}
}
void sceneHandler22_stoolLogic(ExCommand *cmd) {
StaticANIObject *ani;
MessageQueue *mq;
int xpos;
int manId;
if (g_nmi->_aniMan->isIdle() && !(g_nmi->_aniMan->_flags & 0x100)) {
if (cmd->_param == ANI_INV_STOOL) {
if (abs(841 - g_nmi->_aniMan->_ox) <= 1) {
if (abs(449 - g_nmi->_aniMan->_oy) <= 1) {
chainQueue(QU_SC22_PUTSTOOL, 1);
g_vars->scene22_interactionIsDisabled = true;
return;
}
}
goto LABEL_13;
}
if (cmd->_param == ANI_INV_BOX) {
ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_TABURETTE, -1);
if (!ani || !(ani->_flags & 4)) {
if (abs(841 - g_nmi->_aniMan->_ox) <= 1) {
if (abs(449 - g_nmi->_aniMan->_oy) <= 1) {
chainObjQueue(g_nmi->_aniMan, QU_SC22_TRYBOX, 1);
return;
}
}
LABEL_13:
xpos = 841;
manId = ST_MAN_RIGHT;
LABEL_31:
mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, xpos, 449, 1, manId);
if (!mq)
return;
mq->addExCommandToEnd(cmd->createClone());
postExCommand(g_nmi->_aniMan->_id, 2, 841, 449, 0, -1);
return;
}
} else {
if (cmd->_param)
return;
if (g_vars->scene22_dudeIsOnStool) {
if (g_nmi->_aniMan->_movement)
return;
chainQueue(QU_SC22_HANDLEDOWN, 1);
g_vars->scene22_interactionIsDisabled = true;
return;
}
ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_TABURETTE, -1);
if (ani && (ani->_flags & 4)) {
int x = g_nmi->_aniMan->_ox;
int y = g_nmi->_aniMan->_oy;
if (sqrt((double)((841 - x) * (841 - x) + (449 - y) * (449 - y)))
< sqrt((double)((1075 - x) * (1075 - x) + (449 - y) * (449 - y)))) {
if (abs(841 - x) <= 1) {
if (abs(449 - y) <= 1) {
chainQueue(QU_SC22_TOSTOOL, 1);
g_vars->scene22_interactionIsDisabled = true;
return;
}
}
goto LABEL_13;
}
if (abs(1075 - x) > 1 || abs(449 - y) > 1) {
xpos = 1075;
manId = ST_MAN_RIGHT | 0x4000;
goto LABEL_31;
}
AniHandler mgm;
MakeQueueStruct mkQueue;
mgm.attachObject(ANI_MAN);
mkQueue.ani = g_nmi->_aniMan;
mkQueue.staticsId2 = ST_MAN_RIGHT;
mkQueue.x1 = 934;
mkQueue.y1 = 391;
mkQueue.field_1C = 10;
mkQueue.staticsId1 = 0x4145;
mkQueue.x2 = 981;
mkQueue.y2 = 390;
mkQueue.field_10 = 1;
mkQueue.flags = 127;
mkQueue.movementId = rMV_MAN_TURN_SRL;
mq = mgm.makeRunQueue(&mkQueue);
ExCommand *ex = mq->getExCommandByIndex(0);
mq->deleteExCommandByIndex(0, 0);
delete mq;
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC22_TOSTOOL_R), 0, 0);
mq->insertExCommandAt(2, ex);
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
g_vars->scene22_interactionIsDisabled = true;
} else {
if (abs(1010 - g_nmi->_aniMan->_ox) <= 1) {
if (abs(443 - g_nmi->_aniMan->_oy) <= 1) {
chainQueue(QU_SC22_TRYHANDLE, 1);
return;
}
}
mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, 1010, 443, 1, ST_MAN_UP);
if (mq) {
mq->addExCommandToEnd(cmd->createClone());
postExCommand(g_nmi->_aniMan->_id, 2, 1010, 443, 0, -1);
return;
}
}
}
}
}
int sceneHandler22(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_SC22_CRANEOUT_GMA:
chainQueue(QU_MSH_CRANEOUT_GMA, 1);
break;
case MSG_SC22_CHECKGMABOOT:
if (g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_In_15)) {
g_nmi->setObjectState(sO_Boot_15, g_nmi->getObjectEnumState(sO_Boot_15, sO_IsPresent));
}
break;
case MSG_SC22_SHOWSTOOL:
sceneHandler22_showStool();
break;
case MSG_SC22_HIDESTOOL:
sceneHandler22_hideStool();
break;
case MSG_SC22_FROMSTOOL:
g_vars->scene22_dudeIsOnStool = false;
g_vars->scene22_interactionIsDisabled = false;
getCurrSceneSc2MotionController()->activate();
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 1);
break;
case MSG_SC22_ONSTOOL:
g_vars->scene22_dudeIsOnStool = true;
getCurrSceneSc2MotionController()->deactivate();
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 0);
break;
case MSG_SC22_HANDLEDOWN:
sceneHandler22_handleDown();
break;
case 29:
if (!g_vars->scene22_interactionIsDisabled) {
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (ani && ani->_id == ANI_HANDLE_L) {
sceneHandler22_stoolLogic(cmd);
return 0;
}
if (!g_vars->scene22_dudeIsOnStool) {
if (!ani || !canInteractAny(g_nmi->_aniMan, ani, cmd->_param)) {
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picId, 0);
if (!pic || !canInteractAny(g_nmi->_aniMan, pic, cmd->_param)) {
if ((g_nmi->_sceneRect.right - cmd->_sceneClickX < 47 && g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1)
|| (cmd->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0)) {
g_nmi->processArcade(cmd);
return 0;
}
}
}
return 0;
}
if (g_nmi->_aniMan->_statics->_staticsId == ST_MAN_RIGHT && !g_nmi->_aniMan->_movement) {
sceneHandler22_fromStool(cmd);
return 0;
}
}
cmd->_messageKind = 0;
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x <= g_nmi->_sceneWidth - 460) {
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
} else {
g_nmi->_currentScene->_x = g_nmi->_sceneWidth - x;
}
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
g_nmi->sceneAutoScrolling();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,557 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
#include "ngi/floaters.h"
namespace NGI {
bool sceneHandler23_testCalendar() {
int cal0, cal1, cal2, cal3;
if (g_vars->scene23_calend0->_movement)
cal0 = g_vars->scene23_calend0->_movement->_staticsObj2->_staticsId;
else
cal0 = g_vars->scene23_calend0->_statics->_staticsId;
if (g_vars->scene23_calend1->_movement)
cal1 = g_vars->scene23_calend1->_movement->_staticsObj2->_staticsId;
else
cal1 = g_vars->scene23_calend1->_statics->_staticsId;
if (g_vars->scene23_calend2->_movement)
cal2 = g_vars->scene23_calend2->_movement->_staticsObj2->_staticsId;
else
cal2 = g_vars->scene23_calend2->_statics->_staticsId;
if (g_vars->scene23_calend3->_movement)
cal3 = g_vars->scene23_calend3->_movement->_staticsObj2->_staticsId;
else
cal3 = g_vars->scene23_calend3->_statics->_staticsId;
return (cal0 == ST_CND_1 && cal1 == ST_CND_4 && cal2 == ST_CND_0 && cal3 == ST_CND_2 && (g_vars->scene23_giraffee->_flags & 4));
}
void scene23_initScene(Scene *sc) {
g_vars->scene23_calend0 = sc->getStaticANIObject1ById(ANI_CALENDWHEEL, 0);
g_vars->scene23_calend1 = sc->getStaticANIObject1ById(ANI_CALENDWHEEL, 1);
g_vars->scene23_calend2 = sc->getStaticANIObject1ById(ANI_CALENDWHEEL, 2);
g_vars->scene23_calend3 = sc->getStaticANIObject1ById(ANI_CALENDWHEEL, 3);
g_vars->scene23_topReached = false;
g_vars->scene23_isOnStool = false;
g_vars->scene23_someVar = 0;
g_vars->scene23_giraffeTop = sc->getStaticANIObject1ById(ANI_GIRAFFE_TOP, -1);
g_vars->scene23_giraffee = sc->getStaticANIObject1ById(ANI_GIRAFFEE, -1);
g_nmi->_floaters->init(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_23"));
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
if (g_nmi->getObjectState(sO_UpperHatch_23) == g_nmi->getObjectEnumState(sO_UpperHatch_23, sO_Opened)) {
sc->getPictureObjectById(PIC_SC23_BOXOPEN, 0)->_flags |= 4;
sc->getPictureObjectById(PIC_SC23_BOXCLOSED, 0)->_flags &= 0xFFFB;
sc->getPictureObjectById(PIC_SC23_BTN1, 0)->_flags |= 4;
sc->getPictureObjectById(PIC_SC23_BTN2, 0)->_flags |= 4;
sc->getPictureObjectById(PIC_SC23_BTN3, 0)->_flags |= 4;
sc->getPictureObjectById(PIC_SC23_BTN4, 0)->_flags |= 4;
if (g_vars->scene23_giraffee->_statics->_staticsId == ST_GRFG_EMPTY || !(g_vars->scene23_giraffee->_flags & 4)) {
g_vars->scene23_giraffee->changeStatics2(ST_GRFG_BALD);
g_vars->scene23_giraffee->_flags |= 4;
}
g_vars->scene23_calend0->show1(-1, -1, -1, 0);
g_vars->scene23_calend1->show1(-1, -1, -1, 0);
g_vars->scene23_calend2->show1(-1, -1, -1, 0);
g_vars->scene23_calend3->show1(-1, -1, -1, 0);
sc->getStaticANIObject1ById(ANI_LUK23_U, -1)->changeStatics2(ST_LUK23U_OPEN);
} else {
sc->getPictureObjectById(PIC_SC23_BOXOPEN, 0)->_flags &= 0xFFFB;
sc->getPictureObjectById(PIC_SC23_BOXCLOSED, 0)->_flags |= 4;
sc->getPictureObjectById(PIC_SC23_BTN1, 0)->_flags &= 0xFFFB;
sc->getPictureObjectById(PIC_SC23_BTN2, 0)->_flags &= 0xFFFB;
sc->getPictureObjectById(PIC_SC23_BTN3, 0)->_flags &= 0xFFFB;
sc->getPictureObjectById(PIC_SC23_BTN4, 0)->_flags &= 0xFFFB;
g_vars->scene23_giraffee->hide();
g_vars->scene23_calend0->hide();
g_vars->scene23_calend1->hide();
g_vars->scene23_calend2->hide();
g_vars->scene23_calend3->hide();
sc->getStaticANIObject1ById(ANI_LUK23_U, -1)->changeStatics2(ST_LUK23U_CLOSED);
g_nmi->_floaters->genFlies(sc, 600, 90, 0, 0);
}
if (g_nmi->getObjectState(sO_LowerHatch_23) == g_nmi->getObjectEnumState(sO_LowerHatch_23, sO_Opened)) {
g_vars->scene23_giraffeTop->show1(-1, -1, -1, 0);
g_vars->scene23_giraffeTop->changeStatics2(ST_GRFU_UP);
if (g_nmi->getObjectState(sO_LowerPipe_21) == g_nmi->getObjectEnumState(sO_LowerPipe_21, sO_IsOpened)) {
g_vars->scene23_giraffeTop->changeStatics2(ST_GRFU_KISS);
g_vars->scene23_giraffee->hide();
} else {
if (g_nmi->getObjectState(sO_UpperHatch_23) == g_nmi->getObjectEnumState(sO_UpperHatch_23, sO_Opened)
&& (g_vars->scene23_giraffee->_flags & 4))
g_vars->scene23_giraffeTop->setOXY(614, 362);
else
g_vars->scene23_giraffeTop->setOXY(618, 350);
if (sceneHandler23_testCalendar())
g_vars->scene23_calend1->_statics = g_vars->scene23_calend1->getStaticsById(ST_CND_5);
}
sc->getStaticANIObject1ById(ANI_LUK23_D, -1)->changeStatics2(ST_LUK23_OPEN);
if (g_nmi->getObjectState(sO_Lever_23) == g_nmi->getObjectEnumState(sO_Lever_23, sO_Taken))
sc->getStaticANIObject1ById(ANI_INV_LEVERHANDLE, -1)->hide();
sc->getStaticANIObject1ById(ANI_HANDLE23, -1)->hide();
} else {
g_vars->scene23_giraffeTop->hide();
sc->getStaticANIObject1ById(ANI_LUK23_D, -1)->changeStatics2(ST_LUK23_WHANDLE2);
sc->getStaticANIObject1ById(ANI_INV_LEVERHANDLE, -1)->hide();
}
g_nmi->_currentScene = oldsc;
}
void scene23_setGiraffeState() {
if (g_nmi->getObjectState(sO_UpperHatch_23) == g_nmi->getObjectEnumState(sO_UpperHatch_23, sO_Opened)) {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene23_giraffeTop, ST_GRFU_UP, QU_GRFU_TURN_UL, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene23_giraffeTop, ST_GRFU_UP, QU_GRFU_TURN_UD, 0);
}
}
int scene23_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_objectIdAtCursor == PIC_SC23_LADDERU) {
if (g_vars->scene23_topReached)
return g_nmi->_cursorId;
g_nmi->_cursorId = getGameLoaderInventory()->getSelectedItemId() ? PIC_CSR_GOU : PIC_CSR_ITN; // FIXME check
}
if (g_nmi->_objectIdAtCursor == PIC_SC23_BTN1 || g_nmi->_objectIdAtCursor == PIC_SC23_BTN2
|| g_nmi->_objectIdAtCursor == PIC_SC23_BTN3 || g_nmi->_objectIdAtCursor == PIC_SC23_BTN4
|| g_nmi->_objectIdAtCursor == ANI_CALENDWHEEL)
g_nmi->_cursorId = PIC_CSR_LIFT;
return g_nmi->_cursorId;
}
void sceneHandler23_showStool() {
chainQueue(QU_SC23_SHOWSTOOL, 0);
}
void sceneHandler23_hideStool() {
g_nmi->_currentScene->getStaticANIObject1ById(ANI_TABURETTE, -1)->hide();
}
void sceneHandler23_startKiss() {
g_vars->scene23_giraffeTop->changeStatics2(ST_GRFU_UP);
g_vars->scene23_giraffeTop->startMQIfIdle(QU_SC23_STARTKISS, 0);
}
void sceneHandler23_spinWheel1() {
int mv = 0;
switch (g_vars->scene23_calend0->_statics->_staticsId) {
case ST_CND_0:
mv = MV_CND_0_1;
break;
case ST_CND_1:
mv = MV_CND_1_2;
break;
case ST_CND_2:
mv = MV_CND_2_3;
break;
case ST_CND_3:
g_vars->scene23_calend0->changeStatics2(ST_CND_9);
mv = MV_CND_9_0;
break;
default:
break;
}
if (mv)
g_vars->scene23_calend0->startAnim(mv, 0, -1);
if (sceneHandler23_testCalendar())
sceneHandler23_startKiss();
}
void sceneHandler23_spinWheel2and4(StaticANIObject *ani) {
int mv = 0;
switch (ani->_statics->_staticsId) {
case ST_CND_0:
mv = MV_CND_0_1;
break;
case ST_CND_1:
mv = MV_CND_1_2;
break;
case ST_CND_2:
mv = MV_CND_2_3;
break;
case ST_CND_3:
mv = MV_CND_3_4;
break;
case ST_CND_4:
mv = MV_CND_4_5;
break;
case ST_CND_5:
mv = MV_CND_5_6;
break;
case ST_CND_6:
mv = MV_CND_6_7;
break;
case ST_CND_7:
mv = MV_CND_7_8;
break;
case ST_CND_8:
mv = MV_CND_8_9;
break;
case ST_CND_9:
mv = MV_CND_9_0;
break;
default:
break;
}
if (mv)
ani->startAnim(mv, 0, -1);
if (sceneHandler23_testCalendar())
sceneHandler23_startKiss();
}
void sceneHandler23_spinWheel3() {
if (g_vars->scene23_calend2->_statics->_staticsId == ST_CND_0) {
g_vars->scene23_calend2->startAnim(MV_CND_0_1, 0, -1);
} else if (g_vars->scene23_calend2->_statics->_staticsId == ST_CND_1) {
g_vars->scene23_calend2->changeStatics2(ST_CND_9);
g_vars->scene23_calend2->startAnim(MV_CND_9_0, 0, -1);
}
if (sceneHandler23_testCalendar())
sceneHandler23_startKiss();
}
void sceneHandler23_pushButton(ExCommand *cmd) {
if (g_nmi->_aniMan->isIdle() || !(g_nmi->_aniMan->_flags & 0x100)) {
if (!g_vars->scene23_topReached) {
if (g_nmi->_aniMan->_ox != 405 || g_nmi->_aniMan->_oy != 220) {
if (g_nmi->_aniMan->_ox != 276 || g_nmi->_aniMan->_oy != 438
|| g_nmi->_aniMan->_movement || g_nmi->_aniMan->_statics->_staticsId != ST_MAN_RIGHT) {
if (g_nmi->_msgX == 276 && g_nmi->_msgY == 438 )
return;
MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, 276, 438, 1, ST_MAN_RIGHT);
if (mq) {
mq->addExCommandToEnd(cmd->createClone());
postExCommand(g_nmi->_aniMan->_id, 2, 276, 438, 0, -1);
}
} else {
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC23_TOCALENDAR), 0, 0);
mq->addExCommandToEnd(cmd->createClone());
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
}
if (!g_vars->scene23_topReached)
return;
} else {
g_vars->scene23_topReached = true;
}
}
if (!g_nmi->_aniMan->_movement && g_nmi->_aniMan->_statics->_staticsId == ST_MAN_STANDLADDER) {
int mv = 0;
switch (cmd->_messageNum) {
case MSG_SC23_CLICKBTN1:
mv = MV_MAN23_PUSH1;
break;
case MSG_SC23_CLICKBTN2:
mv = MV_MAN23_PUSH2;
break;
case MSG_SC23_CLICKBTN3:
mv = MV_MAN23_PUSH3;
break;
case MSG_SC23_CLICKBTN4:
mv = MV_MAN23_PUSH4;
break;
default:
return;
}
if (mv)
g_nmi->_aniMan->startAnim(mv, 0, -1);
}
}
}
void sceneHandler23_sendClick(StaticANIObject *ani) {
int msg = 0;
switch (ani->_odelay) {
case 0:
msg = MSG_SC23_CLICKBTN1;
break;
case 1:
msg = MSG_SC23_CLICKBTN2;
break;
case 2:
msg = MSG_SC23_CLICKBTN3;
break;
case 3:
msg = MSG_SC23_CLICKBTN4;
break;
default:
break;
}
ExCommand *ex = new ExCommand(0, 17, msg, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 3;
ex->postMessage();
}
void sceneHandler23_checkReachingTop() {
if (g_nmi->_aniMan->_movement || g_nmi->_aniMan->_statics->_staticsId != ST_MAN_STANDLADDER
|| g_nmi->_aniMan->_ox != 405 || g_nmi->_aniMan->_oy != 220)
g_vars->scene23_topReached = false;
else
g_vars->scene23_topReached = true;
}
void sceneHandler23_exitCalendar() {
if (!g_nmi->_aniMan->_movement && g_nmi->_aniMan->_statics->_staticsId == ST_MAN_STANDLADDER
&& !g_nmi->_aniMan->getMessageQueue() && !(g_nmi->_aniMan->_flags & 0x100)) {
chainQueue(QU_SC23_FROMCALENDAREXIT, 1);
g_vars->scene23_someVar = 2;
}
}
void sceneHandler23_fromCalendar(ExCommand *cmd) {
if (!g_nmi->_aniMan->_movement && g_nmi->_aniMan->_statics->_staticsId == ST_MAN_STANDLADDER
&& !g_nmi->_aniMan->getMessageQueue() && !(g_nmi->_aniMan->_flags & 0x100)) {
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC23_FROMCALENDAR), 0, 0);
mq->addExCommandToEnd(cmd->createClone());
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
g_vars->scene23_topReached = false;
g_vars->scene23_someVar = 0;
}
}
void sceneHandler23_fromStool(ExCommand *cmd) {
if (!g_nmi->_aniMan->getMessageQueue() && !(g_nmi->_aniMan->_flags & 0x100)) {
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC23_FROMSTOOL), 0, 0);
mq->addExCommandToEnd(cmd->createClone());
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
cmd->_messageKind = 0;
}
}
int sceneHandler23(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_SC23_FROMSTOOL:
g_vars->scene23_isOnStool = false;
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 1);
break;
case MSG_SC23_HIDEGIRAFFEE:
g_vars->scene23_giraffee->queueMessageQueue(nullptr);
g_vars->scene23_giraffee->_flags &= 0xFFFB;
break;
case MSG_SC23_ONSTOOL:
g_vars->scene23_isOnStool = true;
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 0);
break;
case MSG_SC22_SHOWSTOOL:
sceneHandler23_showStool();
break;
case MSG_SC22_HIDESTOOL:
sceneHandler23_hideStool();
break;
case MSG_SC23_SPINWHEEL1:
sceneHandler23_spinWheel1();
break;
case MSG_SC23_SPINWHEEL2:
sceneHandler23_spinWheel2and4(g_vars->scene23_calend1);
break;
case MSG_SC23_SPINWHEEL3:
sceneHandler23_spinWheel3();
break;
case MSG_SC23_SPINWHEEL4:
sceneHandler23_spinWheel2and4(g_vars->scene23_calend3);
break;
case MSG_SC23_CLICKBTN1:
case MSG_SC23_CLICKBTN2:
case MSG_SC23_CLICKBTN3:
case MSG_SC23_CLICKBTN4:
sceneHandler23_pushButton(cmd);
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
}
g_nmi->_floaters->update();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
case 29:
{
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
int picId;
if (ani && ani->_id == ANI_CALENDWHEEL) {
sceneHandler23_sendClick(ani);
cmd->_messageKind = 0;
}
sceneHandler23_checkReachingTop();
if (g_vars->scene23_topReached) {
picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (picId == PIC_SC23_LADDER) {
sceneHandler23_exitCalendar();
cmd->_messageKind = 0;
break;
}
if (cmd->_sceneClickY > 450) {
sceneHandler23_fromCalendar(cmd);
cmd->_messageKind = 0;
break;
}
break;
}
if (!g_vars->scene23_isOnStool) {
picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (picId == PIC_SC23_LADDERU && !g_vars->scene23_topReached) {
sceneHandler23_pushButton(cmd);
cmd->_messageKind = 0;
break;
}
break;
}
if (ani && ani->_id == ANI_HANDLE23) {
handleObjectInteraction(g_nmi->_aniMan, ani, cmd->_param);
cmd->_messageKind = 0;
} else {
sceneHandler23_fromStool(cmd);
cmd->_messageKind = 0;
}
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,127 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene24_initScene(Scene *sc) {
g_vars->scene24_water = sc->getStaticANIObject1ById(ANI_WATER24, -1);
g_vars->scene24_jet = sc->getStaticANIObject1ById(ANI_JET24, -1);
g_vars->scene24_drop = sc->getStaticANIObject1ById(ANI_DROP_24, -1);
g_vars->scene24_water->setAlpha(0xa0);
g_vars->scene24_jet->setAlpha(0xa0);
g_vars->scene24_drop->setAlpha(0xa0);
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
if (g_nmi->getObjectState(sO_Pool) == g_nmi->getObjectEnumState(sO_Pool, sO_Overfull)) {
g_vars->scene24_jetIsOn = true;
g_vars->scene24_flowIsLow = false;
} else {
g_vars->scene24_jet->hide();
g_vars->scene24_jetIsOn = false;
g_vars->scene24_water->changeStatics2(ST_WTR24_FLOWLOWER);
g_vars->scene24_flowIsLow = true;
}
if (g_nmi->getObjectState(sO_Pool) < g_nmi->getObjectEnumState(sO_Pool, sO_Full)) {
g_vars->scene24_waterIsOn = false;
g_vars->scene24_water->hide();
g_nmi->setObjectState(sO_StairsDown_24, g_nmi->getObjectEnumState(sO_StairsDown_24, sO_IsOpened));
} else {
g_vars->scene24_waterIsOn = true;
g_nmi->setObjectState(sO_StairsDown_24, g_nmi->getObjectEnumState(sO_StairsDown_24, sO_IsClosed));
}
g_nmi->_currentScene = oldsc;
}
void scene24_setPoolState() {
if (g_nmi->getObjectState(sO_Pool) == g_nmi->getObjectEnumState(sO_Pool, sO_Overfull)) {
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_vars->scene24_drop, 0);
g_nmi->playSound(SND_24_007, 1);
} else if (g_nmi->getObjectState(sO_Pool) == g_nmi->getObjectEnumState(sO_Pool, sO_Full)) {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOFLOOR, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOWATER, 1);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOWATER2, 0);
g_nmi->playSound(SND_24_006, 1);
} else if (g_nmi->getObjectState(sO_Pool) == g_nmi->getObjectEnumState(sO_Pool, sO_HalfFull)) {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOFLOOR, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOWATER, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOWATER2, 1);
} else {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOFLOOR, 1);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOWATER, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOWATER2, 0);
}
}
int sceneHandler24(ExCommand *cmd) {
if (cmd->_messageKind == 17 && cmd->_messageNum == 33) {
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200) {
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
}
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
}
if (g_vars->scene24_waterIsOn && !g_vars->scene24_water->_movement) {
if (g_vars->scene24_flowIsLow)
g_vars->scene24_water->startAnim(MV_WTR24_FLOWLOWER, 0, -1);
else
g_vars->scene24_water->startAnim(MV_WTR24_FLOW, 0, -1);
}
if (g_vars->scene24_jetIsOn && !g_vars->scene24_jet->_movement)
g_vars->scene24_jet->startAnim(MV_JET24_FLOW, 0, -1);
g_nmi->_behaviorManager->updateBehaviors();
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,729 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene25_showBoardOnRightFar() {
g_vars->scene25_board->show1(453, 557, MV_BRD25_RIGHT, 0);
g_vars->scene25_board->_priority = 28;
}
void scene25_showBoardOnRightClose() {
g_vars->scene25_board->show1(632, 557, rMV_BRD25_RIGHT, 0);
g_vars->scene25_board->_priority = 28;
}
void scene25_initScene(Scene *sc, int entranceId) {
g_vars->scene25_water = sc->getStaticANIObject1ById(ANI_WATER25, -1);
g_vars->scene25_board = sc->getStaticANIObject1ById(ANI_BOARD25, -1);
g_vars->scene25_drop = sc->getStaticANIObject1ById(ANI_DROP_25, -1);
g_vars->scene25_water->setAlpha(0xa0);
g_vars->scene25_drop->setAlpha(0xa0);
g_vars->scene25_dudeIsOnBoard = false;
if (g_nmi->getObjectState(sO_Pool) < g_nmi->getObjectEnumState(sO_Pool, sO_HalfFull)) {
g_vars->scene25_waterIsPresent = false;
g_vars->scene25_water->hide();
} else {
g_vars->scene25_waterIsPresent = true;
g_nmi->playSound(SND_25_006, 1);
}
int boardState = g_nmi->getObjectState(sO_Board_25);
if (entranceId == TrubaRight) {
if (boardState == g_nmi->getObjectEnumState(sO_Board_25, sO_FarAway)) {
scene25_showBoardOnRightFar();
g_nmi->playSound(SND_25_029, 0);
g_vars->scene25_boardIsSelectable = false;
} else {
if (boardState == g_nmi->getObjectEnumState(sO_Board_25, sO_Nearby)
|| boardState == g_nmi->getObjectEnumState(sO_Board_25, sO_WithDudeOnRight))
scene25_showBoardOnRightClose();
g_vars->scene25_boardIsSelectable = false;
}
} else {
if (boardState == g_nmi->getObjectEnumState(sO_Board_25, sO_WithDudeOnLeft)) {
if (!getGameLoaderInventory()->getCountItemsWithId(ANI_INV_BOARD)) {
getGameLoaderInventory()->addItem(ANI_INV_BOARD, 1);
getGameLoaderInventory()->rebuildItemRects();
}
} else {
g_vars->scene25_boardIsSelectable = true;
}
}
g_vars->scene25_beardersAreThere = false;
g_vars->scene25_beardersCounter = 0;
}
int scene25_updateCursor() {
g_nmi->updateCursorCommon();
if (g_vars->scene25_waterIsPresent) {
int inv = getGameLoaderInventory()->getSelectedItemId();
if (g_nmi->_objectIdAtCursor == ANI_WATER25) {
if ((g_vars->scene25_boardIsSelectable && (!inv || inv == ANI_INV_BOARD)) || (g_vars->scene25_dudeIsOnBoard && (inv == ANI_INV_LOPAT || !inv)))
g_nmi->_cursorId = (g_nmi->_cursorId != PIC_CSR_DEFAULT) ? PIC_CSR_ITN_INV : PIC_CSR_ITN;
} else if (g_nmi->_objectIdAtCursor == ANI_BOARD25 && (!inv || inv == ANI_INV_SWAB || inv == ANI_INV_BROOM || inv == ANI_INV_LOPAT)) {
g_nmi->_cursorId = (g_nmi->_cursorId != PIC_CSR_DEFAULT) ? PIC_CSR_ITN_INV : PIC_CSR_ITN;
}
}
return g_nmi->_cursorId;
}
void scene25_setupWater(Scene *a1, int entranceId) {
if (g_vars->scene25_waterIsPresent) {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene25_drop, ST_DRP25_EMPTY, QU_DRP25_TOFLOOR, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene25_drop, ST_DRP25_EMPTY, QU_DRP25_TOWATER, 1);
if (entranceId != TrubaRight)
g_nmi->playTrack(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_25"), "MUSIC2", 0);
} else {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene25_drop, ST_DRP25_EMPTY, QU_DRP25_TOFLOOR, 1);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene25_drop, ST_DRP25_EMPTY, QU_DRP25_TOWATER, 0);
}
}
void sceneHandler25_stopBearders() {
g_vars->scene25_beardersAreThere = false;
g_vars->scene25_bearders.clear();
}
void sceneHandler25_startBearders() {
g_vars->scene25_bearders.clear();
g_vars->scene25_beardersCounter = 0;
StaticANIObject *bearded = g_nmi->accessScene(SC_COMMON)->getStaticANIObject1ById(ANI_BEARDED_CMN, -1);
for (int i = 0; i < 3; i++) {
StaticANIObject *ani = new StaticANIObject(bearded);
g_vars->scene25_bearders.push_back(ani);
ani->_statics = ani->getStaticsById(ST_BRDCMN_EMPTY);
g_nmi->_currentScene->addStaticANIObject(ani, 1);
}
g_vars->scene25_beardersAreThere = true;
}
void sceneHandler25_enterMan() {
if (g_vars->scene25_waterIsPresent) {
chainQueue(QU_SC25_ENTERUP_WATER, 1);
getCurrSceneSc2MotionController()->deactivate();
} else {
chainQueue(QU_SC25_ENTERUP_FLOOR, 1);
}
}
void sceneHandler25_enterTruba() {
PicAniInfo info;
g_nmi->_aniMan->getPicAniInfo(info);
g_nmi->_aniMan->_messageQueueId = 0;
g_nmi->_aniMan->changeStatics2(g_nmi->_aniMan->_statics->_staticsId);
int x = g_nmi->_aniMan->_ox;
int y = g_nmi->_aniMan->_oy;
g_nmi->_aniMan->setPicAniInfo(info);
int id = g_nmi->_aniMan->_statics->_staticsId;
int qid = 0;
if (id == ST_MAN25_ONBOARD && x == 634 && y == 502) {
g_nmi->_aniMan->changeStatics2(ST_MAN25_ONBOARD);
qid = QU_SC25_MANTOTRUBA;
} else if (id == (ST_MAN25_ONBOARD|0x4000) && x == 632 && y == 502) {
g_nmi->_aniMan->changeStatics2(ST_MAN25_ONBOARD|0x4000);
qid = QU_SC25_MANTOTRUBA_R;
}
if (qid) {
chainQueue(qid, 1);
g_vars->scene25_sneezeFlipper = false;
}
}
void sceneHandler25_saveEntrance(int value) {
g_nmi->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME")->setSubVarAsInt("Entrance", value);
}
void sceneHandler25_toLadder() {
PicAniInfo info;
g_nmi->_aniMan->getPicAniInfo(info);
g_nmi->_aniMan->_messageQueueId = 0;
g_nmi->_aniMan->changeStatics2(g_nmi->_aniMan->_statics->_staticsId);
int x = g_nmi->_aniMan->_ox;
int y = g_nmi->_aniMan->_oy;
g_nmi->_aniMan->setPicAniInfo(info);
int id = g_nmi->_aniMan->_statics->_staticsId;
int qid = 0;
if (id == ST_MAN25_ONBOARD && x == 307 && y == 502) {
g_nmi->_aniMan->changeStatics2(ST_MAN25_ONBOARD);
qid = QU_SC25_BACKTOLADDER;
} else if (id == (ST_MAN25_ONBOARD|0x4000) && x == 192 && y == 502) {
g_nmi->_aniMan->changeStatics2(ST_MAN25_ONBOARD|0x4000);
qid = QU_SC25_BOARDTOLADDER;
}
if (qid) {
chainQueue(qid, 1);
g_vars->scene25_dudeIsOnBoard = false;
g_vars->scene25_boardIsSelectable = true;
g_vars->scene25_sneezeFlipper = false;
sceneHandler25_saveEntrance(TrubaUp);
}
}
void sceneHandler25_animateBearders() {
if (g_nmi->_rnd.getRandomNumber(32767) < 218) {
MessageQueue *mq;
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC25_BEARDED), 0, 1);
mq->setParamInt(-1, g_vars->scene25_bearders[0]->_odelay);
mq->getExCommandByIndex(0)->_x = g_nmi->_rnd.getRandomNumber(650) + 100;
mq->chain(nullptr);
g_vars->scene25_beardersCounter = 0;
if (g_nmi->_rnd.getRandomNumber(32767) < 0x1FFF) {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC25_BEARDED2), 0, 1);
mq->setParamInt(-1, g_vars->scene25_bearders[1]->_odelay);
mq->getExCommandByIndex(0)->_x = g_nmi->_rnd.getRandomNumber(650) + 100;
mq->chain(nullptr);
if (g_nmi->_rnd.getRandomNumber(32767) < 8191) {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC25_BEARDED3), 0, 1);
mq->setParamInt(-1, g_vars->scene25_bearders[2]->_odelay);
mq->getExCommandByIndex(0)->_x = g_nmi->_rnd.getRandomNumber(650) + 100;
mq->chain(nullptr);
}
}
}
}
void sceneHandler25_sneeze() {
if (g_nmi->_rnd.getRandomNumber(32767) % 10) {
if (g_nmi->_aniMan->_statics->_staticsId == ST_MAN25_ONBOARD) {
g_nmi->_aniMan->startAnim(MV_MAN25_ONBOARD, 0, -1);
} else if (g_nmi->_aniMan->_statics->_staticsId == (ST_MAN25_ONBOARD|0x4000)) {
g_nmi->_aniMan->startAnim(rMV_MAN25_ONBOARD, 0, -1);
}
} else if (g_nmi->_aniMan->_statics->_staticsId == ST_MAN25_ONBOARD) {
g_nmi->_aniMan->startAnim(MV_MAN25_CHIH, 0, -1);
} else if (g_nmi->_aniMan->_statics->_staticsId == (ST_MAN25_ONBOARD|0x4000)) {
g_nmi->_aniMan->startAnim(rMV_MAN25_CHIH, 0, -1);
}
}
void sceneHandler25_rowShovel() {
PicAniInfo info;
g_nmi->_aniMan->getPicAniInfo(info);
g_nmi->_aniMan->_messageQueueId = 0;
g_nmi->_aniMan->changeStatics2(g_nmi->_aniMan->_statics->_staticsId);
int x = g_nmi->_aniMan->_ox;
int y = g_nmi->_aniMan->_oy;
g_nmi->_aniMan->setPicAniInfo(info);
int id = g_nmi->_aniMan->_statics->_staticsId;
int qid = 0;
if (id == ST_MAN25_ONBOARD && x == 370 && y == 502) {
g_nmi->_aniMan->changeStatics2(ST_MAN25_ONBOARD);
qid = QU_SC25_ROWTOTRUBA;
} else if (id == (ST_MAN25_ONBOARD|0x4000) && x == 632 && y == 502) {
g_nmi->_aniMan->changeStatics2(ST_MAN25_ONBOARD|0x4000);
qid = QU_SC25_ROWTOLADDER;
g_nmi->playSound(SND_25_030, 0);
}
if (qid) {
chainQueue(qid, 1);
g_vars->scene25_sneezeFlipper = false;
}
}
void sceneHandler25_rowHand() {
PicAniInfo info;
g_nmi->_aniMan->getPicAniInfo(info);
g_nmi->_aniMan->_messageQueueId = 0;
g_nmi->_aniMan->changeStatics2(g_nmi->_aniMan->_statics->_staticsId);
int x = g_nmi->_aniMan->_ox;
int y = g_nmi->_aniMan->_oy;
g_nmi->_aniMan->setPicAniInfo(info);
int id = g_nmi->_aniMan->_statics->_staticsId;
int qid = 0;
if (id == ST_MAN25_ONBOARD && x == 370 && y == 502) {
g_nmi->_aniMan->changeStatics2(ST_MAN25_ONBOARD);
qid = QU_SC25_TRYROWHAND;
} else if (id == (ST_MAN25_ONBOARD|0x4000) && x == 632 && y == 502) {
g_nmi->_aniMan->changeStatics2(ST_MAN25_ONBOARD|0x4000);
qid = QU_SC25_TRYROWHAND_R;
}
if (qid) {
chainObjQueue(g_nmi->_aniMan, qid, 1);
g_vars->scene25_sneezeFlipper = false;
}
}
void sceneHandler25_putBoard() {
if (g_nmi->_aniMan->_statics->_staticsId == ST_MAN_STANDLADDER
|| g_nmi->_aniMan->_statics->_staticsId == ST_MAN_LADDERDOWN_R) {
g_nmi->_aniMan->changeStatics2(ST_MAN_STANDLADDER);
g_nmi->_aniMan->setOXY(281, 481);
chainQueue(QU_SC25_PUTBOARD, 1);
g_vars->scene25_dudeIsOnBoard = true;
g_vars->scene25_sneezeFlipper = false;
g_vars->scene25_boardIsSelectable = false;
}
}
void sceneHandler25_tryWater() {
if (g_nmi->_aniMan->_statics->_staticsId == ST_MAN_STANDLADDER
|| g_nmi->_aniMan->_statics->_staticsId == ST_MAN_LADDERDOWN_R) {
g_nmi->_aniMan->changeStatics2(ST_MAN_STANDLADDER);
chainQueue(QU_SC25_TRYWATER, 1);
}
}
void sceneHandler25_tryRow(int obj) {
PicAniInfo info;
g_nmi->_aniMan->getPicAniInfo(info);
g_nmi->_aniMan->_messageQueueId = 0;
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
int x = g_nmi->_aniMan->_ox;
int y = g_nmi->_aniMan->_oy;
g_nmi->_aniMan->setPicAniInfo(info);
int qid = 0;
if (x == 788 && y == 468) {
if (g_vars->scene25_board->_statics->_staticsId == ST_BRD25_RIGHT2) {
if (obj == ANI_INV_BROOM) {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
qid = QU_SC25_TRYBROOM;
}
if (obj == ANI_INV_LOPAT) {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
qid = QU_SC25_TRYSPADE;
}
if (qid) {
chainQueue(qid, 1);
g_nmi->playSound(SND_25_028, 0);
return;
}
if (obj == ANI_INV_SWAB) {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
chainQueue(QU_SC25_TRYSWAB, 1);
} else if (!obj) {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
chainObjQueue(g_nmi->_aniMan, QU_SC25_TRYHAND, 1);
g_nmi->playSound(SND_25_028, 0);
}
} else if (g_vars->scene25_board->_statics->_staticsId == (ST_BRD25_RIGHT2 | 0x4000) && !obj) {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
chainQueue(QU_SC25_TRUBATOBOARD, 1);
g_vars->scene25_dudeIsOnBoard = true;
}
}
}
void sceneHandler25_ladderUp() {
if (g_nmi->_aniMan->_statics->_staticsId == ST_MAN_STANDLADDER
|| g_nmi->_aniMan->_statics->_staticsId == ST_MAN_LADDERDOWN_R) {
g_nmi->_aniMan->changeStatics2(ST_MAN_STANDLADDER);
chainQueue(QU_SC25_LADDERUP, 1);
}
}
void sceneHandler25_backToPipe() {
if (!g_nmi->_aniMan->_movement && g_nmi->_aniMan->_statics->_staticsId == (ST_MAN_RIGHT|0x4000)) {
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT|0x4000);
chainQueue(QU_SC25_BACKTOTRUBA, 1);
}
}
void sceneHandler25_walkOnLadder(StaticANIObject *ani, Common::Point *pnt, MessageQueue *mq, int flag) {
int aniY = ani->_oy;
int newx = 0, newy = 0;
Common::Point point;
ExCommand *ex;
if (flag) {
if (ani->_movement) {
point = ani->_movement->calcSomeXY(0, ani->_movement->_currDynamicPhaseIndex);
newx = point.x;
aniY = ani->_oy - point.y;
}
}
int pntx = pnt->x;
int pnty = pnt->y;
int numObsolete = -1;
int minDistance = 20000;
ExCommand *lastEx = nullptr;
for (uint i = 0; i < mq->getCount(); i++) {
int curDistance = abs(pnty - aniY);
ex = mq->getExCommandByIndex(i);
if (ex->_messageKind == 1 && ani->_id == ex->_parentId) {
if (ex->_excFlags & 0x10000) {
if (ex->_messageNum == MV_MAN_TOLADDER)
ex->_messageNum = MV_MAN_TOLADDER2;
if (ex->_messageNum == MV_MAN_STARTLADDER)
ex->_messageNum = MV_MAN_STARTLADDER2;
if (ex->_messageNum == MV_MAN_GOLADDER)
ex->_messageNum = MV_MAN_GOLADDER2;
if (ex->_messageNum == MV_MAN_STOPLADDER)
ex->_messageNum = MV_MAN_STOPLADDER2;
}
if (curDistance < minDistance || numObsolete < 0) {
numObsolete = i;
minDistance = curDistance;
lastEx = ex;
newx = pntx;
newy = pnty;
}
point = ani->getMovementById(ex->_messageNum)->calcSomeXY(0, -1);
pntx += point.x;
pnty += point.y;
}
}
for (int i = 0; i < numObsolete; i++)
mq->deleteExCommandByIndex(0, 1);
ex = new ExCommand(ani->_id, 34, 256, 0, 0, 0, 1, 0, 0, 0);
ex->_z = 256;
ex->_messageNum = 0;
ex->_excFlags |= 3;
mq->addExCommandToEnd(ex);
if (flag && ani->_movement && ani->_movement->_id == mq->getExCommandByIndex(0)->_messageNum) {
mq->deleteExCommandByIndex(0, 1);
int movId = ani->_movement->_id;
int idx = ani->_movement->_currDynamicPhaseIndex;
ani->changeStatics2(ani->_movement->_staticsObj1->_staticsId);
ani->setOXY(newx, newy);
ani->startAnim(movId, mq->_id, -1);
ani->_movement->setDynamicPhaseIndex(idx);
} else {
if (!lastEx)
error("sceneHandler25_walkOnLadder(): Incorrect state. Please report this to sev");
ani->changeStatics2(ani->getMovementById(lastEx->_messageNum)->_staticsObj1->_staticsId);
ani->setOXY(newx, newy);
ani->restartMessageQueue(mq);
}
ani->_flags |= 0x100;
}
bool sceneHandler25_isOnLadder(ExCommand *cmd) {
if ((g_nmi->_aniMan->_movement && g_nmi->_aniMan->_movement->_id == MV_MAN_GOLADDERDOWN)
|| g_nmi->_aniMan->_statics->_staticsId == ST_MAN_GOLADDERD) {
Interaction *inter = getGameLoaderInteractionController()->getInteractionByObjectIds(PIC_SC25_LADDERDOWN, ANI_MAN, cmd->_param);
if (!inter)
return 0;
MessageQueue *mq = new MessageQueue(inter->_messageQueue, 0, 1);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(PIC_SC25_LADDERDOWN, 0);
Common::Point point;
point.x = inter->_xOffs + pic->_ox;
point.y = inter->_yOffs + pic->_oy;
mq->setFlags(mq->getFlags() | 1);
sceneHandler25_walkOnLadder(g_nmi->_aniMan, &point, mq, 0);
return true;
} else {
return false;
}
}
int sceneHandler25(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_SC25_STOPBEARDEDS:
sceneHandler25_stopBearders();
break;
case MSG_SC25_STARTBEARDEDS:
sceneHandler25_startBearders();
break;
case MSG_SC25_ENTERMAN:
sceneHandler25_enterMan();
break;
case MSG_SC25_ENTERTRUBA:
sceneHandler25_enterTruba();
break;
case MSG_SC25_TOLADDER:
sceneHandler25_toLadder();
break;
case MSG_BRD_TURN:
switch (g_nmi->_rnd.getRandomNumber(3)) {
case 0:
g_nmi->playSound(SND_25_025, 0);
break;
case 1:
g_nmi->playSound(SND_25_026, 0);
break;
case 2:
default:
g_nmi->playSound(SND_25_027, 0);
break;
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
int y = g_nmi->_aniMan2->_oy;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
if (!g_vars->scene25_waterIsPresent) {
if (y < g_nmi->_sceneRect.top + 200)
g_nmi->_currentScene->_y = y - 300 - g_nmi->_sceneRect.top;
if (y > g_nmi->_sceneRect.bottom - 200)
g_nmi->_currentScene->_y = y + 300 - g_nmi->_sceneRect.bottom;
}
}
if (g_vars->scene25_beardersAreThere) {
g_vars->scene25_beardersCounter++;
if (g_vars->scene25_beardersCounter >= 120)
sceneHandler25_animateBearders();
}
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
if (g_vars->scene25_waterIsPresent && !g_vars->scene25_water->_movement)
g_vars->scene25_water->startAnim(MV_WTR25_FLOW, 0, -1);
if (g_vars->scene25_dudeIsOnBoard && !g_nmi->_aniMan->_movement && g_vars->scene25_sneezeFlipper)
sceneHandler25_sneeze();
g_vars->scene25_sneezeFlipper = true;
if (g_vars->scene25_board->_flags & 4) {
if (!g_vars->scene25_board->_movement) {
if (g_vars->scene25_board->_statics->_staticsId & 0x4000)
g_vars->scene25_board->startAnim(rMV_BRD25_RIGHT, 0, -1);
else
g_vars->scene25_board->startAnim(MV_BRD25_RIGHT, 0, -1);
}
}
break;
case 29:
{
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (!g_vars->scene25_waterIsPresent) {
if ((picId == PIC_SC25_LADDERUP || picId == PIC_SC25_LADDERDOWN) && sceneHandler25_isOnLadder(cmd))
cmd->_messageKind = 0;
return 0;
}
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (ani) {
if (g_nmi->_aniMan != ani) {
if (g_nmi->_aniMan->isIdle()) {
if (!(g_nmi->_aniMan->_flags & 0x100)) {
if (ani->_id == ANI_WATER25) {
if (g_vars->scene25_dudeIsOnBoard) {
if (cmd->_param == ANI_INV_LOPAT) {
sceneHandler25_rowShovel();
return 0;
}
if (!cmd->_param) {
sceneHandler25_rowHand();
return 0;
}
} else {
if (cmd->_param == ANI_INV_BOARD) {
sceneHandler25_putBoard();
return 0;
}
if (!cmd->_param) {
sceneHandler25_tryWater();
return 0;
}
}
} else if (ani->_id == ANI_BOARD25) {
sceneHandler25_tryRow(cmd->_param);
return 0;
}
return 0;
}
}
}
}
if (picId == PIC_SC25_LADDERUP && sceneHandler25_isOnLadder(cmd))
cmd->_messageKind = 0;
if (!g_nmi->_aniMan->isIdle() || (g_nmi->_aniMan->_flags & 0x100))
return 0;
if (g_vars->scene25_dudeIsOnBoard) {
if (picId == PIC_SC25_RTRUBA && !cmd->_param) {
sceneHandler25_enterTruba();
return 0;
}
} else {
if (picId != PIC_SC25_RTRUBA) {
if (picId == PIC_SC25_LADDERUP && !cmd->_param)
sceneHandler25_ladderUp();
return 0;
}
if (!cmd->_param) {
sceneHandler25_backToPipe();
return 0;
}
}
if (g_vars->scene25_dudeIsOnBoard) {
if (picId != PIC_SC25_LADDERUP || cmd->_param)
return 0;
sceneHandler25_toLadder();
return 0;
}
if (picId == PIC_SC25_LADDERUP && !cmd->_param) {
sceneHandler25_ladderUp();
}
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,362 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene26_initScene(Scene *sc) {
g_vars->scene26_chhi = sc->getStaticANIObject1ById(ANI_CHHI, -1);
g_vars->scene26_drop = sc->getStaticANIObject1ById(ANI_DROP_26, -1);
g_vars->scene26_sockPic = sc->getPictureObjectById(PIC_SC26_SOCK, 0);
g_vars->scene26_sock = sc->getStaticANIObject1ById(ANI_SOCK_26, -1);
if (g_nmi->getObjectState(sO_Hatch_26) == g_nmi->getObjectEnumState(sO_Hatch_26, sO_WithSock)) {
g_nmi->setObjectState(sO_Hatch_26, g_nmi->getObjectEnumState(sO_Hatch_26, sO_Closed));
g_nmi->setObjectState(sO_Sock_26, g_nmi->getObjectEnumState(sO_Sock_26, sO_HangsOnPipe));
}
Interaction *inter = getGameLoaderInteractionController()->getInteractionByObjectIds(ANI_LUK26, ANI_MAN, ANI_INV_SOCK);
if (getGameLoaderInventory()->getCountItemsWithId(ANI_INV_VENT) == 0)
inter->_flags &= 0xFFFDFFFF;
else
inter->_flags |= 0x20000;
if (g_nmi->getObjectState(sO_Sock_26) == g_nmi->getObjectEnumState(sO_Sock_26, sO_HangsOnPipe))
g_vars->scene26_sockPic->_flags |= 4;
else
g_vars->scene26_sockPic->_flags &= 0xFFFB;
if (g_nmi->getObjectState(sO_Valve1_26) == g_nmi->getObjectEnumState(sO_Valve1_26, sO_Opened))
g_nmi->playSound(SND_26_018, 1);
}
int scene26_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_objectIdAtCursor != ANI_VENT || g_nmi->_cursorId != PIC_CSR_DEFAULT) {
if (g_nmi->_cursorId == PIC_CSR_ITN && g_nmi->_objectIdAtCursor == PIC_SC26_LTRUBA)
g_nmi->_cursorId = PIC_CSR_GOL;
// WORKAROUND: Fixing cursor
if (g_nmi->_objectIdAtCursor == PIC_SC26_LTRUBA &&
(g_nmi->_cursorId == PIC_CSR_GOU || g_nmi->_cursorId == PIC_CSR_GOD || g_nmi->_cursorId == PIC_CSR_GOR))
g_nmi->_cursorId = PIC_CSR_GOL;
} else {
g_nmi->_cursorId = PIC_CSR_ITN;
}
return g_nmi->_cursorId;
}
void sceneHandler26_updateDrop() {
if (g_nmi->getObjectState(sO_Valve5_26) == g_nmi->getObjectEnumState(sO_Valve5_26, sO_Closed))
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_vars->scene26_drop, 0);
else
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_vars->scene26_drop, 1);
}
void scene26_setupDrop(Scene *sc) {
sceneHandler26_updateDrop();
}
void sceneHandler26_showChi() {
g_vars->scene26_chhi->changeStatics2(ST_CHI_EMPTY);
chainQueue(QU_CHI_SHOW, 1);
}
void sceneHandler26_updatePool() {
if (g_nmi->getObjectState(sO_Valve1_26) == g_nmi->getObjectEnumState(sO_Valve1_26, sO_Opened))
g_nmi->setObjectState(sO_Pool, g_nmi->getObjectEnumState(sO_Pool, sO_Overfull));
else if (g_nmi->getObjectState(sO_Pool) == g_nmi->getObjectEnumState(sO_Pool, sO_Overfull))
g_nmi->setObjectState(sO_Pool, g_nmi->getObjectEnumState(sO_Pool, sO_Full));
if (g_nmi->getObjectState(sO_Valve2_26) == g_nmi->getObjectEnumState(sO_Valve2_26, sO_Opened)) {
if (g_nmi->getObjectState(sO_Pool) >= g_nmi->getObjectEnumState(sO_Pool, sO_Full))
g_nmi->setObjectState(sO_Pool, g_nmi->getObjectEnumState(sO_Pool, sO_HalfFull));
}
if (g_nmi->getObjectState(sO_Valve3_26) == g_nmi->getObjectEnumState(sO_Valve3_26, sO_Opened)) {
if (g_nmi->getObjectState(sO_Pool) >= g_nmi->getObjectEnumState(sO_Pool, sO_HalfFull))
g_nmi->setObjectState(sO_Pool, g_nmi->getObjectEnumState(sO_Pool, sO_Empty));
}
}
void sceneHandler26_hideChi() {
g_vars->scene26_chhi->changeStatics2(ST_CHI_NORM);
chainQueue(QU_CHI_HIDE, 1);
}
void sceneHandler26_testVent() {
if (!g_vars->scene26_activeVent)
return;
if (g_vars->scene26_activeVent->_odelay == 0) {
if (g_nmi->getObjectState(sO_Valve1_26) == g_nmi->getObjectEnumState(sO_Valve1_26, sO_Opened))
g_nmi->stopAllSoundInstances(SND_26_018);
else
g_nmi->playSound(SND_26_018, 1);
if (g_nmi->getObjectState(sO_Valve2_26) == g_nmi->getObjectEnumState(sO_Valve2_26, sO_Opened)) {
chainQueue(QU_SC26_AUTOCLOSE2, 0);
g_nmi->playSound(SND_26_020, 0);
}
if (g_nmi->getObjectState(sO_Valve3_26) == g_nmi->getObjectEnumState(sO_Valve3_26, sO_Opened)) {
chainQueue(QU_SC26_AUTOCLOSE3, 0);
g_nmi->playSound(SND_26_020, 0);
}
} else if (g_vars->scene26_activeVent->_odelay == 1) {
if (g_nmi->getObjectState(sO_Valve2_26) == g_nmi->getObjectEnumState(sO_Valve2_26, sO_Opened))
g_nmi->playSound(SND_26_020, 0);
else
g_nmi->playSound(SND_26_019, 0);
if (g_nmi->getObjectState(sO_Pool) == g_nmi->getObjectEnumState(sO_Pool, sO_Overfull)
|| g_nmi->getObjectState(sO_Pool) == g_nmi->getObjectEnumState(sO_Pool, sO_Full))
g_nmi->playSound(SND_26_003, 0);
if (g_nmi->getObjectState(sO_Valve1_26) == g_nmi->getObjectEnumState(sO_Valve1_26, sO_Opened)) {
g_nmi->stopAllSoundInstances(SND_26_018);
chainQueue(QU_SC26_AUTOCLOSE1, 0);
}
} else if (g_vars->scene26_activeVent->_odelay == 2) {
if (g_nmi->getObjectState(sO_Valve3_26) == g_nmi->getObjectEnumState(sO_Valve3_26, sO_Opened))
g_nmi->playSound(SND_26_020, 0);
else
g_nmi->playSound(SND_26_019, 0);
if (g_nmi->getObjectState(sO_Pool) == g_nmi->getObjectEnumState(sO_Pool, sO_Overfull)
|| g_nmi->getObjectState(sO_Pool) == g_nmi->getObjectEnumState(sO_Pool, sO_Full)
|| g_nmi->getObjectState(sO_Pool) == g_nmi->getObjectEnumState(sO_Pool, sO_HalfFull))
g_nmi->playSound(SND_26_003, 0);
if (g_nmi->getObjectState(sO_Valve1_26) == g_nmi->getObjectEnumState(sO_Valve1_26, sO_Opened)) {
g_nmi->stopAllSoundInstances(SND_26_018);
chainQueue(QU_SC26_AUTOCLOSE1, 0);
}
}
}
void sceneHandler26_showVent() {
if (g_vars->scene26_activeVent) {
int id = g_vars->scene26_activeVent->_statics->_staticsId;
if (id == ST_VNT26_UP2) {
g_vars->scene26_activeVent->changeStatics2(ST_VNT26_RIGHT2);
} else {
if (id != ST_VNT26_RIGHT2)
return;
g_vars->scene26_activeVent->changeStatics2(ST_VNT26_UP2);
}
g_vars->scene26_activeVent->show1(-1, -1, -1, 0);
}
}
void sceneHandler26_hideVent() {
if (g_vars->scene26_activeVent)
g_vars->scene26_activeVent->hide();
}
void sceneHandler26_animateVents(StaticANIObject *ani) {
int qId = 0;
switch (ani->_odelay) {
case 0:
if (g_nmi->getObjectState(sO_Valve1_26) == g_nmi->getObjectEnumState(sO_Valve1_26, sO_Closed)) {
qId = QU_SC26_OPEN1;
} else {
qId = QU_SC26_CLOSE1;
}
break;
case 1:
if (g_nmi->getObjectState(sO_Valve2_26) == g_nmi->getObjectEnumState(sO_Valve2_26, sO_Closed)) {
qId = QU_SC26_OPEN2;
} else {
qId = QU_SC26_CLOSE2;
}
break;
case 2:
if (g_nmi->getObjectState(sO_Valve3_26) == g_nmi->getObjectEnumState(sO_Valve3_26, sO_Closed)) {
qId = QU_SC26_OPEN3;
} else {
qId = QU_SC26_CLOSE3;
}
break;
case 3:
if (g_nmi->getObjectState(sO_Valve4_26) == g_nmi->getObjectEnumState(sO_Valve4_26, sO_Closed)) {
qId = QU_SC26_OPEN4;
} else {
qId = QU_SC26_CLOSE4;
}
break;
case 4:
if (g_nmi->getObjectState(sO_Valve5_26) == g_nmi->getObjectEnumState(sO_Valve5_26, sO_Closed)) {
qId = QU_SC26_OPEN5;
} else {
qId = QU_SC26_CLOSE5;
}
break;
default:
return;
}
if (qId) {
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(qId), 0, 0);
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
}
}
void sceneHandler26_clickVent(StaticANIObject *ani, ExCommand *cmd) {
if (ani->_odelay || g_nmi->getObjectState(sO_Hatch_26) != g_nmi->getObjectEnumState(sO_Hatch_26, sO_Opened)) {
if (g_nmi->_aniMan->isIdle() && !(g_nmi->_aniMan->_flags & 0x100)) {
g_vars->scene26_activeVent = ani;
int x = ani->_ox - 20;
int y = ani->_oy + 61;
if (abs(x - g_nmi->_aniMan->_ox) > 1 || abs(y - g_nmi->_aniMan->_oy) > 1 || g_nmi->_aniMan->_movement || g_nmi->_aniMan->_statics->_staticsId != ST_MAN_UP) {
MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, x, y, 1, ST_MAN_UP);
if (mq) {
ExCommand *ex = new ExCommand(0, 17, MSG_SC26_CLICKVENT, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 3;
ex->_param = ani->_odelay;
mq->addExCommandToEnd(ex);
postExCommand(g_nmi->_aniMan->_id, 2, x, y, 0, -1);
}
} else {
sceneHandler26_animateVents(ani);
}
}
}
cmd->_messageKind = 0;
}
int sceneHandler26(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_SC26_UPDATEDROP:
sceneHandler26_updateDrop();
break;
case MSG_SC26_SHOWCHI:
sceneHandler26_showChi();
break;
case MSG_SC26_UPDATEPOOL:
sceneHandler26_updatePool();
break;
case MSG_SC26_HIDECHI:
sceneHandler26_hideChi();
break;
case MSG_SC26_TESTVENT:
sceneHandler26_testVent();
break;
case MSG_SC26_SHOWVENT:
sceneHandler26_showVent();
break;
case MSG_SC26_CLICKVENT:
{
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_VENT, cmd->_param);
if (ani && ani->_id == ANI_VENT) {
sceneHandler26_clickVent(ani, cmd);
}
}
break;
case MSG_SC26_HIDEVENT:
sceneHandler26_hideVent();
break;
case 29:
{
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (ani && ani->_id == ANI_VENT) {
sceneHandler26_clickVent(ani, cmd);
}
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
}
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,705 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
#define DBG 0
namespace NGI {
struct Bat {
StaticANIObject *ani;
double power;
double angle;
double currX;
double currY;
double powerCos;
double powerSin;
};
void scene27_initScene(Scene *sc) {
g_vars->scene27_hitZone = sc->getPictureObjectById(PIC_SC27_HITZONE2, 0);
g_vars->scene27_driver = sc->getStaticANIObject1ById(ANI_VODILLA, -1);
g_vars->scene27_maid = sc->getStaticANIObject1ById(ANI_MAID, -1);
g_vars->scene27_batHandler = sc->getStaticANIObject1ById(ANI_BITAHANDLER, -1);
g_vars->scene27_balls.clear();
g_vars->scene27_bats.clear();
g_vars->scene27_var07.clear();
g_vars->scene27_driverHasVent = true;
g_vars->scene27_bat = sc->getStaticANIObject1ById(ANI_BITA, -1);
for (int i = 0; i < 4; i++) {
StaticANIObject *newbat = new StaticANIObject(g_vars->scene27_bat);
g_vars->scene27_balls.push_back(newbat);
sc->addStaticANIObject(newbat, 1);
}
g_vars->scene27_dudeIsAiming = false;
g_vars->scene27_maxPhaseReached = false;
g_vars->scene27_wipeIsNeeded = false;
g_vars->scene27_driverPushedButton = false;
g_vars->scene27_numLostBats = 0;
g_vars->scene27_knockCount = 0;
g_vars->scene27_launchPhase = 0;
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
if (g_nmi->getObjectState(sO_Maid) == g_nmi->getObjectEnumState(sO_Maid, sO_WithSwab)) {
g_vars->scene27_maid->changeStatics2(ST_MID_SWAB2);
} else if (g_nmi->getObjectState(sO_Maid) == g_nmi->getObjectEnumState(sO_Maid, sO_WithBroom)) {
g_vars->scene27_maid->changeStatics2(ST_MID_BROOM);
} else if (g_nmi->getObjectState(sO_Maid) == g_nmi->getObjectEnumState(sO_Maid, sO_WithSpade)) {
g_vars->scene27_maid->changeStatics2(ST_MID_SPADE);
}
g_nmi->_currentScene = oldsc;
g_nmi->setArcadeOverlay(PIC_CSR_ARCADE7);
}
int scene27_updateCursor() {
g_nmi->updateCursorCommon();
if (g_vars->scene27_dudeIsAiming) {
if (g_nmi->_cursorId != PIC_CSR_DEFAULT_INV && g_nmi->_cursorId != PIC_CSR_ITN_INV)
g_nmi->_cursorId = PIC_CSR_ARCADE7_D;
} else if (g_nmi->_objectIdAtCursor == ANI_MAN) {
if (g_vars->scene27_maxPhaseReached)
if (g_nmi->_cursorId == PIC_CSR_DEFAULT)
g_nmi->_cursorId = PIC_CSR_ITN;
}
return g_nmi->_cursorId;
}
void sceneHandler27_driverGiveVent() {
g_vars->scene27_driver->changeStatics2(ST_DRV_VENT);
g_vars->scene27_driver->startMQIfIdle(QU_DRV_GIVEVENT, 1);
g_vars->scene27_driverHasVent = false;
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 1);
}
void sceneHandler27_winArcade() {
if (g_nmi->getObjectState(sO_Driver) == g_nmi->getObjectEnumState(sO_Driver, sO_WithSteering)) {
g_vars->scene27_dudeIsAiming = false;
g_nmi->_aniMan->_callback2 = nullptr; // Really NULL
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT);
sceneHandler27_driverGiveVent();
}
}
void sceneHandler27_takeVent() {
if (g_nmi->getObjectState(sO_Maid) == g_nmi->getObjectEnumState(sO_Maid, sO_WithSwab)) {
if (g_vars->scene27_maid->isIdle()) {
if (g_vars->scene27_maid->_flags & 4) {
g_vars->scene27_maid->changeStatics2(ST_MID_SWAB2);
g_vars->scene27_maid->startMQIfIdle(QU_MID_CLEANVENT, 1);
}
}
}
}
void sceneHandler27_showNextBat() {
if (g_vars->scene27_bat) {
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC27_SHOWBET), 0, 1);
mq->setParamInt(-1, g_vars->scene27_bat->_odelay);
mq->chain(nullptr);
}
g_vars->scene27_batHandler->_priority = 1045;
}
int sceneHandler27_updateScreenCallback() {
int res;
res = g_nmi->drawArcadeOverlay(getGameLoaderInteractionController()->_flag24 == 0);
if (!res)
g_nmi->_updateScreenCallback = nullptr;
return res;
}
void sceneHandler27_aniManCallback(int *phase) {
if (!g_vars->scene27_maxPhaseReached) {
if (*phase >= 5)
g_vars->scene27_maxPhaseReached = true;
else
++*phase;
}
}
void sceneHandler27_throwBat() {
if (getGameLoaderInteractionController()->_flag24)
g_nmi->_updateScreenCallback = sceneHandler27_updateScreenCallback;
g_nmi->_aniMan->_callback2 = sceneHandler27_aniManCallback;
g_nmi->_aniMan->startAnim(MV_MAN27_THROWBET, 0, -1);
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 0);
g_vars->scene27_maxPhaseReached = false;
g_vars->scene27_bat->hide();
}
void sceneHandler27_clickBat(ExCommand *cmd) {
int bx = g_vars->scene27_bat->_ox - 5;
int by = g_vars->scene27_bat->_oy - 71;
#if DBG
sceneHandler27_throwBat();
return;
#endif
if (ABS(bx - g_nmi->_aniMan->_ox) > 1 || ABS(by - g_nmi->_aniMan->_oy) > 1
|| g_nmi->_aniMan->_movement || g_nmi->_aniMan->_statics->_staticsId != ST_MAN_RIGHT) {
MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, bx, by, 1, ST_MAN_RIGHT);
if (mq) {
mq->addExCommandToEnd(cmd->createClone());
postExCommand(g_nmi->_aniMan->_id, 2, bx, by, 0, -1);
}
} else {
sceneHandler27_throwBat();
}
}
void sceneHandler27_maidSwab() {
#if DBG
return;
#endif
if (g_nmi->getObjectState(sO_Maid) == g_nmi->getObjectEnumState(sO_Maid, sO_WithSwab))
g_vars->scene27_maid->changeStatics2(ST_MID_SWAB);
}
void sceneHandler27_startBat(StaticANIObject *bat) {
debugC(2, kDebugSceneLogic, "scene27: startBat");
Bat *newbat = new Bat;
newbat->power = g_vars->scene27_launchPhase * 2.5 + 8.0;
newbat->angle = 0;
newbat->ani = bat;
newbat->powerCos = newbat->power * cos(0.0);
newbat->powerSin = newbat->power * sin(0.0);
newbat->currX = newbat->powerCos + (double)g_nmi->_aniMan->_ox + 42.0;
newbat->currY = newbat->powerSin + (double)g_nmi->_aniMan->_oy + 58.0;
bat->_statics = bat->_staticsList[0];
bat->setOXY((int)newbat->currX, (int)newbat->currY);
bat->_flags |= 4;
g_vars->scene27_bats.push_back(newbat);
sceneHandler27_maidSwab();
}
void sceneHandler27_startAiming() {
g_vars->scene27_dudeIsAiming = false;
g_vars->scene27_maxPhaseReached = false;
g_nmi->_aniMan->_callback2 = nullptr; // Really NULL
g_vars->scene27_launchPhase = g_nmi->_aniMan->_movement->_currDynamicPhaseIndex - 6;
int phase = 21 - g_vars->scene27_launchPhase;
if (phase < 14)
phase = 14;
if (phase > 20)
phase = 20;
g_nmi->playSound(SND_27_044, 0);
g_nmi->_aniMan->_movement->setDynamicPhaseIndex(phase);
}
void sceneHandler27_initAiming(ExCommand *cmd) {
g_vars->scene27_aimStartX = cmd->_x;
g_vars->scene27_aimStartY = cmd->_y;
g_vars->scene27_dudeIsAiming = true;
g_vars->scene27_maxPhaseReached = false;
}
void sceneHandler27_aimDude() {
int phase = (g_vars->scene27_aimStartX - g_nmi->_mouseScreenPos.x) / 20 + 6;
if (phase < 6)
phase = 6;
if (phase > 11)
phase = 11;
if (g_nmi->_aniMan->_movement)
g_nmi->_aniMan->_movement->setDynamicPhaseIndex(phase);
}
void sceneHandler27_wipeDo() {
debugC(2, kDebugSceneLogic, "scene27: wipeDo");
for (uint i = 0; i < g_vars->scene27_bats.size(); i++) {
if (g_vars->scene27_bats[i]->currX < 800.0) {
g_vars->scene27_bats[i]->angle = atan2(520.0 - g_vars->scene27_bats[i]->currY, 800.0 - g_vars->scene27_bats[i]->currX);
g_vars->scene27_bats[i]->power += 1.0;
}
}
}
bool sceneHandler27_batFallLogic(uint batn) {
Bat *bat = g_vars->scene27_bats[batn];
int y = (int)((bat->currY - 458.0) * 0.4848484848484849 + 734.0);
if (y >= bat->currX)
return false;
if (bat->currX - y > 15.0 || bat->ani->_statics->_staticsId == ST_BTA_FALL) {
bat->ani->_priority = 2020;
g_vars->scene27_var07.push_back(bat);
if (batn != g_vars->scene27_bats.size() - 1)
g_vars->scene27_bats.remove_at(batn);
} else if (!bat->ani->_movement) {
bat->ani->startAnim(MV_BTA_FALL, 0, -1);
}
return true;
}
bool sceneHandler27_batCalcDistance(int bat1, int bat2) {
double at = atan2(g_vars->scene27_bats[bat1]->currY - g_vars->scene27_bats[bat2]->currY, g_vars->scene27_bats[bat1]->currX - g_vars->scene27_bats[bat2]->currX);
double dy = g_vars->scene27_bats[bat1]->currY - g_vars->scene27_bats[bat2]->currY;
double dx = g_vars->scene27_bats[bat1]->currX - g_vars->scene27_bats[bat2]->currX;
double ay = cos(at);
double ax = sin(at);
return sqrt(ax * ax * 0.25 + ay * ay) * 54.0 > sqrt(dx * dx + dy * dy);
}
void sceneHandler27_knockBats(int bat1n, int bat2n) {
Bat *bat1 = g_vars->scene27_bats[bat1n];
Bat *bat2 = g_vars->scene27_bats[bat2n];
debugC(2, kDebugSceneLogic, "scene27: knockBats(%d, %d)", bat1n, bat2n);
if (bat1->power != 0.0) {
double rndF = (double)g_nmi->_rnd.getRandomNumber(32767) * 0.03 / 32767.0 - 0.015
+ atan2(bat2->currY - bat1->currY, bat2->currX - bat1->currX);
double pow1x = cos(bat1->angle - rndF) * ((bat2->currX - bat1->currX) >= 0 ? bat1->power : -bat1->power);
double pow1y = sin(bat1->angle - rndF) * ((bat2->currY - bat1->currY) >= 0 ? bat1->power : -bat1->power);
debugC(3, kDebugSceneLogic, "scene27: knockBats: bat1 from: powerCos: %f powerSin: %f, power: %f, angle: %f",
bat1->powerCos, bat1->powerSin, bat1->power, bat1->angle);
bat1->powerCos -= pow1x * 1.1;
bat1->powerSin -= pow1y * 1.1;
debugC(3, kDebugSceneLogic, "scene27: knockBats: bat1 to: powerCos: %f powerSin: %f", bat1->powerCos, bat1->powerSin);
double rndF2 = (double)g_nmi->_rnd.getRandomNumber(32767) * 0.03 / 32767.0 - 0.015
+ atan2(bat1->currY - bat2->currY, bat1->currX - bat2->currX);
double pow2x = cos(bat2->angle - rndF2) * ((bat1->currX - bat2->currX) >= 0 ? bat2->power : -bat2->power);
double pow2y = sin(bat2->angle - rndF2) * ((bat1->currY - bat2->currY) >= 0 ? bat2->power : -bat2->power);
debugC(3, kDebugSceneLogic, "scene27: knockBats: bat2 from: powerCos: %f powerSin: %f, power: %f, angle: %f",
bat2->powerCos, bat2->powerSin, bat2->power, bat2->angle);
bat2->powerCos -= pow2x * 1.1;
bat2->powerSin -= pow2y * 1.1;
debugC(3, kDebugSceneLogic, "scene27: knockBats: bat2 to: powerCos: %f powerSin: %f", bat2->powerCos, bat2->powerSin);
double rndCos = cos(rndF);
double rndSin = sin(rndF);
double dy = bat1->currY - bat2->currY;
double dx = bat1->currX - bat2->currX;
double dist = (sqrt(rndSin * rndSin * 0.25 + rndCos * rndCos) * 54.0 - sqrt(dx * dx + dy * dy)) / cos(rndF - bat1->angle);
bat1->currX = bat1->currX - cos(bat1->angle) * (dist + 1.0);
bat1->currY = bat1->currY - sin(bat1->angle) * (dist + 1.0);
bat1->powerCos += pow2x * 0.64;
debugC(3, kDebugSceneLogic, "scene27: knockBats: bat1 x: %g y: %g", bat1->currX, bat1->currY);
if (bat1->currX <= 500.0)
bat1->powerSin = 0.0;
else
bat1->powerSin += pow2y * 0.64;
bat1->angle = atan2(bat1->powerSin, bat1->powerCos);
bat1->power = sqrt(bat1->powerCos * bat1->powerCos + bat1->powerSin * bat1->powerSin);
debugC(3, kDebugSceneLogic, "scene27: knockBats: bat1 corrected: powerCos: %f powerSin: %f, power: %f, angle: %f",
bat1->powerCos, bat1->powerSin, bat1->power, bat1->angle);
bat2->powerCos += pow1x * 0.64;
if (bat2->currX <= 500.0)
bat2->powerSin = 0.0;
else
bat2->powerSin += pow1y * 0.64;
bat2->angle = atan2(bat2->powerSin, bat2->powerCos);
bat2->power = sqrt(bat2->powerCos * bat2->powerCos + bat2->powerSin * bat2->powerSin);
debugC(3, kDebugSceneLogic, "scene27: knockBats: bat2 corrected: powerCos: %f powerSin: %f, power: %f, angle: %f",
bat2->powerCos, bat2->powerSin, bat2->power, bat2->angle);
g_nmi->playSound(SND_27_026, 0);
}
}
void sceneHandler27_batSetColors(int batn) {
Bat *bat = g_vars->scene27_bats[batn];
if (g_vars->scene27_hitZone->isPixelHitAtPos((int)bat->currX, (int)bat->currY) ) {
if (bat->ani->_statics->_staticsId == ST_BTA_NORM) {
if (!bat->ani->_movement)
bat->ani->_statics = bat->ani->getStaticsById(ST_BTA_HILITE);
}
} else {
if (bat->ani->_statics->_staticsId == ST_BTA_HILITE) {
if (!bat->ani->_movement)
bat->ani->_statics = bat->ani->getStaticsById(ST_BTA_NORM);
}
}
}
void sceneHandler27_driverPushButton() {
debugC(2, kDebugSceneLogic, "scene27: driverPushButton");
if (g_nmi->getObjectState(sO_Driver) == g_nmi->getObjectEnumState(sO_Driver, sO_WithSteering)) {
g_vars->scene27_driver->changeStatics2(ST_DRV_VENT);
chainQueue(QU_DRV_PUSHBUTTON, 1);
g_vars->scene27_driverPushedButton = true;
} else {
g_vars->scene27_driver->changeStatics2(ST_DRV_SITNOVENT);
chainQueue(QU_DRV_PUSHBUTTON_NOVENT, 1);
g_vars->scene27_driverPushedButton = true;
}
}
void sceneHandler27_maidSwitchback() {
#ifndef DBG
if (g_nmi->getObjectState(sO_Maid) == g_nmi->getObjectEnumState(sO_Maid, sO_WithSwab)) {
g_vars->scene27_maid->changeStatics2(ST_MID_SWAB);
g_vars->scene27_maid->startMQIfIdle(QU_MID_SWITCHBACK, 1);
}
#endif
}
void sceneHandler27_batLogic() {
if (g_vars->scene27_balls.size()) {
g_vars->scene27_bat = g_vars->scene27_balls[0];
g_vars->scene27_balls.remove_at(0);
int mv;
switch (g_vars->scene27_batHandler->_statics->_staticsId) {
case ST_BTH_5:
mv = MV_BTH_5_4;
break;
case ST_BTH_4:
mv = MV_BTH_4_3;
break;
case ST_BTH_3:
mv = MV_BTH_3_2;
break;
case ST_BTH_2:
mv = MV_BTH_2_1;
break;
case ST_BTH_1:
mv = MV_BTH_1_0;
break;
default:
chainQueue(QU_SC27_RESTARTBETS, 1);
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 1);
return;
}
MessageQueue *mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
mq->setFlags(mq->getFlags() | 1);
ExCommand *ex = new ExCommand(g_vars->scene27_batHandler->_id, 1, mv, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
ex = new ExCommand(0, 17, MSG_SC27_CLICKBET, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 3;
mq->addExCommandToEnd(ex);
mq->chain(nullptr);
} else {
g_vars->scene27_bat = nullptr;
}
}
void sceneHandler27_calcWinArcade() {
if (!g_vars->scene27_wipeIsNeeded && !g_vars->scene27_driverPushedButton) {
int numHilite = 0;
for (uint i = 0; i < g_vars->scene27_bats.size(); i++) {
if (g_vars->scene27_bats[i]->ani->_statics->_staticsId == ST_BTA_HILITE)
numHilite++;
}
if (numHilite >= 3) {
if (g_nmi->getObjectState(sO_Driver) == g_nmi->getObjectEnumState(sO_Driver, sO_WithSteering)) {
sceneHandler27_driverGiveVent();
sceneHandler27_maidSwitchback();
return;
}
}
if (!g_vars->scene27_balls.size()) {
sceneHandler27_driverPushButton();
sceneHandler27_maidSwitchback();
return;
}
sceneHandler27_batLogic();
}
sceneHandler27_maidSwitchback();
}
void sceneHandler27_regenBats() {
debugC(2, kDebugSceneLogic, "scene27: regenBats");
g_vars->scene27_wipeIsNeeded = false;
for (uint i = 0; i < g_vars->scene27_var07.size(); i++) {
g_vars->scene27_var07[i]->ani->hide();
StaticANIObject *newbat = g_vars->scene27_var07[i]->ani;
g_vars->scene27_balls.push_back(newbat);
}
g_vars->scene27_var07.clear();
sceneHandler27_batLogic();
g_vars->scene27_driverPushedButton = false;
}
void sceneHandler27_animateBats() {
int oldCount = g_vars->scene27_knockCount;
g_vars->scene27_numLostBats = 0;
g_vars->scene27_knockCount = 0;
for (uint i = 0; i < g_vars->scene27_bats.size(); i++) {
Bat *bat = g_vars->scene27_bats[i];
bat->currX = cos(bat->angle) * bat->power + bat->currX;
bat->currY = sin(bat->angle) * bat->power + bat->currY;
bat->ani->setOXY((int)bat->currX, (int)bat->currY);
bat->ani->_priority = (int)(600.0 - bat->currY);
double powerDelta;
if (cos(bat->angle) >= 0.0 || bat->currX >= 362.0)
powerDelta = bat->power * 0.035;
else
powerDelta = bat->power * 0.4;
bat->power -= powerDelta;
bat->powerCos = cos(bat->angle) * bat->power;
bat->powerSin = sin(bat->angle) * bat->power;
if (bat->power >= 0.5)
g_vars->scene27_knockCount++;
else
bat->power = 0;
sceneHandler27_batSetColors(i);
if (!sceneHandler27_batFallLogic(i) && !g_vars->scene27_wipeIsNeeded) {
for (uint j = 0; j < g_vars->scene27_bats.size(); j++) {
if (i != j && sceneHandler27_batCalcDistance(i, j))
sceneHandler27_knockBats(i, j);
}
}
}
for (uint i = 0; i < g_vars->scene27_var07.size(); i++) {
Bat *bat = g_vars->scene27_var07[i];
if (bat->currY >= 700.0) {
g_vars->scene27_numLostBats++;
} else {
bat->currX = bat->powerCos + bat->currX;
bat->currY = bat->powerSin + bat->currY;
bat->ani->setOXY((int)bat->currX, (int)bat->currY);
bat->powerSin = bat->powerSin + 1.0;
}
}
if (oldCount != g_vars->scene27_knockCount && !g_vars->scene27_knockCount)
sceneHandler27_calcWinArcade();
if (g_vars->scene27_wipeIsNeeded) {
if (g_vars->scene27_numLostBats == 5)
sceneHandler27_regenBats();
}
}
int sceneHandler27(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_CMN_WINARCADE:
sceneHandler27_winArcade();
break;
case MSG_SC27_TAKEVENT:
sceneHandler27_takeVent();
break;
case MSG_SC27_SHOWNEXTBET:
sceneHandler27_showNextBat();
break;
case MSG_SC27_HANDLERTOFRONT:
g_vars->scene27_batHandler->_priority = 1005;
break;
case MSG_SC27_STARTWIPE:
debugC(2, kDebugSceneLogic, "scene27: STARTWIPE");
g_vars->scene27_wipeIsNeeded = true;
g_nmi->playSound(SND_27_027, 0);
break;
case MSG_SC27_CLICKBET:
sceneHandler27_clickBat(cmd);
break;
case MSG_SC27_STARTBET:
if (g_vars->scene27_bat) {
sceneHandler27_startBat(g_vars->scene27_bat);
}
break;
case 30:
if (g_vars->scene27_dudeIsAiming) {
sceneHandler27_startAiming();
}
break;
case 29:
if (g_nmi->_aniMan == g_nmi->_currentScene->getStaticANIObjectAtPos(g_nmi->_sceneRect.left + cmd->_x, g_nmi->_sceneRect.top + cmd->_y) && g_vars->scene27_maxPhaseReached) {
sceneHandler27_initAiming(cmd);
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
}
if (g_vars->scene27_dudeIsAiming)
sceneHandler27_aimDude();
if (g_vars->scene27_wipeIsNeeded) {
sceneHandler27_wipeDo();
if (!g_nmi->_aniMan->_movement && g_nmi->_aniMan->_statics->_staticsId == ST_MAN_RIGHT)
g_nmi->_aniMan->startAnim(MV_MAN27_FLOW, 0, -1);
}
sceneHandler27_animateBats();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,486 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
#include "ngi/floaters.h"
namespace NGI {
void scene28_initScene(Scene *sc) {
g_vars->scene28_fliesArePresent = true;
g_vars->scene28_beardedDirection = true;
g_vars->scene28_darkeningObject = nullptr;
g_vars->scene28_lighteningObject = nullptr;
g_vars->scene28_headDirection = false;
g_vars->scene28_headBeardedFlipper = false;
g_vars->scene28_lift6inside = false;
g_nmi->_floaters->init(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_28"));
g_nmi->initArcadeKeys("SC_28");
}
int scene28_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_objectIdAtCursor == ANI_LIFT || g_nmi->_objectIdAtCursor == ANI_LIFT_28)
if (g_nmi->_cursorId == PIC_CSR_DEFAULT)
g_nmi->_cursorId = PIC_CSR_ITN;
return g_nmi->_cursorId;
}
void sceneHandler28_lift1ShowAfter() {
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_MAN_28, -1);
g_nmi->_aniMan->_statics = g_nmi->_aniMan->getStaticsById(ST_MAN_SIT|0x4000);
g_nmi->_aniMan->setOXY(ani->_ox + 7, ani->_oy);
g_nmi->_aniMan->_priority = ani->_priority;
g_nmi->_aniMan->show1(-1, -1, -1, 0);
}
void sceneHandler28_makeFaces(ExCommand *cmd) {
g_nmi->_currentScene->getPictureObjectById(PIC_SC28_DARK4, 0)->_flags &= 0xFFFB;
g_vars->scene28_lighteningObject = nullptr;
MessageQueue *mq = g_nmi->_globalMessageQueueList->getMessageQueueById(cmd->_parId);
if (mq) {
int frames[5];
frames[0] = MV_WMN28_IN_1;
frames[1] = MV_WMN28_IN_2;
frames[2] = MV_WMN28_IN_3;
frames[3] = MV_WMN28_IN_4;
frames[4] = MV_WMN28_IN_5;
for (int i = 0; i < 5; i++) {
int pos;
while (frames[pos = g_nmi->_rnd.getRandomNumber(4)] == 0)
;
mq->getExCommandByIndex(i)->_messageNum = frames[pos];
frames[pos] = 0;
}
}
}
void sceneHandler28_trySecondaryPers() {
MessageQueue *mq;
int x;
if (g_vars->scene28_headBeardedFlipper) {
if (g_vars->scene28_beardedDirection) {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_BRD28_GOR), 0, 1);
mq->getExCommandByIndex(0)->_x = g_nmi->_sceneRect.left - 20;
mq->getExCommandByIndex(0)->_param = 1;
mq->setParamInt(-1, 1);
mq->chain(nullptr);
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_BRD28_GOR), 0, 1);
mq->getExCommandByIndex(0)->_x = g_nmi->_sceneRect.left - 40;
mq->getExCommandByIndex(0)->_y += 20;
mq->getExCommandByIndex(0)->_param = 2;
mq->setParamInt(-1, 2);
mq->chain(nullptr);
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_BRD28_GOR), 0, 1);
x = g_nmi->_sceneRect.left - 60;
} else {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_BRD28_GOL), 0, 1);
mq->getExCommandByIndex(0)->_x = g_nmi->_sceneRect.right + 20;
mq->getExCommandByIndex(0)->_param = 1;
mq->setParamInt(-1, 1);
mq->chain(nullptr);
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_BRD28_GOL), 0, 1);
mq->getExCommandByIndex(0)->_x = g_nmi->_sceneRect.right + 40;
mq->getExCommandByIndex(0)->_y += 20;
mq->getExCommandByIndex(0)->_param = 2;
mq->setParamInt(-1, 2);
mq->chain(nullptr);
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_BRD28_GOL), 0, 1);
x = g_nmi->_sceneRect.right + 60;
}
mq->getExCommandByIndex(0)->_x = x;
mq->getExCommandByIndex(0)->_y += 40;
mq->getExCommandByIndex(0)->_param = 3;
mq->setParamInt(-1, 3);
mq->chain( nullptr);
g_vars->scene28_beardedDirection = !g_vars->scene28_beardedDirection;
} else {
if (g_vars->scene28_headDirection) {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_GLV28_GOR), 0, 1);
x = g_nmi->_sceneRect.left - 40;
} else {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_GLV28_GOL), 0, 1);
x = g_nmi->_sceneRect.right + 40;
}
mq->getExCommandByIndex(0)->_x = x;
mq->chain(nullptr);
g_vars->scene28_headDirection = !g_vars->scene28_headDirection;
}
g_vars->scene28_headBeardedFlipper = !g_vars->scene28_headBeardedFlipper;
}
void sceneHandler28_turnOn2() {
if (g_vars->scene28_fliesArePresent) {
g_nmi->_floaters->genFlies(g_nmi->_currentScene, 1013, 329, 60, 4);
g_nmi->_floaters->_array2[g_nmi->_floaters->_array2.size() - 1].val13 = 30;
g_nmi->_floaters->_array2[g_nmi->_floaters->_array2.size() - 1].countdown = g_nmi->_rnd.getRandomNumber(12) + 12;
g_nmi->_floaters->genFlies(g_nmi->_currentScene, 1074, 311, 60, 4);
g_nmi->_floaters->_array2[g_nmi->_floaters->_array2.size() - 1].val13 = 30;
g_nmi->_floaters->_array2[g_nmi->_floaters->_array2.size() - 1].countdown = g_nmi->_rnd.getRandomNumber(12) + 12;
}
g_vars->scene28_fliesArePresent = false;
}
void sceneHandler28_startWork1() {
debugC(2, kDebugSceneLogic, "scene28: startWork");
g_nmi->_aniMan->hide();
StaticANIObject *man = g_nmi->_currentScene->getStaticANIObject1ById(ANI_MAN_28, -1);
man->_statics = man->getStaticsById(ST_MAN28_RIGHT);
man->setOXY(g_nmi->_aniMan->_ox, g_nmi->_aniMan->_oy);
man->_priority = g_nmi->_aniMan->_priority;
man->show1(-1, -1, -1, 0);
chainQueue(QU_SC28_LIFT1_WORK, 1);
}
void sceneHandler28_lift0Start() {
chainQueue(QU_SC28_LIFT0_START, 1);
}
void sceneHandler28_lift1Start() {
g_nmi->_aniMan->_flags |= 0x100;
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 0);
chainQueue(QU_SC28_LIFT1_START, 1);
}
void sceneHandler28_lift2Start() {
chainQueue(QU_SC28_LIFT2_START, 1);
}
void sceneHandler28_lift3Start() {
chainQueue(QU_SC28_LIFT3_START, 1);
}
void sceneHandler28_lift4Start() {
g_nmi->_aniMan->_flags |= 0x100;
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 0);
chainQueue(QU_SC28_WMN_START, 1);
}
void sceneHandler28_lift5Start() {
chainQueue(QU_SC28_LIFT5_START, 1);
}
void sceneHandler28_lift6Start() {
g_nmi->_aniMan->_flags |= 0x100;
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 0);
StaticANIObject *woman = g_nmi->_currentScene->getStaticANIObject1ById(ANI_TIOTIA, -1);
if (woman && (woman->_flags & 4))
chainQueue(QU_SC28_LIFT6_START2, 1);
else
chainQueue(QU_SC28_LIFT6_START, 1);
}
void sceneHandler28_clickLift(int numLift) {
int x = 0;
debugC(2, kDebugSceneLogic, "scene28: clickLift(%d)", numLift);
switch (numLift) {
case 0: x = 600; break;
case 1: x = 824; break;
case 2: x = 1055; break;
case 3: x = 1286; break;
case 4: x = 1517; break;
case 5: x = 1748; break;
case 6: x = 1979; break;
default: break;
}
if (abs(x - g_nmi->_aniMan->_ox) > 1 || abs(472 - g_nmi->_aniMan->_oy) > 1
|| g_nmi->_aniMan->_movement
|| g_nmi->_aniMan->_statics->_staticsId != ST_MAN_UP) {
debugC(2, kDebugSceneLogic, "scene28: clickLift: overwrite");
MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, x, 472, 1, ST_MAN_UP);
if (mq) {
ExCommand *ex = new ExCommand(0, 17, MSG_SC28_CLICKLIFT, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 3;
ex->_param = numLift;
mq->addExCommandToEnd(ex);
postExCommand(g_nmi->_aniMan->_id, 2, x, 472, 0, -1);
}
} else {
switch (numLift) {
case 0:
sceneHandler28_lift0Start();
break;
case 1:
sceneHandler28_lift1Start();
break;
case 2:
sceneHandler28_lift2Start();
break;
case 3:
sceneHandler28_lift3Start();
break;
case 4:
sceneHandler28_lift4Start();
break;
case 5:
sceneHandler28_lift5Start();
break;
case 6:
sceneHandler28_lift6Start();
break;
default:
break;
}
}
}
int sceneHandler28(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_SC28_LIFT6MUSIC:
g_nmi->playTrack(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_28"), "MUSIC_TIOTIA", 1);
break;
case MSG_SC28_LIFT6INSIDE:
g_vars->scene28_lift6inside = true;
break;
case MSG_SC28_LIFT1_SHOWAFTER:
sceneHandler28_lift1ShowAfter();
break;
case MSG_SC28_MAKEFACES:
sceneHandler28_makeFaces(cmd);
break;
case MSG_SC28_TRYVTORPERS:
sceneHandler28_trySecondaryPers();
break;
case MSG_SC28_TURNOFF_0:
g_vars->scene28_lighteningObject = g_nmi->_currentScene->getPictureObjectById(PIC_SC28_DARK0, 0);
g_vars->scene28_lighteningObject->_flags |= 4;
break;
case MSG_SC28_TURNON_0:
g_vars->scene28_darkeningObject = g_nmi->_currentScene->getPictureObjectById(PIC_SC28_DARK0, 0);
break;
case MSG_SC28_TURNON_1:
g_vars->scene28_darkeningObject = g_nmi->_currentScene->getPictureObjectById(PIC_SC28_DARK1, 0);
break;
case MSG_SC28_TURNOFF_1:
g_vars->scene28_lighteningObject = g_nmi->_currentScene->getPictureObjectById(PIC_SC28_DARK1, 0);
g_vars->scene28_lighteningObject->_flags |= 4;
break;
case MSG_SC28_TURNON_2:
g_vars->scene28_darkeningObject = g_nmi->_currentScene->getPictureObjectById(PIC_SC28_DARK2, 0);
sceneHandler28_turnOn2();
break;
case MSG_SC28_TURNOFF_2:
g_vars->scene28_lighteningObject = g_nmi->_currentScene->getPictureObjectById(PIC_SC28_DARK2, 0);
g_vars->scene28_lighteningObject->_flags |= 4;
break;
case MSG_SC28_TURNON_3:
g_vars->scene28_darkeningObject = g_nmi->_currentScene->getPictureObjectById(PIC_SC28_DARK3, 0);
break;
case MSG_SC28_TURNOFF_3:
g_vars->scene28_lighteningObject = g_nmi->_currentScene->getPictureObjectById(PIC_SC28_DARK3, 0);
g_vars->scene28_lighteningObject->_flags |= 4;
break;
case MSG_SC28_TURNON_4:
g_vars->scene28_darkeningObject = g_nmi->_currentScene->getPictureObjectById(PIC_SC28_DARK4, 0);
break;
case MSG_SC28_TURNOFF_4:
g_vars->scene28_lighteningObject = g_nmi->_currentScene->getPictureObjectById(PIC_SC28_DARK4, 0);
g_vars->scene28_lighteningObject->_flags |= 4;
break;
case MSG_SC28_TURNON_6:
g_vars->scene28_darkeningObject = g_nmi->_currentScene->getPictureObjectById(PIC_SC28_DARK6, 0);
break;
case MSG_SC28_TURNOFF_6:
g_vars->scene28_lighteningObject = g_nmi->_currentScene->getPictureObjectById(PIC_SC28_DARK6, 0);
g_vars->scene28_lighteningObject->_flags |= 4;
break;
case MSG_SC28_STARTWORK1:
sceneHandler28_startWork1();
break;
case MSG_SC28_CLICKLIFT:
sceneHandler28_clickLift(cmd->_param);
break;
case MSG_SC28_ENDLIFT1:
case MSG_SC28_ENDLIFT6:
case MSG_SC28_ENDCABIN:
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 1);
g_nmi->_aniMan->_flags &= 0xFEFF;
break;
case 29:
{
if (g_vars->scene28_lift6inside) {
chainObjQueue(g_nmi->_aniMan, QU_SC28_LIFT6_END, 1);
g_nmi->playTrack(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_28"), "MUSIC", 1);
g_vars->scene28_lift6inside = false;
}
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (ani)
if (ani->_id == ANI_LIFT || ani->_id == ANI_LIFT_28 ) {
sceneHandler28_clickLift(ani->_odelay);
cmd->_messageKind = 0;
break;
}
if (!ani || !canInteractAny(g_nmi->_aniMan, ani, cmd->_param)) {
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picId, 0);
if (!pic || !canInteractAny(g_nmi->_aniMan, pic, cmd->_param)) {
if ((g_nmi->_sceneRect.right - cmd->_sceneClickX < 47 && g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1)
|| (cmd->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0))
g_nmi->processArcade(cmd);
}
}
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
g_nmi->sceneAutoScrolling();
}
if (g_vars->scene28_darkeningObject) {
if (g_vars->scene28_darkeningObject->_picture->getAlpha() > 10) {
g_vars->scene28_darkeningObject->_picture->setAlpha(g_vars->scene28_darkeningObject->_picture->getAlpha() - 10);
} else {
g_vars->scene28_darkeningObject->_flags &= 0xFFFB;
g_vars->scene28_darkeningObject = nullptr;
}
}
if (g_vars->scene28_lighteningObject) {
if (g_vars->scene28_lighteningObject->_picture->getAlpha() < 0xF9u) {
g_vars->scene28_lighteningObject->_picture->setAlpha(g_vars->scene28_lighteningObject->_picture->getAlpha() + 6);
} else {
g_vars->scene28_lighteningObject->_picture->setAlpha(0xff);
g_vars->scene28_lighteningObject = nullptr;
}
}
g_nmi->_floaters->update();
for (uint i = 0; i < g_nmi->_floaters->_array2.size(); i++)
if (g_nmi->_floaters->_array2[i].val13 == 1)
g_nmi->_floaters->_array2[i].ani->_priority = 15;
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,850 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
#define DEBUG 0
namespace NGI {
struct WalkingBearder {
StaticANIObject *ani;
int wbflag;
int wbcounter;
};
void scene29_initScene(Scene *sc) {
g_vars->scene29_porter = sc->getStaticANIObject1ById(ANI_PORTER, -1);
g_vars->scene29_shooter1 = sc->getStaticANIObject1ById(ANI_SHOOTER1, -1);
g_vars->scene29_shooter2 = sc->getStaticANIObject1ById(ANI_SHOOTER2, -1);
g_vars->scene29_ass = sc->getStaticANIObject1ById(ANI_ASS, -1);
g_vars->scene29_greenBalls.clear();
g_vars->scene29_flyingGreenBalls.clear();
StaticANIObject *ani = sc->getStaticANIObject1ById(ANI_SHELL_GREEN, -1);
g_vars->scene29_greenBalls.push_back(ani);
for (int i = 0; i < 2; i++) {
StaticANIObject *newani = new StaticANIObject(ani);
sc->addStaticANIObject(newani, 1);
g_vars->scene29_greenBalls.push_back(newani);
}
g_vars->scene29_redBalls.clear();
g_vars->scene29_flyingRedBalls.clear();
ani = sc->getStaticANIObject1ById(ANI_SHELL_RED, -1);
g_vars->scene29_redBalls.push_back(ani);
for (int i = 0; i < 2; i++) {
StaticANIObject *newani = new StaticANIObject(ani);
sc->addStaticANIObject(newani, 1);
g_vars->scene29_redBalls.push_back(newani);
}
g_vars->scene29_bearders.clear();
ani = new StaticANIObject(g_nmi->accessScene(SC_COMMON)->getStaticANIObject1ById(ANI_BEARDED_CMN, -1));
ani->_statics = ani->getStaticsById(ST_BRDCMN_EMPTY);
sc->addStaticANIObject(ani, 1);
WalkingBearder *wb = new WalkingBearder;
wb->ani = ani;
wb->wbflag = 0;
wb->wbcounter = 0;
g_vars->scene29_bearders.push_back(wb);
g_vars->scene29_manIsRiding = false;
g_vars->scene29_arcadeIsOn = false;
g_vars->scene29_reachedFarRight = false;
g_vars->scene29_rideBackEnabled = false;
g_vars->scene29_shootCountdown = 0;
g_vars->scene29_shootDistance = 75;
g_vars->scene29_manIsHit = false;
g_vars->scene29_scrollSpeed = 0;
g_vars->scene29_scrollingDisabled = false;
g_vars->scene29_hitBall = 0;
g_nmi->setArcadeOverlay(PIC_CSR_ARCADE8);
}
void sceneHandler29_winArcade() {
if (g_vars->scene29_shooter2->_flags & 4) {
g_vars->scene29_shootCountdown = 0;
g_vars->scene29_shooter1->changeStatics2(ST_STR1_STAND);
g_vars->scene29_shooter2->changeStatics2(ST_STR2_STAND);
g_vars->scene29_shooter2->_flags &= 0xFFFB;
StaticANIObject *ani;
while (g_vars->scene29_flyingGreenBalls.size()) {
ani = g_vars->scene29_flyingGreenBalls.front();
g_vars->scene29_flyingGreenBalls.remove_at(0);
g_vars->scene29_greenBalls.push_back(ani);
ani->hide();
}
while (g_vars->scene29_flyingRedBalls.size()) {
ani = g_vars->scene29_flyingRedBalls.front();
g_vars->scene29_flyingRedBalls.remove_at(0);
g_vars->scene29_redBalls.push_back(ani);
ani->hide();
}
g_vars->scene29_ass->queueMessageQueue(nullptr);
g_vars->scene29_ass->_flags &= 0xFFFB;
chainQueue(QU_SC29_ESCAPE, 1);
}
g_nmi->setObjectState(sO_LeftPipe_29, g_nmi->getObjectEnumState(sO_LeftPipe_29, sO_IsOpened));
}
void sceneHandler29_shootGreen() {
if (g_vars->scene29_greenBalls.size()) {
int x = g_vars->scene29_shooter1->_ox - 113;
int y = g_vars->scene29_shooter1->_oy - 48;
StaticANIObject *ani = g_vars->scene29_greenBalls.front();
g_vars->scene29_greenBalls.remove_at(0);
ani->show1(x, y, MV_SHG_NORM, 0);
ani->_priority = 5;
g_vars->scene29_flyingGreenBalls.push_back(ani);
}
}
void sceneHandler29_shootRed() {
if (g_vars->scene29_redBalls.size()) {
int x = g_vars->scene29_shooter1->_ox - 101;
int y = g_vars->scene29_shooter1->_oy - 14;
StaticANIObject *ani = g_vars->scene29_redBalls.front();
g_vars->scene29_redBalls.remove_at(0);
ani->show1(x, y, MV_SHR_NORM, 0);
ani->_priority = 5;
g_vars->scene29_flyingRedBalls.push_back(ani);
}
}
void sceneHandler29_manJump() {
if (!g_nmi->_aniMan->_movement || g_nmi->_aniMan->_movement->_id == MV_MAN29_RUN || g_nmi->_aniMan->_movement->_id == MV_MAN29_STANDUP) {
g_vars->scene29_rideBackEnabled = false;
g_vars->scene29_manIsHit = false;
g_vars->scene29_reachedFarRight = true;
g_nmi->_aniMan->changeStatics2(ST_MAN29_RUNR);
g_nmi->_aniMan->startAnim(MV_MAN29_JUMP, 0, -1);
}
g_vars->scene29_manX = g_nmi->_aniMan->_ox;
g_vars->scene29_manY = g_nmi->_aniMan->_oy;
}
void sceneHandler29_manBend() {
if (!g_nmi->_aniMan->_movement || g_nmi->_aniMan->_movement->_id == MV_MAN29_RUN || g_nmi->_aniMan->_movement->_id == MV_MAN29_STANDUP) {
g_vars->scene29_rideBackEnabled = false;
g_vars->scene29_manIsHit = false;
g_vars->scene29_reachedFarRight = true;
g_nmi->_aniMan->changeStatics2(ST_MAN29_RUNR);
g_nmi->_aniMan->startAnim(MV_MAN29_BEND, 0, -1);
}
g_vars->scene29_manX = g_nmi->_aniMan->_ox;
g_vars->scene29_manY = g_nmi->_aniMan->_oy;
}
bool sceneHandler29_checkRedBallHit(StaticANIObject *ani, int maxx) {
#if DEBUG
return false;
#endif
if (!g_vars->scene29_arcadeIsOn || g_vars->scene29_manIsHit)
return false;
if ((ani->_ox >= g_vars->scene29_manX + 42 || ani->_ox <= g_vars->scene29_manX + 8)
&& (ani->_ox < g_vars->scene29_manX + 8 || maxx > g_vars->scene29_manX + 27))
return false;
if (!g_nmi->_aniMan->_movement)
return true;
int phase = g_nmi->_aniMan->_movement->_currDynamicPhaseIndex;
if (g_nmi->_aniMan->_movement->_id != MV_MAN29_BEND && g_nmi->_aniMan->_movement->_id != MV_MAN29_RUN
&& (g_nmi->_aniMan->_movement->_id != MV_MAN29_JUMP || (phase >= 3 && phase <= 6)))
return false;
else
return true;
}
bool sceneHandler29_checkGreenBallHit(StaticANIObject *ani, int maxx) {
#if DEBUG
return false;
#endif
if (!g_vars->scene29_arcadeIsOn || g_vars->scene29_manIsHit)
return false;
if (ani->_ox >= g_vars->scene29_manX + 40) {
if (maxx > g_vars->scene29_manX + 27)
return false;
} else {
if (ani->_ox <= g_vars->scene29_manX + 10) {
if (ani->_ox < g_vars->scene29_manX + 40)
return false;
if (maxx > g_vars->scene29_manX + 27)
return false;
}
}
if (!g_nmi->_aniMan->_movement)
return true;
if (g_nmi->_aniMan->_movement->_id == MV_MAN29_JUMP)
return true;
if (g_nmi->_aniMan->_movement->_id == MV_MAN29_RUN)
return true;
if (g_nmi->_aniMan->_movement->_id == MV_MAN29_BEND) {
if (g_nmi->_aniMan->_movement->_currDynamicPhaseIndex < 1 || g_nmi->_aniMan->_movement->_currDynamicPhaseIndex > 5)
return true;
}
return false;
}
void sceneHandler29_manHit() {
MakeQueueStruct mkQueue;
g_vars->scene29_manIsHit = true;
g_nmi->_aniMan->changeStatics2(ST_MAN29_RUNR);
g_nmi->_aniMan->setOXY(g_vars->scene29_manX, g_vars->scene29_manY);
mkQueue.ani = g_nmi->_aniMan;
mkQueue.staticsId2 = ST_MAN29_SITR;
mkQueue.y1 = 463;
mkQueue.x1 = g_vars->scene29_manX <= 638 ? 351 : 0;
mkQueue.field_1C = 10;
mkQueue.field_10 = 1;
mkQueue.flags = (g_vars->scene29_manX <= 638 ? 2 : 0) | 0x44;
mkQueue.movementId = MV_MAN29_HIT;
MessageQueue *mq = g_vars->scene29_aniHandler.makeRunQueue(&mkQueue);
ExCommand *ex;
if (mq) {
if (g_vars->scene29_manX <= 638) {
ex = new ExCommand(ANI_MAN, 1, MV_MAN29_STANDUP_NORM, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags = 2;
ex->_param = g_nmi->_aniMan->_odelay;
mq->addExCommandToEnd(ex);
ex = new ExCommand(0, 17, MSG_SC29_STOPRIDE, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags = 2;
mq->addExCommandToEnd(ex);
g_vars->scene29_manIsRiding = false;
g_vars->scene29_arcadeIsOn = false;
g_vars->scene29_reachedFarRight = false;
g_vars->scene29_rideBackEnabled = false;
} else {
ex = new ExCommand(ANI_MAN, 1, MV_MAN29_STANDUP, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags = 2;
ex->_param = g_nmi->_aniMan->_odelay;
mq->addExCommandToEnd(ex);
}
mq->setFlags(mq->getFlags() | 1);
if (!mq->chain(g_nmi->_aniMan))
delete mq;
}
}
void sceneHandler29_assHitRed() {
if (g_vars->scene29_ass->_statics->_staticsId == ST_ASS_NORM) {
g_vars->scene29_ass->changeStatics2(ST_ASS_NORM);
g_vars->scene29_ass->startAnim(MV_ASS_HITRED, 0, -1);
}
}
void sceneHandler29_assHitGreen() {
if (g_vars->scene29_ass->_statics->_staticsId == ST_ASS_NORM) {
g_vars->scene29_ass->changeStatics2(ST_ASS_NORM);
g_vars->scene29_ass->startAnim(MV_ASS_HITGREEN, 0, -1);
}
}
void sceneHandler29_ballHitCheck() {
int x, y;
for (int i = (int)g_vars->scene29_flyingGreenBalls.size() - 1; i >= 0; i--) {
StaticANIObject *ani = g_vars->scene29_flyingGreenBalls[i];
x = ani->_ox - 30;
y = ani->_oy;
if (x >= 186) {
if (sceneHandler29_checkGreenBallHit(ani, x)) {
g_vars->scene29_greenBalls.push_back(ani);
g_vars->scene29_flyingGreenBalls.remove_at(i);
sceneHandler29_manHit();
g_nmi->playSound(SND_29_014, 0);
ani->startAnim(MV_SHG_HITMAN, 0, -1);
g_vars->scene29_hitBall = ani->_id;
} else {
ani->setOXY(x, y);
}
} else {
g_vars->scene29_greenBalls.push_back(ani);
ani->hide();
g_vars->scene29_flyingGreenBalls.remove_at(i);
sceneHandler29_assHitGreen();
}
}
for (int i = (int)g_vars->scene29_flyingRedBalls.size() - 1; i >= 0; i--) {
StaticANIObject *ani = g_vars->scene29_flyingRedBalls[i];
x = ani->_ox - 30;
y = ani->_oy;
if (x >= 147) {
if (sceneHandler29_checkRedBallHit(ani, x)) {
g_vars->scene29_redBalls.push_back(ani);
g_vars->scene29_flyingRedBalls.remove_at(i);
sceneHandler29_manHit();
g_nmi->playSound(SND_29_027, 0);
ani->startAnim(MV_SHR_HITMAN, 0, -1);
g_vars->scene29_hitBall = ani->_id;
} else {
ani->setOXY(x, y);
}
} else {
g_vars->scene29_redBalls.push_back(ani);
ani->hide();
g_vars->scene29_flyingRedBalls.remove_at(i);
sceneHandler29_assHitRed();
}
}
}
void sceneHandler29_manFromL() {
debugC(2, kDebugSceneLogic, "scene29: manFromL");
if (g_vars->scene29_manX < 497 && !g_vars->scene29_scrollingDisabled) {
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
chainQueue(QU_SC29_MANFROM_L, 1);
g_vars->scene29_scrollingDisabled = true;
g_nmi->_scrollSpeed = g_vars->scene29_scrollSpeed;
}
}
void sceneHandler29_manFromR() {
debugC(2, kDebugSceneLogic, "scene29: manFromR");
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
chainQueue(QU_SC29_MANFROM_R, 1);
g_vars->scene29_arcadeIsOn = false;
g_vars->scene29_rideBackEnabled = false;
}
int sceneHandler29_updateScreenCallback() {
int res;
res = g_nmi->drawArcadeOverlay(g_vars->scene29_arcadeIsOn);
if (!res)
g_nmi->_updateScreenCallback = nullptr;
return res;
}
void sceneHandler29_manToL() {
debugC(2, kDebugSceneLogic, "scene29: manToL");
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
chainQueue(QU_SC29_MANTO_L, 1);
g_vars->scene29_arcadeIsOn = true;
g_vars->scene29_aniHandler.attachObject(g_nmi->_aniMan->_id);
g_nmi->_updateScreenCallback = sceneHandler29_updateScreenCallback;
g_nmi->_msgY = -1;
g_nmi->_msgX = -1;
}
void sceneHandler29_manToR() {
debugC(2, kDebugSceneLogic, "scene29: manToR");
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
chainQueue(QU_SC29_MANTO_R, 1);
g_vars->scene29_manIsRiding = true;
g_nmi->_msgY = -1;
g_nmi->_msgX = -1;
g_vars->scene29_scrollingDisabled = false;
g_vars->scene29_scrollSpeed = g_nmi->_scrollSpeed;
g_nmi->_scrollSpeed = 4;
}
void sceneHandler29_clickPorter(ExCommand *cmd) {
if (!g_nmi->_aniMan->isIdle() || g_nmi->_aniMan->_flags & 0x100) {
cmd->_messageKind = 0;
return;
}
if (g_vars->scene29_manX <= g_vars->scene29_porter->_ox) {
if (ABS(351 - g_vars->scene29_manX) > 1 || ABS(443 - g_vars->scene29_manY) > 1
|| g_nmi->_aniMan->_movement || g_nmi->_aniMan->_statics->_staticsId != ST_MAN_RIGHT) {
if (g_nmi->_msgX != 351 || g_nmi->_msgY != 443) {
MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, 351, 443, 1, ST_MAN_RIGHT);
if (mq) {
mq->addExCommandToEnd(cmd->createClone());
postExCommand(g_nmi->_aniMan->_id, 2, 351, 443, 0, -1);
}
}
} else {
sceneHandler29_manToL();
}
} else {
g_vars->scene29_manX = g_nmi->_aniMan->_ox;
g_vars->scene29_manY = g_nmi->_aniMan->_oy;
if (ABS(1582 - g_vars->scene29_manX) > 1 || ABS(445 - g_nmi->_aniMan->_oy) > 1
|| g_nmi->_aniMan->_movement || g_nmi->_aniMan->_statics->_staticsId != (0x4000 | ST_MAN_RIGHT)) {
if (g_nmi->_msgX != 1582 || g_nmi->_msgY != 445) {
MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_nmi->_aniMan, 1582, 445, 1, (0x4000 | ST_MAN_RIGHT));
if (mq) {
mq->addExCommandToEnd(cmd->createClone());
postExCommand(g_nmi->_aniMan->_id, 2, 1582, 445, 0, -1);
}
}
} else {
sceneHandler29_manToR();
}
}
}
void sceneHandler29_shootersProcess() {
if (g_nmi->_aniMan->_statics->_staticsId == ST_MAN29_RUNR) {
if (g_vars->scene29_manX > 1436) {
sceneHandler29_manFromR();
} else {
g_vars->scene29_shootDistance = (1310 - g_vars->scene29_manX) * 5213 / 100000 + 25;
if (!g_vars->scene29_manIsHit)
g_nmi->_aniMan->startAnim(MV_MAN29_RUN, 0, -1);
}
}
g_vars->scene29_manX = g_nmi->_aniMan->_ox;
g_vars->scene29_manY = g_nmi->_aniMan->_oy;
}
void sceneHandler29_shootersEscape() {
if (g_vars->scene29_arcadeIsOn) {
g_vars->scene29_manX += 2;
g_nmi->_aniMan->setOXY(g_vars->scene29_manX, g_vars->scene29_manY);
if (g_vars->scene29_manX > 1310 && !g_vars->scene29_shooter1->_movement && !g_vars->scene29_shooter2->_movement
&& g_vars->scene29_shooter1->_statics->_staticsId == ST_STR1_RIGHT) {
debugC(2, kDebugSceneLogic, "scene29: shootersEscape");
g_vars->scene29_shootCountdown = 0;
g_vars->scene29_shooter1->changeStatics2(ST_STR1_STAND);
g_vars->scene29_shooter2->changeStatics2(ST_STR2_STAND);
chainQueue(QU_SC29_ESCAPE, 1);
g_vars->scene29_ass->queueMessageQueue(nullptr);
g_vars->scene29_ass->hide();
g_nmi->setObjectState(sO_LeftPipe_29, g_nmi->getObjectEnumState(sO_LeftPipe_29, sO_IsOpened));
}
} else if (g_vars->scene29_manIsRiding) {
g_vars->scene29_manX -= 4;
g_nmi->_aniMan->setOXY(g_vars->scene29_manX, g_vars->scene29_manY);
}
}
void sceneHandler29_manRideBack() {
g_vars->scene29_manX -= 2;
g_nmi->_aniMan->setOXY(g_vars->scene29_manX, g_vars->scene29_manY);
}
void sceneHandler29_shoot() {
if (g_vars->scene29_arcadeIsOn && g_vars->scene29_manX < 1310) {
if (g_nmi->_rnd.getRandomNumber(32767) <= 16383|| g_vars->scene29_shooter1->_movement || g_vars->scene29_shooter1->_statics->_staticsId != ST_STR1_RIGHT) {
if (!g_vars->scene29_shooter2->_movement && g_vars->scene29_shooter2->_statics->_staticsId == ST_STR2_RIGHT) {
if (g_vars->scene29_shooter2->_flags & 4) {
g_vars->scene29_shooter2->startAnim(MV_STR2_SHOOT, 0, -1);
g_vars->scene29_shootCountdown = 0;
}
}
} else {
g_vars->scene29_shooter1->startAnim(MV_STR1_SHOOT, 0, -1);
g_vars->scene29_shootCountdown = 0;
}
}
}
void sceneHandler29_animBearded() {
MessageQueue *mq;
for (uint i = 0; i < g_vars->scene29_bearders.size(); i++) {
StaticANIObject *ani = g_vars->scene29_bearders[i]->ani;
if (g_vars->scene29_bearders[i]->wbflag) {
int x = ani->_ox;
int y = ani->_oy;
if (!ani->_movement && ani->_statics->_staticsId == (ST_BRDCMN_RIGHT | 0x4000)) {
x -= 4;
if (x - g_vars->scene29_manX < 100 || !g_vars->scene29_arcadeIsOn) {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC29_BRDOUT1), 0, 1);
mq->setParamInt(-1, ani->_odelay);
mq->chain(nullptr);
g_vars->scene29_bearders[i]->wbflag = 0;
g_vars->scene29_bearders[i]->wbcounter = 0;
}
}
if (!ani->_movement && ani->_statics->_staticsId == ST_BRDCMN_GOR)
ani->startAnim(MV_BRDCMN_GOR, 0, -1);
if (ani->_movement) {
if (ani->_movement->_id == MV_BRDCMN_GOR) {
x -= 4;
if (g_vars->scene29_manX - x < 60 || x - g_vars->scene29_manX < -260 || !g_vars->scene29_arcadeIsOn) {
ani->changeStatics2(ST_BRDCMN_RIGHT);
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC29_BRDOUT2), 0, 1);
mq->setParamInt(-1, ani->_odelay);
mq->chain(nullptr);
g_vars->scene29_bearders[i]->wbflag = 0;
g_vars->scene29_bearders[i]->wbcounter = 0;
}
}
}
ani->setOXY(x, y);
continue;
}
if (g_vars->scene29_arcadeIsOn && g_vars->scene29_bearders[i]->wbcounter > 30) {
int newx;
if (g_nmi->_rnd.getRandomNumber(1))
goto dostuff;
if (g_vars->scene29_manX <= 700) {
g_vars->scene29_bearders[i]->wbcounter++;
continue;
}
if (g_vars->scene29_manX >= 1100) {
dostuff:
if (g_vars->scene29_manX <= 700 || g_vars->scene29_manX >= 1350) {
g_vars->scene29_bearders[i]->wbcounter++;
continue;
}
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC29_BRD2), 0, 1);
newx = g_vars->scene29_manX - 200;
} else {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC29_BRD1), 0, 1);
newx = g_vars->scene29_manX + 350;
}
mq->getExCommandByIndex(0)->_x = newx;
mq->setParamInt(-1, ani->_odelay);
mq->chain(nullptr);
g_vars->scene29_bearders[i]->wbflag = 1;
g_vars->scene29_bearders[i]->wbcounter = 0;
}
g_vars->scene29_bearders[i]->wbcounter++;
}
}
int sceneHandler29(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_CMN_WINARCADE:
sceneHandler29_winArcade();
break;
case MSG_SC29_LAUGH:
if (g_vars->scene29_hitBall == ANI_SHELL_GREEN) {
g_nmi->playSound(SND_29_028, 0);
} else {
g_nmi->playSound(SND_29_029, 0);
}
break;
case MSG_SC29_SHOWLASTRED:
if (g_vars->scene29_redBalls.size()) { // original checks size of the scene29_greenBalls which looks like a copy/paste error
debugC(2, kDebugSceneLogic, "scene29: showLastRed");
g_vars->scene29_redBalls.back()->show1(-1, -1, -1, 0);
g_vars->scene29_redBalls.back()->startAnim(MV_SHR_HITASS, 0, -1);
}
break;
case MSG_SC29_SHOOTGREEN:
sceneHandler29_shootGreen();
break;
case MSG_SC29_SHOOTRED:
sceneHandler29_shootRed();
break;
case MSG_SC29_SHOWLASTGREEN:
if (g_vars->scene29_greenBalls.size()) {
debugC(2, kDebugSceneLogic, "scene29: showLastGreen");
g_vars->scene29_greenBalls.back()->show1(-1, -1, -1, 0);
g_vars->scene29_greenBalls.back()->startAnim(MV_SHG_HITASS, 0, -1);
}
break;
case MSG_SC29_STOPRIDE:
g_vars->scene29_manIsRiding = false;
g_vars->scene29_arcadeIsOn = false;
g_vars->scene29_reachedFarRight = false;
g_vars->scene29_rideBackEnabled = false;
debugC(2, kDebugSceneLogic, "scene29: stopRide");
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
break;
case MSG_SC29_DISABLERIDEBACK:
g_vars->scene29_rideBackEnabled = false;
break;
case MSG_SC29_ENABLERIDEBACK:
g_vars->scene29_rideBackEnabled = true;
g_vars->scene29_reachedFarRight = false;
break;
case MSG_SC29_DISABLEPORTER:
g_vars->scene29_reachedFarRight = false;
break;
case MSG_SC29_ENABLEPORTER:
g_vars->scene29_reachedFarRight = true;
g_vars->scene29_rideBackEnabled = false;
g_vars->scene29_manIsHit = false;
break;
case 29:
if (!g_vars->scene29_manIsRiding || g_vars->scene29_arcadeIsOn) {
if (!g_vars->scene29_arcadeIsOn) {
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(g_nmi->_sceneRect.left + cmd->_x, g_nmi->_sceneRect.top + cmd->_y);
if (ani && ani == g_vars->scene29_porter) {
sceneHandler29_clickPorter(cmd);
cmd->_messageKind = 0;
break;
}
} else {
sceneHandler29_manJump();
cmd->_messageKind = 0;
}
}
break;
case 107:
if (g_vars->scene29_arcadeIsOn) {
sceneHandler29_manBend();
}
break;
case 33:
if (g_vars->scene29_arcadeIsOn) {
if (g_vars->scene29_manX > g_nmi->_sceneRect.right - 500)
g_nmi->_currentScene->_x = g_nmi->_sceneRect.right - g_vars->scene29_manX - 350;
if (g_vars->scene29_manX < g_nmi->_sceneRect.left + 100)
g_nmi->_currentScene->_x = g_vars->scene29_manX - g_nmi->_sceneRect.left - 100;
} else if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 300)
g_nmi->_currentScene->_x = x - 400 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 300)
g_nmi->_currentScene->_x = x + 400 - g_nmi->_sceneRect.right;
}
g_vars->scene29_manX = g_nmi->_aniMan->_ox;
g_vars->scene29_manY = g_nmi->_aniMan->_oy;
sceneHandler29_ballHitCheck();
if (!g_vars->scene29_porter->_movement)
g_vars->scene29_porter->startAnim(MV_PTR_MOVEFAST, 0, -1);
if (g_vars->scene29_manIsRiding)
sceneHandler29_manFromL();
else if (g_vars->scene29_arcadeIsOn && !g_nmi->_aniMan->_movement)
sceneHandler29_shootersProcess();
if (g_vars->scene29_reachedFarRight)
sceneHandler29_shootersEscape();
else if (g_vars->scene29_rideBackEnabled)
sceneHandler29_manRideBack();
g_vars->scene29_shootCountdown++;
if (g_vars->scene29_shootCountdown > g_vars->scene29_shootDistance)
sceneHandler29_shoot();
sceneHandler29_animBearded();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
return 0;
}
int scene29_updateCursor() {
g_nmi->updateCursorCommon();
if (g_vars->scene29_arcadeIsOn) {
if (g_nmi->_cursorId != PIC_CSR_DEFAULT_INV && g_nmi->_cursorId != PIC_CSR_ITN_INV)
g_nmi->_cursorId = -1;
} else if (g_vars->scene29_manIsRiding) {
if (g_nmi->_cursorId != PIC_CSR_DEFAULT_INV && g_nmi->_cursorId != PIC_CSR_ITN_INV)
g_nmi->_cursorId = PIC_CSR_DEFAULT;
} else if (g_nmi->_objectIdAtCursor == ANI_PORTER) {
if (g_nmi->_cursorId == PIC_CSR_DEFAULT)
g_nmi->_cursorId = PIC_CSR_ITN;
} else {
if (g_nmi->_objectIdAtCursor == PIC_SC29_LTRUBA && g_nmi->_cursorId == PIC_CSR_ITN)
g_nmi->_cursorId = PIC_CSR_GOL;
}
return g_nmi->_cursorId;
}
} // End of namespace NGI

View File

@@ -0,0 +1,154 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene30_enablePass(Scene *sc) {
MovGraphLink *lnk = getSc2MctlCompoundBySceneId(sc->_sceneId)->getLinkByName(sO_WayToPipe);
if (g_nmi->getObjectState(sO_Leg) == g_nmi->getObjectEnumState(sO_Leg, sO_WithAll))
lnk->_flags &= 0xDFFFFFFF;
else
lnk->_flags |= 0x20000000;
}
void scene30_initScene(Scene *sc, int flag) {
Scene *oldsc = g_nmi->_currentScene;
g_vars->scene30_leg = sc->getStaticANIObject1ById(ANI_LEG, -1);
g_nmi->_currentScene = sc;
if (g_nmi->getObjectState(sO_Leg) == g_nmi->getObjectEnumState(sO_Leg, sO_ShowingHeel))
g_vars->scene30_leg->changeStatics2(ST_LEG_UP);
else if (g_nmi->getObjectState(sO_Leg) == g_nmi->getObjectEnumState(sO_Leg, sO_WithoutJugs))
g_vars->scene30_leg->changeStatics2(ST_LEG_DOWN);
else if (g_nmi->getObjectState(sO_Leg) == g_nmi->getObjectEnumState(sO_Leg, sO_WithBig))
g_vars->scene30_leg->changeStatics2(ST_LEG_DOWN1);
else if (g_nmi->getObjectState(sO_Leg) == g_nmi->getObjectEnumState(sO_Leg, sO_WithSmall))
g_vars->scene30_leg->changeStatics2(ST_LEG_DOWN2);
else if (g_nmi->getObjectState(sO_Leg) == g_nmi->getObjectEnumState(sO_Leg, sO_WithAll))
g_vars->scene30_leg->changeStatics2(ST_LEG_EMPTY);
g_nmi->_currentScene = oldsc;
scene30_enablePass(sc);
if (flag == LiftUp || flag == LiftDown)
g_vars->scene30_liftFlag = 0;
else
g_vars->scene30_liftFlag = 1;
g_nmi->lift_setButton(sO_Level8, ST_LBN_8N);
g_nmi->lift_init(sc, QU_SC30_ENTERLIFT, QU_SC30_EXITLIFT);
}
int scene30_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_cursorId == PIC_CSR_ITN && g_nmi->_objectIdAtCursor == PIC_SC30_LTRUBA) {
g_nmi->_cursorId = PIC_CSR_GOL;
}
return g_nmi->_cursorId;
}
int sceneHandler30(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch(cmd->_messageNum) {
case MSG_LIFT_CLOSEDOOR:
g_nmi->lift_closedoorSeq();
break;
case MSG_LIFT_EXITLIFT:
g_nmi->lift_exitSeq(cmd);
break;
case MSG_LIFT_STARTEXITQUEUE:
g_nmi->lift_startExitQueue();
break;
case MSG_LIFT_CLICKBUTTON:
g_nmi->lift_clickButton();
break;
case MSG_SC30_UPDATEPATH:
scene30_enablePass(g_nmi->_currentScene);
break;
case 64:
g_nmi->lift_hoverButton(cmd);
break;
case MSG_LIFT_GO:
g_nmi->lift_goAnimation();
break;
case 29:
{
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(g_nmi->_sceneRect.left + cmd->_x, g_nmi->_sceneRect.top + cmd->_y);
if (ani && ani->_id == ANI_LIFTBUTTON) {
g_nmi->lift_animateButton(ani);
cmd->_messageKind = 0;
}
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
}
g_nmi->_behaviorManager->updateBehaviors();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,128 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene31_initScene(Scene *sc) {
g_vars->scene31_chantingCountdown = 0;
g_vars->scene31_cactus = sc->getStaticANIObject1ById(ANI_CACTUS_31, -1);
if (g_nmi->getObjectState(sO_Cactus) == g_nmi->getObjectEnumState(sO_Cactus, sO_HasGrown)) {
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
g_vars->scene31_cactus->changeStatics2(ST_CTS31_GROWN2);
g_vars->scene31_cactus->_priority = 22;
g_nmi->_currentScene = oldsc;
} else {
g_vars->scene31_cactus->hide();
}
g_vars->scene31_plusMinus = sc->getStaticANIObject1ById(ANI_PLUSMINUS, -1);
if (g_nmi->getObjectState(sO_Guard_3) == g_nmi->getObjectEnumState(sO_Guard_3, sO_Off))
g_vars->scene31_plusMinus->_statics = g_vars->scene31_plusMinus->getStaticsById(ST_PMS_MINUS);
else
g_vars->scene31_plusMinus->_statics = g_vars->scene31_plusMinus->getStaticsById(ST_PMS_PLUS);
}
void sceneHandler31_testCactus(ExCommand *cmd) {
if ((g_vars->scene31_cactus->_flags & 4) && g_vars->scene31_cactus->_statics->_staticsId == ST_CTS31_GROWN2) {
MessageQueue *mq = g_nmi->_globalMessageQueueList->getMessageQueueById(cmd->_parId);
if (mq) {
mq->getExCommandByIndex(0)->_messageKind = 0;
mq->getExCommandByIndex(0)->_excFlags |= 1;
mq->getExCommandByIndex(1)->_messageKind = 0;
mq->getExCommandByIndex(1)->_excFlags |= 1;
}
}
}
int sceneHandler31(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_SC31_TESTCACTUS:
sceneHandler31_testCactus(cmd);
break;
case MSG_SC15_STOPCHANTING:
g_nmi->stopAllSoundInstances(SND_31_001);
g_vars->scene31_chantingCountdown = 120;
break;
case MSG_SC31_PULL:
if ( g_vars->scene31_plusMinus->_statics->_staticsId == ST_PMS_MINUS)
g_vars->scene31_plusMinus->_statics = g_vars->scene31_plusMinus->getStaticsById(ST_PMS_PLUS);
else
g_vars->scene31_plusMinus->_statics = g_vars->scene31_plusMinus->getStaticsById(ST_PMS_MINUS);
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
}
if (g_vars->scene31_chantingCountdown > 0) {
--g_vars->scene31_chantingCountdown;
if (!g_vars->scene31_chantingCountdown)
g_nmi->playSound(SND_31_001, 1);
}
g_nmi->_behaviorManager->updateBehaviors();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,444 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene32_initScene(Scene *sc) {
g_vars->scene32_flagIsWaving = false;
g_vars->scene32_flagNeedsStopping = false;
g_vars->scene32_dudeIsSitting = false;
g_vars->scene32_cactusCounter = -1;
g_vars->scene32_dudeOnLadder = false;
g_vars->scene32_cactusIsGrowing = false;
g_vars->scene32_flag = sc->getStaticANIObject1ById(ANI_FLAG, -1);
g_vars->scene32_cactus = sc->getStaticANIObject1ById(ANI_CACTUS, -1);
g_vars->scene32_massOrange = sc->getStaticANIObject1ById(ANI_TESTO_ORANGE, -1);
g_vars->scene32_massBlue = sc->getStaticANIObject1ById(ANI_TESTO_BLUE, -1);
g_vars->scene32_massGreen = sc->getStaticANIObject1ById(ANI_TESTO_GREEN, -1);
g_vars->scene32_button = sc->getStaticANIObject1ById(ANI_BUTTON_32, -1);
g_vars->scene32_massOrange->startAnim(MV_TSTO_FLOW, 0, -1);
g_vars->scene32_massOrange->_movement->setDynamicPhaseIndex(15);
g_vars->scene32_massGreen->startAnim(MV_TSTG_FLOW, 0, -1);
g_vars->scene32_massGreen->_movement->setDynamicPhaseIndex(26);
Scene *oldsc = g_nmi->_currentScene;
StaticANIObject *ani;
if (g_nmi->getObjectState(sO_ClockHandle) == g_nmi->getObjectEnumState(sO_ClockHandle, sO_In_32_Lies)) {
ani = sc->getStaticANIObject1ById(ANI_INV_HANDLE, -1);
if (ani) {
g_nmi->_currentScene = sc;
ani->changeStatics2(ST_HDL_LAID);
}
} else {
if (g_nmi->getObjectState(sO_ClockHandle) == g_nmi->getObjectEnumState(sO_ClockHandle, sO_In_32_Sticks)) {
ani = sc->getStaticANIObject1ById(ANI_INV_HANDLE, -1);
g_nmi->_currentScene = sc;
if (ani)
ani->changeStatics2(ST_HDL_PLUGGED);
g_vars->scene32_button->changeStatics2(ST_BTN32_ON);
}
}
g_nmi->_currentScene = oldsc;
if (g_nmi->getObjectState(sO_Cube) == g_nmi->getObjectEnumState(sO_Cube, sO_In_32)) {
MessageQueue *mq = new MessageQueue(sc->getMessageQueueById(QU_KBK32_START), 0, 0);
mq->sendNextCommand();
}
g_nmi->lift_setButton(sO_Level9, ST_LBN_9N);
g_nmi->lift_init(sc, QU_SC32_ENTERLIFT, QU_SC32_EXITLIFT);
g_nmi->initArcadeKeys("SC_32");
if (g_nmi->getObjectState(sO_Cactus) == g_nmi->getObjectEnumState(sO_Cactus, sO_HasGrown)) {
g_nmi->_currentScene = sc;
g_vars->scene32_cactus->changeStatics2(ST_CTS_GROWUP);
g_vars->scene32_cactus->_priority = 22;
g_nmi->_currentScene = oldsc;
}
}
void scene32_setupMusic() {
if (g_nmi->lift_checkButton(sO_Level6))
g_nmi->playTrack(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_32"), "MUSIC2", 1);
}
int scene32_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_objectIdAtCursor == PIC_SC32_LADDER && g_nmi->_cursorId == PIC_CSR_ITN)
g_nmi->_cursorId = g_vars->scene32_dudeOnLadder ? PIC_CSR_GOD : PIC_CSR_GOU;
return g_nmi->_cursorId;
}
void sceneHandler32_tryCube() {
if (g_nmi->getObjectState(sO_Cube) == g_nmi->getObjectEnumState(sO_Cube, sO_In_33))
chainQueue(QU_KBK32_GO, 0);
}
void sceneHandler32_startCactus() {
g_vars->scene32_cactusCounter = 48;
g_vars->scene32_cactusIsGrowing = false;
}
void sceneHandler32_spin(ExCommand *cmd) {
MessageQueue *mq = g_nmi->_globalMessageQueueList->getMessageQueueById(cmd->_parId);
if (!mq || mq->getCount() == 0)
return;
ExCommand *ex = mq->getExCommandByIndex(0);
ExCommand *newex;
if ((g_vars->scene32_cactus->_movement && g_vars->scene32_cactus->_movement->_id == MV_CTS_DEFAULT)
|| g_vars->scene32_cactus->_statics->_staticsId == ST_CTS_GROWUP) {
for (int i = 0; i < 12; i++) {
newex = ex->createClone();
newex->_excFlags |= 2;
mq->insertExCommandAt(1, newex);
}
g_vars->scene32_cactus->changeStatics2(ST_CTS_GROWUP);
chainQueue(QU_CTS_BACK, 1);
g_vars->scene32_cactusIsGrowing = false;
return;
}
if (g_vars->scene32_cactus->_statics->_staticsId == ST_CTS_EMPTY && g_vars->scene32_cactusCounter < 0) {
for (int i = 0; i < 2; i++) {
newex = ex->createClone();
newex->_excFlags |= 2;
mq->insertExCommandAt(1, newex);
}
chainQueue(QU_KDK_DRIZZLE, 0);
}
}
void sceneHandler32_startFlagLeft() {
g_vars->scene32_flag->changeStatics2(ST_FLG_NORM);
g_vars->scene32_flag->startAnim(MV_FLG_STARTL, 0, -1);
g_vars->scene32_flagIsWaving = true;
}
void sceneHandler32_startFlagRight() {
g_vars->scene32_flag->changeStatics2(ST_FLG_NORM);
g_vars->scene32_flag->startAnim(MV_FLG_STARTR, 0, -1);
g_vars->scene32_flagIsWaving = true;
}
void sceneHandler32_trySit(ExCommand *cmd) {
MessageQueue *mq = g_nmi->_globalMessageQueueList->getMessageQueueById(cmd->_parId);
if (!mq || mq->getCount() == 0)
return;
ExCommand *ex = mq->getExCommandByIndex(0);
if (g_vars->scene32_cactusIsGrowing || g_vars->scene32_cactus->_movement
|| g_vars->scene32_cactus->_statics->_staticsId != ST_CTS_EMPTY
|| (g_vars->scene32_cactusCounter >= 0 && g_vars->scene32_cactusCounter <= 20)) {
ex->_messageKind = 0;
ex->_excFlags |= 1;
} else {
ex->_parentId = ANI_MAN;
ex->_messageKind = 1;
ex->_messageNum = MV_MAN32_SITDOWN;
ex->_param = g_nmi->_aniMan->_odelay;
g_vars->scene32_dudeIsSitting = true;
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
}
}
void sceneHandler32_buttonPush() {
if (g_nmi->getObjectState(sO_ClockHandle) == g_nmi->getObjectEnumState(sO_ClockHandle, sO_In_32_Sticks)) {
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_INV_HANDLE, -1);
if (ani)
ani->changeStatics2(ST_HDL_PLUGGED);
chainQueue(QU_SC32_FALLHANDLE, 1);
g_vars->scene32_button->changeStatics2(ST_BTN32_OFF);
}
}
void sceneHandler32_installHandle() {
chainQueue(QU_SC32_SHOWHANDLE, 0);
g_vars->scene32_button->changeStatics2(ST_BTN32_ON);
}
void sceneHandler32_animateCactus() {
if (g_nmi->_aniMan->_statics->_staticsId != ST_MAN32_SIT)
chainQueue(QU_CTS_GROW, 1);
else
chainQueue(QU_CTS_GROWMAN, 1);
g_vars->scene32_cactusCounter = -1;
g_vars->scene32_cactusIsGrowing = true;
}
void sceneHandler32_ladderLogic(ExCommand *cmd) {
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC32_FROMLADDER), 0, 0);
if (g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY) != PIC_SC32_LADDER)
mq->addExCommandToEnd(cmd->createClone());
mq->setFlags(mq->getFlags() | 1);
g_nmi->_aniMan->changeStatics2(ST_MAN_STANDLADDER);
if (!mq->chain(g_nmi->_aniMan))
delete mq;
g_vars->scene32_dudeOnLadder = false;
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
}
void sceneHandler32_potLogic(ExCommand *cmd) {
if (g_vars->scene32_cactusCounter < 0 || g_vars->scene32_cactusCounter > 20) {
MessageQueue *mq = new MessageQueue(g_nmi->_globalMessageQueueList->compact());
ExCommand *ex = new ExCommand(ANI_MAN, 1, MV_MAN32_STANDUP, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 2;
mq->addExCommandToEnd(ex);
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (!ani || ani->_id != ANI_KADKA)
mq->addExCommandToEnd(cmd->createClone());
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
g_vars->scene32_dudeIsSitting = false;
}
}
int sceneHandler32(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_LIFT_CLOSEDOOR:
g_nmi->lift_closedoorSeq();
break;
case MSG_LIFT_EXITLIFT:
g_nmi->lift_exitSeq(cmd);
break;
case MSG_LIFT_STARTEXITQUEUE:
g_nmi->lift_startExitQueue();
break;
case MSG_SC32_TRUBATOBACK:
g_nmi->_currentScene->getPictureObjectById(PIC_SC32_RTRUBA, 0)->_priority = 20;
break;
case MSG_SC32_TRUBATOFRONT:
g_nmi->_currentScene->getPictureObjectById(PIC_SC32_RTRUBA, 0)->_priority = 0;
break;
case MSG_LIFT_CLICKBUTTON:
g_nmi->lift_clickButton();
break;
case MSG_SC33_TRYKUBIK:
sceneHandler32_tryCube();
break;
case MSG_SC32_STARTCACTUS:
sceneHandler32_startCactus();
break;
case MSG_SC32_STOPFLAG:
g_vars->scene32_flagIsWaving = false;
g_vars->scene32_flagNeedsStopping = true;
break;
case MSG_SC32_SPIN:
sceneHandler32_spin(cmd);
break;
case MSG_SC32_STARTFLAGLEFT :
sceneHandler32_startFlagLeft();
break;
case MSG_SC32_STARTFLAGRIGHT:
sceneHandler32_startFlagRight();
break;
case MSG_SC32_TRYSIT:
sceneHandler32_trySit(cmd);
break;
case MSG_LIFT_GO:
g_nmi->lift_goAnimation();
break;
case MSG_SC32_ONLADDER:
g_vars->scene32_dudeOnLadder = true;
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
break;
case MSG_SC6_BTNPUSH:
sceneHandler32_buttonPush();
break;
case 64:
g_nmi->lift_hoverButton(cmd);
break;
case MSG_SC6_INSTHANDLE:
sceneHandler32_installHandle();
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
g_nmi->sceneAutoScrolling();
}
if (!g_vars->scene32_flag->_movement) {
if (g_vars->scene32_flagIsWaving) {
if (g_vars->scene32_flag->_statics->_staticsId == ST_FLG_RIGHT)
g_vars->scene32_flag->startAnim(MV_FLG_CYCLER, 0, -1);
else if (g_vars->scene32_flag->_statics->_staticsId == ST_FLG_LEFT)
g_vars->scene32_flag->startAnim(MV_FLG_CYCLEL, 0, -1);
}
if (g_vars->scene32_flagNeedsStopping && !g_vars->scene32_flagIsWaving) {
if (g_vars->scene32_flag->_statics->_staticsId == ST_FLG_RIGHT)
g_vars->scene32_flag->startAnim(MV_FLG_STOPR, 0, -1);
else if (g_vars->scene32_flag->_statics->_staticsId == ST_FLG_LEFT)
g_vars->scene32_flag->startAnim(MV_FLG_STOPL, 0, -1);
g_vars->scene32_flagNeedsStopping = false;
}
}
if (g_vars->scene32_cactusCounter) {
if (g_vars->scene32_cactusCounter > 0)
--g_vars->scene32_cactusCounter;
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
} else {
sceneHandler32_animateCactus();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
}
break;
case 29:
if (g_vars->scene32_dudeOnLadder) {
sceneHandler32_ladderLogic(cmd);
cmd->_messageKind = 0;
break;
}
if (!g_vars->scene32_dudeIsSitting || g_nmi->_aniMan->_movement) {
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (ani && ani->_id == ANI_LIFTBUTTON) {
g_nmi->lift_animateButton(ani);
cmd->_messageKind = 0;
break;
}
if (g_nmi->_cursorId == PIC_CSR_GOFAR_R || g_nmi->_cursorId == PIC_CSR_GOFAR_L) {
if ((g_nmi->_sceneRect.right - cmd->_sceneClickX < 47 && g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1)
|| (cmd->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0))
g_nmi->processArcade(cmd);
}
break;
}
if (!g_vars->scene32_cactusIsGrowing)
sceneHandler32_potLogic(cmd);
cmd->_messageKind = 0;
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,318 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
const int ventsInit[9] = { 0, 0, 1, 0, 0, 1, 0, 0, 1 };
void scene33_initScene(Scene *sc) {
g_vars->scene33_mug = sc->getStaticANIObject1ById(ANI_MUG_33, -1);
g_vars->scene33_jettie = sc->getStaticANIObject1ById(ANI_JETTIE_FLOW, -1);
g_vars->scene33_cube = nullptr;
g_vars->scene33_cubeX = -1;
g_vars->scene33_handleIsDown = false;
if (g_nmi->getObjectState(sO_Cube) == g_nmi->getObjectEnumState(sO_Cube, sO_In_33)) {
MessageQueue *mq = new MessageQueue(sc->getMessageQueueById(QU_KBK33_START), 0, 0);
mq->sendNextCommand();
}
for (int i = 0; i < 9; i++) {
g_vars->scene33_ventsX[i] = sc->getStaticANIObject1ById(ANI_VENT_33, i)->_ox;
g_vars->scene33_ventsState[i] = ventsInit[i];
}
g_nmi->initArcadeKeys("SC_33");
}
void scene33_setupMusic() {
if (g_nmi->lift_checkButton(sO_Level6))
g_nmi->playTrack(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_33"), "MUSIC2", 1);
}
int scene33_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_objectIdAtCursor == PIC_SC33_ZONES && g_nmi->_cursorId == PIC_CSR_DEFAULT)
g_nmi->_cursorId = PIC_CSR_ITN;
return g_nmi->_cursorId;
}
void sceneHandler33_processJettie(ExCommand *cmd) {
MessageQueue *mq = g_nmi->_globalMessageQueueList->getMessageQueueById(cmd->_parId);
if (mq && g_vars->scene33_jettie->_movement) {
ExCommand *ex = mq->getExCommandByIndex(0);
if (ex) {
ex->_messageKind = 0;
ex->_excFlags |= 1;
}
ex = mq->getExCommandByIndex(1);
if (ex) {
ex->_messageKind = 0;
ex->_excFlags |= 1;
}
}
}
void sceneHandler33_switchVent(StaticANIObject *ani) {
int mv = 0;
if (ani->_statics->_staticsId == ST_VNT33_DOWN)
mv = MV_VNT33_TURNR;
if (ani->_statics->_staticsId == ST_VNT33_RIGHT)
mv = MV_VNT33_TURND;
if (mv)
ani->startAnim(mv, 0, -1);
g_vars->scene33_ventsState[ani->_odelay] = !g_vars->scene33_ventsState[ani->_odelay];
}
void sceneHandler33_processVents() {
for (int i = 0; i < 9; i++)
if (((g_vars->scene33_cubeX < g_vars->scene33_ventsX[i]) != (g_vars->scene33_cube->_ox < g_vars->scene33_ventsX[i]))
&& g_vars->scene33_ventsState[i] != ventsInit[i])
sceneHandler33_switchVent(g_nmi->_currentScene->getStaticANIObject1ById(ANI_VENT_33, i));
g_vars->scene33_cubeX = g_vars->scene33_cube->_ox;
}
void sceneHandler33_tryCube() {
if (g_nmi->getObjectState(sO_Cube) == g_nmi->getObjectEnumState(sO_Cube, sO_In_32))
chainQueue(QU_KBK33_GO, 0);
}
void sceneHandler33_pour() {
bool solved = true;
for (int i = 0; i < 9; i++)
if (g_vars->scene33_ventsState[i] != ventsInit[i])
solved = false;
if (solved) {
if ((g_vars->scene33_mug->_flags & 4) && g_vars->scene33_mug->_statics->_staticsId == ST_MUG33_EMPTY) {
g_vars->scene33_jettie->startAnim(MV_JTI33_POUR, 0, -1);
g_vars->scene33_handleIsDown = false;
return;
}
if ((g_vars->scene33_mug->_flags & 4) && g_vars->scene33_mug->_statics->_staticsId == ST_MUG33_FULL) {
g_vars->scene33_jettie->startAnim(MV_JTI33_POURFULL, 0, -1);
g_vars->scene33_handleIsDown = false;
return;
}
g_vars->scene33_jettie->startAnim(MV_JTI33_FLOW, 0, -1);
}
g_vars->scene33_handleIsDown = false;
}
void sceneHandler33_handleDown() {
if (!g_vars->scene33_handleIsDown && !g_vars->scene33_jettie->_movement && !g_vars->scene33_jettie->getMessageQueue() ) {
chainQueue(QU_SC33_STARTWATER, 0);
g_vars->scene33_handleIsDown = true;
}
}
void sceneHandler33_zoneClickProcess(StaticANIObject *ani) {
if (!ani->_movement) {
sceneHandler33_switchVent(ani);
StaticANIObject *vent1 = nullptr;
StaticANIObject *vent2 = nullptr;
switch (ani->_odelay) {
case 0:
vent1 = g_nmi->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 2);
vent2 = g_nmi->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 3);
break;
case 1:
vent1 = g_nmi->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 3);
vent2 = g_nmi->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 4);
break;
case 2:
vent1 = g_nmi->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 4);
vent2 = g_nmi->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 0);
break;
case 3:
vent1 = g_nmi->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 0);
vent2 = g_nmi->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 1);
break;
case 4:
vent1 = g_nmi->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 1);
vent2 = g_nmi->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 2);
break;
default:
return;
}
if (vent1) {
sceneHandler33_switchVent(vent1);
sceneHandler33_switchVent(vent2);
}
}
}
void sceneHandler33_clickZones(ExCommand *cmd) {
StaticANIObject *closest = nullptr;
double mindist = 1e10;
for (uint i = 0; i < g_nmi->_currentScene->_staticANIObjectList1.size(); i++) {
StaticANIObject *ani = g_nmi->_currentScene->_staticANIObjectList1[i];
if (ani->_id == ANI_VENT_33) {
int dx = ani->_ox - cmd->_sceneClickX;
int dy = ani->_oy - cmd->_sceneClickY;
double dist = sqrt((double)(dx * dx + dy * dy));
if (dist < mindist) {
mindist = dist;
closest = ani;
}
}
}
if (closest)
sceneHandler33_zoneClickProcess(closest);
}
int sceneHandler33(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_SC32_TRUBATOFRONT:
g_nmi->_currentScene->getPictureObjectById(PIC_SC33_LTRUBA, 0)->_priority = 0;
break;
case MSG_SC32_TRUBATOBACK:
g_nmi->_currentScene->getPictureObjectById(PIC_SC33_LTRUBA, 0)->_priority = 20;
break;
case MSG_SC33_TESTMUG:
sceneHandler33_processJettie(cmd);
break;
case MSG_SC33_UPDATEKUBIK:
g_vars->scene33_cube = g_nmi->_currentScene->getStaticANIObject1ById(ANI_KUBIK, -1);
if (g_vars->scene33_cube)
g_vars->scene33_cubeX = g_vars->scene33_cube->_ox;
break;
case MSG_SC33_TRYKUBIK:
sceneHandler33_tryCube();
break;
case MSG_SC33_POUR:
sceneHandler33_pour();
break;
case MSG_SC33_HANDLEDOWN:
sceneHandler33_handleDown();
break;
case 29:
{
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(g_nmi->_sceneRect.left + cmd->_x, g_nmi->_sceneRect.top + cmd->_y);
if (!ani || !canInteractAny(g_nmi->_aniMan, ani, cmd->_param)) {
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picId, 0);
if (pic && pic->_id == PIC_SC33_ZONES) {
sceneHandler33_clickZones(cmd);
break;
}
if (!pic || !canInteractAny(g_nmi->_aniMan, pic, cmd->_param)) {
if ((g_nmi->_sceneRect.right - cmd->_sceneClickX < 47 && g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1) || (cmd->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0))
g_nmi->processArcade(cmd);
}
}
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
g_nmi->sceneAutoScrolling();
}
if (g_vars->scene33_cube)
sceneHandler33_processVents();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,480 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
#include "ngi/floaters.h"
namespace NGI {
void sceneHandler34_setExits() {
int state;
if (g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_NearPipeWithStool)) {
if (g_nmi->getObjectState(sO_Hatch_34) == g_nmi->getObjectEnumState(sO_Hatch_34, sO_Closed))
state = g_nmi->getObjectEnumState(sO_Plank_34, sO_ClosedWithBoot);
else
state = g_nmi->getObjectEnumState(sO_Plank_34, sO_OpenedWithBoot);
} else {
if (g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_OnStool)) {
if (g_nmi->getObjectState(sO_Hatch_34) == g_nmi->getObjectEnumState(sO_Hatch_34, sO_Closed))
state = g_nmi->getObjectEnumState(sO_Plank_34, sO_IsClosed);
else
state = g_nmi->getObjectEnumState(sO_Plank_34, sO_IsOpened);
} else {
state = g_nmi->getObjectEnumState(sO_Plank_34, sO_Passive);
}
}
g_nmi->setObjectState(sO_Plank_34, state);
}
void scene34_initScene(Scene *sc) {
g_vars->scene34_cactus = sc->getStaticANIObject1ById(ANI_CACTUS_34, -1);
g_vars->scene34_vent = sc->getStaticANIObject1ById(ANI_VENT_34, -1);
g_vars->scene34_hatch = sc->getStaticANIObject1ById(ANI_LUK_34, -1);
g_vars->scene34_boot = sc->getStaticANIObject1ById(ANI_BOOT_34, -1);
if (g_nmi->getObjectState(sO_Cactus) == g_nmi->getObjectEnumState(sO_Cactus, sO_HasGrown)) {
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
g_vars->scene34_cactus->changeStatics2(ST_CTS34_EMPTY);
g_vars->scene34_cactus->setOXY(506, 674);
g_vars->scene34_cactus->_priority = 30;
g_vars->scene34_cactus->changeStatics2(ST_CTS34_GROWNEMPTY2);
g_vars->scene34_cactus->_flags |= 4;
g_nmi->_currentScene = oldsc;
}
if (g_nmi->getObjectState(sO_Grandma) == g_nmi->getObjectEnumState(sO_Grandma, sO_Strolling))
g_nmi->setObjectState(sO_Grandma, g_nmi->getObjectEnumState(sO_Grandma, sO_OnStool));
sceneHandler34_setExits();
g_vars->scene34_dudeClimbed = false;
g_vars->scene34_dudeOnBoard = false;
g_vars->scene34_dudeOnCactus = false;
g_vars->scene34_fliesCountdown = g_nmi->_rnd.getRandomNumber(500) + 500;
g_nmi->_floaters->init(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_34"));
g_nmi->lift_setButton(sO_Level7, ST_LBN_7N);
g_nmi->lift_init(sc, QU_SC34_ENTERLIFT, QU_SC34_EXITLIFT);
g_nmi->initArcadeKeys("SC_34");
}
void scene34_initBeh() {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene34_cactus, ST_CTS34_GROWNEMPTY2, QU_CTS34_FALLEFT, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene34_cactus, ST_CTS34_GROWNEMPTY2, QU_CTS34_FALLRIGHT, 0);
}
int scene34_updateCursor() {
g_nmi->updateCursorCommon();
if ((g_nmi->_objectIdAtCursor != ANI_STOOL_34 || getGameLoaderInventory()->getSelectedItemId() != ANI_INV_BOX)
&& (g_nmi->_objectIdAtCursor != ANI_BOX_34 || getGameLoaderInventory()->getSelectedItemId() != ANI_INV_STOOL))
; // emtpy
else
g_nmi->_cursorId = PIC_CSR_ITN_INV;
return g_nmi->_cursorId;
}
void sceneHandler34_leaveBoard() {
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 1);
g_vars->scene34_dudeOnBoard = false;
}
void sceneHandler34_onBoard() {
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 0);
g_vars->scene34_dudeOnBoard = true;
}
void sceneHandler34_testVent() {
if (g_nmi->_aniMan->_movement->_id == MV_MAN34_TURNVENT_R) {
g_vars->scene34_hatch->changeStatics2(ST_LUK34_CLOSED);
chainQueue(QU_LUK34_OPEN, 0);
} else if (g_nmi->_aniMan->_movement->_id == MV_MAN34_TURNVENT_L) {
g_vars->scene34_hatch->changeStatics2(ST_LUK34_OPEN);
chainQueue(QU_LUK34_CLOSE, 0);
}
}
void sceneHandler34_hideStool() {
g_nmi->_currentScene->getStaticANIObject1ById(ANI_STOOL_34, -1)->hide();
}
void sceneHandler34_climb() {
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 0);
g_vars->scene34_dudeClimbed = true;
}
void sceneHandler34_genFlies() {
g_nmi->_floaters->genFlies(g_nmi->_currentScene, 1072, -50, 100, 4);
g_nmi->_floaters->_array2[g_nmi->_floaters->_array2.size() - 1].countdown = 1;
g_nmi->_floaters->_array2[g_nmi->_floaters->_array2.size() - 1].val6 = 1072;
g_nmi->_floaters->_array2[g_nmi->_floaters->_array2.size() - 1].val7 = -50;
g_vars->scene34_fliesCountdown = g_nmi->_rnd.getRandomNumber(500) + 500;
}
void sceneHandler34_fromCactus(ExCommand *cmd) {
if (g_nmi->_aniMan->_movement || g_vars->scene34_cactus->_movement || (g_nmi->_aniMan->_flags & 0x100)) {
cmd->_messageKind = 0;
return;
}
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC34_FROMCACTUS), 0, 0);
ExCommand *ex = new ExCommand(ANI_MAN, 34, 256, 0, 0, 0, 1, 0, 0, 0);
ex->_messageNum = 0;
ex->_excFlags |= 3;
ex->_z = 256;
mq->addExCommandToEnd(ex);
ex = cmd->createClone();
mq->addExCommandToEnd(ex);
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
g_nmi->_aniMan->_flags |= 0x100;
}
void sceneHandler34_animateLeaveBoard(ExCommand *cmd) {
if (!g_nmi->_aniMan->_movement) {
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC34_LEAVEBOARD), 0, 0);
mq->addExCommandToEnd(cmd->createClone());
mq->setFlags(mq->getFlags() | 1);
mq->chain(nullptr);
}
cmd->_messageKind = 0;
}
void sceneHandler34_animateAction(ExCommand *cmd) {
if (g_nmi->_aniMan->_movement)
return;
int ox = g_nmi->_aniMan->_ox;
int oy = g_nmi->_aniMan->_oy;
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(g_nmi->_sceneRect.left + cmd->_x, g_nmi->_sceneRect.top + cmd->_y);
if (!ani || ani->_id != ANI_VENT_34) {
int qId = 0;
if (ox == 887) {
if (oy != 370)
return;
qId = QU_SC34_FROMSTOOL;
} else {
if (ox != 916)
return;
if (oy == 286) {
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC34_FROMBOX), 0, 0);
mq->addExCommandToEnd(cmd->createClone());
mq->chain(nullptr);
sceneHandler34_setExits();
return;
}
if (oy != 345)
return;
qId = QU_SC34_FROMBOX_FLOOR;
}
if (qId) {
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(qId), 0, 0);
mq->addExCommandToEnd(cmd->createClone());
mq->chain(nullptr);
}
return;
}
if (ox == 887) {
if (oy == 370)
g_nmi->_aniMan->startAnim(MV_MAN34_TRYTABUR, 0, -1);
} else if (ox == 916) {
if (oy == 286) {
int id = g_vars->scene34_vent->_statics->_staticsId;
if (id == ST_VNT34_UP2) {
g_nmi->_aniMan->startAnim(MV_MAN34_TURNVENT_R, 0, -1);
} else if (id == ST_VNT34_RIGHT3) {
g_nmi->_aniMan->startAnim(MV_MAN34_TURNVENT_L, 0, -1);
}
} else if (oy == 345) {
g_nmi->_aniMan->startAnim(MV_MAN34_TRY, 0, -1);
}
}
}
void sceneHandler34_showVent() {
if (g_vars->scene34_vent->_statics->_staticsId == ST_VNT34_UP2)
g_vars->scene34_vent->changeStatics2(ST_VNT34_RIGHT3);
else if (g_vars->scene34_vent->_statics->_staticsId == ST_VNT34_RIGHT3)
g_vars->scene34_vent->changeStatics2(ST_VNT34_UP2);
g_vars->scene34_vent->show1(-1, -1, -1, 0);
}
void sceneHandler34_showBox() {
g_nmi->_currentScene->getStaticANIObject1ById(ANI_STOOL_34, -1)->changeStatics2(ST_STL34_BOX2);
}
void sceneHandler34_showStool() {
chainQueue(QU_SC34_SHOWSTOOL, 0);
}
void sceneHandler34_unclimb() {
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 1);
g_vars->scene34_dudeClimbed = false;
}
int sceneHandler34(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_SC4_HIDEBOOT:
g_vars->scene34_boot->_flags &= 0xFFFB;
break;
case MSG_SC34_LEAVEBOARD:
sceneHandler34_leaveBoard();
break;
case MSG_SC34_ONBOARD:
sceneHandler34_onBoard();
break;
case MSG_SC34_TESTVENT:
sceneHandler34_testVent();
break;
case MSG_LIFT_CLICKBUTTON:
g_nmi->lift_clickButton();
break;
case MSG_SC34_FROMCACTUS:
g_vars->scene34_dudeOnCactus = false;
getCurrSceneSc2MotionController()->activate();
getGameLoaderInteractionController()->enableFlag24();
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 1);
break;
case MSG_SC34_RETRYVENT:
if (!g_nmi->_aniMan->isIdle())
break;
g_nmi->_aniMan->changeStatics2(ST_MAN_RIGHT);
g_nmi->_aniMan->_flags &= 0xFEFF;
getGameLoaderInteractionController()->handleInteraction(g_nmi->_aniMan, g_vars->scene34_vent, cmd->_param);
break;
case MSG_SC34_ONBUMP:
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene34_cactus, ST_CTS34_GROWNEMPTY2, QU_CTS34_FALLEFT, 1);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene34_cactus, ST_CTS34_GROWNEMPTY2, QU_CTS34_FALLRIGHT, 1);
break;
case MSG_LIFT_CLOSEDOOR:
g_nmi->lift_closedoorSeq();
break;
case MSG_LIFT_EXITLIFT:
g_nmi->lift_exitSeq(cmd);
break;
case MSG_LIFT_STARTEXITQUEUE:
g_nmi->lift_startExitQueue();
break;
case MSG_SC22_HIDESTOOL:
sceneHandler34_hideStool();
break;
case MSG_SC34_CLIMB:
sceneHandler34_climb();
break;
case MSG_SC34_UNCLIMB:
sceneHandler34_unclimb();
break;
case MSG_SC22_SHOWSTOOL:
sceneHandler34_showStool();
break;
case MSG_SC34_SHOWBOX:
sceneHandler34_showBox();
break;
case MSG_SC34_ONCACTUS:
g_vars->scene34_dudeOnCactus = true;
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
g_nmi->_behaviorManager->setFlagByStaticAniObject(g_nmi->_aniMan, 0);
break;
case MSG_SC34_SHOWVENT:
sceneHandler34_showVent();
break;
case 64:
g_nmi->lift_hoverButton(cmd);
break;
case MSG_LIFT_GO:
g_nmi->lift_goAnimation();
break;
case 29:
{
if (g_vars->scene34_dudeClimbed) {
sceneHandler34_animateAction(cmd);
break;
}
if (g_vars->scene34_dudeOnBoard) {
sceneHandler34_animateLeaveBoard(cmd);
break;
}
if (g_vars->scene34_dudeOnCactus) {
sceneHandler34_fromCactus(cmd);
break;
}
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(g_nmi->_sceneRect.left + cmd->_x, g_nmi->_sceneRect.top + cmd->_y);
if (ani) {
if ((ani->_id == ANI_STOOL_34 && cmd->_param == ANI_INV_BOX) || (ani->_id == ANI_BOX_34 && cmd->_param == ANI_INV_STOOL)) {
getGameLoaderInteractionController()->handleInteraction(g_nmi->_aniMan, g_vars->scene34_vent, cmd->_param);
cmd->_messageKind = 0;
}
if (ani->_id == ANI_LIFTBUTTON) {
g_nmi->lift_animateButton(ani);
cmd->_messageKind = 0;
break;
}
}
if (!ani || !canInteractAny(g_nmi->_aniMan, ani, cmd->_param)) {
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picId, 0);
if (!pic || !canInteractAny(g_nmi->_aniMan, pic, cmd->_param)) {
if ((g_nmi->_sceneRect.right - cmd->_sceneClickX < 47 && g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1) || (cmd->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0)) {
g_nmi->processArcade(cmd);
break;
}
}
}
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
g_nmi->sceneAutoScrolling();
}
--g_vars->scene34_fliesCountdown;
if (!g_vars->scene34_fliesCountdown)
sceneHandler34_genFlies();
g_nmi->_floaters->update();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,267 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
#include "ngi/floaters.h"
namespace NGI {
void scene35_initScene(Scene *sc) {
g_vars->scene35_hose = sc->getStaticANIObject1ById(ANI_HOSE, -1);
g_vars->scene35_bellyInflater = sc->getStaticANIObject1ById(ANI_PUZODUV, -1);
g_vars->scene35_flowCounter = 0;
g_vars->scene35_fliesCounter = 0;
MovGraphLink *lnk = getSc2MctlCompoundBySceneId(sc->_sceneId)->getLinkByName(sO_CloseThing);
if (g_vars->scene35_bellyInflater->_statics->_staticsId == ST_PDV_LARGE)
lnk->_flags |= 0x20000000;
else
lnk->_flags &= 0xDFFFFFFF;
int sndId = 0;
if (g_nmi->getObjectState(sO_Valve_35) == g_nmi->getObjectEnumState(sO_Valve_35, sO_TurnedOn)) {
if ((g_vars->scene35_hose->_flags & 4) && g_vars->scene35_hose->_statics->_staticsId == ST_HZE_NORM) {
sndId = SND_35_012;
} else if (g_vars->scene35_bellyInflater->_statics->_staticsId == ST_PDV_SMALL) {
sndId = SND_35_011;
}
}
if (sndId)
g_nmi->playSound(sndId, 1);
g_nmi->lift_setButton(sO_Level6, ST_LBN_6N);
g_nmi->lift_init(sc, QU_SC35_ENTERLIFT, QU_SC35_EXITLIFT);
g_nmi->initArcadeKeys("SC_35");
g_nmi->_floaters->init(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_35"));
}
void sceneHandler35_stopFlow() {
g_nmi->setObjectState(sO_Valve_35, g_nmi->getObjectEnumState(sO_Valve_35, sO_TurnedOff));
g_nmi->stopAllSoundInstances(SND_35_011);
g_nmi->playSound(SND_35_026, 0);
}
void sceneHandler35_shrink() {
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing, 0);
}
void sceneHandler35_startFlow() {
if (g_nmi->getObjectState(sO_Valve_35) == g_nmi->getObjectEnumState(sO_Valve_35, sO_TurnedOn)) {
if ((g_vars->scene35_hose->_flags & 4) && g_vars->scene35_hose->_statics->_staticsId == ST_HZE_NORM) {
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene35_bellyInflater, ST_PDV_SMALL, QU_PDV_SML_BLINK, 0);
g_nmi->_behaviorManager->setBehaviorEnabled(g_vars->scene35_bellyInflater, ST_PDV_SMALL, QU_PDV_SML_TRY, 0);
g_vars->scene35_bellyInflater->changeStatics2(ST_PDV_SMALL);
g_vars->scene35_bellyInflater->_flags &= ~0x100;
MessageQueue *mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(QU_SC35_EATHOZE), 0, 0);
mq->setFlags(mq->getFlags() | 1);
ExCommand *cmd = new ExCommand(g_vars->scene35_bellyInflater->_id, 34, 256, 0, 0, 0, 1, 0, 0, 0);
cmd->_excFlags |= 3;
cmd->_z = 256;
cmd->_messageNum = 0;
mq->addExCommandToEnd(cmd);
if (!mq->chain(g_vars->scene35_bellyInflater))
delete mq;
g_vars->scene35_bellyInflater->_flags |= 0x100;
getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing, 1);
g_nmi->playSound(SND_35_012, 1);
} else {
if (!g_vars->scene35_flowCounter)
g_vars->scene35_flowCounter = 98;
g_nmi->playSound(SND_35_011, 1);
}
}
}
void sceneHandler35_genFlies() {
StaticANIObject *fly = g_nmi->_currentScene->getStaticANIObject1ById(ANI_FLY, -1);
int xoff = 0;
if ((!fly || !(fly->_flags & 4)) && !(g_nmi->_rnd.getRandomNumber(32767) % 30)) {
int x, y;
if (g_nmi->_rnd.getRandomNumber(1)) {
x = 600;
y = 0;
} else {
x = 0;
y = 600;
}
int numFlies = g_nmi->_rnd.getRandomNumber(3) + 1;
while (numFlies--) {
g_nmi->_floaters->genFlies(g_nmi->_currentScene, g_nmi->_rnd.getRandomNumber(55) + 1057, g_nmi->_rnd.getRandomNumber(60) + x + xoff, 4, 1);
xoff += 40;
g_nmi->_floaters->_array2[g_nmi->_floaters->_array2.size() - 1].val2 = 1084;
g_nmi->_floaters->_array2[g_nmi->_floaters->_array2.size() - 1].val3 = y;
g_nmi->_floaters->_array2[g_nmi->_floaters->_array2.size() - 1].val11 = 8.0;
}
g_vars->scene35_fliesCounter = 0;
}
}
int sceneHandler35(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_LIFT_CLOSEDOOR:
g_nmi->lift_closedoorSeq();
break;
case MSG_LIFT_EXITLIFT:
g_nmi->lift_exitSeq(cmd);
break;
case MSG_LIFT_STARTEXITQUEUE:
g_nmi->lift_startExitQueue();
break;
case MSG_LIFT_CLICKBUTTON:
g_nmi->lift_clickButton();
break;
case MSG_SC35_STOPFLOW:
sceneHandler35_stopFlow();
break;
case MSG_SC35_CHECKPIPESOUND:
if (g_nmi->getObjectState(sO_Valve_35) == g_nmi->getObjectEnumState(sO_Valve_35, sO_TurnedOn)) {
g_nmi->stopAllSoundInstances(SND_35_011);
g_nmi->playSound(SND_35_012, 1);
g_vars->scene35_flowCounter = 0;
}
break;
case MSG_SC35_SHRINK:
sceneHandler35_shrink();
break;
case MSG_LIFT_GO:
g_nmi->lift_goAnimation();
break;
case MSG_SC35_STARTFLOW:
case MSG_SC35_PLUGHOSE:
sceneHandler35_startFlow();
break;
case 64:
g_nmi->lift_hoverButton(cmd);
break;
case 29:
{
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(g_nmi->_sceneRect.left + cmd->_x, g_nmi->_sceneRect.top + cmd->_y);
if (ani)
if (ani->_id == ANI_LIFTBUTTON) {
g_nmi->lift_animateButton(ani);
cmd->_messageKind = 0;
break;
}
if (!ani || !canInteractAny(g_nmi->_aniMan, ani, cmd->_param)) {
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picId, 0);
if (!pic || !canInteractAny(g_nmi->_aniMan, pic, cmd->_param)) {
if ((g_nmi->_sceneRect.right - cmd->_sceneClickX < 47 && g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1) || (cmd->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0)) {
g_nmi->processArcade(cmd);
break;
}
}
}
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
g_nmi->sceneAutoScrolling();
}
if (g_vars->scene35_flowCounter > 0) {
--g_vars->scene35_flowCounter;
if (!g_vars->scene35_flowCounter)
sceneHandler35_stopFlow();
}
g_vars->scene35_fliesCounter++;
if (g_vars->scene35_fliesCounter >= 160)
sceneHandler35_genFlies();
g_nmi->_floaters->update();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,96 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene36_initScene(Scene *sc) {
g_vars->scene36_rotohrust = sc->getStaticANIObject1ById(ANI_ROTOHRUST, -1);
g_vars->scene36_scissors = sc->getStaticANIObject1ById(ANI_SCISSORS_36, -1);
}
int scene36_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_cursorId != PIC_CSR_ITN || g_nmi->_objectIdAtCursor != ANI_ROTOHRUST) {
if (g_nmi->_objectIdAtCursor == PIC_SC36_MASK && g_nmi->_cursorId == PIC_CSR_DEFAULT && (g_vars->scene36_scissors->_flags & 4))
g_nmi->_cursorId = PIC_CSR_ITN;
} else if (g_vars->scene36_rotohrust->_statics->_staticsId == ST_RHT_OPEN)
g_nmi->_cursorId = PIC_CSR_GOL;
return g_nmi->_cursorId;
}
int sceneHandler36(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case 29:
if (g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY) == PIC_SC36_MASK)
if (g_vars->scene36_scissors)
if (g_vars->scene36_scissors->_flags & 4)
if (g_nmi->_aniMan->isIdle())
if (!(g_nmi->_aniMan->_flags & 0x100) && g_nmi->_msgObjectId2 != g_vars->scene36_scissors->_id ) {
handleObjectInteraction(g_nmi->_aniMan, g_vars->scene36_scissors, cmd->_param);
cmd->_messageKind = 0;
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
}
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,332 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
Ring::Ring() {
ani = nullptr;
x = 0;
y = 0;
numSubRings = 0;
for (int i = 0; i < 10; i++)
subRings[i] = 0;
state = false;
}
void scene37_initScene(Scene *sc) {
Ring *ring;
StaticANIObject *ani;
for (uint i = 0; i < g_vars->scene37_rings.size(); i++)
delete g_vars->scene37_rings[i];
g_vars->scene37_rings.clear();
g_vars->scene37_lastDudeX = -1;
ring = new Ring();
ani = sc->getStaticANIObject1ById(ANI_GUARD_37, 0);
ring->ani = ani;
ring->x = ani->_ox - 40;
ring->y = ani->_ox + 40;
ring->numSubRings = 3;
ring->subRings[0] = 1;
ring->subRings[1] = 4;
ring->subRings[2] = 8;
ring->state = false;
g_vars->scene37_rings.push_back(ring);
ring = new Ring();
ani = sc->getStaticANIObject1ById(ANI_GUARD_37, 1);
ring->ani = ani;
ring->x = ani->_ox - 40;
ring->y = ani->_ox + 40;
ring->numSubRings = 3;
ring->subRings[0] = 2;
ring->subRings[1] = 5;
ring->subRings[2] = 9;
ring->state = false;
g_vars->scene37_rings.push_back(ring);
ring = new Ring();
ani = sc->getStaticANIObject1ById(ANI_GUARD_37, 2);
ring->ani = ani;
ring->x = ani->_ox - 40;
ring->y = ani->_ox + 40;
ring->numSubRings = 3;
ring->subRings[0] = 3;
ring->subRings[1] = 7;
ring->subRings[2] = 11;
ring->state = false;
g_vars->scene37_rings.push_back(ring);
g_nmi->setObjectState(sO_LeftPipe_37, g_nmi->getObjectEnumState(sO_LeftPipe_37, sO_IsClosed));
Scene *oldsc = g_nmi->_currentScene;
g_nmi->_currentScene = sc;
g_vars->scene37_pipeIsOpen = false;
g_vars->scene37_plusMinus1 = sc->getStaticANIObject1ById(ANI_PLUSMINUS, 1);
for (int i = 0; i < g_vars->scene37_rings[0]->numSubRings; i++) {
ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_RING, g_vars->scene37_rings[0]->subRings[i]);
if (g_nmi->getObjectState(sO_Guard_1) == g_nmi->getObjectEnumState(sO_Guard_1, sO_On)) {
g_vars->scene37_plusMinus1->_statics = g_vars->scene37_plusMinus1->getStaticsById(ST_PMS_PLUS);
ani->changeStatics2(ST_RNG_OPEN);
} else {
g_vars->scene37_plusMinus1->_statics = g_vars->scene37_plusMinus1->getStaticsById(ST_PMS_MINUS);
ani->changeStatics2(ST_RNG_CLOSED2);
}
}
g_vars->scene37_plusMinus2 = sc->getStaticANIObject1ById(ANI_PLUSMINUS, 2);
for (int i = 0; i < g_vars->scene37_rings[1]->numSubRings; i++) {
ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_RING, g_vars->scene37_rings[1]->subRings[i]);
if (g_nmi->getObjectState(sO_Guard_2) == g_nmi->getObjectEnumState(sO_Guard_2, sO_On)) {
g_vars->scene37_plusMinus2->_statics = g_vars->scene37_plusMinus2->getStaticsById(ST_PMS_PLUS);
ani->changeStatics2(ST_RNG_OPEN);
} else {
g_vars->scene37_plusMinus2->_statics = g_vars->scene37_plusMinus2->getStaticsById(ST_PMS_MINUS);
ani->changeStatics2(ST_RNG_CLOSED2);
}
}
g_vars->scene37_plusMinus3 = sc->getStaticANIObject1ById(ANI_PLUSMINUS, 3);
for (int i = 0; i < g_vars->scene37_rings[2]->numSubRings; i++) {
ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_RING, g_vars->scene37_rings[2]->subRings[i]);
if (g_nmi->getObjectState(sO_Guard_3) == g_nmi->getObjectEnumState(sO_Guard_3, sO_On)) {
g_vars->scene37_plusMinus3->_statics = g_vars->scene37_plusMinus3->getStaticsById(ST_PMS_PLUS);
ani->changeStatics2(ST_RNG_OPEN);
} else {
g_vars->scene37_plusMinus3->_statics = g_vars->scene37_plusMinus3->getStaticsById(ST_PMS_MINUS);
ani->changeStatics2(ST_RNG_CLOSED2);
}
}
g_nmi->_currentScene = oldsc;
g_nmi->initArcadeKeys("SC_37");
}
int scene37_updateCursor() {
g_nmi->updateCursorCommon();
if (g_nmi->_cursorId == PIC_CSR_ITN && g_nmi->_objectIdAtCursor == PIC_SC37_MASK) {
if (g_vars->scene37_pipeIsOpen)
g_nmi->_cursorId = PIC_CSR_GOL;
}
return g_nmi->_cursorId;
}
void sceneHandler37_updateRing(int ringNum) {
g_vars->scene37_rings[ringNum]->ani->changeStatics2(ST_GRD37_STAND);
g_vars->scene37_rings[ringNum]->ani->startAnim(MV_GRD37_PULL, 0, -1);
g_vars->scene37_rings[ringNum]->state = !g_vars->scene37_rings[ringNum]->state;
StaticANIObject *ani;
for (int i = 0; i < g_vars->scene37_rings[ringNum]->numSubRings; i++) {
ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_RING, g_vars->scene37_rings[ringNum]->subRings[i]);
if ((ani->_movement && ani->_movement->_id != MV_RNG_CLOSE) || ani->_statics->_staticsId != ST_RNG_CLOSED2) {
ani->changeStatics2(ST_RNG_OPEN);
ani->startAnim(MV_RNG_CLOSE, 0, -1);
} else {
ani->changeStatics2(ST_RNG_CLOSED2);
ani->startAnim(MV_RNG_OPEN, 0, -1);
}
}
g_vars->scene37_pipeIsOpen = true;
for (uint i = 0; i < g_vars->scene37_rings.size(); i++) {
for (int j = 0; j < g_vars->scene37_rings[i]->numSubRings; j++) {
ani = g_nmi->_currentScene->getStaticANIObject1ById(ANI_RING, g_vars->scene37_rings[i]->subRings[j]);
debugC(2, kDebugSceneLogic, "ring[%d][%d]: mov: %d st: %d", i, j, (ani->_movement ? ani->_movement->_id : 0), ani->_statics->_staticsId);
if (ani->_movement) {
if (ani->_movement->_id == MV_RNG_CLOSE)
g_vars->scene37_pipeIsOpen = false;
} else {
if (ani->_statics->_staticsId == ST_RNG_CLOSED2)
g_vars->scene37_pipeIsOpen = false;
}
}
}
debugC(1, kDebugSceneLogic, "Pipe is: %s", g_vars->scene37_pipeIsOpen ? "open" : "closed");
int state;
if (g_vars->scene37_pipeIsOpen)
state = g_nmi->getObjectEnumState(sO_LeftPipe_37, sO_IsOpened);
else
state = g_nmi->getObjectEnumState(sO_LeftPipe_37, sO_IsClosed);
g_nmi->setObjectState(sO_LeftPipe_37, state);
}
void sceneHandler37_setRingsState() {
if (g_vars->scene37_lastDudeX == -1) {
g_vars->scene37_lastDudeX = g_vars->scene37_dudeX;
} else {
for (uint i = 0; i < g_vars->scene37_rings.size(); i++) {
int x = g_vars->scene37_rings[i]->x;
if (g_vars->scene37_lastDudeX > x && g_vars->scene37_dudeX <= x && !g_vars->scene37_rings[i]->state)
sceneHandler37_updateRing(i);
x = g_vars->scene37_rings[i]->y;
if (g_vars->scene37_lastDudeX < x && g_vars->scene37_dudeX >= x) {
if (g_vars->scene37_rings[i]->state)
sceneHandler37_updateRing(i);
}
}
g_vars->scene37_lastDudeX = g_vars->scene37_dudeX;
}
}
int sceneHandler37(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch(cmd->_messageNum) {
case MSG_SC37_EXITLEFT:
sceneHandler37_updateRing(0);
sceneHandler37_updateRing(1);
sceneHandler37_updateRing(2);
break;
case 29:
{
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
if (!ani || !canInteractAny(g_nmi->_aniMan, ani, cmd->_param)) {
int picId = g_nmi->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
PictureObject *pic = g_nmi->_currentScene->getPictureObjectById(picId, 0);
if (!pic || !canInteractAny(g_nmi->_aniMan, pic, cmd->_param)) {
if ((g_nmi->_sceneRect.right - cmd->_sceneClickX < 47 && g_nmi->_sceneRect.right < g_nmi->_sceneWidth - 1)
|| (cmd->_sceneClickX - g_nmi->_sceneRect.left < 47 && g_nmi->_sceneRect.left > 0)) {
g_nmi->processArcade(cmd);
break;
}
}
}
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
g_vars->scene37_dudeX = x;
if (x >= 500) {
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
} else {
g_nmi->_currentScene->_x = -g_nmi->_sceneRect.left;
}
x = g_vars->scene37_dudeX;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
g_nmi->sceneAutoScrolling();
}
sceneHandler37_setRingsState();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
++g_vars->scene37_soundFlipper;
break;
case MSG_SC37_PULL:
if (g_vars->scene37_rings[0]->ani->_movement && g_vars->scene37_rings[0]->ani->_movement->_id == MV_GRD37_PULL) {
if ((g_nmi->getObjectState(sO_Guard_1) == g_nmi->getObjectEnumState(sO_Guard_1, sO_On) && !g_vars->scene37_rings[0]->state)
|| (g_nmi->getObjectState(sO_Guard_1) == g_nmi->getObjectEnumState(sO_Guard_1, sO_Off) && g_vars->scene37_rings[0]->state)) {
g_vars->scene37_plusMinus1->_statics = g_vars->scene37_plusMinus1->getStaticsById(ST_PMS_PLUS);
} else {
g_vars->scene37_plusMinus1->_statics = g_vars->scene37_plusMinus1->getStaticsById(ST_PMS_MINUS);
}
} else if (g_vars->scene37_rings[1]->ani->_movement && g_vars->scene37_rings[1]->ani->_movement->_id == MV_GRD37_PULL) {
if ((g_nmi->getObjectState(sO_Guard_2) == g_nmi->getObjectEnumState(sO_Guard_2, sO_On) && !g_vars->scene37_rings[1]->state)
|| (g_nmi->getObjectState(sO_Guard_2) == g_nmi->getObjectEnumState(sO_Guard_2, sO_Off) && g_vars->scene37_rings[1]->state)) {
g_vars->scene37_plusMinus2->_statics = g_vars->scene37_plusMinus2->getStaticsById(ST_PMS_PLUS);
} else {
g_vars->scene37_plusMinus2->_statics = g_vars->scene37_plusMinus2->getStaticsById(ST_PMS_MINUS);
}
} else if (g_vars->scene37_rings[2]->ani->_movement && g_vars->scene37_rings[2]->ani->_movement->_id == MV_GRD37_PULL) {
if ((g_nmi->getObjectState(sO_Guard_3) == g_nmi->getObjectEnumState(sO_Guard_3, sO_On) && !g_vars->scene37_rings[2]->state)
|| (g_nmi->getObjectState(sO_Guard_3) == g_nmi->getObjectEnumState(sO_Guard_3, sO_Off) && g_vars->scene37_rings[2]->state)) {
g_vars->scene37_plusMinus3->_statics = g_vars->scene37_plusMinus3->getStaticsById(ST_PMS_PLUS);
} else {
g_vars->scene37_plusMinus3->_statics = g_vars->scene37_plusMinus3->getStaticsById(ST_PMS_MINUS);
}
}
if (g_vars->scene37_soundFlipper) {
g_nmi->playSound(SND_37_007, 0);
g_vars->scene37_soundFlipper = 0;
}
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View File

@@ -0,0 +1,411 @@
/* 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
namespace NGI {
void scene38_setBottleState(Scene *sc) {
ExCommand *ex = sc->getMessageQueueById(QU_SC38_SHOWBOTTLE_ONTABLE)->getExCommandByIndex(0);
if (g_vars->scene38_bottle->_ox == ex->_x && g_vars->scene38_bottle->_oy == ex->_y) {
if (g_nmi->lift_checkButton(sO_Level5) ) {
ex = sc->getMessageQueueById(QU_SC38_SHOWBOTTLE)->getExCommandByIndex(0);
g_vars->scene38_bottle->setOXY(ex->_x, ex->_y);
g_vars->scene38_bottle->_priority = ex->_z;
g_nmi->setObjectState(sO_Bottle_38, g_nmi->getObjectEnumState(sO_Bottle_38, sO_Blocked));
}
}
}
void scene38_initScene(Scene *sc) {
g_vars->scene38_boss = sc->getStaticANIObject1ById(ANI_GLAVAR, -1);
g_vars->scene38_tally = sc->getStaticANIObject1ById(ANI_DYLDA, -1);
g_vars->scene38_shorty = sc->getStaticANIObject1ById(ANI_MALYSH, -1);
g_vars->scene38_domino0 = sc->getStaticANIObject1ById(ANI_DOMINO38, 0);
g_vars->scene38_dominos = sc->getStaticANIObject1ById(ANI_DOMINOS, 0);
g_vars->scene38_domino1 = sc->getStaticANIObject1ById(ANI_DOMINO38, 1);
g_vars->scene38_bottle = sc->getStaticANIObject1ById(ANI_BOTTLE38, 0);
g_vars->scene38_bossCounter = 0;
g_vars->scene38_lastBossAnim = 0;
g_vars->scene38_bossAnimCounter = 0;
g_vars->scene38_tallyCounter = 15;
g_vars->scene38_lastTallyAnim = 0;
g_vars->scene38_tallyAnimCounter = 0;
g_vars->scene38_shortyCounter = 30;
g_vars->scene38_lastShortyAnim = 0;
g_vars->scene38_shortyAnimCounter = 0;
scene38_setBottleState(sc);
if (g_nmi->getObjectState(sO_Boss) == g_nmi->getObjectEnumState(sO_Boss, sO_IsSleeping)) {
g_vars->scene38_shorty->_flags &= 0xFFFB;
g_vars->scene38_tally->stopAnim_maybe();
g_vars->scene38_tally->_flags &= 0xFFFB;
g_vars->scene38_domino0->_flags &= 0xFFFB;
g_vars->scene38_dominos->_flags &= 0xFFFB;
g_vars->scene38_domino1->_flags &= 0xFFFB;
}
g_nmi->lift_init(sc, QU_SC38_ENTERLIFT, QU_SC38_EXITLIFT);
g_nmi->lift_setButtonStatics(sc, ST_LBN_0N);
}
void sceneHandler38_tryTakeBottle() {
g_vars->scene38_boss->changeStatics2(ST_GLV_NOHAMMER);
g_vars->scene38_boss->startAnim(MV_GLV_LOOKMAN, 0, -1);
g_vars->scene38_bossCounter = 0;
}
void sceneHandler38_postHammerKick() {
g_vars->scene38_domino1->setOXY(g_vars->scene38_domino1->_ox, g_vars->scene38_domino1->_oy + 2);
}
void sceneHandler38_propose() {
if (!g_vars->scene38_tally->_movement) {
if (g_vars->scene38_tally->_flags & 4) {
if (!(g_vars->scene38_tally->_flags & 2) && g_vars->scene38_tallyCounter > 0
&& g_nmi->_rnd.getRandomNumber(32767) < 32767) {
chainQueue(QU_DLD_DENY, 0);
g_vars->scene38_tallyCounter = 0;
}
}
}
}
void sceneHandler38_point() {
if ((!g_vars->scene38_boss->_movement && ((g_vars->scene38_boss->_flags & 4) || !(g_vars->scene38_boss->_flags & 2)))
&& g_vars->scene38_bossCounter > 0
&& g_nmi->_rnd.getRandomNumber(32767) < 32767) {
if (g_vars->scene38_boss->_statics->_staticsId == ST_GLV_HAMMER) {
chainQueue(QU_GLV_TOSMALL, 0);
g_vars->scene38_bossCounter = 0;
} else {
if (g_vars->scene38_boss->_statics->_staticsId == ST_GLV_NOHAMMER)
chainQueue(QU_GLV_TOSMALL_NOHMR, 0);
g_vars->scene38_bossCounter = 0;
}
}
}
void sceneHandler38_hammerKick() {
if (!g_vars->scene38_shorty->_movement) {
if (g_vars->scene38_shorty->_flags & 4) {
if (!(g_vars->scene38_shorty->_flags & 2) && g_vars->scene38_shortyCounter > 1
&& g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_LEFT2
&& g_nmi->_rnd.getRandomNumber(32767) < 3276) {
chainQueue(QU_MLS_TURNR, 0);
g_vars->scene38_shortyCounter = 0;
}
}
}
g_vars->scene38_domino1->setOXY(g_vars->scene38_domino1->_ox, g_vars->scene38_domino1->_oy - 2);
if (g_vars->scene38_dominos->_statics->_staticsId == ST_DMS_3)
g_vars->scene38_dominos->startAnim(MV_DMS_THREE, 0, -1);
else if (g_vars->scene38_dominos->_statics->_staticsId == ST_DMS_4)
g_vars->scene38_dominos->startAnim(MV_DMS_FOUR, 0, -1);
}
void sceneHandler38_drink() {
if (!g_vars->scene38_shorty->_movement) {
if (g_vars->scene38_shorty->_flags & 4) {
if (!(g_vars->scene38_shorty->_flags & 2) && g_vars->scene38_shortyCounter > 0
&& g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_LEFT2
&& g_nmi->_rnd.getRandomNumber(32767) < 3276) {
chainQueue(QU_MLS_TURNR, 0);
g_vars->scene38_shortyCounter = 0;
}
}
}
}
void sceneHandler38_animateAlcoholics() {
MessageQueue *mq;
if (g_vars->scene38_boss->_movement || !(g_vars->scene38_boss->_flags & 4) || (g_vars->scene38_boss->_flags & 2)) {
g_vars->scene38_bossCounter = 0;
} else {
g_vars->scene38_bossCounter++;
}
if (g_vars->scene38_bossCounter >= 50) {
int bossSt = g_vars->scene38_boss->_statics->_staticsId;
if (bossSt == ST_GLV_SLEEP2) {
g_vars->scene38_bossCounter = 0;
} else if ((g_vars->scene38_domino0->_flags & 4) && g_vars->scene38_domino0->_statics->_staticsId == ST_DMN38_6) {
if (bossSt == ST_GLV_HAMMER) {
chainQueue(QU_GLV_TAKEDOMINO, 1);
g_vars->scene38_bossCounter = 0;
}
if (bossSt == ST_GLV_NOHAMMER) {
chainQueue(QU_GLV_TAKEDOMINO_NOHMR, 1);
g_vars->scene38_bossCounter = 0;
}
} else {
if ((g_vars->scene38_bottle->_flags & 4) && g_vars->scene38_bottle->_statics->_staticsId == ST_BTL38_FULL && bossSt == ST_GLV_NOHAMMER) {
chainQueue(QU_GLV_DRINKBOTTLE, 1);
g_vars->scene38_bossCounter = 0;
} else {
int bossAnim = 0;
if (g_nmi->_rnd.getRandomNumber(32767) >= 1310 || g_vars->scene38_boss->_statics->_staticsId != ST_GLV_HAMMER) {
if (g_nmi->_rnd.getRandomNumber(32767) >= 1310) {
if (g_nmi->_rnd.getRandomNumber(32767) < 1310) {
if (bossSt == ST_GLV_HAMMER)
bossAnim = QU_GLV_DRINK;
else if (bossSt == ST_GLV_NOHAMMER)
bossAnim = QU_GLV_DRINK_NOHMR;
}
} else {
if (bossSt == ST_GLV_HAMMER)
bossAnim = QU_GLV_PROPOSE;
else if (bossSt == ST_GLV_NOHAMMER)
bossAnim = QU_GLV_PROPOSE_NOHMR;
}
} else {
bossAnim = QU_GLV_HMRKICK;
}
if (g_vars->scene38_lastBossAnim == bossAnim) {
g_vars->scene38_bossAnimCounter++;
if (g_vars->scene38_bossAnimCounter > 2)
bossAnim = 0;
} else {
g_vars->scene38_lastBossAnim = bossAnim;
g_vars->scene38_bossAnimCounter = 1;
}
if (bossAnim > 0) {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(bossAnim), 0, 0);
mq->chain(nullptr);
g_vars->scene38_bossCounter = 0;
}
}
}
}
if (g_vars->scene38_tally->_movement || !(g_vars->scene38_tally->_flags & 4) || (g_vars->scene38_tally->_flags & 2)) {
g_vars->scene38_tallyCounter = 0;
} else {
g_vars->scene38_tallyCounter++;
}
if (g_vars->scene38_tallyCounter >= 50) {
int tallyAnim = 0;
if (g_nmi->_rnd.getRandomNumber(32767) >= 1310) {
if (g_nmi->_rnd.getRandomNumber(32767) >= 1310) {
if (g_nmi->_rnd.getRandomNumber(32767) >= 1310) {
if (g_nmi->_rnd.getRandomNumber(32767) < 1310)
tallyAnim = QU_DLD_ICK;
} else {
tallyAnim = QU_DLD_GLOT;
}
} else {
tallyAnim = QU_DLD_BLINK;
}
} else {
if (g_vars->scene38_domino1->_statics->_staticsId == ST_DMN38_NORM3) {
tallyAnim = QU_DLD_TAKE1;
} else if (g_vars->scene38_domino1->_statics->_staticsId == ST_DMN38_NORM4) {
tallyAnim = QU_DLD_TAKE2;
}
}
if (g_vars->scene38_lastTallyAnim == tallyAnim) {
g_vars->scene38_tallyAnimCounter++;
if (g_vars->scene38_tallyAnimCounter++ > 2)
tallyAnim = 0;
} else {
g_vars->scene38_lastTallyAnim = tallyAnim;
g_vars->scene38_tallyAnimCounter = 1;
}
if (tallyAnim > 0) {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(tallyAnim), 0, 0);
mq->chain(nullptr);
g_vars->scene38_tallyCounter = 0;
}
}
if (g_vars->scene38_shorty->_movement || !(g_vars->scene38_shorty->_flags & 4) || (g_vars->scene38_shorty->_flags & 2)) {
g_vars->scene38_shortyCounter = 0;
return;
}
g_vars->scene38_shortyCounter++;
if (g_vars->scene38_shortyCounter < 50)
return;
int shortyAnim = 0;
if (g_nmi->_rnd.getRandomNumber(32767) >= 1310) {
if (g_nmi->_rnd.getRandomNumber(32767) >= 1310 || g_vars->scene38_shorty->_statics->_staticsId != ST_MLS_LEFT2) {
if (g_vars->scene38_boss->_statics->_staticsId != ST_GLV_SLEEP2 && g_vars->scene38_bossCounter > 30 && g_nmi->_rnd.getRandomNumber(32767) < 0x3FFF && g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_LEFT2)
shortyAnim = QU_MLS_HAND;
} else {
shortyAnim = QU_MLS_BLINK;
}
} else {
if (g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_RIGHT2) {
shortyAnim = QU_MLS_TURNL;
} else if (g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_LEFT2) {
shortyAnim = QU_MLS_TURNR;
}
}
if (g_vars->scene38_lastShortyAnim == shortyAnim) {
g_vars->scene38_shortyAnimCounter++;
if (g_vars->scene38_shortyAnimCounter > 2)
return;
} else {
g_vars->scene38_lastShortyAnim = shortyAnim;
g_vars->scene38_shortyAnimCounter = 1;
}
if (shortyAnim > 0) {
mq = new MessageQueue(g_nmi->_currentScene->getMessageQueueById(shortyAnim), 0, 0);
mq->chain(nullptr);
g_vars->scene38_shortyCounter = 0;
}
}
int sceneHandler38(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_LIFT_EXITLIFT:
g_nmi->lift_exitSeq(cmd);
break;
case MSG_LIFT_CLOSEDOOR:
g_nmi->lift_closedoorSeq();
break;
case MSG_LIFT_STARTEXITQUEUE:
g_nmi->lift_startExitQueue();
break;
case MSG_SC38_TRYTAKEBOTTLE:
sceneHandler38_tryTakeBottle();
break;
case MSG_SC38_POSTHMRKICK:
sceneHandler38_postHammerKick();
break;
case MSG_SC38_PROPOSE:
sceneHandler38_propose();
break;
case MSG_LIFT_CLICKBUTTON:
g_nmi->lift_clickButton();
break;
case MSG_SC38_POINT:
sceneHandler38_point();
break;
case MSG_LIFT_GO:
g_nmi->lift_goAnimation();
break;
case MSG_SC38_HMRKICK:
sceneHandler38_hammerKick();
break;
case MSG_SC38_DRINK:
sceneHandler38_drink();
break;
case 64:
g_nmi->lift_hoverButton(cmd);
break;
case 29:
{
StaticANIObject *ani = g_nmi->_currentScene->getStaticANIObjectAtPos(g_nmi->_sceneRect.left + cmd->_x, g_nmi->_sceneRect.top + cmd->_y);
if (ani && ani->_id == ANI_LIFTBUTTON) {
g_nmi->lift_animateButton(ani);
cmd->_messageKind = 0;
}
}
break;
case 33:
if (g_nmi->_aniMan2) {
int x = g_nmi->_aniMan2->_ox;
if (x < g_nmi->_sceneRect.left + 200)
g_nmi->_currentScene->_x = x - 300 - g_nmi->_sceneRect.left;
if (x > g_nmi->_sceneRect.right - 200)
g_nmi->_currentScene->_x = x + 300 - g_nmi->_sceneRect.right;
}
sceneHandler38_animateAlcoholics();
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
return 0;
}
} // End of namespace NGI

View 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/>.
*
*/
#include "ngi/ngi.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/input.h"
#include "ngi/interaction.h"
namespace NGI {
void sceneDbgMenu_initScene(Scene *sc) {
g_vars->selector = sc->getPictureObjectById(PIC_SCD_SEL, 0);
getGameLoaderInteractionController()->disableFlag24();
setInputDisabled(false);
}
GameObject *sceneHandlerDbgMenu_getObjectAtXY(int x, int y) {
if (!g_nmi->_currentScene)
return nullptr;
for (uint i = 1; i < g_nmi->_currentScene->_picObjList.size(); i++) {
PictureObject *pic = g_nmi->_currentScene->_picObjList[i];
if (x >= pic->_ox && y >= pic->_oy) {
const Dims dims = pic->getDimensions();
if (x <= pic->_ox + dims.x && y <= pic->_oy + dims.y && pic != g_vars->selector)
return pic;
}
}
return nullptr;
}
int sceneHandlerDbgMenu(ExCommand *ex) {
if (ex->_messageKind != 17)
return 0;
int mx = g_nmi->_mouseScreenPos.x + g_nmi->_sceneRect.left;
int my = g_nmi->_mouseScreenPos.y + g_nmi->_sceneRect.top;
if (ex->_messageNum == 29) {
GameObject *obj = sceneHandlerDbgMenu_getObjectAtXY(mx, my);
if (obj && canInteractAny(nullptr, obj, -3) ) {
getGameLoaderInteractionController()->enableFlag24();
handleObjectInteraction(nullptr, obj, 0);
}
return 0;
}
if (ex->_messageNum != 33) {
if (ex->_messageNum == MSG_RESTARTGAME) {
g_nmi->_needRestart = true;
return 0;
}
return 0;
}
g_nmi->_cursorId = PIC_CSR_DEFAULT;
GameObject *obj = g_nmi->_currentScene->getStaticANIObjectAtPos(mx, my);
if (obj) {
if (canInteractAny(nullptr, obj, -3)) {
g_nmi->_cursorId = PIC_CSR_DEFAULT;
g_nmi->setCursor(PIC_CSR_DEFAULT);
return 0;
}
} else {
obj = sceneHandlerDbgMenu_getObjectAtXY(mx, my);
if (obj && canInteractAny(nullptr, obj, -3) ) {
g_vars->selector->_flags |= 4;
g_vars->selector->setOXY(obj->_ox, obj->_oy);
g_nmi->_cursorId = PIC_CSR_DEFAULT;
g_nmi->setCursor(PIC_CSR_DEFAULT);
return 0;
}
g_vars->selector->_flags &= 0xFFFB;
}
g_nmi->setCursor(g_nmi->_cursorId);
return 0;
}
} // End of namespace NGI

View 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 "ngi/ngi.h"
#include "ngi/objectnames.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/statics.h"
#include "ngi/interaction.h"
#include "ngi/behavior.h"
#include "ngi/modal.h"
#include "audio/mixer.h"
namespace NGI {
void sceneFinal_initScene() {
g_nmi->_gameLoader->loadScene(SC_FINAL2);
g_nmi->accessScene(SC_FINAL2)->setPictureObjectsFlag4();
g_nmi->_gameLoader->loadScene(SC_FINAL3);
g_nmi->accessScene(SC_FINAL3)->setPictureObjectsFlag4();
g_nmi->_gameLoader->loadScene(SC_FINAL4);
g_nmi->accessScene(SC_FINAL4)->setPictureObjectsFlag4();
getGameLoaderInventory()->setIsLocked(false);
getGameLoaderInventory()->slideIn();
g_nmi->_updateFlag = false;
g_nmi->_flgCanOpenMap = false;
g_vars->sceneFinal_var01 = 0;
g_vars->sceneFinal_var02 = 0;
g_vars->sceneFinal_var03 = 0;
g_vars->sceneFinal_trackHasStarted = false;
}
int sceneFinal_updateCursor() {
if (g_vars->sceneFinal_var01)
g_nmi->_cursorId = 0;
else
g_nmi->updateCursorCommon();
return g_nmi->_cursorId;
}
void sceneHandlerFinal_endFinal() {
g_vars->sceneFinal_var01 = 0;
}
void sceneHandlerFinal_startMusic(const char *track) {
g_nmi->startSoundStream1(track);
g_vars->sceneFinal_trackHasStarted = true;
}
void sceneHandlerFinal_goto4() {
g_nmi->_currentScene = g_nmi->accessScene(SC_FINAL4);
g_nmi->_gameLoader->loadScene(SC_FINAL4);
chainQueue(QU_FN4_DOFINAL, 1);
}
void sceneHandlerFinal_goto3() {
g_nmi->_currentScene = g_nmi->accessScene(SC_FINAL3);
chainQueue(QU_FN3_DOFINAL, 1);
}
void sceneHandlerFinal_goto2() {
g_nmi->_currentScene = g_nmi->accessScene(SC_FINAL2);
chainQueue(QU_FN2_DOFINAL, 1);
}
void sceneHandlerFinal_startFinal() {
g_vars->sceneFinal_var01 = 1;
getCurrSceneSc2MotionController()->deactivate();
getGameLoaderInteractionController()->disableFlag24();
g_nmi->_aniMan2 = nullptr;
g_nmi->_aniMan->_flags &= 0xFFFB;
chainQueue(QU_FIN1_TAKECOIN, 1);
g_nmi->playTrack(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_FINAL1"), "MUSIC2", 1);
g_nmi->_modalObject = new ModalFinal;
}
void sceneHandlerFinal_fallCoin() {
StaticANIObject *coin = g_nmi->_currentScene->getStaticANIObject1ById(ANI_FIN_COIN, -1);
if (!coin->_movement) {
if (!coin->_statics || coin->_statics->_staticsId != ST_FCN_NORM)
chainQueue(QU_FIN1_FALLCOIN, 1);
}
}
void updateMusic() {
if (g_vars->sceneFinal_trackHasStarted && !g_nmi->_mixer->isSoundHandleActive(g_nmi->_soundStream1)) { // loop music
sceneHandlerFinal_startMusic("track16.ogg");
}
}
int sceneHandlerFinal(ExCommand *cmd) {
if (cmd->_messageKind != 17)
return 0;
switch (cmd->_messageNum) {
case MSG_FIN_ENDFINAL:
sceneHandlerFinal_endFinal();
break;
case MSG_FN4_STARTMUSIC:
sceneHandlerFinal_startMusic("track16.ogg");
break;
case MSG_FIN_GOTO4:
sceneHandlerFinal_goto4();
g_nmi->playTrack(g_nmi->getGameLoaderGameVar()->getSubVarByName("SC_FINAL1"), "MUSIC3", 1);
break;
case MSG_FIN_GOTO3:
sceneHandlerFinal_goto3();
break;
case MSG_FIN_GOTO2:
sceneHandlerFinal_goto2();
break;
case MSG_FIN_STARTFINAL:
sceneHandlerFinal_startFinal();
break;
case 33:
if (g_nmi->_aniMan2) {
g_vars->sceneFinal_var03 = g_nmi->_aniMan2->_ox;
if (g_vars->sceneFinal_var03 < 450 && g_vars->sceneFinal_var02 >= 450 )
sceneHandlerFinal_fallCoin();
g_vars->sceneFinal_var02 = g_vars->sceneFinal_var03;
}
g_nmi->_behaviorManager->updateBehaviors();
g_nmi->startSceneTrack();
break;
default:
break;
}
updateMusic();
return 0;
}
} // End of namespace NGI

View 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/>.
*
*/
#include "ngi/ngi.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/modal.h"
#include "ngi/statics.h"
namespace NGI {
int sceneIntro_updateCursor() {
g_nmi->_cursorId = 0;
return 0;
}
void sceneIntro_initScene(Scene *sc) {
g_nmi->_gameLoader->loadScene(SC_INTRO2);
g_vars->sceneIntro_aniin1man = sc->getStaticANIObject1ById(ANI_IN1MAN, -1);
g_vars->sceneIntro_needSleep = true;
g_vars->sceneIntro_needGetup = false;
g_vars->sceneIntro_playing = true;
g_vars->sceneIntro_needBlackout = false;
if (g_nmi->_recordEvents || g_nmi->_inputArFlag)
g_vars->sceneIntro_skipIntro = false;
g_nmi->_modalObject = new ModalIntro;
}
void sceneHandlerIntro_part1() {
g_nmi->_currentScene = g_nmi->accessScene(SC_INTRO1);
chainQueue(QU_INTR_FINISH, 0);
}
void sceneHandlerIntro_part2() {
g_nmi->_currentScene = g_nmi->accessScene(SC_INTRO2);
chainQueue(QU_IN2_DO, 0);
}
int sceneHandlerIntro(ExCommand *ex) {
if (ex->_messageKind != 17)
return 0;
switch (ex->_messageNum) {
case MSG_INTR_ENDINTRO:
g_vars->sceneIntro_playing = 0;
return 0;
case MSG_INTR_SWITCHTO1:
sceneHandlerIntro_part1();
return 0;
case MSG_INTR_GETUPMAN:
g_vars->sceneIntro_needSleep = 0;
g_vars->sceneIntro_needGetup = 1;
return 0;
case MSG_INTR_SWITCHTO2:
sceneHandlerIntro_part2();
return 0;
case 33:
// fall through
break;
default:
return 0;
}
if (g_vars->sceneIntro_needSleep) {
if (!g_vars->sceneIntro_aniin1man->_movement && g_vars->sceneIntro_aniin1man->_statics->_staticsId == ST_IN1MAN_SLEEP)
g_vars->sceneIntro_aniin1man->startAnim(MV_IN1MAN_SLEEP, 0, -1);
} else if (g_vars->sceneIntro_needGetup && !g_vars->sceneIntro_aniin1man->_movement &&
g_vars->sceneIntro_aniin1man->_statics->_staticsId == ST_IN1MAN_SLEEP) {
g_vars->sceneIntro_needGetup = 0;
chainQueue(QU_INTR_GETUPMAN, 0);
}
g_nmi->startSceneTrack();
return 0;
}
} // End of namespace NGI

View 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 "ngi/ngi.h"
#include "ngi/constants.h"
#include "ngi/gameloader.h"
#include "ngi/motion.h"
#include "ngi/scenes.h"
#include "ngi/modal.h"
#include "ngi/statics.h"
namespace NGI {
int sceneIntroDemo_updateCursor() {
g_nmi->_cursorId = 0;
return 0;
}
void sceneIntroDemo_initScene(Scene *sc) {
g_vars->sceneIntro_needSleep = true;
g_vars->sceneIntro_needGetup = false;
g_vars->sceneIntro_playing = true;
g_vars->sceneIntro_needBlackout = false;
if (g_nmi->_recordEvents || g_nmi->_inputArFlag)
g_vars->sceneIntro_skipIntro = false;
g_nmi->_modalObject = new ModalIntroDemo;
}
void sceneHandlerIntroDemo_part1() {
g_nmi->_currentScene = g_nmi->accessScene(SC_INTRO1);
chainQueue(QU_INTR_FINISH, 0);
}
void sceneHandlerIntroDemo_part2() {
chainQueue(QU_IN2_DO, 0);
}
int sceneHandlerIntroDemo(ExCommand *ex) {
if (ex->_messageKind != 17)
return 0;
switch (ex->_messageNum) {
case MSG_INTR_ENDINTRO:
g_vars->sceneIntro_playing = 0;
return 0;
case MSG_INTR_SWITCHTO1:
sceneHandlerIntroDemo_part1();
return 0;
case MSG_INTR_GETUPMAN:
g_vars->sceneIntro_needSleep = 0;
g_vars->sceneIntro_needGetup = 1;
return 0;
case MSG_INTR_SWITCHTO2:
sceneHandlerIntroDemo_part2();
return 0;
case 33:
g_nmi->startSceneTrack();
break;
default:
return 0;
}
return 0;
}
} // End of namespace NGI