diff options
Diffstat (limited to 'engines/tony/tonychar.cpp')
-rw-r--r-- | engines/tony/tonychar.cpp | 1945 |
1 files changed, 1945 insertions, 0 deletions
diff --git a/engines/tony/tonychar.cpp b/engines/tony/tonychar.cpp new file mode 100644 index 0000000000..c7fa1e4a7b --- /dev/null +++ b/engines/tony/tonychar.cpp @@ -0,0 +1,1945 @@ +/* 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; + } + + 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; + } + } + + 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; + } + 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; + } + 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; + } + 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; + } + } +} + + +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; + } + 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; + } + 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; + } + 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; + } + } +} + + +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; + } + + // 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + + 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; + } + + 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; + } + 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; + } + + 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; + } + + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + + _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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + + 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; + } + + 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; + } + break; + + case TALK_WITHRECIPESTATIC: + switch (_talkDirection) { + case UP: + case LEFT: + bodyEndPat = BPAT_WITHRECIPELEFT_END; + break; + + case DOWN: + case RIGHT: + bodyEndPat = BPAT_WITHRECIPERIGHT_END; + 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; + } + break; + + case TALK_WITHCARDSSTATIC: + switch (_talkDirection) { + case UP: + case LEFT: + bodyEndPat = BPAT_WITHCARDSLEFT_END; + break; + + case DOWN: + case RIGHT: + bodyEndPat = BPAT_WITHCARDSRIGHT_END; + 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; + } + break; + + case TALK_WITHMEGAPHONESTATIC: + switch (_talkDirection) { + case UP: + case LEFT: + bodyEndPat = BPAT_WITHMEGAPHONELEFT_END; + break; + + case DOWN: + case RIGHT: + bodyEndPat = BPAT_WITHMEGAPHONERIGHT_END; + 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; + } + 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; + + 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 |