Browse Source

Implement Co-op animations via Python

Florian Meißner 13 years ago committed by Adam Johnson
parent
commit
69e6381736
  1. 63
      Sources/Plasma/FeatureLib/pfPython/cyAvatar.cpp
  2. 1
      Sources/Plasma/FeatureLib/pfPython/cyAvatar.h
  3. 22
      Sources/Plasma/FeatureLib/pfPython/cyAvatarGlue.cpp

63
Sources/Plasma/FeatureLib/pfPython/cyAvatar.cpp

@ -356,6 +356,69 @@ void cyAvatar::RunBehaviorAndReply(pyKey& behKey, pyKey& replyKey, bool netForce
}
/////////////////////////////////////////////////////////////////////////////
//
// Function : RunCoopAnim
// PARAMETERS : targetKey - target avatar pyKey
// activeAvatarAnim - animation name
// targetAvatarAnim - animation name
// range - how far away are we allowed to be? (default in glue: 6)
// dist - how close shall the avatar move? (default in glue: 3)
// move - shall he move at all? (default in glue: true)
//
// PURPOSE : Seek near another avatar and run animations on both
//
bool cyAvatar::RunCoopAnim(pyKey& targetKey, plString activeAvatarAnim, plString targetAvatarAnim, float range, float dist, bool move)
{
if (fRecvr.Count() > 0 && fRecvr[0]) {
// get the participating avatars
plArmatureMod* activeAv = plAvatarMgr::FindAvatar(fRecvr[0]);
plArmatureMod* targetAv = plAvatarMgr::FindAvatar(targetKey.getKey());
activeAvatarAnim = activeAv->MakeAnimationName(activeAvatarAnim);
targetAvatarAnim = targetAv->MakeAnimationName(targetAvatarAnim);
if (activeAv && targetAv) {
// set seek position and rotation of the avatars
hsPoint3 avPos, targetPos;
activeAv->GetPositionAndRotationSim(&avPos, nullptr);
targetAv->GetPositionAndRotationSim(&targetPos, nullptr);
hsVector3 av2target(&targetPos, &avPos); //targetPos - avPos
if (av2target.Magnitude() > range)
return false;
av2target.Normalize();
if (move)
avPos = targetPos - dist * av2target;
// create the messages and let one task queue the next
const int bcastToNetMods = plMessage::kNetPropagate | plMessage::kNetForce | plMessage::kPropagateToModifiers;
plAvOneShotMsg *avAnim = new plAvOneShotMsg(nullptr, fRecvr[0], fRecvr[0], 0.f, true, activeAvatarAnim, false, false);
avAnim->SetBCastFlag(bcastToNetMods);
plAvOneShotMsg *targetAnim = new plAvOneShotMsg(nullptr, targetKey.getKey(), targetKey.getKey(), 0.f, true, targetAvatarAnim, false, false);
targetAnim->SetBCastFlag(bcastToNetMods);
targetAnim->fFinishMsg = avAnim;
plAvSeekMsg *targetSeek = new plAvSeekMsg(nullptr, targetKey.getKey(), nullptr, 0.f, true);
targetSeek->SetBCastFlag(bcastToNetMods);
targetSeek->fTargetPos = targetPos;
targetSeek->fTargetLookAt = avPos;
targetSeek->fFinishMsg = targetAnim;
plAvSeekMsg *avSeek = new plAvSeekMsg(nullptr, fRecvr[0], nullptr, 0.f, true);
avSeek->SetBCastFlag(bcastToNetMods);
avSeek->fTargetPos = avPos;
avSeek->fTargetLookAt = targetPos;
avSeek->fFinishMsg = targetSeek;
// start the circus, messages are processed "backwards"
avSeek->Send();
return true;
}
}
return false;
}
/////////////////////////////////////////////////////////////////////////////
//
// Function : NextStage

1
Sources/Plasma/FeatureLib/pfPython/cyAvatar.h

@ -105,6 +105,7 @@ public:
// oneShot Avatar
virtual void RunBehavior(pyKey &behKey, bool netForce, bool netProp);
virtual void RunBehaviorAndReply(pyKey& behKey, pyKey& replyKey, bool netForce, bool netProp);
virtual bool RunCoopAnim(pyKey& targetKey, plString activeAvatarAnim, plString targetAvatarAnim, float range, float dist, bool move);
// for the multistage behaviors
virtual void NextStage(pyKey &behKey, float transTime, bool setTime, float newTime,

22
Sources/Plasma/FeatureLib/pfPython/cyAvatarGlue.cpp

@ -139,6 +139,27 @@ PYTHON_METHOD_DEFINITION(ptAvatar, runBehaviorSetNotify, args)
PYTHON_RETURN_NONE;
}
PYTHON_METHOD_DEFINITION(ptAvatar, runCoopAnim, args)
{
PyObject* keyObj;
PyObject* animAv1;
PyObject* animAv2;
float range = 6;
float dist = 3;
bool move = true;
if (!PyArg_ParseTuple(args, "OOO|ffb", &keyObj, &animAv1, &animAv2, &range, &dist, &move) || !pyKey::Check(keyObj) ||
!PyString_CheckEx(animAv1) || !PyString_CheckEx(animAv2))
{
PyErr_SetString(PyExc_TypeError, "runCoopAnim expects a ptkey and two strings and an optional float and boolean");
PYTHON_RETURN_ERROR;
}
pyKey* key = pyKey::ConvertFrom(keyObj);
const plString& animName1 = PyString_AsStringEx(animAv1);
const plString& animName2 = PyString_AsStringEx(animAv2);
PYTHON_RETURN_BOOL(self->fThis->RunCoopAnim(*key, animName1, animName2, range, dist, move));
}
PYTHON_METHOD_DEFINITION(ptAvatar, nextStage, args)
{
PyObject* keyObj = NULL;
@ -629,6 +650,7 @@ PYTHON_START_METHODS_TABLE(ptAvatar)
PYTHON_METHOD(ptAvatar, oneShot, "Params: seekKey,duration,usePhysicsFlag,animationName,drivableFlag,reversibleFlag\nPlays a one-shot animation on the avatar"),
PYTHON_METHOD(ptAvatar, runBehavior, "Params: behaviorKey,netForceFlag\nRuns a behavior on the avatar. Can be a single or multi-stage behavior."),
PYTHON_METHOD(ptAvatar, runBehaviorSetNotify, "Params: behaviorKey,replyKey,netForceFlag\nSame as runBehavior, except send notifications to specified keyed object"),
PYTHON_METHOD(ptAvatar, runCoopAnim, "Params: targetKey,activeAvatarAnim,targetAvatarAnim,dist,move\nSeek near another avatar and run animations on both."),
PYTHON_METHOD(ptAvatar, nextStage, "Params: behaviorKey,transitionTime,setTimeFlag,newTime,SetDirectionFlag,isForward,netForce\nTells a multistage behavior to go to the next stage (Why does Matt like so many parameters?)"),
PYTHON_METHOD(ptAvatar, previousStage, "Params: behaviorKey,transitionTime,setTimeFlag,newTime,SetDirectionFlag,isForward,netForce\nTells a multistage behavior to go to the previous stage"),
PYTHON_METHOD(ptAvatar, gotoStage, "Params: behaviorKey,stage,transitionTime,setTimeFlag,newTime,SetDirectionFlag,isForward,netForce\nTells a multistage behavior to go to a particular stage"),

Loading…
Cancel
Save