diff --git a/Sources/Plasma/FeatureLib/pfPython/cyAvatar.cpp b/Sources/Plasma/FeatureLib/pfPython/cyAvatar.cpp index 94add76f..0708e757 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyAvatar.cpp +++ b/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); } diff --git a/Sources/Plasma/FeatureLib/pfPython/cyAvatar.h b/Sources/Plasma/FeatureLib/pfPython/cyAvatar.h index 2db1369e..e18a4b6c 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyAvatar.h +++ b/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() diff --git a/Sources/Plasma/FeatureLib/pfPython/cyAvatarGlue.cpp b/Sources/Plasma/FeatureLib/pfPython/cyAvatarGlue.cpp index bd7b09e0..8d931036 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyAvatarGlue.cpp +++ b/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 &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); diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp b/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp index 2eff36c6..d7957df1 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp +++ b/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; diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.h b/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.h index eca77155..6ce8b9f4 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.h +++ b/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);