bool SingleBarkTask::Perform( Subsystem &subsystem ) { if( gameLocal.time < _barkStartTime ) { return false; // waiting for start delay to pass } // This task may not be performed with empty entity pointers idAI *owner = _owner.GetEntity(); assert( owner != NULL ); // If an endtime has been set, the bark is already playing if( _endTime > 0 ) { // Finish the task when the time is over return ( gameLocal.time >= _endTime ); } if( _soundName.IsEmpty() ) { DM_LOG( LC_AI, LT_ERROR )LOGSTRING( "SingleBarkTask has empty soundname, ending task.\r" ); return true; } // No end time set yet, emit our bark // grayman #2169 - no barks while underwater // grayman #3182 - no barks when an idle animation is playing and _allowDuringAnim == false // An idle animation that includes a voice frame command will have set // the wait state to 'idle'. An idle animation that has no voice frame // command will have set the wait state to 'idle_no_voice'. _barkLength = 0; bool canPlay = true; if( ( idStr( owner->WaitState() ) == "idle" ) && !_allowDuringAnim ) { // grayman #3182 canPlay = false; } if( canPlay && !owner->MouthIsUnderwater() ) { // grayman #3182 int msgTag = 0; // grayman #3355 // Push the message and play the sound if( _message != NULL ) { // Setup the message to be propagated, if we have one msgTag = gameLocal.GetNextMessageTag(); // grayman #3355 owner->AddMessage( _message, msgTag ); } owner->GetMind()->GetMemory().currentlyBarking = true; // grayman #3182 - idle anims w/voices cannot start // until this bark is finished _barkLength = owner->PlayAndLipSync( _soundName, "talk1", msgTag ); // grayman #3355 // Sanity check the returned length if( _barkLength == 0 ) { DM_LOG( LC_AI, LT_DEBUG )LOGSTRING( "Received 0 sound length when playing %s.\r", _soundName.c_str() ); } } _barkStartTime = gameLocal.time; _endTime = _barkStartTime + _barkLength; // End the task as soon as we've finished playing the sound return !IsBarking(); }
bool RepeatedBarkTask::Perform(Subsystem& subsystem) { DM_LOG(LC_AI, LT_INFO)LOGSTRING("RepeatedBarkTask performing.\r"); idAI* owner = _owner.GetEntity(); // This task may not be performed with empty entity pointers assert(owner != NULL); // grayman #3182 - when the bark itself is finished, allow idle animations again // Use _prevBarkDone to keep from setting playIdleAnimations over and over and over. if ( !_prevBarkDone && !IsBarking() ) { owner->GetMind()->GetMemory().currentlyBarking = false; _priority = -1; // reset priority _prevBarkDone = true; } if (gameLocal.time >= _nextBarkTime) { // The time has come, bark now // grayman #2169 - no barks while underwater // grayman #3182 - no idle barks while performing an idle animation. // An idle animation that includes a voice frame command will have set // the wait state to 'idle'. An idle animation that has no voice frame // command will have set the wait state to 'idle_no_voice'. if ( !owner->MouthIsUnderwater() && ( idStr(owner->WaitState()) != "idle" ) ) { int msgTag = 0; // grayman #3355 // Setup the message to be propagated, if we have one if (_message != NULL) { msgTag = gameLocal.GetNextMessageTag(); // grayman #3355 owner->AddMessage(_message,msgTag); } owner->GetMind()->GetMemory().currentlyBarking = true; // grayman #3182 - idle anims cannot start // until this bark is finished _prevBarkDone = false; // grayman #3182 _barkLength = owner->PlayAndLipSync(_soundName, "talk1", msgTag); } else { _barkLength = 0; } _barkStartTime = gameLocal.time; // Reset the timer if (_barkRepeatIntervalMax > 0) { _nextBarkTime = static_cast<int>(_barkStartTime + _barkLength + _barkRepeatIntervalMin + gameLocal.random.RandomFloat() * (_barkRepeatIntervalMax - _barkRepeatIntervalMin)); } else { _nextBarkTime = _barkStartTime + _barkLength + _barkRepeatIntervalMin; } } return false; // not finished yet }