// Finish --------------------------------------------------------------------------------------- // ------- void plAvTaskSeek::Finish(plArmatureMod *avatar, plArmatureBrain *brain, double time, float elapsed) { plAvBrainHuman *huBrain = plAvBrainHuman::ConvertNoRef(brain); if(huBrain) { // this will process any queued input messages so if the user pressed or released a key while we were busy, we'll note it now. avatar->ResumeInput(); IUndoLimitPlayersInput(avatar); if (plAvOneShotTask::fForce3rdPerson && avatar->IsLocalAvatar() && (fFlags & plAvSeekMsg::kSeekFlagUnForce3rdPersonOnFinish)) { // create message plCameraMsg* pMsg = new plCameraMsg; pMsg->SetBCastFlag(plMessage::kBCastByExactType); pMsg->SetBCastFlag(plMessage::kNetPropagate, false); pMsg->SetCmd(plCameraMsg::kResponderUndoThirdPerson); plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } avatar->SynchIfLocal(hsTimer::GetSysSeconds(), false); } if (fNotifyFinishedKey) { plAvTaskSeekDoneMsg *msg = new plAvTaskSeekDoneMsg(avatar->GetKey(), fNotifyFinishedKey); msg->fAborted = (fState == kSeekAbort); msg->Send(); } plAvatarMgr::GetInstance()->GetLog()->AddLine("Finished SMART SEEK"); //inform controller we are done seeking if (avatar->GetController()) avatar->GetController()->SetSeek(false); }
void plAvOneShotTask::LeaveAge(plArmatureMod *avatar) { if (fAnimInstance) fAnimInstance->Stop(); if (fEnablePhysicsAtEnd) avatar->EnablePhysics(true); IUndoLimitPlayersInput(avatar); fIgnore = true; }
// PROCESS // Move closer to the goal position and orientation bool plAvSeekTask::Process(plArmatureMod *avatar, plArmatureBrain *brain, double time, float elapsed) { hsQuat rotation; hsPoint3 position; avatar->GetPositionAndRotationSim(&position, &rotation); // We've had a history of odd bugs caused by assuming a rotation quat is normalized. // This line here seems to be fixing one of them. (Avatars scaling oddly when smart seeking.) rotation.Normalize(); double timeToGo = fTargetTime - time - elapsed; // time from *beginning* of this interval to the goal if (fCleanup) { avatar->EnablePhysics( fPhysicalAtStart ); IUndoLimitPlayersInput(avatar); return false; // we're done processing } else if(timeToGo < .01) { fTargetRotation.Normalize(); avatar->SetPositionAndRotationSim(&fTargetPosition, &fTargetRotation); fCleanup = true; // we're going to wait one frame for the transform to propagate return true; // still running until next frame/cleanup } else { hsPoint3 posToGo = fTargetPosition - position; // vec from here to the goal float thisPercentage = (float)(elapsed / timeToGo); hsPoint3 newPosition = position + posToGo * thisPercentage; hsQuat newRotation; newRotation.SetFromSlerp(rotation, fTargetRotation, thisPercentage); newRotation.Normalize(); avatar->SetPositionAndRotationSim(&newPosition, &newRotation); return true; // we're still processing } }
// PROCESS bool plAvOneShotTask::Process(plArmatureMod *avatar, plArmatureBrain *brain, double time, float elapsed) { // *** if we are under mouse control, adjust it here avatar->ApplyAnimations(time, elapsed); if(fAnimInstance) { if(fAnimInstance->IsFinished()) { const plAGAnim * animation = fAnimInstance->GetAnimation(); double endTime = (fBackwards ? animation->GetStart() : animation->GetEnd()); fAnimInstance->SetCurrentTime((float)endTime); avatar->ApplyAnimations(time, elapsed); if(--fWaitFrames == 0) { avatar->DetachAnimation(fAnimInstance); avatar->GetRootAnimator()->Enable(false); plAvBrainHuman *humanBrain = plAvBrainHuman::ConvertNoRef(brain); if(fEnablePhysicsAtEnd) { #if 0//ndef PLASMA_EXTERNAL_RELEASE if (!humanBrain || humanBrain->fWalkingStrategy->HitGroundInThisAge()) { // For some reason, calling CheckValidPosition at the beginning of // an age can cause detectors to incorrectly report collisions. So // we only call this if we're in the age. // // It's only debugging code anyway to help the artist check that // their oneshot doesn't end while penetrating geometry. char *overlaps = nil; if (avatar->GetPhysical()) avatar->GetPhysical()->CheckValidPosition(&overlaps); if (overlaps) { char *buffy = new char[64 + strlen(overlaps)]; sprintf(buffy, "Oneshot ends overlapping %s", overlaps); plConsoleMsg *showLine = new plConsoleMsg( plConsoleMsg::kAddLine, buffy ); showLine->Send(); delete[] overlaps; delete[] buffy; } } #endif } if (humanBrain) humanBrain->ResetIdle(); IUndoLimitPlayersInput(avatar); // this is for a console command hack if (plAvOneShotTask::fForce3rdPerson && avatar->IsLocalAvatar()) { // create message plCameraMsg* pMsg = new plCameraMsg; pMsg->SetBCastFlag(plMessage::kBCastByExactType); pMsg->SetBCastFlag(plMessage::kNetPropagate, false); pMsg->SetCmd(plCameraMsg::kResponderUndoThirdPerson); plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } return false; } else return true; // still running; waiting for fWaitFrames == 0 } else return true; } else return false; }