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:
parent
d321764e39
commit
5ec54ab780
6 changed files with 188 additions and 67 deletions
2
TODO
2
TODO
|
@ -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
141
actor.cpp
|
@ -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
32
actor.h
|
@ -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_;
|
||||
|
|
29
costume.cpp
29
costume.cpp
|
@ -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)
|
||||
|
|
|
@ -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
45
lua.cpp
|
@ -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 },
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue