2003-08-15 18:00:22 +00:00
|
|
|
// Residual - Virtual machine to run LucasArts' 3D adventure games
|
2005-01-01 10:23:18 +00:00
|
|
|
// Copyright (C) 2003-2005 The ScummVM-Residual Team (www.scummvm.org)
|
2003-08-15 18:00:22 +00:00
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2.1 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library 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
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
2003-08-24 17:56:03 +00:00
|
|
|
#include "stdafx.h"
|
2003-08-15 19:41:26 +00:00
|
|
|
#include "actor.h"
|
|
|
|
#include "engine.h"
|
|
|
|
#include "costume.h"
|
2004-09-11 14:09:43 +00:00
|
|
|
#include "lipsynch.h"
|
2004-03-20 09:38:33 +00:00
|
|
|
#include "localize.h"
|
2004-01-23 11:10:59 +00:00
|
|
|
#include "driver_gl.h"
|
2005-01-01 12:27:57 +00:00
|
|
|
|
2004-09-11 14:09:43 +00:00
|
|
|
#include "mixer/mixer.h"
|
|
|
|
|
2005-01-01 21:07:52 +00:00
|
|
|
#include "imuse/imuse.h"
|
|
|
|
|
2005-01-01 12:27:57 +00:00
|
|
|
#include <cmath>
|
|
|
|
#include <cstring>
|
|
|
|
|
2003-08-15 18:00:22 +00:00
|
|
|
Actor::Actor(const char *name) :
|
2004-12-09 23:55:43 +00:00
|
|
|
_name(name), _talkColor(255, 255, 255), _pos(0, 0, 0),
|
|
|
|
_pitch(0), _yaw(0), _roll(0), _walkRate(0), _turnRate(0),
|
2005-01-01 21:07:52 +00:00
|
|
|
_visible(true), _lipSynch(NULL), _turning(false), _walking(false),
|
2004-12-09 23:55:43 +00:00
|
|
|
_restCostume(NULL), _restChore(-1),
|
|
|
|
_walkCostume(NULL), _walkChore(-1), _walkedLast(false), _walkedCur(false),
|
|
|
|
_turnCostume(NULL), _leftTurnChore(-1), _rightTurnChore(-1),
|
|
|
|
_lastTurnDir(0), _currTurnDir(0),
|
|
|
|
_mumbleCostume(NULL), _mumbleChore(-1) {
|
2004-12-31 21:35:04 +00:00
|
|
|
g_engine->registerActor(this);
|
2004-12-09 23:55:43 +00:00
|
|
|
_lookingMode = false;
|
|
|
|
_constrain = false;
|
2004-03-24 01:36:05 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < 10; i++) {
|
2004-12-09 23:55:43 +00:00
|
|
|
_talkCostume[i] = NULL;
|
|
|
|
_talkChore[i] = -1;
|
2004-03-24 01:36:05 +00:00
|
|
|
}
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2003-08-22 11:37:39 +00:00
|
|
|
void Actor::turnTo(float pitch, float yaw, float roll) {
|
2004-12-09 23:55:43 +00:00
|
|
|
_pitch = pitch;
|
|
|
|
_roll = roll;
|
|
|
|
if (_yaw != yaw) {
|
|
|
|
_turning = true;
|
|
|
|
_destYaw = yaw;
|
2004-02-24 08:20:45 +00:00
|
|
|
} else
|
2004-12-09 23:55:43 +00:00
|
|
|
_turning = false;
|
2003-08-22 11:37:39 +00:00
|
|
|
}
|
|
|
|
|
2003-08-22 12:28:33 +00:00
|
|
|
void Actor::walkTo(Vector3d p) {
|
2004-02-24 08:20:45 +00:00
|
|
|
// For now, this is just the ignoring-boxes version (which afaict
|
|
|
|
// isn't even in the original). This will eventually need a
|
|
|
|
// following-boxes version also.
|
2004-12-09 23:55:43 +00:00
|
|
|
if (p == _pos)
|
|
|
|
_walking = false;
|
2004-02-24 08:20:45 +00:00
|
|
|
else {
|
2004-12-09 23:55:43 +00:00
|
|
|
_walking = true;
|
|
|
|
_destPos = p;
|
2004-02-24 08:20:45 +00:00
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
if (p.x() != _pos.x() || p.y() != _pos.y())
|
|
|
|
turnTo(_pitch, yawTo(p), _roll);
|
2004-02-24 08:20:45 +00:00
|
|
|
}
|
2003-08-22 12:28:33 +00:00
|
|
|
}
|
|
|
|
|
2004-03-25 15:43:05 +00:00
|
|
|
bool Actor::isWalking() const {
|
2004-12-09 23:55:43 +00:00
|
|
|
return _walkedLast || _walkedCur || _walking;
|
2004-03-25 15:43:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Actor::isTurning() const {
|
2004-12-09 23:55:43 +00:00
|
|
|
if (_turning)
|
2004-03-25 15:43:05 +00:00
|
|
|
return true;
|
2004-12-09 23:55:43 +00:00
|
|
|
|
|
|
|
if (_lastTurnDir != 0 || _currTurnDir != 0)
|
2004-03-25 15:43:05 +00:00
|
|
|
return true;
|
2004-12-09 23:55:43 +00:00
|
|
|
|
2004-03-25 15:43:05 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2003-08-15 18:00:22 +00:00
|
|
|
void Actor::walkForward() {
|
2004-12-31 21:35:04 +00:00
|
|
|
float dist = g_engine->perSecond(_walkRate);
|
2004-12-09 23:55:43 +00:00
|
|
|
float yaw_rad = _yaw * (M_PI / 180), pitch_rad = _pitch * (M_PI / 180);
|
2004-02-24 08:20:45 +00:00
|
|
|
Vector3d forwardVec(-std::sin(yaw_rad) * std::cos(pitch_rad),
|
|
|
|
std::cos(yaw_rad) * std::cos(pitch_rad),
|
|
|
|
std::sin(pitch_rad));
|
2004-12-09 23:55:43 +00:00
|
|
|
Vector3d destPos = _pos + forwardVec * dist;
|
2004-03-25 09:33:17 +00:00
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
if (!_constrain) {
|
|
|
|
_pos = destPos;
|
|
|
|
_walkedCur = true;
|
|
|
|
} else {
|
2004-12-31 21:35:04 +00:00
|
|
|
Sector *sector = g_engine->currScene()->findPointSector(destPos, 0x1000);
|
2004-03-25 09:33:17 +00:00
|
|
|
if (sector != NULL) {
|
2004-12-09 23:55:43 +00:00
|
|
|
_pos = sector->projectToPlane(destPos);
|
|
|
|
_walkedCur = true;
|
2004-03-25 09:33:17 +00:00
|
|
|
}
|
|
|
|
}
|
2004-03-24 01:36:05 +00:00
|
|
|
}
|
|
|
|
|
2004-03-25 15:43:05 +00:00
|
|
|
Vector3d Actor::puckVector() const {
|
2004-12-09 23:55:43 +00:00
|
|
|
float yaw_rad = _yaw * (M_PI / 180);
|
2004-03-25 15:43:05 +00:00
|
|
|
Vector3d forwardVec(-std::sin(yaw_rad), std::cos(yaw_rad), 0);
|
|
|
|
|
2004-12-31 21:35:04 +00:00
|
|
|
Sector *sector = g_engine->currScene()->findPointSector(_pos, 0x1000);
|
2004-03-25 15:43:05 +00:00
|
|
|
if (sector == NULL)
|
|
|
|
return forwardVec;
|
|
|
|
else
|
|
|
|
return sector->projectToPuckVector(forwardVec);
|
|
|
|
}
|
|
|
|
|
2004-03-24 01:36:05 +00:00
|
|
|
void Actor::setRestChore(int chore, Costume *cost) {
|
2004-12-09 23:55:43 +00:00
|
|
|
if (_restCostume == cost && _restChore == chore)
|
2004-03-25 15:43:05 +00:00
|
|
|
return;
|
2004-12-09 23:55:43 +00:00
|
|
|
|
|
|
|
if (_restChore >= 0)
|
|
|
|
_restCostume->stopChore(_restChore);
|
|
|
|
|
|
|
|
_restCostume = cost;
|
|
|
|
_restChore = chore;
|
|
|
|
|
|
|
|
if (_restChore >= 0)
|
|
|
|
_restCostume->playChoreLooping(_restChore);
|
2004-03-24 01:36:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Actor::setWalkChore(int chore, Costume *cost) {
|
2004-12-09 23:55:43 +00:00
|
|
|
if (_walkCostume == cost && _walkChore == chore)
|
2004-03-25 15:43:05 +00:00
|
|
|
return;
|
2004-12-09 23:55:43 +00:00
|
|
|
|
|
|
|
if (_walkChore >= 0)
|
|
|
|
_walkCostume->stopChore(_walkChore);
|
|
|
|
|
|
|
|
_walkCostume = cost;
|
|
|
|
_walkChore = chore;
|
2004-03-24 01:36:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Actor::setTurnChores(int left_chore, int right_chore, Costume *cost) {
|
2004-12-09 23:55:43 +00:00
|
|
|
if (_turnCostume == cost && _leftTurnChore == left_chore &&
|
|
|
|
_rightTurnChore == right_chore)
|
2004-03-25 15:43:05 +00:00
|
|
|
return;
|
2004-12-09 23:55:43 +00:00
|
|
|
|
|
|
|
if (_leftTurnChore >= 0) {
|
|
|
|
_turnCostume->stopChore(_leftTurnChore);
|
|
|
|
_turnCostume->stopChore(_rightTurnChore);
|
2004-03-24 01:36:05 +00:00
|
|
|
}
|
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
_turnCostume = cost;
|
|
|
|
_leftTurnChore = left_chore;
|
|
|
|
_rightTurnChore = right_chore;
|
|
|
|
|
|
|
|
if ((left_chore >= 0 && right_chore < 0) || (left_chore < 0 && right_chore >= 0))
|
2004-03-24 01:36:05 +00:00
|
|
|
error("Unexpectedly got only one turn chore\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void Actor::setTalkChore(int index, int chore, Costume *cost) {
|
|
|
|
if (index < 1 || index > 10)
|
|
|
|
error("Got talk chore index out of range (%d)\n", index);
|
2004-12-09 23:55:43 +00:00
|
|
|
|
2004-03-24 01:36:05 +00:00
|
|
|
index--;
|
2004-12-09 23:55:43 +00:00
|
|
|
|
|
|
|
if (_talkCostume[index] == cost && _talkChore[index] == chore)
|
2004-03-25 15:43:05 +00:00
|
|
|
return;
|
2004-12-09 23:55:43 +00:00
|
|
|
|
|
|
|
if (_talkChore[index] >= 0)
|
|
|
|
_talkCostume[index]->stopChore(_talkChore[index]);
|
|
|
|
|
|
|
|
_talkCostume[index] = cost;
|
|
|
|
_talkChore[index] = chore;
|
2004-03-24 01:36:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Actor::setMumbleChore(int chore, Costume *cost) {
|
2004-12-09 23:55:43 +00:00
|
|
|
if (_mumbleChore >= 0)
|
|
|
|
_mumbleCostume->stopChore(_mumbleChore);
|
|
|
|
|
|
|
|
_mumbleCostume = cost;
|
|
|
|
_mumbleChore = chore;
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Actor::turn(int dir) {
|
2004-12-31 21:35:04 +00:00
|
|
|
float delta = g_engine->perSecond(_turnRate) * dir;
|
2004-12-09 23:55:43 +00:00
|
|
|
_yaw += delta;
|
|
|
|
_currTurnDir = dir;
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
float Actor::angleTo(const Actor &a) const {
|
2004-12-09 23:55:43 +00:00
|
|
|
float yaw_rad = _yaw * (M_PI / 180);
|
2004-02-24 08:20:45 +00:00
|
|
|
Vector3d forwardVec(-std::sin(yaw_rad), std::cos(yaw_rad), 0);
|
2004-12-09 23:55:43 +00:00
|
|
|
Vector3d delta = a.pos() - _pos;
|
2004-02-24 08:20:45 +00:00
|
|
|
delta.z() = 0;
|
2004-12-09 23:55:43 +00:00
|
|
|
|
2004-02-24 08:20:45 +00:00
|
|
|
return angle(forwardVec, delta) * (180 / M_PI);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2003-08-22 12:28:33 +00:00
|
|
|
float Actor::yawTo(Vector3d p) const {
|
2004-12-09 23:55:43 +00:00
|
|
|
Vector3d dpos = p - _pos;
|
|
|
|
|
2004-02-24 08:20:45 +00:00
|
|
|
if (dpos.x() == 0 && dpos.y() == 0)
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return std::atan2(-dpos.x(), dpos.y()) * (180 / M_PI);
|
2003-08-22 12:28:33 +00:00
|
|
|
}
|
|
|
|
|
2005-01-02 13:34:50 +00:00
|
|
|
void Actor::sayLine(const char *msg, const char *msgId) {
|
|
|
|
assert(msg);
|
|
|
|
assert(msgId);
|
2004-02-24 08:20:45 +00:00
|
|
|
|
2005-01-02 13:34:50 +00:00
|
|
|
if (msg[0] == '/' || msg[0] == 0 || msgId[0] == 0)
|
2004-02-24 08:20:45 +00:00
|
|
|
return;
|
2004-12-09 23:55:43 +00:00
|
|
|
|
2005-01-02 13:34:50 +00:00
|
|
|
std::string soundName = msgId;
|
|
|
|
std::string soundLip = msgId;
|
|
|
|
soundName += ".wav";
|
|
|
|
soundLip += ".lip";
|
2004-12-09 23:55:43 +00:00
|
|
|
|
2005-01-02 13:34:50 +00:00
|
|
|
if (_talkSoundName == soundName)
|
2005-01-01 21:07:52 +00:00
|
|
|
return;
|
2004-09-11 14:09:43 +00:00
|
|
|
|
2005-01-01 21:07:52 +00:00
|
|
|
if (g_imuse->getSoundStatus(_talkSoundName.c_str()))
|
|
|
|
shutUp();
|
|
|
|
|
2005-01-02 13:34:50 +00:00
|
|
|
_lipSynch = g_resourceloader->loadLipSynch(soundLip.c_str());
|
|
|
|
_talkSoundName = soundName;
|
2005-01-01 21:07:52 +00:00
|
|
|
g_imuse->startVoice(_talkSoundName.c_str());
|
|
|
|
_talkAnim = -1;
|
2004-03-24 01:36:05 +00:00
|
|
|
}
|
2003-08-15 18:00:22 +00:00
|
|
|
|
|
|
|
bool Actor::talking() {
|
2005-01-01 21:07:52 +00:00
|
|
|
return g_imuse->getSoundStatus(_talkSoundName.c_str());
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2003-08-21 06:51:02 +00:00
|
|
|
void Actor::shutUp() {
|
2005-01-01 21:07:52 +00:00
|
|
|
if (_lipSynch != NULL) {
|
|
|
|
g_imuse->stopSound(_talkSoundName.c_str());
|
|
|
|
if (_talkChore[_talkAnim] >= 0)
|
|
|
|
_talkCostume[_talkAnim]->stopChore(_talkChore[_talkAnim]);
|
|
|
|
_lipSynch = NULL;
|
|
|
|
} else if (_mumbleChore >= 0)
|
|
|
|
_mumbleCostume->stopChore(_mumbleChore);
|
2005-01-02 13:34:50 +00:00
|
|
|
_talkSoundName = "";
|
2003-08-21 06:51:02 +00:00
|
|
|
}
|
|
|
|
|
2003-08-20 14:29:59 +00:00
|
|
|
void Actor::pushCostume(const char *name) {
|
2004-12-31 21:35:04 +00:00
|
|
|
Costume *newCost = g_resourceloader->loadCostume(name, currentCostume());
|
2004-12-09 23:55:43 +00:00
|
|
|
_costumeStack.push_back(newCost);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2003-08-20 14:29:59 +00:00
|
|
|
void Actor::setCostume(const char *name) {
|
2004-12-09 23:55:43 +00:00
|
|
|
if (!_costumeStack.empty())
|
2004-02-24 08:20:45 +00:00
|
|
|
popCostume();
|
2004-12-09 23:55:43 +00:00
|
|
|
|
2004-02-24 08:20:45 +00:00
|
|
|
pushCostume(name);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Actor::popCostume() {
|
2004-12-09 23:55:43 +00:00
|
|
|
if (!_costumeStack.empty()) {
|
|
|
|
freeCostumeChore(_costumeStack.back(), _restCostume, _restChore);
|
|
|
|
freeCostumeChore(_costumeStack.back(), _walkCostume, _walkChore);
|
|
|
|
|
|
|
|
if (_turnCostume == _costumeStack.back()) {
|
|
|
|
_turnCostume = NULL;
|
|
|
|
_leftTurnChore = -1;
|
|
|
|
_rightTurnChore = -1;
|
2004-03-24 01:36:05 +00:00
|
|
|
}
|
2004-12-09 23:55:43 +00:00
|
|
|
|
|
|
|
freeCostumeChore(_costumeStack.back(), _mumbleCostume, _mumbleChore);
|
2004-03-24 01:36:05 +00:00
|
|
|
for (int i = 0; i < 10; i++)
|
2004-12-09 23:55:43 +00:00
|
|
|
freeCostumeChore(_costumeStack.back(), _talkCostume[i], _talkChore[i]);
|
|
|
|
delete _costumeStack.back();
|
|
|
|
_costumeStack.pop_back();
|
2004-02-24 08:20:45 +00:00
|
|
|
}
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Actor::clearCostumes() {
|
2004-02-24 08:20:45 +00:00
|
|
|
// Make sure to destroy costume copies in reverse order
|
2004-12-09 23:55:43 +00:00
|
|
|
while (!_costumeStack.empty())
|
2004-03-24 01:36:05 +00:00
|
|
|
popCostume();
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2003-08-26 09:36:47 +00:00
|
|
|
void Actor::setHead( int joint1, int joint2, int joint3, float maxRoll, float maxPitch, float maxYaw ) {
|
2004-12-09 23:55:43 +00:00
|
|
|
if (!_costumeStack.empty()) {
|
|
|
|
_costumeStack.back()->setHead(joint1, joint2, joint3, maxRoll, maxPitch, maxYaw);
|
2003-08-26 09:36:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-08-15 18:00:22 +00:00
|
|
|
Costume *Actor::findCostume(const char *name) {
|
2004-12-09 23:55:43 +00:00
|
|
|
for (std::list<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); i++)
|
2004-02-24 08:20:45 +00:00
|
|
|
if (std::strcmp((*i)->filename(), name) == 0)
|
|
|
|
return *i;
|
2004-12-09 23:55:43 +00:00
|
|
|
|
2004-02-24 08:20:45 +00:00
|
|
|
return NULL;
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Actor::update() {
|
2004-03-26 09:28:13 +00:00
|
|
|
// Snap actor to walkboxes if following them. This might be
|
|
|
|
// necessary for example after activating/deactivating
|
|
|
|
// walkboxes, etc.
|
2004-12-09 23:55:43 +00:00
|
|
|
if (_constrain && !_walking) {
|
2004-12-31 21:35:04 +00:00
|
|
|
g_engine->currScene()->findClosestSector(_pos, NULL, &_pos);
|
2004-03-26 09:28:13 +00:00
|
|
|
}
|
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
if (_turning) {
|
2004-12-31 21:35:04 +00:00
|
|
|
float turnAmt = g_engine->perSecond(_turnRate);
|
2004-12-09 23:55:43 +00:00
|
|
|
float dyaw = _destYaw - _yaw;
|
2004-02-24 08:20:45 +00:00
|
|
|
while (dyaw > 180)
|
|
|
|
dyaw -= 360;
|
|
|
|
while (dyaw < -180)
|
|
|
|
dyaw += 360;
|
|
|
|
if (turnAmt >= std::abs(dyaw)) {
|
2004-12-09 23:55:43 +00:00
|
|
|
_yaw = _destYaw;
|
|
|
|
_turning = false;
|
2004-02-24 08:20:45 +00:00
|
|
|
}
|
|
|
|
else if (dyaw > 0)
|
2004-12-09 23:55:43 +00:00
|
|
|
_yaw += turnAmt;
|
2004-02-24 08:20:45 +00:00
|
|
|
else
|
2004-12-09 23:55:43 +00:00
|
|
|
_yaw -= turnAmt;
|
|
|
|
_currTurnDir = (dyaw > 0 ? 1 : -1);
|
2004-02-24 08:20:45 +00:00
|
|
|
}
|
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
if (_walking) {
|
|
|
|
Vector3d dir = _destPos - _pos;
|
2004-02-24 08:20:45 +00:00
|
|
|
float dist = dir.magnitude();
|
|
|
|
|
|
|
|
if (dist > 0)
|
|
|
|
dir /= dist;
|
|
|
|
|
2004-12-31 21:35:04 +00:00
|
|
|
float walkAmt = g_engine->perSecond(_walkRate);
|
2004-02-24 08:20:45 +00:00
|
|
|
|
|
|
|
if (walkAmt >= dist) {
|
2004-12-09 23:55:43 +00:00
|
|
|
_pos = _destPos;
|
|
|
|
_walking = false;
|
|
|
|
_turning = false;
|
|
|
|
} else
|
|
|
|
_pos += dir * walkAmt;
|
2004-03-25 15:43:05 +00:00
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
_walkedCur = true;
|
2004-02-24 08:20:45 +00:00
|
|
|
}
|
|
|
|
|
2004-03-24 01:36:05 +00:00
|
|
|
// The rest chore might have been stopped because of a
|
|
|
|
// StopActorChore(nil). Restart it if so.
|
2004-12-09 23:55:43 +00:00
|
|
|
if (_restChore >= 0 && _restCostume->isChoring(_restChore, false) < 0)
|
|
|
|
_restCostume->playChoreLooping(_restChore);
|
2004-03-24 01:36:05 +00:00
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
if (_walkChore >= 0) {
|
|
|
|
if (_walkedCur) {
|
|
|
|
if (_walkCostume->isChoring(_walkChore, false) < 0)
|
|
|
|
_walkCostume->playChoreLooping(_walkChore);
|
|
|
|
} else {
|
|
|
|
if (_walkCostume->isChoring(_walkChore, false) >= 0)
|
|
|
|
_walkCostume->stopChore(_walkChore);
|
2004-03-24 01:36:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
if (_leftTurnChore >= 0) {
|
|
|
|
if (_walkedCur)
|
|
|
|
_currTurnDir = 0;
|
|
|
|
if (_lastTurnDir != 0 && _lastTurnDir != _currTurnDir)
|
|
|
|
_turnCostume->stopChore(getTurnChore(_lastTurnDir));
|
|
|
|
if (_currTurnDir != 0 && _currTurnDir != _lastTurnDir)
|
|
|
|
_turnCostume->playChoreLooping(getTurnChore(_currTurnDir));
|
|
|
|
} else
|
|
|
|
_currTurnDir = 0;
|
|
|
|
|
|
|
|
_walkedLast = _walkedCur;
|
|
|
|
_walkedCur = false;
|
|
|
|
_lastTurnDir = _currTurnDir;
|
|
|
|
_currTurnDir = 0;
|
2004-03-24 01:36:05 +00:00
|
|
|
|
2004-09-11 14:09:43 +00:00
|
|
|
// Update lip synching
|
2005-01-01 21:07:52 +00:00
|
|
|
if (_lipSynch != NULL) {
|
|
|
|
int posSound = g_imuse->getPosIn60HzTicks(_talkSoundName.c_str());
|
|
|
|
if (posSound != -1) {
|
|
|
|
int anim = _lipSynch->getAnim(posSound);
|
|
|
|
if (_talkAnim != anim) {
|
|
|
|
if (_talkAnim != -1 && _talkChore[_talkAnim] >= 0)
|
|
|
|
_talkCostume[_talkAnim]->stopChore(_talkChore[_talkAnim]);
|
|
|
|
if (anim != -1) {
|
|
|
|
_talkAnim = anim;
|
|
|
|
if (_talkChore[_talkAnim] >= 0) {
|
|
|
|
_talkCostume[_talkAnim]->playChoreLooping(_talkChore[_talkAnim]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-12-09 23:55:43 +00:00
|
|
|
}
|
|
|
|
|
2005-01-01 21:07:52 +00:00
|
|
|
if (!g_imuse->isVoicePlaying())
|
2004-09-11 14:09:43 +00:00
|
|
|
shutUp();
|
2005-01-01 21:07:52 +00:00
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
for (std::list<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); i++) {
|
|
|
|
(*i)->setPosRotate(_pos, _pitch, _yaw, _roll);
|
2004-02-24 08:20:45 +00:00
|
|
|
(*i)->update();
|
|
|
|
}
|
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
if (_lookingMode) {
|
2004-12-31 21:35:04 +00:00
|
|
|
float lookAtAmt = g_engine->perSecond(_lookAtRate);
|
2004-02-24 08:20:45 +00:00
|
|
|
}
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Actor::draw() {
|
2004-12-09 23:55:43 +00:00
|
|
|
for (std::list<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); i++)
|
2004-03-23 13:05:08 +00:00
|
|
|
(*i)->setupTextures();
|
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
if (!_costumeStack.empty()) {
|
|
|
|
g_driver->startActorDraw(_pos, _yaw, _pitch, _roll);
|
|
|
|
_costumeStack.back()->draw();
|
2004-02-24 08:20:45 +00:00
|
|
|
g_driver->finishActorDraw();
|
|
|
|
}
|
2004-12-09 23:55:43 +00:00
|
|
|
}
|