scummvm/engines/tony/tonychar.cpp
2021-12-26 18:48:43 +01:00

2099 lines
40 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* 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