Browse Source

Repeatable emote animations...

... It's multistage majick!
Adam Johnson 11 years ago
parent
commit
f9a72e1a8f
  1. 31
      Sources/Plasma/FeatureLib/pfPython/cyAvatar.cpp
  2. 11
      Sources/Plasma/FeatureLib/pfPython/cyAvatar.h
  3. 22
      Sources/Plasma/FeatureLib/pfPython/cyAvatarGlue.cpp
  4. 44
      Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp
  5. 2
      Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.h

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

@ -1831,35 +1831,10 @@ bool cyAvatar::ExitPBMode()
//
// PURPOSE : Makes the avatar enter a custom anim loop.
//
void cyAvatar::EnterAnimMode(plString animName)
{
plArmatureMod *fAvMod = plAvatarMgr::GetInstance()->GetLocalAvatar();
if (!fAvMod->FindAnimInstance(animName)) {
plKey avKey = fAvMod->GetKey();
plAvAnimTask *animTask = new plAvAnimTask(animName, 0.0, 1.0, 1.0, 0.0, true, true, true);
plAvTaskMsg *taskMsg = new plAvTaskMsg(avKey, avKey, animTask);
taskMsg->SetBCastFlag(plMessage::kNetPropagate);
taskMsg->Send();
}
}
/////////////////////////////////////////////////////////////////////////////
//
// Function : ExitAnimMode
// PARAMETERS : animName - string
//
// PURPOSE : Makes the avatar stop the custom anim loop.
//
void cyAvatar::ExitAnimMode(plString animName)
bool cyAvatar::EnterAnimMode(const plString& animName)
{
plArmatureMod *fAvMod = plAvatarMgr::GetInstance()->GetLocalAvatar();
if (fAvMod->FindAnimInstance(animName)) {
plKey avKey = fAvMod->GetKey();
plAvAnimTask *animTask = new plAvAnimTask(animName, -1.0);
plAvTaskMsg *taskMsg = new plAvTaskMsg(avKey, avKey, animTask);
taskMsg->SetBCastFlag(plMessage::kNetPropagate);
taskMsg->Send();
}
plArmatureMod* fAvMod = plAvatarMgr::GetInstance()->GetLocalAvatar();
return PushRepeatEmote(fAvMod, animName);
}

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

@ -520,17 +520,8 @@ public:
//
// PURPOSE : Makes the avatar enter a custom anim loop.
//
static void EnterAnimMode(plString animName);
static bool EnterAnimMode(const plString& animName);
/////////////////////////////////////////////////////////////////////////////
//
// Function : ExitAnimMode
// PARAMETERS : animName - string
//
// PURPOSE : Makes the avatar stop the custom anim loop.
//
static void ExitAnimMode(plString animName);
/////////////////////////////////////////////////////////////////////////////
//
// Function : GetCurrentMode()

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

@ -801,28 +801,15 @@ PYTHON_GLOBAL_METHOD_DEFINITION_NOARGS(PtAvatarExitAFK, "Tells the local avatar
PYTHON_GLOBAL_METHOD_DEFINITION(PtAvatarEnterAnimMode, args, "Params: animName\nEnter a custom anim loop (netpropagated)")
{
char* animName;
if (!PyArg_ParseTuple(args, "s", &animName))
PyObject* animNameObj;
if (!PyArg_ParseTuple(args, "O", &animNameObj) || !PyString_CheckEx(animNameObj))
{
PyErr_SetString(PyExc_TypeError, "PtAvatarEnterAnimMode expects a string");
PYTHON_RETURN_ERROR;
}
cyAvatar::EnterAnimMode(animName);
PYTHON_RETURN_NONE;
}
PYTHON_GLOBAL_METHOD_DEFINITION(PtAvatarExitAnimMode, args, "Params: animName\nExit a custom anim loop (netpropagated)")
{
char* animName;
if (!PyArg_ParseTuple(args, "s", &animName))
{
PyErr_SetString(PyExc_TypeError, "PtAvatarExitAnimMode expects a string");
PYTHON_RETURN_ERROR;
}
cyAvatar::ExitAnimMode(animName);
PYTHON_RETURN_NONE;
plString animName = PyString_AsStringEx(animNameObj);
PYTHON_RETURN_BOOL(cyAvatar::EnterAnimMode(animName));
}
PYTHON_BASIC_GLOBAL_METHOD_DEFINITION(PtDisableMovementKeys, cyAvatar::DisableMovementControls, "Disable avatar movement input")
@ -919,7 +906,6 @@ void cyAvatar::AddPlasmaMethods(std::vector<PyMethodDef> &methods)
PYTHON_GLOBAL_METHOD_NOARGS(methods, PtAvatarEnterAFK);
PYTHON_GLOBAL_METHOD_NOARGS(methods, PtAvatarExitAFK);
PYTHON_GLOBAL_METHOD(methods, PtAvatarEnterAnimMode);
PYTHON_GLOBAL_METHOD(methods, PtAvatarExitAnimMode);
// Suspend avatar input
PYTHON_BASIC_GLOBAL_METHOD(methods, PtDisableMovementKeys);

44
Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp

@ -1358,13 +1358,11 @@ bool PushWalk::PreCondition(double time, float elapsed)
//
/////////////////////////////////////////////////////////////////////////////////////////
bool PushSimpleMultiStage(plArmatureMod *avatar, const char *enterAnim, const char *idleAnim, const char *exitAnim,
bool netPropagate, bool autoExit, plAGAnim::BodyUsage bodyUsage, plAvBrainGeneric::BrainType type /* = kGeneric */)
static bool CanPushGenericBrain(plArmatureMod* avatar, const char** anims, size_t numAnims, plAvBrainGeneric::BrainType type)
{
plAvBrainHuman *huBrain = plAvBrainHuman::ConvertNoRef(avatar->FindBrainByClass(plAvBrainHuman::Index()));
const char *names[3] = {enterAnim, idleAnim, exitAnim};
if (!huBrain || !huBrain->fWalkingStrategy->IsOnGround() || !huBrain->fWalkingStrategy->HitGroundInThisAge() || huBrain->IsRunningTask() ||
!avatar->IsPhysicsEnabled() || avatar->FindMatchingGenericBrain(names, 3))
!avatar->IsPhysicsEnabled() || avatar->FindMatchingGenericBrain(anims, numAnims))
return false;
// XXX
@ -1375,6 +1373,17 @@ bool PushSimpleMultiStage(plArmatureMod *avatar, const char *enterAnim, const ch
return false;
}
// still here??? W00T!
return true;
}
bool PushSimpleMultiStage(plArmatureMod *avatar, const char *enterAnim, const char *idleAnim, const char *exitAnim,
bool netPropagate, bool autoExit, plAGAnim::BodyUsage bodyUsage, plAvBrainGeneric::BrainType type /* = kGeneric */)
{
const char* names[3] = {enterAnim, idleAnim, exitAnim};
if (!CanPushGenericBrain(avatar, names, arrsize(names), type))
return false;
// if autoExit is true, then we will immediately exit the idle loop when the user hits a move
// key. otherwise, we'll loop until someone sends a message telling us explicitly to advance
plAnimStage::AdvanceType idleAdvance = autoExit ? plAnimStage::kAdvanceOnMove : plAnimStage::kAdvanceNone;
@ -1412,6 +1421,33 @@ bool PushSimpleMultiStage(plArmatureMod *avatar, const char *enterAnim, const ch
return true;
}
bool PushRepeatEmote(plArmatureMod* avatar, const plString& anim)
{
const char* names[1] = { anim.c_str() };
if (!CanPushGenericBrain(avatar, names, arrsize(names), plAvBrainGeneric::kGeneric))
return false;
plAnimStageVec* v = new plAnimStageVec;
plAnimStage* theStage = new plAnimStage(anim, 0,
plAnimStage::kForwardAuto, plAnimStage::kBackNone,
plAnimStage::kAdvanceOnMove, plAnimStage::kRegressNone,
-1);
v->push_back(theStage);
plAvBrainGeneric* b = new plAvBrainGeneric(v, nullptr, nullptr, nullptr, plAvBrainGeneric::kExitAnyTask | plAvBrainGeneric::kExitNewBrain,
2.0f, 2.0f, plAvBrainGeneric::kMoveStandstill);
b->SetBodyUsage(plAGAnim::kBodyFull);
b->SetType(plAvBrainGeneric::kGeneric);
plAvTaskBrain* bt = new plAvTaskBrain(b);
plAvTaskMsg* btm = new plAvTaskMsg(plAvatarMgr::GetInstance()->GetKey(), avatar->GetKey(), bt);
btm->SetBCastFlag(plMessage::kNetPropagate, true);
btm->Send();
return true;
}
bool AvatarEmote(plArmatureMod *avatar, const char *emoteName)
{
bool result = false;

2
Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.h

@ -402,7 +402,7 @@ public:
bool PushSimpleMultiStage(plArmatureMod *avatar, const char *enterAnim, const char *idleAnim,
const char *exitAnim, bool netPropagate, bool autoExit, plAGAnim::BodyUsage bodyUsage,
plAvBrainGeneric::BrainType type = plAvBrainGeneric::kGeneric);
bool PushRepeatEmote(plArmatureMod* avatar, const plString& anim);
bool AvatarEmote(plArmatureMod *avatar, const char *emoteName);

Loading…
Cancel
Save