/* 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. * */ /* * This code is based on original Tony Tough source code * * Copyright (c) 1997-2003 Nayma Software */ #include "tony/mpal/memory.h" #include "tony/mpal/mpalutils.h" #include "tony/game.h" #include "tony/tonychar.h" #include "tony/tony.h" namespace Tony { bool RMTony::_bAction = false; void RMTony::initStatics() { _bAction = false; } RMTony::RMTony() { _bShow = false; _bShowShadow = false; _bBodyFront = false; _bActionPending = false; _actionItem = NULL; _action = 0; _actionParm = 0; _bShepherdess = false; _bIsStaticTalk = false; _bIsTalking = false; _nPatB4Talking = 0; _nTalkType = TALK_NORMAL; _talkDirection = UP; _nTimeLastStep = 0; _hActionThread = CORO_INVALID_PID_VALUE; } void RMTony::waitEndOfAction(CORO_PARAM, const void *param) { CORO_BEGIN_CONTEXT; CORO_END_CONTEXT(_ctx); uint32 pid = *(const uint32 *)param; CORO_BEGIN_CODE(_ctx); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, pid, CORO_INFINITE); _bAction = false; CORO_END_CODE; } RMGfxSourceBuffer *RMTony::newItemSpriteBuffer(int dimx, int dimy, bool bPreRLE) { RMGfxSourceBuffer8RLE *spr; assert(_cm == CM_256); spr = new RMGfxSourceBuffer8RLEByteAA; spr->setAlphaBlendColor(1); if (bPreRLE) spr->setAlreadyCompressed(); return spr; } void RMTony::init() { RMRes tony(0); RMRes body(9999); // Tony is shown by default _bShow = _bShowShadow = true; // No action pending _bActionPending = false; _bAction = false; _bShepherdess = false; _bIsTalking = false; _bIsStaticTalk = false; // Opens the buffer Common::SeekableReadStream *ds = tony.getReadStream(); // Reads his details from the stream readFromStream(*ds, true); // Closes the buffer delete ds; // Reads Tony's body ds = body.getReadStream(); _body.readFromStream(*ds, true); delete ds; _body.setPattern(0); _nTimeLastStep = g_vm->getTime(); } void RMTony::close() { // Deallocation of missing item //_shadow.destroy(); } void RMTony::doFrame(CORO_PARAM, RMGfxTargetBuffer *bigBuf, int curLoc) { CORO_BEGIN_CONTEXT; int time; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); if (!_nInList && _bShow) bigBuf->addPrim(new RMGfxPrimitive(this)); setSpeed(GLOBALS._nCfgTonySpeed); // Runs the normal character movement _ctx->time = g_vm->getTime(); do { _nTimeLastStep += (1000 / 40); CORO_INVOKE_2(RMCharacter::doFrame, bigBuf, curLoc); } while (_ctx->time > _nTimeLastStep + (1000 / 40)); // Check if we are at the end of a path if (endOfPath() && _bActionPending) { // Must perform the action on which we clicked _bActionPending = false; } if (_bIsTalking || _bIsStaticTalk) _body.doFrame(bigBuf, false); CORO_END_CODE; } void RMTony::show() { _bShow = true; _bShowShadow = true; } void RMTony::hide(bool bShowShadow) { _bShow = false; _bShowShadow = bShowShadow; } void RMTony::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) { CORO_BEGIN_CONTEXT; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); // Call the Draw() of the parent class if Tony is visible if (_bShow && _bDrawNow) { if (_bBodyFront) { prim->getDst().setEmpty(); prim->getDst().offset(-44, -134); if (_bShepherdess) prim->getDst().offset(1, 4); CORO_INVOKE_2(RMCharacter::draw, bigBuf, prim); } if (_bIsTalking || _bIsStaticTalk) { // Offest direction from scrolling prim->getDst().setEmpty(); prim->getDst().offset(-_curScroll); prim->getDst().offset(_pos); prim->getDst().offset(-44, -134); prim->getDst() += _nBodyOffset; CORO_INVOKE_2(_body.draw, bigBuf, prim); } if (!_bBodyFront) { prim->getDst().setEmpty(); prim->getDst().offset(-44, -134); if (_bShepherdess) prim->getDst().offset(0, 3); CORO_INVOKE_2(RMCharacter::draw, bigBuf, prim); } } CORO_END_CODE; } void RMTony::moveAndDoAction(CORO_PARAM, RMPoint dst, RMItem *item, int nAction, int nActionParm) { CORO_BEGIN_CONTEXT; bool result; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); // Makes normal movement, but remember if you must then perform an action if (item == NULL) { _bActionPending = false; _actionItem = NULL; } else { _actionItem = item; _action = nAction; _actionParm = nActionParm; _bActionPending = true; } CORO_INVOKE_2(RMCharacter::move, dst, &_ctx->result); if (!_ctx->result) { _bActionPending = false; _actionItem = NULL; } CORO_END_CODE; } void RMTony::executeAction(int nAction, int nActionItem, int nParm) { uint32 pid; if (nAction == TA_COMBINE) { pid = mpalQueryDoAction(TA_COMBINE, nParm, nActionItem); // If you failed the combine, we have RECEIVECOMBINE as a fallback if (pid == CORO_INVALID_PID_VALUE) { pid = mpalQueryDoAction(TA_RECEIVECOMBINE, nActionItem, nParm); // If you failed with that, go with the generic // @@@ CombineGive! if (pid == CORO_INVALID_PID_VALUE) { pid = mpalQueryDoAction(TA_COMBINE, nParm, 0); if (pid == CORO_INVALID_PID_VALUE) { pid = mpalQueryDoAction(TA_RECEIVECOMBINE, nActionItem, 0); } } } } else { // Perform the action pid = mpalQueryDoAction(nAction, nActionItem, 0); } if (pid != CORO_INVALID_PID_VALUE) { _bAction = true; CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32)); _hActionThread = pid; } else if (nAction != TA_GOTO) { if (nAction == TA_TALK) { pid = mpalQueryDoAction(6, 1, 0); _bAction = true; CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32)); _hActionThread = pid; } else if (nAction == TA_PERORATE) { pid = mpalQueryDoAction(7, 1, 0); _bAction = true; CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32)); _hActionThread = pid; } else { pid = mpalQueryDoAction(5, 1, 0); _bAction = true; CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32)); _hActionThread = pid; } } } void RMTony::stopNoAction(CORO_PARAM) { CORO_BEGIN_CONTEXT; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); if (_bAction) CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _hActionThread, CORO_INFINITE); _bActionPending = false; _actionItem = NULL; CORO_INVOKE_0(stop); CORO_END_CODE; } void RMTony::stop(CORO_PARAM) { CORO_BEGIN_CONTEXT; uint32 pid; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); if (_actionItem != NULL) { // Call MPAL to choose the direction _ctx->pid = mpalQueryDoAction(21, _actionItem->mpalCode(), 0); if (_ctx->pid == CORO_INVALID_PID_VALUE) CORO_INVOKE_0(RMCharacter::stop); else { _bNeedToStop = false; // If we make the OnWhichDirection, we don't need at least after the Stop(). _bMoving = false; CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->pid, CORO_INFINITE); // @@@ Put an assert after 10 seconds } } else { CORO_INVOKE_0(RMCharacter::stop); } if (!_bActionPending) return; _bActionPending = false; executeAction(_action, _actionItem->mpalCode(), _actionParm); _actionItem = NULL; CORO_END_CODE; } int RMTony::getCurPattern() { int nPatt = RMCharacter::getCurPattern(); if (!_bShepherdess) return nPatt; switch (nPatt) { case PAT_PAST_STANDUP: return PAT_STANDUP; case PAT_PAST_STANDDOWN: return PAT_STANDDOWN; case PAT_PAST_STANDLEFT: return PAT_STANDLEFT; case PAT_PAST_STANDRIGHT: return PAT_STANDRIGHT; case PAT_PAST_WALKUP: return PAT_WALKUP; case PAT_PAST_WALKDOWN: return PAT_WALKDOWN; case PAT_PAST_WALKLEFT: return PAT_WALKLEFT; case PAT_PAST_WALKRIGHT: return PAT_WALKRIGHT; default: break; } return nPatt; } void RMTony::setPattern(int nPatt, bool bPlayP0) { if (_bShepherdess) { switch (nPatt) { case PAT_STANDUP: nPatt = PAT_PAST_STANDUP; break; case PAT_STANDDOWN: nPatt = PAT_PAST_STANDDOWN; break; case PAT_STANDLEFT: nPatt = PAT_PAST_STANDLEFT; break; case PAT_STANDRIGHT: nPatt = PAT_PAST_STANDRIGHT; break; case PAT_WALKUP: nPatt = PAT_PAST_WALKUP; break; case PAT_WALKDOWN: nPatt = PAT_PAST_WALKDOWN; break; case PAT_WALKLEFT: nPatt = PAT_PAST_WALKLEFT; break; case PAT_WALKRIGHT: nPatt = PAT_PAST_WALKRIGHT; break; default: break; } } RMCharacter::setPattern(nPatt, bPlayP0); } void RMTony::take(int nWhere, int nPart) { if (nPart == 0) { switch (getCurPattern()) { case PAT_STANDDOWN: assert(0); // Not while you're doing a StandDown break; case PAT_STANDUP: switch (nWhere) { case 0: setPattern(PAT_TAKEUP_UP1); break; case 1: setPattern(PAT_TAKEUP_MID1); break; case 2: setPattern(PAT_TAKEUP_DOWN1); break; default: break; } break; case PAT_STANDRIGHT: switch (nWhere) { case 0: setPattern(PAT_TAKERIGHT_UP1); break; case 1: setPattern(PAT_TAKERIGHT_MID1); break; case 2: setPattern(PAT_TAKERIGHT_DOWN1); break; default: break; } break; case PAT_STANDLEFT: switch (nWhere) { case 0: setPattern(PAT_TAKELEFT_UP1); break; case 1: setPattern(PAT_TAKELEFT_MID1); break; case 2: setPattern(PAT_TAKELEFT_DOWN1); break; default: break; } break; default: break; } } else if (nPart == 1) { setPattern(getCurPattern() + 1); } else if (nPart == 2) { switch (getCurPattern()) { case PAT_TAKEUP_UP2: case PAT_TAKEUP_MID2: case PAT_TAKEUP_DOWN2: setPattern(PAT_STANDUP); break; case PAT_TAKELEFT_UP2: case PAT_TAKELEFT_MID2: case PAT_TAKELEFT_DOWN2: setPattern(PAT_STANDLEFT); break; case PAT_TAKERIGHT_UP2: case PAT_TAKERIGHT_MID2: case PAT_TAKERIGHT_DOWN2: setPattern(PAT_STANDRIGHT); break; default: break; } } } void RMTony::put(int nWhere, int nPart) { if (nPart == 0) { switch (getCurPattern()) { case PAT_STANDDOWN: break; case PAT_STANDUP: switch (nWhere) { case 0: setPattern(PAT_PUTUP_UP1); break; case 1: setPattern(PAT_PUTUP_MID1); break; case 2: setPattern(PAT_PUTUP_DOWN1); break; default: break; } break; case PAT_STANDRIGHT: switch (nWhere) { case 0: setPattern(PAT_PUTRIGHT_UP1); break; case 1: setPattern(PAT_PUTRIGHT_MID1); break; case 2: setPattern(PAT_PUTRIGHT_DOWN1); break; default: break; } break; case PAT_STANDLEFT: switch (nWhere) { case 0: setPattern(PAT_PUTLEFT_UP1); break; case 1: setPattern(PAT_PUTLEFT_MID1); break; case 2: setPattern(PAT_PUTLEFT_DOWN1); break; default: break; } break; default: break; } } else if (nPart == 1) { setPattern(getCurPattern() + 1); } else if (nPart == 2) { switch (getCurPattern()) { case PAT_PUTUP_UP2: case PAT_PUTUP_MID2: case PAT_PUTUP_DOWN2: setPattern(PAT_STANDUP); break; case PAT_PUTLEFT_UP2: case PAT_PUTLEFT_MID2: case PAT_PUTLEFT_DOWN2: setPattern(PAT_STANDLEFT); break; case PAT_PUTRIGHT_UP2: case PAT_PUTRIGHT_MID2: case PAT_PUTRIGHT_DOWN2: setPattern(PAT_STANDRIGHT); break; default: break; } } } bool RMTony::startTalkCalculate(CharacterTalkType nTalkType, int &headStartPat, int &bodyStartPat, int &headLoopPat, int &bodyLoopPat) { assert(!_bIsTalking); _bIsTalking = true; _nPatB4Talking = getCurPattern(); _nTalkType = nTalkType; // Set the direction of speech ONLY if we are not in a static animation (since it would have already been done) if (!_bIsStaticTalk) { switch (_nPatB4Talking) { case PAT_STANDDOWN: _talkDirection = DOWN; break; case PAT_TAKELEFT_UP2: case PAT_TAKELEFT_MID2: case PAT_TAKELEFT_DOWN2: case PAT_GETUPLEFT: case PAT_STANDLEFT: _talkDirection = LEFT; break; case PAT_TAKERIGHT_UP2: case PAT_TAKERIGHT_MID2: case PAT_TAKERIGHT_DOWN2: case PAT_GETUPRIGHT: case PAT_STANDRIGHT: _talkDirection = RIGHT; break; case PAT_TAKEUP_UP2: case PAT_TAKEUP_MID2: case PAT_TAKEUP_DOWN2: case PAT_STANDUP: _talkDirection = UP; break; default: break; } // Puts the body in front by default _bBodyFront = true; } if (_bShepherdess) { // Talking whilst a shepherdess switch (_talkDirection) { case UP: setPattern(PAT_PAST_TALKUP); break; case DOWN: setPattern(PAT_PAST_TALKDOWN); break; case LEFT: setPattern(PAT_PAST_TALKLEFT); break; case RIGHT: setPattern(PAT_PAST_TALKRIGHT); break; default: break; } return false; } headStartPat = bodyStartPat = 0; bodyLoopPat = 0; switch (nTalkType) { case TALK_NORMAL: _bBodyFront = false; headStartPat = 0; bodyStartPat = 0; switch (_talkDirection) { case DOWN: headLoopPat = PAT_TALK_DOWN; bodyLoopPat = BPAT_STANDDOWN; _nBodyOffset.set(4, 53); break; case LEFT: headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_STANDLEFT; _nBodyOffset.set(6, 56); break; case RIGHT: headLoopPat = PAT_TALK_RIGHT; bodyLoopPat = BPAT_STANDRIGHT; _nBodyOffset.set(6, 56); break; case UP: headLoopPat = PAT_TALK_UP; bodyLoopPat = BPAT_STANDUP; _nBodyOffset.set(6, 53); break; default: break; } break; case TALK_HIPS: _bBodyFront = false; switch (_talkDirection) { case UP: _nBodyOffset.set(2, 42); headStartPat = PAT_HEAD_UP; bodyStartPat = BPAT_HIPSUP_START; headLoopPat = PAT_TALK_UP; bodyLoopPat = BPAT_HIPSUP_LOOP; break; case DOWN: _nBodyOffset.set(2, 48); headStartPat = PAT_HEAD_DOWN; bodyStartPat = BPAT_HIPSDOWN_START; headLoopPat = PAT_TALK_DOWN; bodyLoopPat = BPAT_HIPSDOWN_LOOP; break; case LEFT: _nBodyOffset.set(-3, 53); headStartPat = PAT_HEAD_LEFT; bodyStartPat = BPAT_HIPSLEFT_START; headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_HIPSLEFT_LOOP; break; case RIGHT: _nBodyOffset.set(2, 53); headStartPat = PAT_HEAD_RIGHT; bodyStartPat = BPAT_HIPSRIGHT_START; headLoopPat = PAT_TALK_RIGHT; bodyLoopPat = BPAT_HIPSRIGHT_LOOP; break; default: break; } break; case TALK_SING: _nBodyOffset.set(-10, 25); headStartPat = PAT_HEAD_LEFT; bodyStartPat = BPAT_SINGLEFT_START; headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_SINGLEFT_LOOP; break; case TALK_LAUGH: _bBodyFront = false; switch (_talkDirection) { case UP: case DOWN: case LEFT: _nBodyOffset.set(6, 56); headStartPat = PAT_LAUGHLEFT_START; bodyStartPat = BPAT_STANDLEFT; headLoopPat = PAT_LAUGHLEFT_LOOP; bodyLoopPat = BPAT_LAUGHLEFT; break; case RIGHT: _nBodyOffset.set(6, 56); headStartPat = PAT_LAUGHRIGHT_START; bodyStartPat = BPAT_STANDRIGHT; headLoopPat = PAT_LAUGHRIGHT_LOOP; bodyLoopPat = BPAT_LAUGHRIGHT; break; default: break; } break; case TALK_LAUGH2: _bBodyFront = false; switch (_talkDirection) { case UP: case DOWN: case LEFT: _nBodyOffset.set(6, 56); headStartPat = PAT_LAUGHLEFT_START; bodyStartPat = BPAT_STANDLEFT; headLoopPat = PAT_LAUGHLEFT_LOOP; break; case RIGHT: _nBodyOffset.set(6, 56); headStartPat = PAT_LAUGHRIGHT_START; bodyStartPat = BPAT_STANDRIGHT; headLoopPat = PAT_LAUGHRIGHT_LOOP; bodyLoopPat = BPAT_LAUGHRIGHT; break; default: break; } break; case TALK_INDICATE: switch (_talkDirection) { case UP: case DOWN: case LEFT: _nBodyOffset.set(-4, 40); headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_INDICATELEFT; break; case RIGHT: _nBodyOffset.set(5, 40); headLoopPat = PAT_TALK_RIGHT; bodyLoopPat = BPAT_INDICATERIGHT; break; default: break; } break; case TALK_SCARED: switch (_talkDirection) { case UP: _nBodyOffset.set(-4, -11); headStartPat = PAT_HEAD_UP; bodyStartPat = BPAT_SCAREDUP_START; headLoopPat = PAT_TALK_UP; bodyLoopPat = BPAT_SCAREDUP_LOOP; break; case DOWN: _nBodyOffset.set(-5, 45); headStartPat = PAT_SCAREDDOWN_START; bodyStartPat = BPAT_SCAREDDOWN_START; headLoopPat = PAT_SCAREDDOWN_LOOP; bodyLoopPat = BPAT_SCAREDDOWN_LOOP; break; case RIGHT: _nBodyOffset.set(-4, 41); headStartPat = PAT_SCAREDRIGHT_START; bodyStartPat = BPAT_SCAREDRIGHT_START; headLoopPat = PAT_SCAREDRIGHT_LOOP; bodyLoopPat = BPAT_SCAREDRIGHT_LOOP; break; case LEFT: _nBodyOffset.set(-10, 41); headStartPat = PAT_SCAREDLEFT_START; bodyStartPat = BPAT_SCAREDLEFT_START; headLoopPat = PAT_SCAREDLEFT_LOOP; bodyLoopPat = BPAT_SCAREDLEFT_LOOP; break; default: break; } break; case TALK_SCARED2: _bBodyFront = false; switch (_talkDirection) { case UP: bodyStartPat = BPAT_STANDUP; bodyLoopPat = BPAT_STANDUP; _nBodyOffset.set(6, 53); headStartPat = PAT_HEAD_UP; headLoopPat = PAT_TALK_UP; break; case DOWN: bodyStartPat = BPAT_STANDDOWN; bodyLoopPat = BPAT_STANDDOWN; _nBodyOffset.set(4, 53); headStartPat = PAT_SCAREDDOWN_START; headLoopPat = PAT_SCAREDDOWN_LOOP; break; case RIGHT: bodyStartPat = BPAT_STANDRIGHT; bodyLoopPat = BPAT_STANDRIGHT; _nBodyOffset.set(6, 56); headStartPat = PAT_SCAREDRIGHT_START; headLoopPat = PAT_SCAREDRIGHT_LOOP; break; case LEFT: bodyStartPat = BPAT_STANDLEFT; bodyLoopPat = BPAT_STANDLEFT; _nBodyOffset.set(6, 56); headStartPat = PAT_SCAREDLEFT_START; headLoopPat = PAT_SCAREDLEFT_LOOP; break; default: break; } break; case TALK_WITHGLASSES: _nBodyOffset.set(4, 53); headLoopPat = PAT_TALK_DOWN; bodyLoopPat = BPAT_GLASS; break; case TALK_WITHWORM: _nBodyOffset.set(9, 56); headLoopPat = PAT_TALK_RIGHT; bodyLoopPat = BPAT_WORM; break; case TALK_WITHHAMMER: _nBodyOffset.set(6, 56); headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_HAMMER; break; case TALK_WITHROPE: _nBodyOffset.set(-3, 38); headLoopPat = PAT_TALK_RIGHT; bodyLoopPat = BPAT_ROPE; break; case TALK_WITHSECRETARY: _nBodyOffset.set(-17, 12); headLoopPat = PAT_TALK_RIGHT; bodyLoopPat = BPAT_WITHSECRETARY; break; case TALK_WITHRABBIT: switch (_talkDirection) { case LEFT: case UP: _nBodyOffset.set(-21, -5); bodyStartPat = BPAT_WITHRABBITLEFT_START; headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_WITHRABBITLEFT_LOOP; break; case DOWN: case RIGHT: _nBodyOffset.set(-4, -5); bodyStartPat = BPAT_WITHRABBITRIGHT_START; headLoopPat = PAT_TALK_RIGHT; bodyLoopPat = BPAT_WITHRABBITRIGHT_LOOP; break; default: break; } break; case TALK_WITHRECIPE: switch (_talkDirection) { case LEFT: case UP: _nBodyOffset.set(-61, -7); bodyStartPat = BPAT_WITHRECIPELEFT_START; headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_WITHRECIPELEFT_LOOP; break; case DOWN: case RIGHT: _nBodyOffset.set(-5, -7); bodyStartPat = BPAT_WITHRECIPERIGHT_START; headLoopPat = PAT_TALK_RIGHT; bodyLoopPat = BPAT_WITHRECIPERIGHT_LOOP; break; default: break; } break; case TALK_WITHCARDS: switch (_talkDirection) { case LEFT: case UP: _nBodyOffset.set(-34, -2); bodyStartPat = BPAT_WITHCARDSLEFT_START; headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_WITHCARDSLEFT_LOOP; break; case DOWN: case RIGHT: _nBodyOffset.set(-4, -2); bodyStartPat = BPAT_WITHCARDSRIGHT_START; headLoopPat = PAT_TALK_RIGHT; bodyLoopPat = BPAT_WITHCARDSRIGHT_LOOP; break; default: break; } break; case TALK_WITHSNOWMAN: switch (_talkDirection) { case LEFT: case UP: _nBodyOffset.set(-35, 2); bodyStartPat = BPAT_WITHSNOWMANLEFT_START; headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_WITHSNOWMANLEFT_LOOP; break; case DOWN: case RIGHT: _nBodyOffset.set(-14, 2); bodyStartPat = BPAT_WITHSNOWMANRIGHT_START; headLoopPat = PAT_TALK_RIGHT; bodyLoopPat = BPAT_WITHSNOWMANRIGHT_LOOP; break; default: break; } break; case TALK_WITHSNOWMANSTATIC: case TALK_WITHRECIPESTATIC: case TALK_WITHRABBITSTATIC: case TALK_WITHCARDSSTATIC: case TALK_WITH_NOTEBOOK: case TALK_WITHMEGAPHONESTATIC: switch (_talkDirection) { case LEFT: case UP: headLoopPat = PAT_TALK_LEFT; break; case DOWN: case RIGHT: headLoopPat = PAT_TALK_RIGHT; break; default: break; } break; // The beard is the only case in which the head is animated separately while the body is the standard case TALK_WITHBEARDSTATIC: switch (_talkDirection) { case LEFT: case UP: headLoopPat = PAT_TALKBEARD_LEFT; bodyLoopPat = BPAT_STANDLEFT; _nBodyOffset.set(6, 56); break; case DOWN: case RIGHT: headLoopPat = PAT_TALKBEARD_RIGHT; bodyLoopPat = BPAT_STANDRIGHT; _nBodyOffset.set(6, 56); break; default: break; } break; case TALK_DISGUSTED: switch (_talkDirection) { case LEFT: case UP: _nBodyOffset.set(6, 56); headStartPat = PAT_DISGUSTEDLEFT_START; bodyStartPat = BPAT_STANDLEFT; headLoopPat = PAT_DISGUSTEDLEFT_LOOP; break; case DOWN: case RIGHT: _nBodyOffset.set(6, 56); headStartPat = PAT_DISGUSTEDRIGHT_START; bodyStartPat = BPAT_STANDRIGHT; headLoopPat = PAT_DISGUSTEDRIGHT_LOOP; break; default: break; } break; case TALK_SARCASTIC: switch (_talkDirection) { case LEFT: case UP: _nBodyOffset.set(6, 56); headStartPat = PAT_SARCASTICLEFT_START; bodyStartPat = BPAT_STANDLEFT; headLoopPat = PAT_SARCASTICLEFT_LOOP; break; case DOWN: case RIGHT: _nBodyOffset.set(6, 56); headStartPat = PAT_SARCASTICRIGHT_START; bodyStartPat = BPAT_STANDRIGHT; headLoopPat = PAT_SARCASTICRIGHT_LOOP; break; default: break; } break; case TALK_MACBETH1: _nBodyOffset.set(-33, -1); headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_MACBETH1; break; case TALK_MACBETH2: _nBodyOffset.set(-33, -1); headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_MACBETH2; break; case TALK_MACBETH3: _nBodyOffset.set(-33, -1); headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_MACBETH3; break; case TALK_MACBETH4: _nBodyOffset.set(-33, -1); headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_MACBETH4; break; case TALK_MACBETH5: _nBodyOffset.set(-33, -1); headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_MACBETH5; break; case TALK_MACBETH6: _nBodyOffset.set(-33, -1); headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_MACBETH6; break; case TALK_MACBETH7: _nBodyOffset.set(-33, -1); headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_MACBETH7; break; case TALK_MACBETH8: _nBodyOffset.set(-33, -1); headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_MACBETH8; break; case TALK_MACBETH9: _nBodyOffset.set(-33, -1); headLoopPat = PAT_TALK_LEFT; bodyLoopPat = BPAT_MACBETH9; break; case TALK_SCAREDSTATIC: _bBodyFront = false; switch (_talkDirection) { case DOWN: bodyStartPat = BPAT_STANDDOWN; bodyLoopPat = BPAT_STANDDOWN; _nBodyOffset.set(4, 53); headStartPat = PAT_SCAREDDOWN_STAND; headLoopPat = PAT_SCAREDDOWN_LOOP; break; case RIGHT: bodyStartPat = BPAT_STANDRIGHT; bodyLoopPat = BPAT_STANDRIGHT; _nBodyOffset.set(6, 56); headStartPat = PAT_SCAREDRIGHT_STAND; headLoopPat = PAT_SCAREDRIGHT_LOOP; break; case LEFT: bodyStartPat = BPAT_STANDLEFT; bodyLoopPat = BPAT_STANDLEFT; _nBodyOffset.set(6, 56); headStartPat = PAT_SCAREDLEFT_STAND; headLoopPat = PAT_SCAREDLEFT_LOOP; break; default: break; } break; default: break; } return true; } void RMTony::startTalk(CORO_PARAM, CharacterTalkType nTalkType) { CORO_BEGIN_CONTEXT; int headStartPat, bodyStartPat; int headLoopPat, bodyLoopPat; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); _ctx->headStartPat = _ctx->bodyStartPat = 0; _ctx->headLoopPat = _ctx->bodyLoopPat = 0; if (!startTalkCalculate(nTalkType, _ctx->headStartPat, _ctx->bodyStartPat, _ctx->headLoopPat, _ctx->bodyLoopPat)) return; // Perform the set pattern if (_ctx->headStartPat != 0 || _ctx->bodyStartPat != 0) { setPattern(_ctx->headStartPat); _body.setPattern(_ctx->bodyStartPat); if (_ctx->bodyStartPat != 0) CORO_INVOKE_0(_body.waitForEndPattern); if (_ctx->headStartPat != 0) CORO_INVOKE_0(waitForEndPattern); } setPattern(_ctx->headLoopPat); if (_ctx->bodyLoopPat) _body.setPattern(_ctx->bodyLoopPat); CORO_END_CODE; } bool RMTony::endTalkCalculate(int &headStandPat, int &headEndPat, int &bodyEndPat, int &finalPat, bool &bStatic) { bodyEndPat = 0; headEndPat = 0; switch (_talkDirection) { case UP: finalPat = PAT_STANDUP; headStandPat = PAT_HEAD_UP; break; case DOWN: finalPat = PAT_STANDDOWN; headStandPat = PAT_HEAD_DOWN; break; case LEFT: finalPat = PAT_STANDLEFT; headStandPat = PAT_HEAD_LEFT; break; case RIGHT: finalPat = PAT_STANDRIGHT; headStandPat = PAT_HEAD_RIGHT; break; default: break; } if (_bShepherdess) { setPattern(finalPat); _bIsTalking = false; return false; } bStatic = false; switch (_nTalkType) { case TALK_NORMAL: bodyEndPat = 0; break; case TALK_HIPS: switch (_talkDirection) { case UP: bodyEndPat = BPAT_HIPSUP_END; break; case DOWN: bodyEndPat = BPAT_HIPSDOWN_END; break; case LEFT: bodyEndPat = BPAT_HIPSLEFT_END; break; case RIGHT: bodyEndPat = BPAT_HIPSRIGHT_END; break; default: break; } break; case TALK_SING: bodyEndPat = BPAT_SINGLEFT_END; break; case TALK_LAUGH: case TALK_LAUGH2: if (_talkDirection == LEFT) headEndPat = PAT_LAUGHLEFT_END; else if (_talkDirection == RIGHT) headEndPat = PAT_LAUGHRIGHT_END; bodyEndPat = 0; break; case TALK_DISGUSTED: switch (_talkDirection) { case UP: case LEFT: headEndPat = PAT_DISGUSTEDLEFT_END; break; case DOWN: case RIGHT: headEndPat = PAT_DISGUSTEDRIGHT_END; break; default: break; } bodyEndPat = 0; break; case TALK_SARCASTIC: switch (_talkDirection) { case UP: case LEFT: headEndPat = PAT_SARCASTICLEFT_END; break; case DOWN: case RIGHT: headEndPat = PAT_SARCASTICRIGHT_END; break; default: break; } bodyEndPat = 0; break; case TALK_INDICATE: break; case TALK_SCARED: switch (_talkDirection) { case UP: bodyEndPat = BPAT_SCAREDUP_END; break; case DOWN: headEndPat = PAT_SCAREDDOWN_END; bodyEndPat = BPAT_SCAREDDOWN_END; break; case RIGHT: headEndPat = PAT_SCAREDRIGHT_END; bodyEndPat = BPAT_SCAREDRIGHT_END; break; case LEFT: headEndPat = PAT_SCAREDLEFT_END; bodyEndPat = BPAT_SCAREDLEFT_END; break; default: break; } break; case TALK_SCARED2: switch (_talkDirection) { case UP: bodyEndPat = 0; break; case DOWN: headEndPat = PAT_SCAREDDOWN_END; bodyEndPat = 0; break; case RIGHT: headEndPat = PAT_SCAREDRIGHT_END; bodyEndPat = 0; break; case LEFT: headEndPat = PAT_SCAREDLEFT_END; bodyEndPat = 0; break; default: break; } break; case TALK_WITHRABBIT: switch (_talkDirection) { case UP: case LEFT: finalPat = PAT_STANDLEFT; bodyEndPat = BPAT_WITHRABBITLEFT_END; break; case RIGHT: case DOWN: finalPat = PAT_STANDRIGHT; bodyEndPat = BPAT_WITHRABBITRIGHT_END; break; default: break; } break; case TALK_WITHRECIPE: switch (_talkDirection) { case UP: case LEFT: finalPat = PAT_STANDLEFT; bodyEndPat = BPAT_WITHRECIPELEFT_END; break; case RIGHT: case DOWN: finalPat = PAT_STANDRIGHT; bodyEndPat = BPAT_WITHRECIPERIGHT_END; break; default: break; } break; case TALK_WITHCARDS: switch (_talkDirection) { case UP: case LEFT: finalPat = PAT_STANDLEFT; bodyEndPat = BPAT_WITHCARDSLEFT_END; break; case RIGHT: case DOWN: finalPat = PAT_STANDRIGHT; bodyEndPat = BPAT_WITHCARDSRIGHT_END; break; default: break; } break; case TALK_WITHSNOWMAN: switch (_talkDirection) { case UP: case LEFT: finalPat = PAT_STANDLEFT; bodyEndPat = BPAT_WITHSNOWMANLEFT_END; break; case RIGHT: case DOWN: finalPat = PAT_STANDRIGHT; bodyEndPat = BPAT_WITHSNOWMANRIGHT_END; break; default: break; } break; case TALK_WITHWORM: finalPat = PAT_WITHWORM; break; case TALK_WITHROPE: finalPat = PAT_WITHROPE; break; case TALK_WITHSECRETARY: finalPat = PAT_WITHSECRETARY; break; case TALK_WITHHAMMER: finalPat = PAT_WITHHAMMER; break; case TALK_WITHGLASSES: finalPat = PAT_WITHGLASSES; break; case TALK_MACBETH1: case TALK_MACBETH2: case TALK_MACBETH3: case TALK_MACBETH4: case TALK_MACBETH5: case TALK_MACBETH6: case TALK_MACBETH7: case TALK_MACBETH8: finalPat = 0; break; case TALK_SCAREDSTATIC: switch (_talkDirection) { case DOWN: headStandPat = PAT_SCAREDDOWN_STAND; bodyEndPat = 0; break; case RIGHT: headStandPat = PAT_SCAREDRIGHT_STAND; bodyEndPat = 0; break; case LEFT: headStandPat = PAT_SCAREDLEFT_STAND; bodyEndPat = 0; break; default: break; } break; default: break; } return true; } void RMTony::endTalk(CORO_PARAM) { CORO_BEGIN_CONTEXT; int headStandPat, headEndPat; int bodyEndPat, finalPat; bool bStatic; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); _ctx->headStandPat = _ctx->headEndPat = 0; _ctx->bodyEndPat = _ctx->finalPat = 0; _ctx->bStatic = false; _ctx->bodyEndPat = 0; _ctx->headEndPat = 0; if (!endTalkCalculate(_ctx->headStandPat, _ctx->headEndPat, _ctx->bodyEndPat, _ctx->finalPat, _ctx->bStatic)) return; // Handles the end of an animated and static, leaving everything unchanged if (_bIsStaticTalk) { if (_nTalkType == TALK_WITHBEARDSTATIC) { setPattern(0); if (_talkDirection == UP || _talkDirection == LEFT) { _body.setPattern(BPAT_WITHBEARDLEFT_STATIC); _nBodyOffset.set(-41, -14); } else if (_talkDirection == DOWN || _talkDirection == RIGHT) { _body.setPattern(BPAT_WITHBEARDRIGHT_STATIC); _nBodyOffset.set(-26, -14); } } else { setPattern(_ctx->headStandPat); CORO_INVOKE_0(_body.waitForEndPattern); } _bIsTalking = false; return; } // Set the pattern if (_ctx->headEndPat != 0 && _ctx->bodyEndPat != 0) { setPattern(_ctx->headEndPat); CORO_INVOKE_0(_body.waitForEndPattern); _body.setPattern(_ctx->bodyEndPat); CORO_INVOKE_0(waitForEndPattern); CORO_INVOKE_0(_body.waitForEndPattern); } else if (_ctx->bodyEndPat != 0) { setPattern(_ctx->headStandPat); CORO_INVOKE_0(_body.waitForEndPattern); _body.setPattern(_ctx->bodyEndPat); CORO_INVOKE_0(_body.waitForEndPattern); } else if (_ctx->headEndPat != 0) { CORO_INVOKE_0(_body.waitForEndPattern); setPattern(_ctx->headEndPat); CORO_INVOKE_0(waitForEndPattern); } else { CORO_INVOKE_0(_body.waitForEndPattern); } if (_ctx->finalPat != 0) { _body.setPattern(0); setPattern(_ctx->finalPat); } _bIsTalking = false; CORO_END_CODE; } void RMTony::startStaticCalculate(CharacterTalkType nTalk, int &headPat, int &headLoopPat, int &bodyStartPat, int &bodyLoopPat) { int nPat = getCurPattern(); headLoopPat = -1; switch (nPat) { case PAT_STANDDOWN: _talkDirection = DOWN; headPat = PAT_HEAD_RIGHT; break; case PAT_TAKELEFT_UP2: case PAT_TAKELEFT_MID2: case PAT_TAKELEFT_DOWN2: case PAT_GETUPLEFT: case PAT_STANDLEFT: _talkDirection = LEFT; headPat = PAT_HEAD_LEFT; break; case PAT_TAKERIGHT_UP2: case PAT_TAKERIGHT_MID2: case PAT_TAKERIGHT_DOWN2: case PAT_GETUPRIGHT: case PAT_STANDRIGHT: _talkDirection = RIGHT; headPat = PAT_HEAD_RIGHT; break; case PAT_TAKEUP_UP2: case PAT_TAKEUP_MID2: case PAT_TAKEUP_DOWN2: case PAT_STANDUP: _talkDirection = UP; headPat = PAT_HEAD_LEFT; break; default: break; } _bBodyFront = true; switch (nTalk) { case TALK_WITHRABBITSTATIC: switch (_talkDirection) { case UP: case LEFT: _nBodyOffset.set(-21, -5); bodyStartPat = BPAT_WITHRABBITLEFT_START; bodyLoopPat = BPAT_WITHRABBITLEFT_LOOP; break; case DOWN: case RIGHT: _nBodyOffset.set(-4, -5); bodyStartPat = BPAT_WITHRABBITRIGHT_START; bodyLoopPat = BPAT_WITHRABBITRIGHT_LOOP; break; default: break; } break; case TALK_WITHCARDSSTATIC: switch (_talkDirection) { case UP: case LEFT: _nBodyOffset.set(-34, -2); bodyStartPat = BPAT_WITHCARDSLEFT_START; bodyLoopPat = BPAT_WITHCARDSLEFT_LOOP; break; case DOWN: case RIGHT: _nBodyOffset.set(-4, -2); bodyStartPat = BPAT_WITHCARDSRIGHT_START; bodyLoopPat = BPAT_WITHCARDSRIGHT_LOOP; break; default: break; } break; case TALK_WITHRECIPESTATIC: switch (_talkDirection) { case UP: case LEFT: _nBodyOffset.set(-61, -7); bodyStartPat = BPAT_WITHRECIPELEFT_START; bodyLoopPat = BPAT_WITHRECIPELEFT_LOOP; break; case DOWN: case RIGHT: _nBodyOffset.set(-5, -7); bodyStartPat = BPAT_WITHRECIPERIGHT_START; bodyLoopPat = BPAT_WITHRECIPERIGHT_LOOP; break; default: break; } break; case TALK_WITHSNOWMANSTATIC: switch (_talkDirection) { case UP: case LEFT: _nBodyOffset.set(-35, 2); bodyStartPat = BPAT_WITHSNOWMANLEFT_START; bodyLoopPat = BPAT_WITHSNOWMANLEFT_LOOP; break; case DOWN: case RIGHT: _nBodyOffset.set(-14, 2); bodyStartPat = BPAT_WITHSNOWMANRIGHT_START; bodyLoopPat = BPAT_WITHSNOWMANRIGHT_LOOP; break; default: break; } break; case TALK_WITH_NOTEBOOK: switch (_talkDirection) { case UP: case LEFT: _nBodyOffset.set(-16, -9); bodyStartPat = BPAT_WITHNOTEBOOKLEFT_START; bodyLoopPat = BPAT_WITHNOTEBOOKLEFT_LOOP; break; case DOWN: case RIGHT: _nBodyOffset.set(-6, -9); bodyStartPat = BPAT_WITHNOTEBOOKRIGHT_START; bodyLoopPat = BPAT_WITHNOTEBOOKRIGHT_LOOP; break; default: break; } break; case TALK_WITHMEGAPHONESTATIC: switch (_talkDirection) { case UP: case LEFT: _nBodyOffset.set(-41, -8); bodyStartPat = BPAT_WITHMEGAPHONELEFT_START; bodyLoopPat = BPAT_WITHMEGAPHONELEFT_LOOP; break; case DOWN: case RIGHT: _nBodyOffset.set(-14, -8); bodyStartPat = BPAT_WITHMEGAPHONERIGHT_START; bodyLoopPat = BPAT_WITHMEGAPHONERIGHT_LOOP; break; default: break; } break; case TALK_WITHBEARDSTATIC: switch (_talkDirection) { case UP: case LEFT: _nBodyOffset.set(-41, -14); bodyStartPat = BPAT_WITHBEARDLEFT_START; bodyLoopPat = BPAT_STANDLEFT; headLoopPat = PAT_TALKBEARD_LEFT; headPat = 0; break; case DOWN: case RIGHT: _nBodyOffset.set(-26, -14); bodyStartPat = BPAT_WITHBEARDRIGHT_START; bodyLoopPat = BPAT_STANDRIGHT; headLoopPat = PAT_TALKBEARD_RIGHT; headPat = 0; break; default: break; } break; case TALK_SCAREDSTATIC: switch (_talkDirection) { case DOWN: headPat = PAT_SCAREDDOWN_START; bodyLoopPat = BPAT_STANDDOWN; bodyStartPat = BPAT_STANDDOWN; headLoopPat = PAT_SCAREDDOWN_STAND; _nBodyOffset.set(4, 53); break; case LEFT: headPat = PAT_SCAREDLEFT_START; bodyLoopPat = BPAT_STANDLEFT; bodyStartPat = BPAT_STANDLEFT; headLoopPat = PAT_SCAREDLEFT_STAND; _nBodyOffset.set(6, 56); break; case RIGHT: headPat = PAT_SCAREDRIGHT_START; bodyLoopPat = BPAT_STANDRIGHT; bodyStartPat = BPAT_STANDRIGHT; headLoopPat = PAT_SCAREDRIGHT_STAND; _nBodyOffset.set(6, 56); break; case UP: default: break; } default: break; } } void RMTony::startStatic(CORO_PARAM, CharacterTalkType nTalk) { CORO_BEGIN_CONTEXT; int headPat, headLoopPat; int bodyStartPat, bodyLoopPat; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); _ctx->headPat = _ctx->headLoopPat = 0; _ctx->bodyStartPat = _ctx->bodyLoopPat = 0; startStaticCalculate(nTalk, _ctx->headPat, _ctx->headLoopPat, _ctx->bodyStartPat, _ctx->bodyLoopPat); // e vai con i pattern _bIsStaticTalk = true; setPattern(_ctx->headPat); _body.setPattern(_ctx->bodyStartPat); CORO_INVOKE_0(_body.waitForEndPattern); CORO_INVOKE_0(waitForEndPattern); if (_ctx->headLoopPat != -1) setPattern(_ctx->headLoopPat); _body.setPattern(_ctx->bodyLoopPat); CORO_END_CODE; } void RMTony::endStaticCalculate(CharacterTalkType nTalk, int &bodyEndPat, int &finalPat, int &headEndPat) { switch (_talkDirection) { case UP: case LEFT: finalPat = PAT_STANDLEFT; break; case RIGHT: case DOWN: finalPat = PAT_STANDRIGHT; break; default: break; } switch (nTalk) { case TALK_WITHSNOWMANSTATIC: switch (_talkDirection) { case UP: case LEFT: bodyEndPat = BPAT_WITHSNOWMANLEFT_END; break; case DOWN: case RIGHT: bodyEndPat = BPAT_WITHSNOWMANRIGHT_END; break; default: break; } break; case TALK_WITHRECIPESTATIC: switch (_talkDirection) { case UP: case LEFT: bodyEndPat = BPAT_WITHRECIPELEFT_END; break; case DOWN: case RIGHT: bodyEndPat = BPAT_WITHRECIPERIGHT_END; break; default: break; } break; case TALK_WITHRABBITSTATIC: switch (_talkDirection) { case UP: case LEFT: bodyEndPat = BPAT_WITHRABBITLEFT_END; break; case DOWN: case RIGHT: bodyEndPat = BPAT_WITHRABBITRIGHT_END; break; default: break; } break; case TALK_WITHCARDSSTATIC: switch (_talkDirection) { case UP: case LEFT: bodyEndPat = BPAT_WITHCARDSLEFT_END; break; case DOWN: case RIGHT: bodyEndPat = BPAT_WITHCARDSRIGHT_END; break; default: break; } break; case TALK_WITH_NOTEBOOK: switch (_talkDirection) { case UP: case LEFT: bodyEndPat = BPAT_WITHNOTEBOOKLEFT_END; break; case DOWN: case RIGHT: bodyEndPat = BPAT_WITHNOTEBOOKRIGHT_END; break; default: break; } break; case TALK_WITHMEGAPHONESTATIC: switch (_talkDirection) { case UP: case LEFT: bodyEndPat = BPAT_WITHMEGAPHONELEFT_END; break; case DOWN: case RIGHT: bodyEndPat = BPAT_WITHMEGAPHONERIGHT_END; break; default: break; } break; case TALK_WITHBEARDSTATIC: switch (_talkDirection) { case UP: case LEFT: bodyEndPat = BPAT_WITHBEARDLEFT_END; break; case DOWN: case RIGHT: bodyEndPat = BPAT_WITHBEARDRIGHT_END; break; default: break; } break; case TALK_SCAREDSTATIC: switch (_talkDirection) { case LEFT: headEndPat = PAT_SCAREDLEFT_END; break; case DOWN: headEndPat = PAT_SCAREDDOWN_END; break; case RIGHT: headEndPat = PAT_SCAREDRIGHT_END; break; case UP: default: break; } break; default: break; } } void RMTony::endStatic(CORO_PARAM, CharacterTalkType nTalk) { CORO_BEGIN_CONTEXT; int bodyEndPat; int finalPat; int headEndPat; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); _ctx->bodyEndPat = 0; _ctx->finalPat = 0; _ctx->headEndPat = 0; endStaticCalculate(nTalk, _ctx->bodyEndPat, _ctx->finalPat, _ctx->headEndPat); if (_ctx->headEndPat != 0) { setPattern(_ctx->headEndPat); CORO_INVOKE_0(waitForEndPattern); } else { // Play please _body.setPattern(_ctx->bodyEndPat); CORO_INVOKE_0(_body.waitForEndPattern); } setPattern(_ctx->finalPat); _body.setPattern(0); _bIsStaticTalk = false; CORO_END_CODE; } /** * Waits until the end of a pattern */ void RMTony::waitForEndPattern(CORO_PARAM, uint32 hCustomSkip) { RMCharacter::waitForEndPattern(coroParam, hCustomSkip); } /** * Check if currently in an action */ bool RMTony::inAction() { return (_bActionPending && _action != 0) | _bAction; } /** * Check if there needs to be an update for scrolling movement */ bool RMTony::mustUpdateScrolling() { return ((!inAction()) || (isMoving())); } /** * Returns Tony's position */ RMPoint RMTony::position() { return _pos; } /** * Set the scrolling position */ void RMTony::setScrollPosition(const RMPoint &pt) { RMCharacter::setScrollPosition(pt); } /** * Tony disguises himself! */ void RMTony::setShepherdess(bool bIsPast) { _bShepherdess = bIsPast; } int RMTony::getShepherdess() { return _bShepherdess; } void RMTony::playSfx(int nSfx) { RMItem::playSfx(nSfx); } } // End of namespace Tony