/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "fullpipe/fullpipe.h" #include "fullpipe/objectnames.h" #include "fullpipe/constants.h" #include "fullpipe/gameloader.h" #include "fullpipe/motion.h" #include "fullpipe/scenes.h" #include "fullpipe/statics.h" #include "fullpipe/interaction.h" #include "fullpipe/behavior.h" namespace Fullpipe { 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_balls.numBalls = 0; g_vars->scene29_balls.pTail = 0; g_vars->scene29_balls.field_8 = 0; g_vars->scene29_balls.pHead = 0; free(g_vars->scene29_balls.cPlex); g_vars->scene29_balls.cPlex = 0; StaticANIObject *ani; g_vars->scene29_greenBalls.numBalls = 0; g_vars->scene29_greenBalls.pTail = 0; g_vars->scene29_greenBalls.field_8 = 0; g_vars->scene29_greenBalls.pHead = 0; free(g_vars->scene29_greenBalls.cPlex); g_vars->scene29_greenBalls.cPlex = 0; ani = sc->getStaticANIObject1ById(ANI_SHELL_GREEN, -1); Ball *b = g_vars->scene29_balls.sub04(g_vars->scene29_balls.field_8, 0); b->ani = ani; if (g_vars->scene29_balls.field_8) g_vars->scene29_balls.field_8->p0 = b; else g_vars->scene29_balls.pHead = b; g_vars->scene29_balls.field_8 = b; for (int i = 0; i < 2; i++) { StaticANIObject *newani = new StaticANIObject(ani); sc->addStaticANIObject(newani, 1); b = g_vars->scene29_balls.sub04(g_vars->scene29_balls.field_8, 0); b->ani = ani; if (g_vars->scene29_balls.field_8) g_vars->scene29_balls.field_8->p0 = b; else g_vars->scene29_balls.pHead = b; g_vars->scene29_balls.field_8 = b; } g_vars->scene29_redBalls.numBalls = 0; g_vars->scene29_redBalls.pTail = 0; g_vars->scene29_redBalls.field_8 = 0; g_vars->scene29_redBalls.pHead = 0; free(g_vars->scene29_redBalls.cPlex); g_vars->scene29_redBalls.cPlex = 0; g_vars->scene29_flyingRedBalls.numBalls = 0; g_vars->scene29_flyingRedBalls.pTail = 0; g_vars->scene29_flyingRedBalls.field_8 = 0; g_vars->scene29_flyingRedBalls.pHead = 0; free(g_vars->scene29_flyingRedBalls.cPlex); g_vars->scene29_flyingRedBalls.cPlex = 0; ani = sc->getStaticANIObject1ById(ANI_SHELL_RED, -1); b = g_vars->scene29_redBalls.sub04(g_vars->scene29_redBalls.field_8, 0); b->ani = ani; if (g_vars->scene29_redBalls.field_8) g_vars->scene29_redBalls.field_8->p0 = b; else g_vars->scene29_redBalls.pHead = b; g_vars->scene29_redBalls.field_8 = b; for (int i = 0; i < 2; i++) { StaticANIObject *newani = new StaticANIObject(ani); sc->addStaticANIObject(newani, 1); b = g_vars->scene29_redBalls.sub04(g_vars->scene29_redBalls.field_8, 0); b->ani = ani; if (g_vars->scene29_redBalls.field_8) g_vars->scene29_redBalls.field_8->p0 = b; else g_vars->scene29_redBalls.pHead = b; g_vars->scene29_redBalls.field_8 = b; } g_vars->scene29_bearders.clear(); ani = new StaticANIObject(g_fp->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_fp->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; Ball *newball, *ball, *oldp0; while (g_vars->scene29_greenBalls.numBalls) { ball = g_vars->scene29_greenBalls.pHead; ani = g_vars->scene29_greenBalls.pHead->ani; oldp0 = g_vars->scene29_greenBalls.pHead->p0; g_vars->scene29_greenBalls.pHead = g_vars->scene29_greenBalls.pHead->p0; if (g_vars->scene29_greenBalls.pHead) oldp0->p1 = 0; else g_vars->scene29_greenBalls.field_8 = 0; ball->p0 = g_vars->scene29_greenBalls.pTail; g_vars->scene29_greenBalls.pTail = ball; g_vars->scene29_greenBalls.numBalls--; if (!g_vars->scene29_greenBalls.numBalls) g_vars->scene29_greenBalls.reset(); ani->hide(); newball = g_vars->scene29_balls.sub04(g_vars->scene29_balls.field_8, 0); newball->ani = ani; if (g_vars->scene29_balls.field_8) g_vars->scene29_balls.field_8->p0 = newball; else g_vars->scene29_balls.pHead = newball; g_vars->scene29_balls.field_8 = newball; } while (g_vars->scene29_flyingRedBalls.numBalls) { ball = g_vars->scene29_flyingRedBalls.pHead; ani = g_vars->scene29_flyingRedBalls.pHead->ani; oldp0 = g_vars->scene29_flyingRedBalls.pHead->p0; g_vars->scene29_flyingRedBalls.pHead = g_vars->scene29_flyingRedBalls.pHead->p0; if (g_vars->scene29_flyingRedBalls.pHead) oldp0->p1 = 0; else g_vars->scene29_flyingRedBalls.field_8 = 0; ball->p0 = g_vars->scene29_flyingRedBalls.pTail; g_vars->scene29_flyingRedBalls.pTail = ball; g_vars->scene29_flyingRedBalls.numBalls--; if (!g_vars->scene29_flyingRedBalls.numBalls) { g_vars->scene29_flyingRedBalls.numBalls = 0; g_vars->scene29_flyingRedBalls.pTail = 0; g_vars->scene29_flyingRedBalls.field_8 = 0; g_vars->scene29_flyingRedBalls.pHead = 0; free(g_vars->scene29_flyingRedBalls.cPlex); g_vars->scene29_flyingRedBalls.cPlex = 0; } ani->hide(); newball = g_vars->scene29_redBalls.sub04(g_vars->scene29_redBalls.field_8, 0); newball->ani = ani; if (g_vars->scene29_redBalls.field_8) g_vars->scene29_redBalls.field_8->p0 = newball; else g_vars->scene29_redBalls.pHead = newball; g_vars->scene29_redBalls.field_8 = newball; } g_vars->scene29_ass->queueMessageQueue(0); g_vars->scene29_ass->_flags &= 0xFFFB; chainQueue(QU_SC29_ESCAPE, 1); } g_fp->setObjectState(sO_LeftPipe_29, g_fp->getObjectEnumState(sO_LeftPipe_29, sO_IsOpened)); } void sceneHandler29_shootGreen() { if (g_vars->scene29_balls.numBalls) { int x = g_vars->scene29_shooter1->_ox - 113; int y = g_vars->scene29_shooter1->_oy - 48; StaticANIObject *ani = g_vars->scene29_balls.pHead->ani; Ball *oldhead = g_vars->scene29_balls.pHead; Ball *oldp0 = g_vars->scene29_balls.pHead->p0; g_vars->scene29_balls.pHead = g_vars->scene29_balls.pHead->p0; if (g_vars->scene29_balls.pHead) oldp0->p1 = 0; else g_vars->scene29_balls.field_8 = 0; oldhead->p0 = g_vars->scene29_balls.pTail; g_vars->scene29_balls.pTail = oldhead; g_vars->scene29_balls.numBalls--; if (!g_vars->scene29_balls.numBalls) { g_vars->scene29_balls.numBalls = 0; g_vars->scene29_balls.pTail = 0; g_vars->scene29_balls.field_8 = 0; g_vars->scene29_balls.pHead = 0; free(g_vars->scene29_balls.cPlex); g_vars->scene29_balls.cPlex = 0; } ani->show1(x, y, MV_SHG_NORM, 0); ani->_priority = 5; Ball *runPtr = g_vars->scene29_greenBalls.pTail; Ball *lastP = g_vars->scene29_greenBalls.field_8; if (!g_vars->scene29_greenBalls.pTail) { g_vars->scene29_greenBalls.cPlex = (byte *)calloc(g_vars->scene29_greenBalls.cPlexLen, sizeof(Ball)); byte *p1 = g_vars->scene29_greenBalls.cPlex + (g_vars->scene29_greenBalls.cPlexLen - 1) * sizeof(Ball); if (g_vars->scene29_greenBalls.cPlexLen - 1 < 0) { runPtr = g_vars->scene29_greenBalls.pTail; } else { runPtr = g_vars->scene29_greenBalls.pTail; for (int j = 0; j < g_vars->scene29_greenBalls.cPlexLen; j++) { ((Ball *)p1)->p1 = runPtr; runPtr = (Ball *)p1; p1 -= sizeof(Ball); } g_vars->scene29_greenBalls.pTail = runPtr; } } g_vars->scene29_greenBalls.pTail = runPtr->p0; runPtr->p1 = lastP; runPtr->p0 = 0; runPtr->ani = ani; g_vars->scene29_greenBalls.numBalls++; if (g_vars->scene29_greenBalls.field_8) { g_vars->scene29_greenBalls.field_8->p0 = runPtr; g_vars->scene29_greenBalls.field_8 = runPtr; } else { g_vars->scene29_greenBalls.pHead = runPtr; g_vars->scene29_greenBalls.field_8 = runPtr; } } } void sceneHandler29_shootRed() { if (g_vars->scene29_balls.numBalls) { int x = g_vars->scene29_shooter1->_ox - 101; int y = g_vars->scene29_shooter1->_oy - 14; StaticANIObject *ani = g_vars->scene29_balls.pHead->ani; Ball *oldhead = g_vars->scene29_balls.pHead; Ball *oldp0 = g_vars->scene29_balls.pHead->p0; g_vars->scene29_balls.pHead = g_vars->scene29_balls.pHead->p0; if (g_vars->scene29_balls.pHead) oldp0->p1 = 0; else g_vars->scene29_balls.field_8 = 0; oldhead->p0 = g_vars->scene29_balls.pTail; g_vars->scene29_balls.pTail = oldhead; g_vars->scene29_balls.numBalls--; if (!g_vars->scene29_balls.numBalls) { g_vars->scene29_balls.numBalls = 0; g_vars->scene29_balls.pTail = 0; g_vars->scene29_balls.field_8 = 0; g_vars->scene29_balls.pHead = 0; free(g_vars->scene29_balls.cPlex); g_vars->scene29_balls.cPlex = 0; } ani->show1(x, y, MV_SHR_NORM, 0); ani->_priority = 5; Ball *runPtr = g_vars->scene29_flyingRedBalls.pTail; Ball *lastP = g_vars->scene29_flyingRedBalls.field_8; if (!g_vars->scene29_flyingRedBalls.pTail) { g_vars->scene29_flyingRedBalls.cPlex = (byte *)calloc(g_vars->scene29_flyingRedBalls.cPlexLen, sizeof(Ball)); byte *p1 = g_vars->scene29_flyingRedBalls.cPlex + (g_vars->scene29_flyingRedBalls.cPlexLen - 1) * sizeof(Ball); if (g_vars->scene29_flyingRedBalls.cPlexLen - 1 < 0) { runPtr = g_vars->scene29_flyingRedBalls.pTail; } else { runPtr = g_vars->scene29_flyingRedBalls.pTail; for (int j = 0; j < g_vars->scene29_flyingRedBalls.cPlexLen; j++) { ((Ball *)p1)->p1 = runPtr; runPtr = (Ball *)p1; p1 -= sizeof(Ball); } g_vars->scene29_flyingRedBalls.pTail = runPtr; } } g_vars->scene29_flyingRedBalls.pTail = runPtr->p0; runPtr->p1 = lastP; runPtr->p0 = 0; runPtr->ani = ani; g_vars->scene29_flyingRedBalls.numBalls++; if (g_vars->scene29_flyingRedBalls.field_8) { g_vars->scene29_flyingRedBalls.field_8->p0 = runPtr; g_vars->scene29_flyingRedBalls.field_8 = runPtr; } else { g_vars->scene29_flyingRedBalls.pHead = runPtr; g_vars->scene29_flyingRedBalls.field_8 = runPtr; } } } void sceneHandler29_manJump() { if (!g_fp->_aniMan->_movement || g_fp->_aniMan->_movement->_id == MV_MAN29_RUN || g_fp->_aniMan->_movement->_id == MV_MAN29_STANDUP) { g_vars->scene29_rideBackEnabled = false; g_vars->scene29_manIsHit = false; g_vars->scene29_reachedFarRight = true; g_fp->_aniMan->changeStatics2(ST_MAN29_RUNR); g_fp->_aniMan->startAnim(MV_MAN29_JUMP, 0, -1); } g_vars->scene29_manX = g_fp->_aniMan->_ox; g_vars->scene29_manY = g_fp->_aniMan->_oy; } void sceneHandler29_manBend() { if (!g_fp->_aniMan->_movement || g_fp->_aniMan->_movement->_id == MV_MAN29_RUN || g_fp->_aniMan->_movement->_id == MV_MAN29_STANDUP) { g_vars->scene29_rideBackEnabled = false; g_vars->scene29_manIsHit = false; g_vars->scene29_reachedFarRight = true; g_fp->_aniMan->changeStatics2(ST_MAN29_RUNR); g_fp->_aniMan->startAnim(MV_MAN29_BEND, 0, -1); } g_vars->scene29_manX = g_fp->_aniMan->_ox; g_vars->scene29_manY = g_fp->_aniMan->_oy; } bool sceneHandler29_checkRedBallHit(StaticANIObject *ani, int maxx) { 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_fp->_aniMan->_movement) return true; int phase = g_fp->_aniMan->_movement->_currDynamicPhaseIndex; if (g_fp->_aniMan->_movement->_id != MV_MAN29_BEND && g_fp->_aniMan->_movement->_id != MV_MAN29_RUN && (g_fp->_aniMan->_movement->_id != MV_MAN29_JUMP || (phase >= 3 && phase <= 6))) return false; else return true; } bool sceneHandler29_checkGreenBallHit(StaticANIObject *ani, int maxx) { 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_fp->_aniMan->_movement) return true; if (g_fp->_aniMan->_movement->_id == MV_MAN29_JUMP) return true; if (g_fp->_aniMan->_movement->_id == MV_MAN29_RUN) return true; if (g_fp->_aniMan->_movement->_id == MV_MAN29_BEND) { if (g_fp->_aniMan->_movement->_currDynamicPhaseIndex < 1 || g_fp->_aniMan->_movement->_currDynamicPhaseIndex > 5) return true; } return false; } void sceneHandler29_manHit() { MGMInfo mgminfo; g_vars->scene29_manIsHit = true; g_fp->_aniMan->changeStatics2(ST_MAN29_RUNR); g_fp->_aniMan->setOXY(g_vars->scene29_manX, g_vars->scene29_manY); mgminfo.ani = g_fp->_aniMan; mgminfo.staticsId2 = ST_MAN29_SITR; mgminfo.y1 = 463; mgminfo.x1 = g_vars->scene29_manX <= 638 ? 351 : 0; mgminfo.field_1C = 10; mgminfo.field_10 = 1; mgminfo.flags = (g_vars->scene29_manX <= 638 ? 2 : 0) | 0x44; mgminfo.movementId = MV_MAN29_HIT; MessageQueue *mq = g_vars->scene29_mgm.genMovement(&mgminfo); 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->_keyCode = g_fp->_aniMan->_okeyCode; 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->_keyCode = g_fp->_aniMan->_okeyCode; mq->addExCommandToEnd(ex); } mq->setFlags(mq->getFlags() | 1); if (!mq->chain(g_fp->_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() { Ball *ball = g_vars->scene29_greenBalls.pHead; Ball *newball; int x, y; while (ball) { x = ball->ani->_ox - 30; y = ball->ani->_oy; if (x >= 186) { if (sceneHandler29_checkGreenBallHit(ball->ani, x)) { newball = g_vars->scene29_balls.sub04(g_vars->scene29_balls.field_8, 0); newball->ani = ball->ani; if (g_vars->scene29_balls.field_8) g_vars->scene29_balls.field_8->p0 = newball; else g_vars->scene29_balls.pHead = newball; g_vars->scene29_balls.field_8 = newball; if (ball == g_vars->scene29_greenBalls.pHead) g_vars->scene29_greenBalls.pHead = ball->p0; else ball->p1->p0 = ball->p0; if (ball == g_vars->scene29_greenBalls.field_8) g_vars->scene29_greenBalls.field_8 = ball->p1; else ball->p0->p1 = ball->p1; g_vars->scene29_greenBalls.init(&ball); sceneHandler29_manHit(); g_fp->playSound(SND_29_014, 0); ball->ani->startAnim(MV_SHG_HITMAN, 0, -1); g_vars->scene29_hitBall = ball->ani->_id; } else { ball->ani->setOXY(x, y); } } else { newball = g_vars->scene29_balls.sub04(g_vars->scene29_balls.field_8, 0); newball->ani = ball->ani; if (g_vars->scene29_balls.field_8) g_vars->scene29_balls.field_8->p0 = newball; else g_vars->scene29_balls.pHead = newball; g_vars->scene29_balls.field_8 = newball; ball->ani->hide(); if (ball == g_vars->scene29_greenBalls.pHead) g_vars->scene29_greenBalls.pHead = ball->p0; else ball->p1->p0 = ball->p0; if (ball == g_vars->scene29_greenBalls.field_8) g_vars->scene29_greenBalls.field_8 = ball->p1; else ball->p0->p1 = ball->p1; g_vars->scene29_greenBalls.init(&ball); sceneHandler29_assHitGreen(); } ball = ball->p0; } ball = g_vars->scene29_flyingRedBalls.pHead; while (ball) { x = ball->ani->_ox - 30; y = ball->ani->_oy; if (x >= 147) { if (sceneHandler29_checkRedBallHit(ball->ani, x)) { newball = g_vars->scene29_redBalls.sub04(g_vars->scene29_redBalls.field_8, 0); newball->ani = ball->ani; if (g_vars->scene29_redBalls.field_8) g_vars->scene29_redBalls.field_8->p0 = newball; else g_vars->scene29_redBalls.pHead = newball; g_vars->scene29_redBalls.field_8 = newball; g_vars->scene29_flyingRedBalls.removeBall(ball); sceneHandler29_manHit(); g_fp->playSound(SND_29_027, 0); ball->ani->startAnim(MV_SHR_HITMAN, 0, -1); g_vars->scene29_hitBall = ball->ani->_id; } else { ball->ani->setOXY(x, y); } } else { newball = g_vars->scene29_redBalls.sub04(g_vars->scene29_redBalls.field_8, 0); newball->ani = ball->ani; if (g_vars->scene29_redBalls.field_8) g_vars->scene29_redBalls.field_8->p0 = newball; else g_vars->scene29_redBalls.pHead = newball; g_vars->scene29_redBalls.field_8 = newball; ball->ani->hide(); if (ball == g_vars->scene29_flyingRedBalls.pHead) g_vars->scene29_flyingRedBalls.pHead = ball->p0; else ball->p1->p0 = ball->p0; if (ball == g_vars->scene29_flyingRedBalls.field_8) g_vars->scene29_flyingRedBalls.field_8 = ball->p1; else ball->p0->p1 = ball->p1; g_vars->scene29_flyingRedBalls.init(&ball); sceneHandler29_assHitRed(); } ball = ball->p0; } } void sceneHandler29_manFromL() { if (g_vars->scene29_manX < 497 && !g_vars->scene29_scrollingDisabled) { getCurrSceneSc2MotionController()->activate(); getGameLoaderInteractionController()->enableFlag24(); g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000); chainQueue(QU_SC29_MANFROM_L, 1); g_vars->scene29_scrollingDisabled = true; g_fp->_scrollSpeed = g_vars->scene29_scrollSpeed; } } void sceneHandler29_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_fp->drawArcadeOverlay(g_vars->scene29_arcadeIsOn); if (!res) g_fp->_updateScreenCallback = 0; return res; } void sceneHandler29_manToL() { getCurrSceneSc2MotionController()->deactivate(); getGameLoaderInteractionController()->disableFlag24(); chainQueue(QU_SC29_MANTO_L, 1); g_vars->scene29_arcadeIsOn = true; g_vars->scene29_mgm.addItem(g_fp->_aniMan->_id); g_fp->_updateScreenCallback = sceneHandler29_updateScreenCallback; g_fp->_msgY = -1; g_fp->_msgX = -1; } void sceneHandler29_manToR() { getCurrSceneSc2MotionController()->deactivate(); getGameLoaderInteractionController()->disableFlag24(); chainQueue(QU_SC29_MANTO_R, 1); g_vars->scene29_manIsRiding = true; g_fp->_msgY = -1; g_fp->_msgX = -1; g_vars->scene29_scrollingDisabled = false; g_vars->scene29_scrollSpeed = g_fp->_scrollSpeed; g_fp->_scrollSpeed = 4; } void sceneHandler29_clickPorter(ExCommand *cmd) { if (!g_fp->_aniMan->isIdle() || g_fp->_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_fp->_aniMan->_movement || g_fp->_aniMan->_statics->_staticsId != ST_MAN_RIGHT) { if (g_fp->_msgX != 351 || g_fp->_msgY != 443) { MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_fp->_aniMan, 351, 443, 1, ST_MAN_RIGHT); if (mq) { mq->addExCommandToEnd(cmd->createClone()); postExCommand(g_fp->_aniMan->_id, 2, 351, 443, 0, -1); } } } else { sceneHandler29_manToL(); } } else { g_vars->scene29_manX = g_fp->_aniMan->_ox; g_vars->scene29_manY = g_fp->_aniMan->_oy; if (ABS(1582 - g_vars->scene29_manX) > 1 || ABS(445 - g_fp->_aniMan->_oy) > 1 || g_fp->_aniMan->_movement || g_fp->_aniMan->_statics->_staticsId != (0x4000 | ST_MAN_RIGHT)) { if (g_fp->_msgX != 1582 || g_fp->_msgY != 445) { MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_fp->_aniMan, 1582, 445, 1, (0x4000 | ST_MAN_RIGHT)); if (mq) { mq->addExCommandToEnd(cmd->createClone()); postExCommand(g_fp->_aniMan->_id, 2, 1582, 445, 0, -1); } } } else { sceneHandler29_manToR(); } } } void sceneHandler29_shootersProcess() { if (g_fp->_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_fp->_aniMan->startAnim(MV_MAN29_RUN, 0, -1); } } g_vars->scene29_manX = g_fp->_aniMan->_ox; g_vars->scene29_manY = g_fp->_aniMan->_oy; } void sceneHandler29_shootersEscape() { if (g_vars->scene29_arcadeIsOn) { g_vars->scene29_manX += 2; g_fp->_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) { 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(0); g_vars->scene29_ass->hide(); g_fp->setObjectState(sO_LeftPipe_29, g_fp->getObjectEnumState(sO_LeftPipe_29, sO_IsOpened)); } } else if (g_vars->scene29_manIsRiding) { g_vars->scene29_manX -= 4; g_fp->_aniMan->setOXY(g_vars->scene29_manX, g_vars->scene29_manY); } } void sceneHandler29_manRideBack() { g_vars->scene29_manX -= 2; g_fp->_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_fp->_rnd->getRandomNumber(1) || 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_fp->_currentScene->getMessageQueueById(QU_SC29_BRDOUT1), 0, 1); mq->replaceKeyCode(-1, ani->_okeyCode); mq->chain(0); 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_fp->_currentScene->getMessageQueueById(QU_SC29_BRDOUT2), 0, 1); mq->replaceKeyCode(-1, ani->_okeyCode); mq->chain(0); 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_fp->_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_fp->_currentScene->getMessageQueueById(QU_SC29_BRD2), 0, 1); newx = g_vars->scene29_manX - 200; } else { mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC29_BRD1), 0, 1); newx = g_vars->scene29_manX + 350; } mq->getExCommandByIndex(0)->_x = newx; mq->replaceKeyCode(-1, ani->_okeyCode); mq->chain(0); 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_fp->playSound(SND_29_028, 0); break; } g_fp->playSound(SND_29_029, 0); break; case MSG_SC29_SHOWLASTRED: if (g_vars->scene29_redBalls.numBalls) { // original uses scene29_balls which looks like a copy/paste error g_vars->scene29_redBalls.field_8->ani->show1(-1, -1, -1, 0); g_vars->scene29_redBalls.field_8->ani->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_balls.numBalls) { g_vars->scene29_balls.field_8->ani->show1(-1, -1, -1, 0); g_vars->scene29_balls.field_8->ani->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; 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_fp->_currentScene->getStaticANIObjectAtPos(g_fp->_sceneRect.left + cmd->_x, g_fp->_sceneRect.top + cmd->_y); if (ani && ani == g_vars->scene29_porter) { sceneHandler29_clickPorter(cmd); cmd->_messageKind = 0; break; } break; } sceneHandler29_manJump(); cmd->_messageKind = 0; break; } break; case 107: if (g_vars->scene29_arcadeIsOn) sceneHandler29_manBend(); break; case 33: if (g_vars->scene29_arcadeIsOn) { if (g_vars->scene29_manX > g_fp->_sceneRect.right - 500) g_fp->_currentScene->_x = g_fp->_sceneRect.right - g_vars->scene29_manX - 350; if (g_vars->scene29_manX < g_fp->_sceneRect.left + 100) g_fp->_currentScene->_x = g_vars->scene29_manX - g_fp->_sceneRect.left - 100; } else if (g_fp->_aniMan2) { int x = g_fp->_aniMan2->_ox; if (x < g_fp->_sceneRect.left + 300) g_fp->_currentScene->_x = x - 400 - g_fp->_sceneRect.left; if (x > g_fp->_sceneRect.right - 300) g_fp->_currentScene->_x = x + 400 - g_fp->_sceneRect.right; } g_vars->scene29_manX = g_fp->_aniMan->_ox; g_vars->scene29_manY = g_fp->_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_fp->_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_fp->_behaviorManager->updateBehaviors(); g_fp->startSceneTrack(); break; } return 0; } int scene29_updateCursor() { g_fp->updateCursorCommon(); if (g_vars->scene29_arcadeIsOn) { if (g_fp->_cursorId != PIC_CSR_DEFAULT_INV && g_fp->_cursorId != PIC_CSR_ITN_INV) g_fp->_cursorId = -1; } else if (g_vars->scene29_manIsRiding) { if (g_fp->_cursorId != PIC_CSR_DEFAULT_INV && g_fp->_cursorId != PIC_CSR_ITN_INV) g_fp->_cursorId = PIC_CSR_DEFAULT; } else if (g_fp->_objectIdAtCursor == ANI_PORTER) { if (g_fp->_cursorId == PIC_CSR_DEFAULT) g_fp->_cursorId = PIC_CSR_ITN; } else { if (g_fp->_objectIdAtCursor == PIC_SC29_LTRUBA && g_fp->_cursorId == PIC_CSR_ITN) g_fp->_cursorId = PIC_CSR_GOL; } return g_fp->_cursorId; } } // End of namespace Fullpipe