Implemented playing chores for walking, turning, mumbling.

TODO: processing *.lip files and using that data to play the specific
talkChore_[i] chores instead of the generic mumble chore.
This commit is contained in:
Daniel Schepler 2004-03-24 01:36:05 +00:00
parent d321764e39
commit 5ec54ab780
6 changed files with 188 additions and 67 deletions

2
TODO
View file

@ -12,4 +12,4 @@ Unassigned (help wanted):
* Proper vsscanf implementation in textsplit.cpp for platforms without it (MSVC, etc)
* Cross platform GUI for debug input dialogs (ctrl+e ctrl+g etc) - original used MFC
* Fix the screenblocks zBuffer code
* Lip syncing

141
actor.cpp
View file

@ -28,10 +28,20 @@
Actor::Actor(const char *name) :
name_(name), talkColor_(255, 255, 255), pos_(0, 0, 0),
pitch_(0), yaw_(0), roll_(0), walkRate_(0), turnRate_(0),
visible_(true), talkSound_(NULL), turning_(false), walking_(false), walkChore_(-1) {
visible_(true), talkSound_(NULL), turning_(false), walking_(false),
restCostume_(NULL), restChore_(-1),
walkCostume_(NULL), walkChore_(-1), lastWalkTime_(-1),
turnCostume_(NULL), leftTurnChore_(-1), rightTurnChore_(-1),
lastTurnDir_(0), currTurnDir_(0),
mumbleCostume_(NULL), mumbleChore_(-1) {
Engine::instance()->registerActor(this);
lookingMode_ = false;
constrain_ = false;
for (int i = 0; i < 10; i++) {
talkCostume_[i] = NULL;
talkChore_[i] = -1;
}
}
void Actor::turnTo(float pitch, float yaw, float roll) {
@ -85,13 +95,62 @@ void Actor::walkForward() {
Vector3d forwardVec(-std::sin(yaw_rad) * std::cos(pitch_rad),
std::cos(yaw_rad) * std::cos(pitch_rad),
std::sin(pitch_rad));
if (validBoxVector(forwardVec, dist))
if (validBoxVector(forwardVec, dist)) {
pos_ += forwardVec * dist;
lastWalkTime_ = Engine::instance()->frameStart();
}
}
void Actor::setRestChore(int chore, Costume *cost) {
if (restChore_ >= 0)
restCostume_->stopChore(restChore_);
restCostume_ = cost;
restChore_ = chore;
restCostume_->playChoreLooping(restChore_);
}
void Actor::setWalkChore(int chore, Costume *cost) {
if (walkChore_ >= 0)
walkCostume_->stopChore(walkChore_);
walkCostume_ = cost;
walkChore_ = chore;
}
void Actor::setTurnChores(int left_chore, int right_chore, Costume *cost) {
if (leftTurnChore_ >= 0) {
turnCostume_->stopChore(leftTurnChore_);
turnCostume_->stopChore(rightTurnChore_);
}
turnCostume_ = cost;
leftTurnChore_ = left_chore;
rightTurnChore_ = right_chore;
if ((left_chore >= 0 && right_chore < 0) ||
(left_chore < 0 && right_chore >= 0))
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);
index--;
if (talkChore_[index] >= 0)
talkCostume_[index]->stopChore(talkChore_[index]);
talkCostume_[index] = cost;
talkChore_[index] = chore;
}
void Actor::setMumbleChore(int chore, Costume *cost) {
if (mumbleChore_ >= 0)
mumbleCostume_->stopChore(mumbleChore_);
mumbleCostume_ = cost;
mumbleChore_ = chore;
}
void Actor::turn(int dir) {
float delta = Engine::instance()->perSecond(turnRate_) * dir;
yaw_ += delta;
currTurnDir_ = dir;
}
float Actor::angleTo(const Actor &a) const {
@ -126,33 +185,23 @@ void Actor::sayLine(const char *msg) {
std::string msgText = Localizer::instance()->localize(secondSlash + 1);
std::string msgId(msg + 1, secondSlash);
talkSound_ = ResourceLoader::instance()->loadSound((msgId + ".wav").c_str());
if (talkSound_ != NULL)
if (talkSound_ != NULL) {
Mixer::instance()->playVoice(talkSound_);
//FIXME: Ender - Disabled until I work out why the wrong Chores play
// if (!costumeStack_.empty()) {
// printf("Requesting talk chore\n");
// costumeStack_.back()->playTalkChores();
//}
if (mumbleChore_ >= 0)
mumbleCostume_->playChoreLooping(mumbleChore_);
}
}
bool Actor::talking() {
if (talkSound_ == NULL)
return false;
if (talkSound_->done()) {
//FIXME: Ender - Disabled until I work out why the wrong Chores play
//if (!costumeStack_.empty())
//costumeStack_.back()->stopTalkChores();
talkSound_ = NULL;
return false;
}
return true;
return (talkSound_ != NULL && ! talkSound_->done());
}
void Actor::shutUp() {
if (talkSound_) {
Mixer::instance()->stopVoice(talkSound_);
talkSound_ = NULL;
if (mumbleChore_ >= 0)
mumbleCostume_->stopChore(mumbleChore_);
}
}
@ -170,6 +219,16 @@ void Actor::setCostume(const char *name) {
void Actor::popCostume() {
if (! costumeStack_.empty()) {
freeCostumeChore(costumeStack_.back(), restCostume_, restChore_);
freeCostumeChore(costumeStack_.back(), walkCostume_, walkChore_);
if (turnCostume_ == costumeStack_.back()) {
turnCostume_ = NULL;
leftTurnChore_ = -1;
rightTurnChore_ = -1;
}
freeCostumeChore(costumeStack_.back(), mumbleCostume_, mumbleChore_);
for (int i = 0; i < 10; i++)
freeCostumeChore(costumeStack_.back(), talkCostume_[i], talkChore_[i]);
delete costumeStack_.back();
costumeStack_.pop_back();
}
@ -177,10 +236,8 @@ void Actor::popCostume() {
void Actor::clearCostumes() {
// Make sure to destroy costume copies in reverse order
while (! costumeStack_.empty()) {
delete costumeStack_.back();
costumeStack_.pop_back();
}
while (! costumeStack_.empty())
popCostume();
}
void Actor::setHead( int joint1, int joint2, int joint3, float maxRoll, float maxPitch, float maxYaw ) {
@ -213,6 +270,7 @@ void Actor::update() {
yaw_ += turnAmt;
else
yaw_ -= turnAmt;
currTurnDir_ = (dyaw > 0 ? 1 : -1);
}
if (walking_) {
@ -233,6 +291,43 @@ void Actor::update() {
pos_ += dir * walkAmt;
}
// The rest chore might have been stopped because of a
// StopActorChore(nil). Restart it if so.
if (restChore_ >= 0 && restCostume_->isChoring(restChore_, false) < 0)
restCostume_->playChoreLooping(restChore_);
bool isWalking = (walking_ ||
lastWalkTime_ == Engine::instance()->frameStart());
if (walkChore_ >= 0) {
if (isWalking) {
if (walkCostume_->isChoring(walkChore_, false) < 0)
walkCostume_->playChoreLooping(walkChore_);
}
else {
if (walkCostume_->isChoring(walkChore_, false) >= 0)
walkCostume_->stopChore(walkChore_);
}
}
if (leftTurnChore_ >= 0) {
if (isWalking)
currTurnDir_ = 0;
if (lastTurnDir_ != 0 && lastTurnDir_ != currTurnDir_)
turnCostume_->stopChore(getTurnChore(lastTurnDir_));
if (currTurnDir_ != 0 && currTurnDir_ != lastTurnDir_)
turnCostume_->playChoreLooping(getTurnChore(currTurnDir_));
}
else
currTurnDir_ = 0;
lastTurnDir_ = currTurnDir_;
currTurnDir_ = 0;
if (talkSound_ != NULL && talkSound_->done()) {
talkSound_ = NULL;
if (mumbleChore_ >= 0)
mumbleCostume_->stopChore(mumbleChore_);
}
for (std::list<Costume *>::iterator i = costumeStack_.begin();
i != costumeStack_.end(); i++) {
(*i)->setPosRotate( pos_, pitch_, yaw_, roll_ );

32
actor.h
View file

@ -71,7 +71,11 @@ public:
void shutUp();
bool talking();
void setWalkChore(int choreNumber) { walkChore_ = choreNumber; }
void setRestChore(int choreNumber, Costume *cost);
void setWalkChore(int choreNumber, Costume *cost);
void setTurnChores(int left_chore, int right_chore, Costume *cost);
void setTalkChore(int index, int choreNumber, Costume *cost);
void setMumbleChore(int choreNumber, Costume *cost);
void pushCostume(const char *name);
void setCostume(const char *name);
@ -133,7 +137,33 @@ private:
Vector3d destPos_;
// chores
Costume *restCostume_;
int restChore_;
Costume *walkCostume_;
int walkChore_;
int lastWalkTime_;
Costume *turnCostume_;
int leftTurnChore_, rightTurnChore_;
int lastTurnDir_, currTurnDir_;
Costume *talkCostume_[10];
int talkChore_[10];
Costume *mumbleCostume_;
int mumbleChore_;
int getTurnChore(int dir) {
return (dir > 0 ? rightTurnChore_ : leftTurnChore_);
}
void freeCostumeChore(Costume *toFree, Costume *&cost, int &chore) {
if (cost == toFree) {
cost = NULL;
chore = -1;
}
}
// lookAt
Vector3d lookAtVector_;

View file

@ -586,9 +586,6 @@ Costume::Costume(const char *filename, const char *data, int len, Costume *prevC
ts.scanString("chore %d", 1, &which);
chores_[which].load(this, ts);
}
for (int i=0; i < MAX_TALK_CHORES; i++)
talkChores_[i] = -1;
}
Costume::~Costume() {
@ -736,32 +733,6 @@ int Costume::isChoring(bool excludeLooping) {
return -1;
}
void Costume::playTalkChores() {
for (int i=0; i<MAX_TALK_CHORES; i++) {
if (talkChores_[i] > -1) {
printf("Running talk chore %d (%d)!\n", i, talkChores_[i], chores_[talkChores_[i]].name_);
chores_[talkChores_[i]].playLooping(); }
printf("Woo\n");
}
}
void Costume::stopTalkChores() {
for (int i=0; i<MAX_TALK_CHORES; i++) {
if ((talkChores_[i] > -1) && (chores_[i].playing_)) {
printf("Stopping talk chore %d!\n", i);
chores_[talkChores_[i]-1].stop();
}
}
}
void Costume::setTalkChore(int index, int chore) {
if (index > MAX_TALK_CHORES)
return;
printf("Setting chore %d(+1) to %d - %s\n", index, chore, chores_[chore].name_);
talkChores_[index-1] = chore;
}
void Costume::setupTextures() {
for (int i = 0; i < numComponents_; i++)
if (components_[i] != NULL)

View file

@ -21,7 +21,6 @@
#include <string>
#include "matrix4.h"
#define MAX_TALK_CHORES 10
class TextSplitter;
class Actor;
@ -41,10 +40,6 @@ public:
int isChoring(int num, bool excludeLooping);
int isChoring(bool excludeLooping);
void playTalkChores();
void stopTalkChores();
void setTalkChore(int index, int chore);
void setHead( int joint1, int joint2, int joint3, float maxRoll, float maxPitch, float maxYaw );
void update();
@ -128,7 +123,6 @@ private:
int numChores_;
Chore *chores_;
int talkChores_[MAX_TALK_CHORES];
Matrix4 matrix_;
};

45
lua.cpp
View file

@ -276,15 +276,46 @@ static void GetActorTalkColor() {
lua_pushusertag(c, color_tag);
}
static void SetActorRestChore() {
Actor *act = check_actor(1);
int chore = check_int(2);
Costume *costume = get_costume(act, 3, "SetActorRestChore");
act->setRestChore(chore, costume);
}
static void SetActorWalkChore() {
Actor *act = check_actor(1);
int chore = check_int(2);
Costume *costume = get_costume(act, 3, "SetActorWalkChore");
act->setWalkChore(chore, costume);
}
static void SetActorTurnChores() {
Actor *act = check_actor(1);
int left_chore = check_int(2);
int right_chore = check_int(3);
Costume *costume = get_costume(act, 4, "SetActorTurnChores");
act->setTurnChores(left_chore, right_chore, costume);
}
static void SetActorTalkChore() {
Actor *act = check_actor(1);
int index = check_int(2);
int chore = check_int(3);
Costume *costume = get_costume(act, 4, "setActorTalkChore");
if (!costume)
return;
costume->setTalkChore(index, chore);
act->setTalkChore(index, chore, costume);
}
static void SetActorMumblechore() {
Actor *act = check_actor(1);
int chore = check_int(2);
Costume *costume = get_costume(act, 3, "SetActorMumblechore");
act->setMumbleChore(chore, costume);
}
static void SetActorVisibility() {
@ -1268,10 +1299,6 @@ static char *stubFuncs[] = {
"SetActorReflection",
"GetActorPuckVector",
"GetActorRect",
"SetActorMumblechore",
"SetActorRestChore",
"SetActorTurnChores",
"SetActorWalkChore",
"GetActorNodeLocation",
"SetActorTimeScale",
"GetActorTimeScale",
@ -1495,7 +1522,11 @@ struct luaL_reg builtins[] = {
{ "IsActorMoving", IsActorMoving },
{ "TurnActor", TurnActor },
{ "PushActorCostume", PushActorCostume },
{ "SetActorRestChore", SetActorRestChore },
{ "SetActorWalkChore", SetActorWalkChore },
{ "SetActorTurnChores", SetActorTurnChores },
{ "SetActorTalkChore", SetActorTalkChore },
{ "SetActorMumblechore", SetActorMumblechore },
{ "SetActorCostume", SetActorCostume },
{ "GetActorCostume", GetActorCostume },
{ "PopActorCostume", PopActorCostume },