mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-26 04:35:16 +00:00
EMI: Add attaching functionality to actors
This commit is contained in:
parent
155b7027ce
commit
34a0a1a82c
@ -45,6 +45,10 @@
|
||||
#include "engines/grim/gfx_base.h"
|
||||
#include "engines/grim/model.h"
|
||||
|
||||
#include "engines/grim/emi/costumeemi.h"
|
||||
#include "engines/grim/emi/skeleton.h"
|
||||
#include "engines/grim/emi/costume/emiskel_component.h"
|
||||
|
||||
#include "common/foreach.h"
|
||||
|
||||
namespace Grim {
|
||||
@ -73,7 +77,7 @@ Actor::Actor(const Common::String &actorName) :
|
||||
_visible(true), _lipSync(NULL), _turning(false), _walking(false),
|
||||
_walkedLast(false), _walkedCur(false),
|
||||
_lastTurnDir(0), _currTurnDir(0),
|
||||
_sayLineText(0) {
|
||||
_sayLineText(0), _attachedActor(NULL), _attachedJoint("") {
|
||||
_lookingMode = false;
|
||||
_constrain = false;
|
||||
_talkSoundName = "";
|
||||
@ -107,6 +111,9 @@ Actor::Actor() :
|
||||
_collisionMode = CollisionOff;
|
||||
_collisionScale = 1.f;
|
||||
|
||||
_attachedActor = NULL;
|
||||
_attachedJoint = "";
|
||||
|
||||
for (int i = 0; i < MAX_SHADOWS; i++) {
|
||||
_shadowArray[i].active = false;
|
||||
_shadowArray[i].dontNegate = false;
|
||||
@ -1636,6 +1643,33 @@ void Actor::collisionHandlerCallback(Actor *other) const {
|
||||
LuaBase::instance()->callback("collisionHandler", objects);
|
||||
}
|
||||
|
||||
void Actor::attachToActor(Actor *other, const char *joint) {
|
||||
assert(other != NULL);
|
||||
if (other == _attachedActor)
|
||||
return;
|
||||
if (_attachedActor != NULL)
|
||||
detach();
|
||||
|
||||
EMICostume * cost = dynamic_cast<EMICostume *>(other->getCurrentCostume());
|
||||
assert(cost != NULL);
|
||||
|
||||
Common::String jointStr = joint ? joint : "";
|
||||
// If 'other' has a skeleton, check if it has the joint.
|
||||
// Some models (pile o' boulders) don't have a skeleton,
|
||||
// so we don't make the check in that case.
|
||||
if (cost->_emiSkel && cost->_emiSkel->_obj)
|
||||
assert(cost->_emiSkel->_obj->hasJoint(jointStr));
|
||||
|
||||
_attachedActor = other;
|
||||
_attachedJoint = jointStr;
|
||||
}
|
||||
|
||||
void Actor::detach() {
|
||||
if (_attachedActor != NULL) {
|
||||
_attachedJoint = "";
|
||||
_attachedActor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned const int Actor::Chore::fadeTime = 150;
|
||||
|
||||
|
@ -37,6 +37,7 @@ class Costume;
|
||||
class LipSync;
|
||||
class Font;
|
||||
class Set;
|
||||
class Joint;
|
||||
|
||||
struct Plane {
|
||||
Common::String setName;
|
||||
@ -455,6 +456,8 @@ public:
|
||||
|
||||
static void saveStaticState(SaveGame *state);
|
||||
static void restoreStaticState(SaveGame *state);
|
||||
void attachToActor(Actor *other, const char *joint);
|
||||
void detach();
|
||||
|
||||
private:
|
||||
void costumeMarkerCallback(int marker);
|
||||
@ -581,6 +584,8 @@ private:
|
||||
bool _puckOrient;
|
||||
|
||||
static bool _isTalkingBackground;
|
||||
Actor *_attachedActor;
|
||||
Common::String _attachedJoint;
|
||||
|
||||
friend class GrimEngine;
|
||||
};
|
||||
|
@ -712,7 +712,7 @@ void Lua_V2::AttachActor() {
|
||||
// Missing lua parts
|
||||
lua_Object attachedObj = lua_getparam(1);
|
||||
lua_Object actorObj = lua_getparam(2);
|
||||
lua_Object targetObj = lua_getparam(3);
|
||||
lua_Object jointObj = lua_getparam(3);
|
||||
|
||||
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
||||
return;
|
||||
@ -728,22 +728,13 @@ void Lua_V2::AttachActor() {
|
||||
if (!attached)
|
||||
return;
|
||||
|
||||
const char * target = NULL;
|
||||
if (!lua_isnil(targetObj)) {
|
||||
target = lua_getstring(targetObj);
|
||||
const char * joint = NULL;
|
||||
if (!lua_isnil(jointObj)) {
|
||||
joint = lua_getstring(jointObj);
|
||||
}
|
||||
|
||||
bool hasJoint = true;
|
||||
if (target != NULL) {
|
||||
EMICostume * cost = dynamic_cast<EMICostume *>(actor->getCurrentCostume());
|
||||
EMISkelComponent * skelc = cost->_emiSkel;
|
||||
if (!skelc) goto blah;
|
||||
Skeleton * skel = skelc->_obj;
|
||||
if (!skel) goto blah;
|
||||
hasJoint = skel->hasJoint(target);
|
||||
}
|
||||
blah:
|
||||
warning("Lua_V2::AttachActor: attaching %s to %s (on %s) joint %s", attached->getName().c_str(), actor->getName().c_str(), target ? target : "(none)", hasJoint ? "FOUND" : "NOT FOUND");
|
||||
attached->attachToActor(actor, joint);
|
||||
warning("Lua_V2::AttachActor: attaching %s to %s (on %s)", attached->getName().c_str(), actor->getName().c_str(), joint ? joint : "(none)");
|
||||
}
|
||||
|
||||
void Lua_V2::DetachActor() {
|
||||
@ -758,6 +749,7 @@ void Lua_V2::DetachActor() {
|
||||
return;
|
||||
|
||||
warning("Lua_V2::DetachActor: detaching %s from parent actor", attached->getName().c_str());
|
||||
attached->detach();
|
||||
}
|
||||
|
||||
} // end of namespace Grim
|
||||
|
@ -114,10 +114,10 @@ void Skeleton::setAnim(AnimationEmi *anim) {
|
||||
resetAnim();
|
||||
}
|
||||
|
||||
int Skeleton::findJointIndex(Common::String name, int max) {
|
||||
int Skeleton::findJointIndex(const Common::String & name, int max) const {
|
||||
if (_numJoints > 0) {
|
||||
for (int i = 0; i < max; i++) {
|
||||
if (_joints[i]._name == name) {
|
||||
for(int i = 0; i < max; i++) {
|
||||
if(!_joints[i]._name.compareToIgnoreCase(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@ -213,4 +213,16 @@ void Skeleton::animate(float delta) {
|
||||
} // end for
|
||||
}
|
||||
|
||||
bool Skeleton::hasJoint(const Common::String & name) const {
|
||||
return name.empty() || findJointIndex(name, _numJoints) >= 0;
|
||||
}
|
||||
|
||||
Joint * Skeleton::getJointNamed(const Common::String & name) const {
|
||||
if (name.empty()) {
|
||||
return & _joints[0];
|
||||
} else {
|
||||
return & _joints[findJointIndex(name, _numJoints)];
|
||||
}
|
||||
}
|
||||
|
||||
} // end of namespace Grim
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "math/mathfwd.h"
|
||||
#include "math/quat.h"
|
||||
#include "engines/grim/object.h"
|
||||
#include "engines/grim/actor.h"
|
||||
|
||||
namespace Common {
|
||||
class SeekableReadStream;
|
||||
@ -63,8 +64,9 @@ public:
|
||||
void resetAnim();
|
||||
void setAnim(AnimationEmi *anim);
|
||||
void animate(float time);
|
||||
int findJointIndex(Common::String name, int max);
|
||||
bool hasJoint(const Common::String & name) { return findJointIndex(name, _numJoints) >= 0; }
|
||||
int findJointIndex(const Common::String & name, int max) const;
|
||||
bool hasJoint(const Common::String & name) const;
|
||||
Joint * getJointNamed(const Common::String & name) const;
|
||||
float _time;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user